From fb5f1c6052f773468a5010e479c196be93f27aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristhian=20Fern=C3=A1ndez?= Date: Mon, 12 Feb 2024 15:34:56 -0500 Subject: [PATCH] feat: post install catalog apps (#293) --- internal/controller/controller.go | 26 ++++++++------- internal/db/gitopsCatalog.go | 2 +- internal/gitopsCatalog/gitopsCatalog.go | 2 +- internal/router/api/v1/secrets.go | 9 ++++- internal/router/api/v1/services.go | 8 +++-- internal/services/services.go | 9 +++-- main.go | 23 +++++++++++++ pkg/types/cluster.go | 42 +++++++++++++----------- {internal => pkg}/types/gitopsCatalog.go | 0 9 files changed, 81 insertions(+), 40 deletions(-) rename {internal => pkg}/types/gitopsCatalog.go (100%) diff --git a/internal/controller/controller.go b/internal/controller/controller.go index fe91b670..c5769b9c 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -49,18 +49,19 @@ type ClusterController struct { AlertsEmail string // auth - AWSAuth pkgtypes.AWSAuth - CivoAuth pkgtypes.CivoAuth - DigitaloceanAuth pkgtypes.DigitaloceanAuth - VultrAuth pkgtypes.VultrAuth - CloudflareAuth pkgtypes.CloudflareAuth - GitAuth pkgtypes.GitAuth - VaultAuth pkgtypes.VaultAuth - GoogleAuth pkgtypes.GoogleAuth - AwsAccessKeyID string - AwsSecretAccessKey string - NodeType string - NodeCount int + AWSAuth pkgtypes.AWSAuth + CivoAuth pkgtypes.CivoAuth + DigitaloceanAuth pkgtypes.DigitaloceanAuth + VultrAuth pkgtypes.VultrAuth + CloudflareAuth pkgtypes.CloudflareAuth + GitAuth pkgtypes.GitAuth + VaultAuth pkgtypes.VaultAuth + GoogleAuth pkgtypes.GoogleAuth + AwsAccessKeyID string + AwsSecretAccessKey string + NodeType string + NodeCount int + PostInstallCatalogApps []pkgtypes.GitopsCatalogApp // configs ProviderConfig providerConfigs.ProviderConfig @@ -185,6 +186,7 @@ func (clctrl *ClusterController) InitController(def *pkgtypes.ClusterDefinition) clctrl.HttpClient = http.DefaultClient clctrl.NodeType = def.NodeType clctrl.NodeCount = def.NodeCount + clctrl.PostInstallCatalogApps = def.PostInstallCatalogApps clctrl.AWSAuth = def.AWSAuth clctrl.CivoAuth = def.CivoAuth diff --git a/internal/db/gitopsCatalog.go b/internal/db/gitopsCatalog.go index f61eb104..f90df01a 100644 --- a/internal/db/gitopsCatalog.go +++ b/internal/db/gitopsCatalog.go @@ -10,7 +10,7 @@ import ( "fmt" "github.com/kubefirst/kubefirst-api/internal/gitopsCatalog" - "github.com/kubefirst/kubefirst-api/internal/types" + "github.com/kubefirst/kubefirst-api/pkg/types" log "github.com/rs/zerolog/log" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" diff --git a/internal/gitopsCatalog/gitopsCatalog.go b/internal/gitopsCatalog/gitopsCatalog.go index 341ec64c..5cbe5219 100644 --- a/internal/gitopsCatalog/gitopsCatalog.go +++ b/internal/gitopsCatalog/gitopsCatalog.go @@ -10,7 +10,7 @@ import ( "fmt" "github.com/kubefirst/kubefirst-api/internal/gitShim" - "github.com/kubefirst/kubefirst-api/internal/types" + "github.com/kubefirst/kubefirst-api/pkg/types" "gopkg.in/yaml.v2" ) diff --git a/internal/router/api/v1/secrets.go b/internal/router/api/v1/secrets.go index fd94c9f1..797226ef 100644 --- a/internal/router/api/v1/secrets.go +++ b/internal/router/api/v1/secrets.go @@ -101,7 +101,14 @@ func UpdateClusterSecret(c *gin.Context) { clusterDir := fmt.Sprintf("%s/.k1/%s", homeDir, clusterName) - kcfg := k8s.CreateKubeConfig(false, fmt.Sprintf("%s/kubeconfig", clusterDir)) + env, _ := env.GetEnv(constants.SilenceGetEnv) + + var inCluster bool = false + if env.InCluster == "true" { + inCluster = true + } + + kcfg := k8s.CreateKubeConfig(inCluster, fmt.Sprintf("%s/kubeconfig", clusterDir)) err = k8s.UpdateSecretV2(kcfg.Clientset, "kubefirst", secret, clusterSecretUpdates) if err != nil { diff --git a/internal/router/api/v1/services.go b/internal/router/api/v1/services.go index 3e3ae0ac..8ab7e5a2 100644 --- a/internal/router/api/v1/services.go +++ b/internal/router/api/v1/services.go @@ -14,6 +14,8 @@ import ( "github.com/kubefirst/kubefirst-api/internal/db" "github.com/kubefirst/kubefirst-api/internal/services" "github.com/kubefirst/kubefirst-api/internal/types" + pkgtypes "github.com/kubefirst/kubefirst-api/pkg/types" + "github.com/kubefirst/kubefirst-api/internal/utils" ) @@ -99,7 +101,7 @@ func PostAddServiceToCluster(c *gin.Context) { return } valid, hasKeys := false, false - var appDef types.GitopsCatalogApp + var appDef pkgtypes.GitopsCatalogApp for _, app := range apps.Apps { if app.Name == serviceName { valid = true @@ -117,7 +119,7 @@ func PostAddServiceToCluster(c *gin.Context) { } // Bind to variable as application/json, handle error - var serviceDefinition types.GitopsCatalogAppCreateRequest + var serviceDefinition pkgtypes.GitopsCatalogAppCreateRequest err = c.Bind(&serviceDefinition) if err != nil { c.JSON(http.StatusBadRequest, types.JSONFailureResponse{ @@ -170,7 +172,7 @@ func PostAddServiceToCluster(c *gin.Context) { return } - err = services.CreateService(&cl, serviceName, &appDef, &serviceDefinition) + err = services.CreateService(&cl, serviceName, &appDef, &serviceDefinition, false) if err != nil { c.JSON(http.StatusBadRequest, types.JSONFailureResponse{ Message: err.Error(), diff --git a/internal/services/services.go b/internal/services/services.go index 117e77ca..34aa6f34 100644 --- a/internal/services/services.go +++ b/internal/services/services.go @@ -41,7 +41,7 @@ import ( ) // CreateService -func CreateService(cl *pkgtypes.Cluster, serviceName string, appDef *types.GitopsCatalogApp, req *types.GitopsCatalogAppCreateRequest) error { +func CreateService(cl *pkgtypes.Cluster, serviceName string, appDef *pkgtypes.GitopsCatalogApp, req *pkgtypes.GitopsCatalogAppCreateRequest, excludeArgoSync bool) error { switch cl.Status { case constants.ClusterStatusDeleted, constants.ClusterStatusDeleting, constants.ClusterStatusError, constants.ClusterStatusProvisioning: return fmt.Errorf("cluster %s - unable to deploy service %s to cluster: cannot deploy services to a cluster in %s state", cl.ClusterName, serviceName, cl.Status) @@ -208,6 +208,7 @@ func CreateService(cl *pkgtypes.Cluster, serviceName string, appDef *types.Gitop Username: cl.GitAuth.User, Password: cl.GitAuth.Token, }, + Force: true, }) if err != nil { return fmt.Errorf("cluster %s - error pushing commit for service file: %s", cl.ClusterName, err) @@ -226,6 +227,10 @@ func CreateService(cl *pkgtypes.Cluster, serviceName string, appDef *types.Gitop return err } + if excludeArgoSync { + return nil + } + // Wait for ArgoCD application sync argocdClient, err := argocdapi.NewForConfig(kcfg.RestConfig) if err != nil { @@ -573,7 +578,7 @@ func CreateTokensFromDatabaseRecord(cl *pkgtypes.Cluster, registryPath string) * return gitopsTemplateTokens } -func DetokenizeConfigKeys(serviceFilePath string, configKeys []types.GitopsCatalogAppKeys) error { +func DetokenizeConfigKeys(serviceFilePath string, configKeys []pkgtypes.GitopsCatalogAppKeys) error { return filepath.Walk(serviceFilePath, func(path string, info os.FileInfo, err error) error { if err != nil { return err diff --git a/main.go b/main.go index 20db7b0f..516e181a 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ package main import ( "fmt" + "time" "github.com/kubefirst/kubefirst-api/docs" "github.com/kubefirst/kubefirst-api/internal/db" @@ -17,6 +18,7 @@ import ( "github.com/kubefirst/kubefirst-api/internal/services" apitelemetry "github.com/kubefirst/kubefirst-api/internal/telemetry" "github.com/kubefirst/kubefirst-api/internal/utils" + "github.com/kubefirst/kubefirst-api/pkg/types" "github.com/kubefirst/metrics-client/pkg/telemetry" log "github.com/rs/zerolog/log" @@ -60,8 +62,29 @@ func main() { log.Info().Msgf("adding default services for cluster %s", importedCluster.ClusterName) services.AddDefaultServices(&importedCluster) + if importedCluster.PostInstallCatalogApps != nil { + go func() { + for _, catalogApp := range importedCluster.PostInstallCatalogApps { + log.Info().Msgf("installing catalog application %s", catalogApp.Name) + + request := &types.GitopsCatalogAppCreateRequest{ + SecretKeys: catalogApp.SecretKeys, + ConfigKeys: catalogApp.ConfigKeys, + } + + err = services.CreateService(&importedCluster, catalogApp.Name, &catalogApp, request, true) + if err != nil { + log.Info().Msgf("Error creating default environments %s", err.Error()) + } + } + }() + } + if importedCluster.CloudProvider != "k3d" { go func() { + log.Info().Msgf("Waiting for services to be created %s", importedCluster.ClusterName) + time.Sleep(time.Second * 30) + log.Info().Msgf("adding default environments for cluster %s", importedCluster.ClusterName) err := environments.CreateDefaultEnvironments(importedCluster) if err != nil { diff --git a/pkg/types/cluster.go b/pkg/types/cluster.go index 2c5d58d7..31a19b1b 100644 --- a/pkg/types/cluster.go +++ b/pkg/types/cluster.go @@ -14,17 +14,18 @@ import ( type ClusterDefinition struct { //Cluster - AdminEmail string `json:"admin_email" binding:"required"` - CloudProvider string `json:"cloud_provider" binding:"required,oneof=aws civo digitalocean vultr google"` - CloudRegion string `json:"cloud_region" binding:"required"` - ClusterName string `json:"cluster_name,omitempty"` - DomainName string `json:"domain_name" binding:"required"` - SubdomainName string `json:"subdomain_name,omitempty"` - DnsProvider string `json:"dns_provider,omitempty" binding:"required"` - Type string `json:"type" binding:"required,oneof=mgmt workload"` - ForceDestroy bool `bson:"force_destroy,omitempty" json:"force_destroy,omitempty"` - NodeType string `json:"node_type" binding:"required"` - NodeCount int `json:"node_count" binding:"required"` + AdminEmail string `json:"admin_email" binding:"required"` + CloudProvider string `json:"cloud_provider" binding:"required,oneof=aws civo digitalocean vultr google"` + CloudRegion string `json:"cloud_region" binding:"required"` + ClusterName string `json:"cluster_name,omitempty"` + DomainName string `json:"domain_name" binding:"required"` + SubdomainName string `json:"subdomain_name,omitempty"` + DnsProvider string `json:"dns_provider,omitempty" binding:"required"` + Type string `json:"type" binding:"required,oneof=mgmt workload"` + ForceDestroy bool `bson:"force_destroy,omitempty" json:"force_destroy,omitempty"` + NodeType string `json:"node_type" binding:"required"` + NodeCount int `json:"node_count" binding:"required"` + PostInstallCatalogApps []GitopsCatalogApp `bson:"post_install_catalog_apps,omitempty" json:"post_install_catalog_apps,omitempty"` //Git GitopsTemplateURL string `json:"gitops_template_url"` @@ -57,15 +58,16 @@ type Cluster struct { InProgress bool `bson:"in_progress" json:"in_progress"` // Identifiers - AlertsEmail string `bson:"alerts_email" json:"alerts_email"` - CloudProvider string `bson:"cloud_provider" json:"cloud_provider"` - CloudRegion string `bson:"cloud_region" json:"cloud_region"` - ClusterName string `bson:"cluster_name" json:"cluster_name"` - ClusterID string `bson:"cluster_id" json:"cluster_id"` - ClusterType string `bson:"cluster_type" json:"cluster_type"` - DomainName string `bson:"domain_name" json:"domain_name"` - SubdomainName string `bson:"subdomain_name" json:"subdomain_name,omitempty"` - DnsProvider string `bson:"dns_provider" json:"dns_provider"` + AlertsEmail string `bson:"alerts_email" json:"alerts_email"` + CloudProvider string `bson:"cloud_provider" json:"cloud_provider"` + CloudRegion string `bson:"cloud_region" json:"cloud_region"` + ClusterName string `bson:"cluster_name" json:"cluster_name"` + ClusterID string `bson:"cluster_id" json:"cluster_id"` + ClusterType string `bson:"cluster_type" json:"cluster_type"` + DomainName string `bson:"domain_name" json:"domain_name"` + SubdomainName string `bson:"subdomain_name" json:"subdomain_name,omitempty"` + DnsProvider string `bson:"dns_provider" json:"dns_provider"` + PostInstallCatalogApps []GitopsCatalogApp `bson:"post_install_catalog_apps,omitempty" json:"post_install_catalog_apps,omitempty"` // Auth AWSAuth AWSAuth `bson:"aws_auth,omitempty" json:"aws_auth,omitempty"` diff --git a/internal/types/gitopsCatalog.go b/pkg/types/gitopsCatalog.go similarity index 100% rename from internal/types/gitopsCatalog.go rename to pkg/types/gitopsCatalog.go