Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions cmd/agent/cluster_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package agent

import (
"encoding/json"
"fmt"
"log"
"os/exec"
)

// AgentClusterConfig holds the configuration retrieved from the cluster
type AgentClusterConfig struct {
Token string
ClusterName string
APIURL string
}

// getAgentConfigFromCluster attempts to retrieve the agent configuration from the running cluster.
// It checks for the 'pipeops-agent-config' secret in the 'pipeops-system' namespace.
func getAgentConfigFromCluster() (*AgentClusterConfig, error) {
// Check if kubectl is available
if _, err := exec.LookPath("kubectl"); err != nil {
return nil, fmt.Errorf("kubectl not found")
}

// 1. Get the secret in JSON format
// kubectl get secret pipeops-agent-config -n pipeops-system -o json
cmd := exec.Command("kubectl", "get", "secret", "pipeops-agent-config", "-n", "pipeops-system", "-o", "json")
output, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("failed to get pipeops-agent-config secret: %w", err)
}

// 2. Parse the secret
var secret struct {
Data map[string][]byte `json:"data"`
}
if err := json.Unmarshal(output, &secret); err != nil {
return nil, fmt.Errorf("failed to parse secret json: %w", err)
}

config := &AgentClusterConfig{}

// 3. Extract and decode values
if tokenData, ok := secret.Data["PIPEOPS_TOKEN"]; ok {
config.Token = string(tokenData)
} else if tokenData, ok := secret.Data["AGENT_TOKEN"]; ok { // Fallback for older versions
config.Token = string(tokenData)
}

if clusterNameData, ok := secret.Data["PIPEOPS_CLUSTER_NAME"]; ok {
config.ClusterName = string(clusterNameData)
} else if clusterNameData, ok := secret.Data["CLUSTER_NAME"]; ok { // Fallback
config.ClusterName = string(clusterNameData)
}

if apiURLData, ok := secret.Data["PIPEOPS_API_URL"]; ok {
config.APIURL = string(apiURLData)
}

if config.Token == "" {
return nil, fmt.Errorf("token not found in secret")
}

log.Println("[INFO] Detected existing PipeOps agent configuration in cluster")
return config, nil
}
26 changes: 26 additions & 0 deletions cmd/agent/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,21 @@ Examples:
if clusterName == "" {
clusterName = os.Getenv("CLUSTER_NAME")
}

// Try to auto-detect existing configuration if token or cluster name is missing
if token == "" || clusterName == "" {
if existingConfig, err := getAgentConfigFromCluster(); err == nil {
if token == "" {
token = existingConfig.Token
log.Println("[INFO] Using token from existing cluster configuration")
}
if clusterName == "" {
clusterName = existingConfig.ClusterName
log.Printf("[INFO] Using cluster name '%s' from existing configuration", clusterName)
}
}
}

if clusterName == "" {
clusterName = "pipeops-cluster"
}
Expand Down Expand Up @@ -141,6 +156,11 @@ Examples:
return nil
}

// Check for existing agent configuration in the cluster
if _, err := getAgentConfigFromCluster(); err == nil {
return nil
}

return fmt.Errorf("Error: PipeOps token is required. Provide token as argument: 'pipeops agent install <token>' or set PIPEOPS_TOKEN environment variable")
}
return nil
Expand Down Expand Up @@ -216,6 +236,12 @@ func installNewCluster(cmd *cobra.Command, token, clusterName, clusterType strin
func installOnExistingCluster(cmd *cobra.Command, token, clusterName string, enableMonitoring bool) {
log.Println("Installing PipeOps agent on existing cluster...")

if token == "" {
if existingConfig, err := getAgentConfigFromCluster(); err == nil {
token = existingConfig.Token
}
}

if token == "" {
log.Fatalf("Error: PipeOps token is required. Please provide it as an argument or set PIPEOPS_TOKEN environment variable.")
}
Expand Down
23 changes: 19 additions & 4 deletions cmd/agent/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,30 @@ var updateCmd = &cobra.Command{
Long: `The "update" command updates the PipeOps agent installed on your Kubernetes cluster to the latest available version.`,
Run: func(cmd *cobra.Command, args []string) {
token := getPipeOpsToken(cmd, args)
if token == "" {
log.Fatalf("Error: PipeOps token is required. Please login or set PIPEOPS_TOKEN environment variable.")
}

clusterName, _ := cmd.Flags().GetString("cluster-name")
if clusterName == "" {
clusterName = os.Getenv("CLUSTER_NAME")
}

// Try to auto-detect existing configuration if token or cluster name is missing
if token == "" || clusterName == "" {
if existingConfig, err := getAgentConfigFromCluster(); err == nil {
if token == "" {
token = existingConfig.Token
log.Println("[INFO] Using token from existing cluster configuration")
}
if clusterName == "" {
clusterName = existingConfig.ClusterName
log.Printf("[INFO] Using cluster name '%s' from existing configuration", clusterName)
}
}
}

if token == "" {
log.Fatalf("Error: PipeOps token is required. Please login or set PIPEOPS_TOKEN environment variable.")
}

clusterType, _ := cmd.Flags().GetString("cluster-type")
if clusterType == "" {
clusterType = os.Getenv("CLUSTER_TYPE")
Expand All @@ -38,7 +53,7 @@ var updateCmd = &cobra.Command{
if err != nil {
log.Fatalf("Error: %v", err)
}

envVars := []string{
fmt.Sprintf("PIPEOPS_TOKEN=%s", token),
"UPDATE=true",
Expand Down