Skip to content

Commit

Permalink
Merge pull request #339 from kube-tarian/use-git-default-apps
Browse files Browse the repository at this point in the history
use default applist from template repo
  • Loading branch information
vramk23 authored Nov 26, 2023
2 parents 155c623 + 94b54d4 commit 5299f2e
Show file tree
Hide file tree
Showing 13 changed files with 180 additions and 82 deletions.
1 change: 0 additions & 1 deletion capten/agent/internal/crossplane/package_providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}) {
Expand Down
2 changes: 1 addition & 1 deletion capten/config-worker/internal/crossplane/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
18 changes: 11 additions & 7 deletions capten/config-worker/internal/crossplane/argocd_app_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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"`
Expand Down
80 changes: 57 additions & 23 deletions capten/config-worker/internal/crossplane/config_cluster_updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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")
Expand All @@ -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")
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand All @@ -146,29 +160,49 @@ 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,
DefApps: 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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 5 additions & 2 deletions capten/config-worker/internal/crossplane/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
95 changes: 95 additions & 0 deletions capten/config-worker/internal/file_util/file_util.go
Original file line number Diff line number Diff line change
@@ -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
}
4 changes: 2 additions & 2 deletions charts/kad/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
34 changes: 0 additions & 34 deletions charts/kad/crossplane_cluster_default_apps.json

This file was deleted.

5 changes: 4 additions & 1 deletion charts/kad/crossplane_plugin_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
{
Expand Down
Loading

0 comments on commit 5299f2e

Please sign in to comment.