From 94b54d4960bae2e840759bd24be3f9ac89f15131 Mon Sep 17 00:00:00 2001 From: Venkatreddy KP Date: Sun, 26 Nov 2023 22:41:46 +0530 Subject: [PATCH] use default applist from template repo --- .../internal/crossplane/package_providers.go | 1 - .../internal/crossplane/activity.go | 2 +- .../internal/crossplane/argocd_app_values.go | 18 ++-- .../crossplane/config_cluster_updates.go | 80 +++++++++++----- .../crossplane/config_crossplane_app.go | 6 +- .../internal/crossplane/types.go | 7 +- .../internal/file_util/file_util.go | 95 +++++++++++++++++++ charts/kad/Chart.yaml | 4 +- .../kad/crossplane_cluster_default_apps.json | 34 ------- charts/kad/crossplane_plugin_config.json | 5 +- .../templates/config-worker-deployment.yaml | 6 +- charts/kad/templates/configmap-plugins.yaml | 1 - charts/kad/values.yaml | 3 +- 13 files changed, 180 insertions(+), 82 deletions(-) create mode 100644 capten/config-worker/internal/file_util/file_util.go delete mode 100644 charts/kad/crossplane_cluster_default_apps.json diff --git a/capten/agent/internal/crossplane/package_providers.go b/capten/agent/internal/crossplane/package_providers.go index e6392b2e..83e22f8f 100644 --- a/capten/agent/internal/crossplane/package_providers.go +++ b/capten/agent/internal/crossplane/package_providers.go @@ -60,7 +60,6 @@ func (h *ProvidersSyncHandler) OnAdd(obj interface{}) { h.log.Errorf("failed to update Provider object, %v", err) return } - } func (h *ProvidersSyncHandler) OnUpdate(oldObj, newObj interface{}) { diff --git a/capten/config-worker/internal/crossplane/activity.go b/capten/config-worker/internal/crossplane/activity.go index faa4041e..9cf8e398 100644 --- a/capten/config-worker/internal/crossplane/activity.go +++ b/capten/config-worker/internal/crossplane/activity.go @@ -56,7 +56,7 @@ func processConfigurationActivity(ctx context.Context, params model.ConfigurePar status, err := cp.configureProjectAndApps(ctx, reqLocal) if err != nil { logger.Errorf("failed to configure crossplane project, %v", err) - err = fmt.Errorf("failed to configure crossplane project") + return string(model.WorkFlowStatusFailed), fmt.Errorf("failed to configure crossplane project") } return status, nil default: diff --git a/capten/config-worker/internal/crossplane/argocd_app_values.go b/capten/config-worker/internal/crossplane/argocd_app_values.go index 4bb56a86..44b11408 100644 --- a/capten/config-worker/internal/crossplane/argocd_app_values.go +++ b/capten/config-worker/internal/crossplane/argocd_app_values.go @@ -15,12 +15,16 @@ type GlobalValues struct { } type DefaultApps struct { - Name string `json:"name,omitempty"` - ValuesPath string `json:"valuesPath,omitempty"` - RepoURL string `json:"repoURL,omitempty"` - Namespace string `json:"namespace,omitempty"` - Chart string `json:"chart,omitempty"` - TargetRevision string `json:"targetRevision,omitempty"` + Name string `yaml:"name" json:"name,omitempty"` + ValuesPath string `yaml:"valuesPath" json:"valuesPath,omitempty"` + RepoURL string `yaml:"repoURL" json:"repoURL,omitempty"` + Namespace string `yaml:"namespace" json:"namespace,omitempty"` + Chart string `yaml:"chart" json:"chart,omitempty"` + TargetRevision string `yaml:"targetRevision" json:"targetRevision,omitempty"` +} + +type DefaultAppList struct { + DefaultApps []DefaultApps `yaml:"defaultApps"` } type Cluster struct { @@ -29,7 +33,7 @@ type Cluster struct { DefApps []DefaultApps `json:"defaultApps,omitempty"` } -type ArgoCDAppValue struct { +type ClusterConfigValues struct { Project string `json:"project,omitempty"` Global GlobalValues `json:"global,omitempty"` Src Source `json:"source,omitempty"` diff --git a/capten/config-worker/internal/crossplane/config_cluster_updates.go b/capten/config-worker/internal/crossplane/config_cluster_updates.go index 44298eb4..d711670f 100644 --- a/capten/config-worker/internal/crossplane/config_cluster_updates.go +++ b/capten/config-worker/internal/crossplane/config_cluster_updates.go @@ -6,13 +6,14 @@ import ( "fmt" "os" "path/filepath" - "strings" "github.com/intelops/go-common/logging" "github.com/kube-tarian/kad/capten/common-pkg/k8s" + fileutil "github.com/kube-tarian/kad/capten/config-worker/internal/file_util" "github.com/kube-tarian/kad/capten/model" agentmodel "github.com/kube-tarian/kad/capten/model" "github.com/pkg/errors" + "gopkg.in/yaml.v2" ) func getAppNameNamespace(ctx context.Context, fileName string) (string, string, error) { @@ -42,13 +43,12 @@ 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) + logger.Infof("configuring crossplane project for cluster %s update", req.ManagedClusterName) 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") } - logger.Infof("CreateCluster argocd err: ", err) accessToken, err := cp.helper.GetAccessToken(ctx, req.GitProjectId) if err != nil { return string(agentmodel.WorkFlowStatusFailed), errors.WithMessage(err, "failed to get token from vault") @@ -65,11 +65,21 @@ func (cp *CrossPlaneApp) configureClusterUpdate(ctx context.Context, req *model. defer os.RemoveAll(customerRepo) clusterValuesFile := filepath.Join(customerRepo, cp.pluginConfig.ClusterEndpointUpdates.ClusterValuesFile) - err = updateClusterEndpointDetials(clusterValuesFile, req.ManagedClusterName, endpoint, cp.cfg.ClusterDefaultAppsFile) + defaultAppListFile := filepath.Join(templateRepo, cp.pluginConfig.ClusterEndpointUpdates.DefaultAppListFile) + err = updateClusterEndpointDetials(clusterValuesFile, req.ManagedClusterName, endpoint, defaultAppListFile) if err != nil { return string(agentmodel.WorkFlowStatusFailed), errors.WithMessage(err, "failed to replace the file") } + defaultAppValPath := filepath.Join(templateRepo, cp.pluginConfig.ClusterEndpointUpdates.DefaultAppValuesPath) + clusterDefaultAppValPath := filepath.Join(customerRepo, + cp.pluginConfig.ClusterEndpointUpdates.ClusterDefaultAppValuesPath, req.ManagedClusterName) + err = cp.syncDefaultAppVaules(req.ManagedClusterName, defaultAppValPath, clusterDefaultAppValPath) + if err != nil { + return string(agentmodel.WorkFlowStatusFailed), errors.WithMessage(err, "failed to sync default app value files") + } + logger.Infof("default app vaules synched for cluster %s", req.ManagedClusterName) + err = cp.helper.AddToGit(ctx, model.CrossPlaneClusterUpdate, req.RepoURL, accessToken) if err != nil { return string(agentmodel.WorkFlowStatusFailed), errors.WithMessage(err, "failed to add git repo") @@ -106,8 +116,8 @@ func updateClusterEndpointDetials(valuesFileName, clusterName, clusterEndpoint, return err } - var argoCDAppValue ArgoCDAppValue - err = json.Unmarshal(jsonData, &argoCDAppValue) + var clusterConfig ClusterConfigValues + err = json.Unmarshal(jsonData, &clusterConfig) if err != nil { return err } @@ -117,22 +127,26 @@ func updateClusterEndpointDetials(valuesFileName, clusterName, clusterEndpoint, return err } - var found bool - clusters := *argoCDAppValue.Clusters + clusters := []Cluster{} + if clusterConfig.Clusters != nil { + clusters = *clusterConfig.Clusters + } + + var clusterFound bool for index := range clusters { if clusters[index].Name == clusterName { clusters[index] = prepareClusterData(clusterName, clusterEndpoint, defaultApps) - found = true + clusterFound = true break } } - if !found { + if !clusterFound { clusters = append(clusters, prepareClusterData(clusterName, clusterEndpoint, defaultApps)) } - argoCDAppValue.Clusters = &clusters - jsonBytes, err := json.Marshal(argoCDAppValue) + clusterConfig.Clusters = &clusters + jsonBytes, err := json.Marshal(clusterConfig) if err != nil { return err } @@ -146,12 +160,31 @@ func updateClusterEndpointDetials(valuesFileName, clusterName, clusterEndpoint, return err } -func prepareClusterData(clusterName, endpoint string, defaultApps []DefaultApps) Cluster { - for index := range defaultApps { - localObj := &defaultApps[index] - localObj.ValuesPath = strings.ReplaceAll(localObj.ValuesPath, clusterNameSub, clusterName) +func (cp *CrossPlaneApp) syncDefaultAppVaules(clusterName, defaultAppVaulesPath, clusterDefaultAppVaulesPath string) error { + if err := fileutil.CreateFolderIfNotExist(clusterDefaultAppVaulesPath); err != nil { + return err + } + + if err := fileutil.SyncFiles(defaultAppVaulesPath, clusterDefaultAppVaulesPath); err != nil { + return err } + if err := fileutil.UpdateFilesInFolderWithTempaltes(clusterDefaultAppVaulesPath, cp.prepareTemplateVaules(clusterName)); err != nil { + return err + } + + return nil +} + +func (cp *CrossPlaneApp) prepareTemplateVaules(clusterName string) map[string]string { + val := map[string]string{ + "DomainName": cp.cfg.DomainName, + "ClusterName": clusterName, + } + return val +} + +func prepareClusterData(clusterName, endpoint string, defaultApps []DefaultApps) Cluster { return Cluster{ Name: clusterName, Server: endpoint, @@ -159,16 +192,17 @@ func prepareClusterData(clusterName, endpoint string, defaultApps []DefaultApps) } } -func readClusterDefaultApps(clusterDefaultApp string) ([]DefaultApps, error) { - data, err := os.ReadFile(filepath.Clean(clusterDefaultApp)) +func readClusterDefaultApps(clusterDefaultAppsFile string) ([]DefaultApps, error) { + data, err := os.ReadFile(filepath.Clean(clusterDefaultAppsFile)) if err != nil { - return nil, fmt.Errorf("failed to read clusterDefaultApp File: %s, err: %w", clusterDefaultApp, err) + return nil, fmt.Errorf("failed to read default applist File: %s, err: %w", clusterDefaultAppsFile, err) } - var defaultApps []DefaultApps - err = json.Unmarshal(data, &defaultApps) + var appList DefaultAppList + err = yaml.Unmarshal(data, &appList) if err != nil { - return nil, fmt.Errorf("%w", err) + return nil, fmt.Errorf("failed to unmarshall default apps file: %s, err: %w", clusterDefaultAppsFile, err) } - return defaultApps, nil + + return appList.DefaultApps, nil } diff --git a/capten/config-worker/internal/crossplane/config_crossplane_app.go b/capten/config-worker/internal/crossplane/config_crossplane_app.go index 6abbf2fc..aa4294c0 100644 --- a/capten/config-worker/internal/crossplane/config_crossplane_app.go +++ b/capten/config-worker/internal/crossplane/config_crossplane_app.go @@ -17,14 +17,10 @@ import ( "github.com/pkg/errors" ) -var ( - clusterNameSub = "{CLUSTER_NAME}" -) - type Config struct { PluginConfigFile string `envconfig:"CROSSPLANE_PLUGIN_CONFIG_FILE" default:"/crossplane_plugin_config.json"` - ClusterDefaultAppsFile string `envconfig:"CROSSPLANE_CLUSTER_DEFAULT_APPS" default:"/crossplane_cluster_default_apps.json"` CloudProviderEntityName string `envconfig:"CLOUD_PROVIDER_ENTITY_NAME" default:"cloud-provider"` + DomainName string `envconfig:"DOMAIN_NAME" default:"capten"` } type CrossPlaneApp struct { diff --git a/capten/config-worker/internal/crossplane/types.go b/capten/config-worker/internal/crossplane/types.go index 60dbdaf7..acf4ad4b 100644 --- a/capten/config-worker/internal/crossplane/types.go +++ b/capten/config-worker/internal/crossplane/types.go @@ -7,8 +7,11 @@ type appConfig struct { } type clusterUpdateConfig struct { - MainAppGitPath string `json:"mainAppGitPath"` - ClusterValuesFile string `json:"clusterValuesFile"` + MainAppGitPath string `json:"mainAppGitPath"` + ClusterValuesFile string `json:"clusterValuesFile"` + DefaultAppListFile string `json:"defaultAppListFile"` + DefaultAppValuesPath string `json:"defaultAppValuesPath"` + ClusterDefaultAppValuesPath string `json:"clusterDefaultAppValuesPath"` } type crossplanePluginConfig struct { diff --git a/capten/config-worker/internal/file_util/file_util.go b/capten/config-worker/internal/file_util/file_util.go new file mode 100644 index 00000000..78bee042 --- /dev/null +++ b/capten/config-worker/internal/file_util/file_util.go @@ -0,0 +1,95 @@ +package fileutil + +import ( + "bytes" + "html/template" + "io" + "os" + "path/filepath" +) + +func CreateFolderIfNotExist(folderPath string) error { + if _, err := os.Stat(folderPath); os.IsNotExist(err) { + err := os.MkdirAll(folderPath, 0755) + if err != nil { + return err + } + } + return nil +} + +func SyncFiles(sourceFolder, destinationFolder string) error { + files, err := os.ReadDir(sourceFolder) + if err != nil { + return err + } + + for _, file := range files { + sourceFilePath := filepath.Join(sourceFolder, file.Name()) + destinationFilePath := filepath.Join(destinationFolder, file.Name()) + + if _, err := os.Stat(destinationFilePath); os.IsNotExist(err) { + if err := copyFile(sourceFilePath, destinationFilePath); err != nil { + return err + } + } + } + return nil +} + +func copyFile(src, dst string) error { + srcFile, err := os.Open(src) + if err != nil { + return err + } + defer srcFile.Close() + + dstFile, err := os.Create(dst) + if err != nil { + return err + } + defer dstFile.Close() + + _, err = io.Copy(dstFile, srcFile) + return err +} + +func applyTemplate(templateString string, data map[string]string) (string, error) { + tmpl, err := template.New("local").Parse(templateString) + if err != nil { + return "", err + } + + var outputBuffer bytes.Buffer + if err := tmpl.Execute(&outputBuffer, data); err != nil { + return "", err + } + + return outputBuffer.String(), nil +} + +func UpdateFilesInFolderWithTempaltes(folderPath string, data map[string]string) error { + files, err := os.ReadDir(folderPath) + if err != nil { + return err + } + + for _, file := range files { + filePath := filepath.Join(folderPath, file.Name()) + + content, err := os.ReadFile(filePath) + if err != nil { + return err + } + + newContent, err := applyTemplate(string(content), data) + if err != nil { + return err + } + + if err := os.WriteFile(filePath, []byte(newContent), os.ModePerm); err != nil { + return err + } + } + return nil +} diff --git a/charts/kad/Chart.yaml b/charts/kad/Chart.yaml index bcb68b83..32657fe5 100644 --- a/charts/kad/Chart.yaml +++ b/charts/kad/Chart.yaml @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.2.12 +version: 0.2.13 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.22.0" +appVersion: "1.23.0" diff --git a/charts/kad/crossplane_cluster_default_apps.json b/charts/kad/crossplane_cluster_default_apps.json deleted file mode 100644 index 8004f5a2..00000000 --- a/charts/kad/crossplane_cluster_default_apps.json +++ /dev/null @@ -1,34 +0,0 @@ - [ - { - "name": "falco", - "valuesPath": "infra/clusters/app-configs{CLUSTER_NAME}/default-apps/falco-values.yaml", - "repoURL": "https://kube-tarian.github.io/helmrepo-supporting-tools", - "namespace": "falco", - "chart": "falco", - "targetRevision": "0.0.1" - }, - { - "name": "kyverno", - "valuesPath": "infra/clusters/app-configs{CLUSTER_NAME}/default-apps/kyverno-values.yaml", - "repoURL": "https://kube-tarian.github.io/helmrepo-supporting-tools", - "namespace": "kyverno", - "chart": "kyverno", - "targetRevision": "1.0.2" - }, - { - "name": "prometheus", - "valuesPath": "infra/clusters/app-configs{CLUSTER_NAME}/default-apps/prometheus-values.yaml", - "repoURL": "https://kube-tarian.github.io/helmrepo-supporting-tools", - "namespace": "prometheus", - "chart": "kube-prometheus-stack", - "targetRevision": "1.0.3" - }, - { - "name": "promtail", - "valuesPath": "infra/clusters/app-configs{CLUSTER_NAME}/default-apps/promtail-values.yaml", - "repoURL": "https://kube-tarian.github.io/helmrepo-supporting-tools", - "namespace": "promtail", - "chart": "promtail", - "targetRevision": "1.0.0" - } -] \ No newline at end of file diff --git a/charts/kad/crossplane_plugin_config.json b/charts/kad/crossplane_plugin_config.json index dbfddab2..a573d4fe 100644 --- a/charts/kad/crossplane_plugin_config.json +++ b/charts/kad/crossplane_plugin_config.json @@ -8,7 +8,10 @@ }, "clusterUpdateConfig":{ "mainAppGitPath": "infra/crossplane/crossplane-main-app.yaml", - "clusterValuesFile": "infra/clusters/argocd-apps/values.yaml" + "clusterValuesFile": "infra/clusters/argocd-apps/values.yaml", + "defaultAppListFile": "default-apps-templates/app_list.yaml", + "defaultAppValuesPath": "default-apps-templates/values", + "clusterDefaultAppValuesPath": "infra/clusters/app-configs" }, "argoCDApps": [ { diff --git a/charts/kad/templates/config-worker-deployment.yaml b/charts/kad/templates/config-worker-deployment.yaml index 357b0887..6d4db4a8 100644 --- a/charts/kad/templates/config-worker-deployment.yaml +++ b/charts/kad/templates/config-worker-deployment.yaml @@ -41,8 +41,6 @@ spec: path: {{ .Values.configWorker.tektonPluginConfigFile }} - key: CROSSPLANE_PLUGIN_CONFIG path: {{ .Values.configWorker.crossplanePluginConfigFile }} - - key: CROSSPLANE_CLUSTER_DEFAULT_APPS - path: {{ .Values.configWorker.crossplaneClusterDefaultApps }} containers: - name: {{ .Chart.Name }}-config-worker securityContext: @@ -67,6 +65,8 @@ spec: value: "{{ .Values.service.port }}" - name: VAULT_ADDR value: {{ .Values.vault.address }} + - name: DOMAIN_NAME + value: {{ .Values.domainName }} - name: GIT_CLONE_DIR value: {{ .Values.configWorker.configWorkerGitCloneDir }} - name: VAULT_ROLE @@ -81,8 +81,6 @@ spec: value: "{{ .Values.configWorker.pluginConfigDir }}/{{ .Values.configWorker.tektonPluginConfigFile }}" - name: CROSSPLANE_PLUGIN_CONFIG_FILE value: "{{ .Values.configWorker.pluginConfigDir }}/{{ .Values.configWorker.crossplanePluginConfigFile }}" - - name: CROSSPLANE_CLUSTER_DEFAULT_APPS - value: "{{ .Values.configWorker.pluginConfigDir }}/{{ .Values.configWorker.crossplaneClusterDefaultApps }}" - name: CASSANDRA_USERNAME valueFrom: secretKeyRef: diff --git a/charts/kad/templates/configmap-plugins.yaml b/charts/kad/templates/configmap-plugins.yaml index d93f0f0c..3c612231 100644 --- a/charts/kad/templates/configmap-plugins.yaml +++ b/charts/kad/templates/configmap-plugins.yaml @@ -12,4 +12,3 @@ data: CROSSPLANE_PLUGIN_CONFIG: | {{- $fileName := .Values.configWorker.crossplanePluginConfigFile }} {{ .Files.Get $fileName | indent 4 }} - diff --git a/charts/kad/values.yaml b/charts/kad/values.yaml index 59b5ac87..15bc426d 100644 --- a/charts/kad/values.yaml +++ b/charts/kad/values.yaml @@ -42,6 +42,8 @@ service: type: ClusterIP port: 8080 +domainName: capten + vault: address: http://vault:8200 role: vault-role-capten-agent @@ -120,7 +122,6 @@ configWorker: pluginConfigDir: "/configs" tektonPluginConfigFile: "tekton_plugin_config.json" crossplanePluginConfigFile: "crossplane_plugin_config.json" - crossplaneClusterDefaultApps: "crossplane_cluster_default_apps.json" temporal: external: true