package populate import ( "context" "database/sql" "encoding/json" "fmt" "os" "github.com/doug-martin/goqu/v9" goext "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" helmApi "github.com/fluxcd/helm-controller/api/v2beta1" "edge-infra.dev/pkg/edge/api/clients" "edge-infra.dev/pkg/edge/api/graph/mapper" "edge-infra.dev/pkg/edge/api/services" ) const ( edgeInfoConfigMapMatcher = "{\"kind\":\"ConfigMap\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"edge-info\"" createWorkload = "INSERT INTO helm_workloads (cluster_edge_id, workload_name, workload_namespace, helm_chart, helm_repo, helm_chart_version, helm_config, helm_repo_secret) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT DO NOTHING;" getWorkload = "SELECT helm_edge_id from helm_workloads WHERE workload_name = $1 AND cluster_edge_id = $2" createSecret = "INSERT INTO helm_secrets (secret_name, helm_edge_id) VALUES ($1, $2) ON CONFLICT DO NOTHING;" ) func HelmWorkloadsTable(ctx context.Context, db *sql.DB, bqClient clients.BQClient, bqTableName string, clusterEdgeID string) bool { var configValues *string q, err := buildBQQuery(bqTableName, clusterEdgeID) if err != nil { fmt.Println("an error occurred", clusterEdgeID, err) os.Exit(1) } results, err := bqClient.Read(ctx, q) if err != nil { fmt.Println("an error occurred", clusterEdgeID, err) os.Exit(1) } hrs, err := services.ConvertToHelmReleases(ctx, results) if err != nil { fmt.Println("an error occurred", clusterEdgeID, err) os.Exit(1) } for _, hr := range hrs { fmt.Printf("processing helm release cluster edge id: %s, hr name: %s\n", clusterEdgeID, hr.Name) //update db if hr.Spec.Values == nil { configValues = nil } else { hr := string(hr.Spec.Values.Raw) configValues = &hr } _, err := db.ExecContext(ctx, createWorkload, clusterEdgeID, hr.Name, hr.Spec.TargetNamespace, hr.Spec.Chart.Spec.Chart, hr.Spec.Chart.Spec.SourceRef.Name, hr.Spec.Chart.Spec.Version, configValues, hr.Labels[mapper.SecretManagerSecretLabel]) if err != nil { fmt.Println(fmt.Errorf("cluster edge id: %s, hr name: %s err: %w", clusterEdgeID, hr.Name, err)) } addSecrets(ctx, db, bqTableName, clusterEdgeID, hr, bqClient) } return false } func addSecrets(ctx context.Context, db *sql.DB, bqTableName string, clusterEdgeID string, hr helmApi.HelmRelease, bqClient clients.BQClient) { var helmEdgeID string row := db.QueryRow(getWorkload, hr.Name, clusterEdgeID) err := row.Scan(&helmEdgeID) if err != nil { fmt.Println("an error occurred", clusterEdgeID, err) os.Exit(1) } q, err := buildSecretsBQQuery(bqTableName, clusterEdgeID, hr.Spec.TargetNamespace) if err != nil { fmt.Println("an error occurred", clusterEdgeID, err) os.Exit(1) } results, err := bqClient.Read(ctx, q) if err != nil { fmt.Println("an error occurred", clusterEdgeID, err) os.Exit(1) } for _, sec := range results { externalSecret := &goext.ExternalSecret{} err := json.Unmarshal([]byte(sec), externalSecret) if err != nil { fmt.Println("an error occurred", clusterEdgeID, err) os.Exit(1) } _, err = db.ExecContext(ctx, createSecret, externalSecret.Name, helmEdgeID) if err != nil { fmt.Println(fmt.Errorf("cluster edge id: %s, hr name: %s err: %w", clusterEdgeID, hr.Name, err)) } } } func buildBQQuery(bqTableName, clusterEdgeID string) (string, error) { queryBuilder := goqu.Dialect("mysql").Select("resource").From(bqTableName). Where(goqu.C("k8s_group").Eq("helm.toolkit.fluxcd.io")). Where(goqu.C("version").Eq("v2beta1")). Where(goqu.C("kind").Eq("HelmRelease")). Where(goqu.C("operation").Neq("delete")). Where(goqu.C("cluster_edge_id").Eq(clusterEdgeID)) q, _, err := queryBuilder.ToSQL() return q, err } func buildSecretsBQQuery(bqTableName, clusterEdgeID, namespace string) (string, error) { queryBuilder := goqu.Dialect("mysql").Select("resource").From(bqTableName). Where(goqu.C("k8s_group").Eq("external-secrets.io")). Where(goqu.C("version").Eq("v1beta1")). Where(goqu.C("kind").Eq("ExternalSecret")). Where(goqu.C("operation").Neq("delete")). Where(goqu.C("namespace").Eq(namespace)). Where(goqu.C("cluster_edge_id").Eq(clusterEdgeID)) q, _, err := queryBuilder.ToSQL() return q, err }