Skip to content

Commit

Permalink
fix cluster claim update
Browse files Browse the repository at this point in the history
  • Loading branch information
vramk23 committed Nov 25, 2023
1 parent f79d74d commit 5ee288e
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 111 deletions.
22 changes: 9 additions & 13 deletions capten/agent/internal/crossplane/cluster_claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import (
)

var (
readyStatusType = "ready"
nodePoolStatusType = "nodepool"
controlPlaneStatusType = "controlplane"
readyStatusType = "ready"

clusterNotReadyStatus = "NotReady"
clusterReadyStatus = "Ready"
Expand Down Expand Up @@ -167,10 +165,12 @@ func (h *ClusterClaimSyncHandler) updateManagedClusters(clusterCliams []model.Cl

for _, clusterCliam := range clusterCliams {
h.log.Infof("processing cluster claim %s", clusterCliam.Metadata.Name)
nodePoolStatus, controlPlaneStatus, readyStatus := getClusterClaimStatus(clusterCliam.Status.Conditions)
h.log.Infof("cluster claim %s status: %s-%s-%s", clusterCliam.Metadata.Name, nodePoolStatus, controlPlaneStatus, readyStatus)
readyStatus := h.getClusterClaimStatus(clusterCliam.Status.Conditions)
h.log.Infof("cluster claim %s status: %s-%s-%s", clusterCliam.Metadata.Name,
clusterCliam.Status.NodePoolStatus, clusterCliam.Status.ControlPlaneStatus, readyStatus)

if !(strings.EqualFold(nodePoolStatus, "active") && strings.EqualFold(controlPlaneStatus, "active")) {
if !(strings.EqualFold(clusterCliam.Status.NodePoolStatus, "active") &&
strings.EqualFold(clusterCliam.Status.ControlPlaneStatus, "active")) {
h.log.Infof("cluster %s is not created", clusterCliam.Metadata.Name)
return nil
}
Expand Down Expand Up @@ -221,7 +221,6 @@ func (h *ClusterClaimSyncHandler) updateManagedClusters(clusterCliams []model.Cl
h.log.Infof("updated the cluster claim %s with status %s", managedCluster.ClusterName, managedCluster.ClusterDeployStatus)

if managedCluster.ClusterDeployStatus == clusterReadyStatus {
// call config-worker.
err = h.triggerClusterUpdates(clusterCliam.Spec.Id, managedCluster.Id)
if err != nil {
h.log.Info("failed to trigger cluster update workflow, %v", err)
Expand Down Expand Up @@ -252,21 +251,18 @@ func (h *ClusterClaimSyncHandler) triggerClusterUpdates(clusterName, managedClus
return err
}

ci := model.CrossplaneClusterUpdate{RepoURL: proj.GitProjectUrl, GitProjectId: proj.GitProjectId, Name: clusterName, ManagedClusterId: managedClusterID}
ci := model.CrossplaneClusterUpdate{RepoURL: proj.GitProjectUrl, GitProjectId: proj.GitProjectId,
ManagedClusterName: clusterName, ManagedClusterId: managedClusterID}
wd := workers.NewConfig(h.tc, h.log)
_, err = wd.SendEvent(context.TODO(), &model.ConfigureParameters{Resource: model.CrossPlaneResource, Action: model.CrossPlaneClusterUpdate}, ci)
return err
}

func getClusterClaimStatus(conditions []model.ClusterClaimCondition) (nodePoolStatus, controlPlaneStatus, readyStatus string) {
func (h *ClusterClaimSyncHandler) getClusterClaimStatus(conditions []model.ClusterClaimCondition) (readyStatus string) {
for _, condition := range conditions {
switch strings.ToLower(condition.Type) {
case readyStatusType:
readyStatus = condition.Status
case nodePoolStatusType:
nodePoolStatus = condition.Status
case controlPlaneStatusType:
controlPlaneStatus = condition.Status
}
}
return
Expand Down
56 changes: 13 additions & 43 deletions capten/common-pkg/plugins/argocd/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ package argocd

import (
"context"
"encoding/base64"
"fmt"
"strings"

"github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/io"
"gopkg.in/yaml.v2"
"k8s.io/client-go/tools/clientcmd"
k8sapi "k8s.io/client-go/tools/clientcmd/api"
)

Expand All @@ -18,29 +17,17 @@ const (
CredIdentifier = "kubeconfig"
)

func parseKubeconfigString(kubeconfigString string) (*k8sapi.Config, error) {
config := &k8sapi.Config{}
err := yaml.Unmarshal([]byte(kubeconfigString), config)
if err != nil {
return nil, err
}
return config, nil
}

func (a *ArgoCDClient) CreateOrUpdateCluster(ctx context.Context, clusterName, kubeconfigData string) error {
kubeConfig, err := parseKubeconfigString(kubeconfigData)
a.logger.Infof("Cluster create or update request for cluster %s", clusterName)
kubeConfig, err := clientcmd.Load([]byte(kubeconfigData))
if err != nil {
return err
return fmt.Errorf("kubeconfig parse failed, %v", err)
}

clusterData, ok := kubeConfig.Clusters[clusterName]
if !ok {
return fmt.Errorf("cluster %s not found in kubeconfig", clusterName)
}
caData, err := base64.StdEncoding.DecodeString(string(clusterData.CertificateAuthorityData))
if err != nil {
return err
}

var clusterCAuthInfo *k8sapi.AuthInfo
for _, authInfo := range kubeConfig.AuthInfos {
Expand All @@ -52,23 +39,6 @@ func (a *ArgoCDClient) CreateOrUpdateCluster(ctx context.Context, clusterName, k
return fmt.Errorf("auth info not found for cluster")
}

var clientCertData []byte
if len(clusterCAuthInfo.ClientCertificateData) != 0 {
clientCertData, err = base64.StdEncoding.DecodeString(string(clusterCAuthInfo.ClientCertificateData))
if err != nil {
return err
}
}

a.logger.Infof("Cluster create or update request for cluster %s", clusterName)
var clientKeyData []byte
if len(clusterCAuthInfo.ClientKeyData) != 0 {
clientKeyData, err = base64.StdEncoding.DecodeString(string(clusterCAuthInfo.ClientKeyData))
if err != nil {
return err
}
}

conn, appClient, err := a.client.NewClusterClient()
if err != nil {
return fmt.Errorf("failed to create argocd cluster client, %v", err)
Expand All @@ -85,16 +55,16 @@ func (a *ArgoCDClient) CreateOrUpdateCluster(ctx context.Context, clusterName, k
Username: clusterCAuthInfo.Username,
Password: clusterCAuthInfo.Password,
TLSClientConfig: v1alpha1.TLSClientConfig{
ServerName: clusterData.Server,
CAData: caData,
CertData: clientCertData,
KeyData: clientKeyData,
ServerName: "kubernetes",
CAData: clusterData.CertificateAuthorityData,
CertData: clusterCAuthInfo.ClientCertificateData,
KeyData: clusterCAuthInfo.ClientKeyData,
},
},
},
})
if err != nil {
if strings.Contains(err.Error(), "already exists") {
if strings.Contains(err.Error(), "already exists") || strings.Contains(err.Error(), "use upsert flag to force update") {
update = true
}
return fmt.Errorf("failed to create cluster %s, %v", clusterName, err)
Expand All @@ -110,10 +80,10 @@ func (a *ArgoCDClient) CreateOrUpdateCluster(ctx context.Context, clusterName, k
Username: clusterCAuthInfo.Username,
Password: clusterCAuthInfo.Password,
TLSClientConfig: v1alpha1.TLSClientConfig{
ServerName: clusterData.Server,
CAData: caData,
CertData: clientCertData,
KeyData: clientKeyData,
ServerName: "kubernetes",
CAData: clusterData.CertificateAuthorityData,
CertData: clusterCAuthInfo.ClientCertificateData,
KeyData: clusterCAuthInfo.ClientKeyData,
},
},
},
Expand Down
71 changes: 46 additions & 25 deletions capten/config-worker/internal/crossplane/config_cluster_updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func getAppNameNamespace(ctx context.Context, fileName string) (string, string,

func (cp *CrossPlaneApp) configureClusterUpdate(ctx context.Context, req *model.CrossplaneClusterUpdate) (status string, err error) {
logger.Infof("configuring the cluster endpoint for %s", req.RepoURL)
endpoint, err := cp.helper.CreateCluster(ctx, req.ManagedClusterId, req.Name)
endpoint, err := cp.helper.CreateCluster(ctx, req.ManagedClusterId, req.ManagedClusterName)
if err != nil {
return string(agentmodel.WorkFlowStatusFailed), errors.WithMessage(err, "failed to CreateCluster in argocd app")
}
Expand All @@ -64,9 +64,8 @@ func (cp *CrossPlaneApp) configureClusterUpdate(ctx context.Context, req *model.
defer os.RemoveAll(templateRepo)
defer os.RemoveAll(customerRepo)

fileName := filepath.Join(customerRepo, cp.pluginConfig.ClusterEndpointUpdates.File)
// replace cluster endpoint
err = updateClusterEndpointDetials(fileName, req.Name, endpoint, cp.cfg.ClusterDefaultAppsFile)
clusterValuesFile := filepath.Join(customerRepo, cp.pluginConfig.ClusterEndpointUpdates.ClusterValuesFile)
err = updateClusterEndpointDetials(clusterValuesFile, req.ManagedClusterName, endpoint, cp.cfg.ClusterDefaultAppsFile)
if err != nil {
return string(agentmodel.WorkFlowStatusFailed), errors.WithMessage(err, "failed to replace the file")
}
Expand Down Expand Up @@ -96,8 +95,8 @@ func (cp *CrossPlaneApp) configureClusterUpdate(ctx context.Context, req *model.
return string(agentmodel.WorkFlowStatusCompleted), nil
}

func updateClusterEndpointDetials(filename, clusterName, clusterEndpoint, defaultAppFile string) error {
data, err := os.ReadFile(filename)
func updateClusterEndpointDetials(valuesFileName, clusterName, clusterEndpoint, defaultAppFile string) error {
data, err := os.ReadFile(valuesFileName)
if err != nil {
return err
}
Expand All @@ -108,35 +107,31 @@ func updateClusterEndpointDetials(filename, clusterName, clusterEndpoint, defaul
}

var argoCDAppValue ArgoCDAppValue

err = json.Unmarshal(jsonData, &argoCDAppValue)
if err != nil {
return err
}

defaultApps, err := readClusterDefaultApps(defaultAppFile)
if err != nil {
return err
}

var found bool
clusters := *argoCDAppValue.Clusters
for index := range clusters {
cluster := &clusters[index]
if cluster.Name == clusterName {
defaultApps, err := readClusterDefaultApps(defaultAppFile)
if err != nil {
return err
}

for index := range defaultApps {
localObj := &defaultApps[index]
strings.ReplaceAll(localObj.ValuesPath, clusterNameSub, clusterName)
}

logger.Infof("udpated the req endpoint details to %s for name %s ", clusterEndpoint, clusterName)
cluster.Server = clusterEndpoint

if clusters[index].Name == clusterName {
clusters[index] = prepareClusterData(clusterName, clusterEndpoint, defaultApps)
found = true
break
}
}

argoCDAppValue.Clusters = &clusters
if !found {
clusters = append(clusters, prepareClusterData(clusterName, clusterEndpoint, defaultApps))
}

argoCDAppValue.Clusters = &clusters
jsonBytes, err := json.Marshal(argoCDAppValue)
if err != nil {
return err
Expand All @@ -147,7 +142,33 @@ func updateClusterEndpointDetials(filename, clusterName, clusterEndpoint, defaul
return err
}

err = os.WriteFile(filename, yamlBytes, os.ModeAppend)

err = os.WriteFile(valuesFileName, yamlBytes, os.ModeAppend)
return err
}

func prepareClusterData(clusterName, endpoint string, defaultApps []DefaultApps) Cluster {
for index := range defaultApps {
localObj := &defaultApps[index]
strings.ReplaceAll(localObj.ValuesPath, clusterNameSub, clusterName)
}

return Cluster{
Name: clusterName,
Server: endpoint,
DefApps: defaultApps,
}
}

func readClusterDefaultApps(clusterDefaultApp string) ([]DefaultApps, error) {
data, err := os.ReadFile(filepath.Clean(clusterDefaultApp))
if err != nil {
return nil, fmt.Errorf("failed to read clusterDefaultApp File: %s, err: %w", clusterDefaultApp, err)
}

var defaultApps []DefaultApps
err = json.Unmarshal(data, &defaultApps)
if err != nil {
return nil, fmt.Errorf("%w", err)
}
return defaultApps, nil
}
14 changes: 0 additions & 14 deletions capten/config-worker/internal/crossplane/config_crossplane_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,6 @@ func readCrossPlanePluginConfig(pluginFile string) (*crossplanePluginConfig, err
return &pluginData, nil
}

func readClusterDefaultApps(clusterDefaultApp string) ([]DefaultApps, error) {
data, err := os.ReadFile(filepath.Clean(clusterDefaultApp))
if err != nil {
return nil, fmt.Errorf("failed to read clusterDefaultApp File: %s, err: %w", clusterDefaultApp, err)
}

var defaultApps []DefaultApps
err = json.Unmarshal(data, &defaultApps)
if err != nil {
return nil, fmt.Errorf("%w", err)
}
return defaultApps, nil
}

func (cp *CrossPlaneApp) configureProjectAndApps(ctx context.Context, req *model.CrossplaneUseCase) (status string, err error) {
accessToken, err := cp.helper.GetAccessToken(ctx, req.VaultCredIdentifier)
if err != nil {
Expand Down
18 changes: 9 additions & 9 deletions capten/config-worker/internal/crossplane/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ type appConfig struct {
SynchApp bool `json:"synchApp"`
}

type clusterConfig struct {
MainAppGitPath string `json:"mainAppGitPath"`
File string `json:"file"`
type clusterUpdateConfig struct {
MainAppGitPath string `json:"mainAppGitPath"`
ClusterValuesFile string `json:"clusterValuesFile"`
}

type crossplanePluginConfig struct {
TemplateGitRepo string `json:"templateGitRepo"`
CrossplaneConfigSyncPath string `json:"crossplaneConfigSyncPath"`
ProviderConfigSyncPath string `json:"providerConfigSyncPath"`
ProviderPackages map[string]string `json:"providerPackages"`
ArgoCDApps []appConfig `json:"argoCDApps"`
ClusterEndpointUpdates clusterConfig `json:"clusterEndpointUpdates"`
TemplateGitRepo string `json:"templateGitRepo"`
CrossplaneConfigSyncPath string `json:"crossplaneConfigSyncPath"`
ProviderConfigSyncPath string `json:"providerConfigSyncPath"`
ProviderPackages map[string]string `json:"providerPackages"`
ArgoCDApps []appConfig `json:"argoCDApps"`
ClusterEndpointUpdates clusterUpdateConfig `json:"clusterUpdateConfig"`
}

const (
Expand Down
8 changes: 4 additions & 4 deletions capten/model/config_workflow_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ type CrossplaneUseCase struct {
}

type CrossplaneClusterUpdate struct {
Name string `json:"name,omitempty"`
GitProjectId string `json:"gitProjectId,omitempty"`
ManagedClusterId string `json:"managedClusterId,omitempty"`
RepoURL string `json:"repoURL,omitempty"`
ManagedClusterName string `json:"managedClusterName,omitempty"`
ManagedClusterId string `json:"managedClusterId,omitempty"`
GitProjectId string `json:"gitProjectId,omitempty"`
RepoURL string `json:"repoURL,omitempty"`
}
4 changes: 3 additions & 1 deletion capten/model/crossplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ type ClusterClaimCondition struct {
}

type ClusterClaimStatus struct {
Conditions []ClusterClaimCondition `json:"conditions,omitempty" protobuf:"bytes,1,opt,name=conditions"`
Conditions []ClusterClaimCondition `json:"conditions,omitempty" protobuf:"bytes,1,opt,name=conditions"`
ControlPlaneStatus string `json:"controlPlaneStatus,omitempty"`
NodePoolStatus string `json:"nodePoolStatus,omitempty"`
}

type ClusterClaim struct {
Expand Down
4 changes: 2 additions & 2 deletions charts/kad/crossplane_plugin_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
"aws": "xpkg.upbound.io/crossplane-contrib/provider-aws:v0.33.0",
"gcp": "xpkg.upbound.io/crossplane-contrib/provider-gcp:v0.22.0"
},
"clusterEndpointUpdates":{
"clusterUpdateConfig":{
"mainAppGitPath": "infra/crossplane/crossplane-main-app.yaml",
"file": "infra/clusters/argocd-apps/values.yaml"
"clusterValuesFile": "infra/clusters/argocd-apps/values.yaml"
},
"argoCDApps": [
{
Expand Down

0 comments on commit 5ee288e

Please sign in to comment.