package clusterctl import ( "context" "database/sql" "flag" "fmt" "time" "github.com/peterbourgon/ff/v3" bsltypes "edge-infra.dev/pkg/edge/api/bsl/types" "edge-infra.dev/pkg/edge/api/services" "edge-infra.dev/pkg/edge/api/services/artifacts" clustersvc "edge-infra.dev/pkg/edge/api/services/cluster" "edge-infra.dev/pkg/edge/bsl" "edge-infra.dev/pkg/edge/k8objectsutils" ipranger "edge-infra.dev/pkg/f8n/ipranger/server" "edge-infra.dev/pkg/lib/gcp/cloudsql" ) type Config struct { CreateClient ContainerClusterClientFunc EdgeAPI string TopLevelProjectID string IPRangerClient *ipranger.Client DefaultRequeue time.Duration TopLevelCNRMSA string TotpSecret string Domain string DatasyncDNSName string DatasyncDNSZone string LDKey string GCPRegion string GCPZone string GCPForemanProjectNumber string // How long WaitForSet checks for shipment readiness. When zero, WaitForSet is skipped. WaitForSetTimeout time.Duration ClusterReconcilerConcurrency int GKEClusterReconcilerConcurrency int // DB is used to create a dbinfrastatus.EdgeDB wrapper. Infra status recording is disabled when DB is nil. DB *sql.DB // DatabaseName is passed into the cluster-infra shipment. DatabaseName string DatabaseUser string DatabaseConnectionName string GCPService services.GCPService BSLClient *bsl.Client BSLAccessKey bsl.AccessKey BSLConfig bsltypes.BSPConfig ArtifactsService artifacts.Service // Configuration for Plugins PluginConcurrency int // Configuration for number waitforset concurrent threads BackgroundWaitForSetConcurrency int // Helm cache maximum limit HelmCacheLimit int // Edge Security Compliance Settings EdgeSecMaxLeasePeriod string EdgeSecMaxValidityPeriod string } func NewConfig(args []string) (*Config, error) { fs := flag.NewFlagSet("clusterctl", flag.ExitOnError) cfg := &Config{} cfg.bind(fs) if err := ff.Parse(fs, args, ff.WithEnvVarNoPrefix()); err != nil { return nil, fmt.Errorf("failed to parse configuration: %w", err) } return cfg, nil } func (c *Config) bind(fs *flag.FlagSet) { fs.StringVar(&c.EdgeAPI, "edge-api", "", "The URL for the Edge API") fs.StringVar(&c.TopLevelProjectID, "top-level-project-id", "", "The Foreman Project ID") fs.DurationVar(&c.DefaultRequeue, "default-requeue", 30*time.Second, "The default requeue interval") fs.StringVar(&c.TopLevelCNRMSA, "top-level-cnrm-sa", "", "The top level cnrm service account") fs.StringVar(&c.TotpSecret, "totp-secret-key", "", "The totp secret for authenication to the Edge API") fs.StringVar(&c.Domain, "domain", "", "The Edge Domain") fs.StringVar(&c.BSLAccessKey.SharedKey, "edge-bsl-shared-key", "", "The shared key for BSL access") fs.StringVar(&c.BSLAccessKey.SecretKey, "edge-bsl-secret-key", "", "The secret key for BSL access") fs.StringVar(&c.BSLConfig.Endpoint, "bsl-endpoint", "", "The BSL endpoint for a specific environment") fs.StringVar(&c.BSLConfig.Root, "bsl-root-org", "", "The BSL root org") fs.StringVar(&c.BSLConfig.OrganizationPrefix, "bsp-organization-prefix", "", "The BSL organization prefix for a specific environment") fs.StringVar(&c.DatasyncDNSName, "datasync-dns-name", "", "The Datasync DNS Name") fs.StringVar(&c.DatasyncDNSZone, "datasync-dns-zone", "", "The Datasync DNS Zone") fs.DurationVar(&c.WaitForSetTimeout, "wait-for-set-timeout", 2*time.Minute, "The Reconciler wait for set timeout duration") fs.IntVar(&c.ClusterReconcilerConcurrency, "cluster-concurrency", 24, "The concurrency value for the cluster reconciler") fs.IntVar(&c.GKEClusterReconcilerConcurrency, "gkecluster-concurrency", 6, "The concurrency value for the gke cluster reconciler") fs.StringVar(&c.DatabaseName, "sql-db-name", "", "The Database Name") fs.StringVar(&c.DatabaseUser, "sql-user", "", "The Database User") fs.StringVar(&c.DatabaseConnectionName, "sql-connection-name", "", "The Database Connection Name") fs.StringVar(&c.LDKey, "ld-key", "", "Launch Darkly Key") fs.StringVar(&c.GCPRegion, "gcp-region", "", "GCP Region - eg: us-east1") fs.StringVar(&c.GCPZone, "gcp-zone", "", "GCP Zone - eg: a/b/c") fs.IntVar(&c.PluginConcurrency, "plugin-concurrency", 24, "The concurrency value for plugins") fs.IntVar(&c.BackgroundWaitForSetConcurrency, "wait-for-set-concurrency", 5, "The concurrency for background waitforset processing") fs.IntVar(&c.HelmCacheLimit, "helm-cache-limit", 1200, "The maximum entries allowed in the helm cache") fs.StringVar(&c.EdgeSecMaxLeasePeriod, "edge-sec-max-lease-period", "", "Maximum secret lease period") fs.StringVar(&c.EdgeSecMaxValidityPeriod, "edge-sec-max-validity-period", "", "Maximum secret validity period") fs.StringVar(&c.GCPForemanProjectNumber, "gcp-foreman-project-number", "", "The Foreman GCP Project Number") } func (c *Config) AfterParse() error { db, err := cloudsql.GCPPostgresConnection(c.DatabaseConnectionName). DBName(c.DatabaseName). Username(c.DatabaseUser). NewConnection() if err != nil { return fmt.Errorf("failed to create sql connection: %w", err) } pingCtx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() if err := db.PingContext(pingCtx); err != nil { return fmt.Errorf("failed to ping sql connection: %w", err) } c.DB = db c.CreateClient = k8objectsutils.CreateClient c.IPRangerClient = ipranger.NewClient(ipranger.ClusterLocalSvcHost) gcpClientSvc := services.NewGcpClientService() c.GCPService = services.NewGcpService(gcpClientSvc, c.TopLevelProjectID, nil) c.BSLClient = bsl.NewBSLClient(c.BSLConfig).SetDefaultAccessKey(c.BSLAccessKey.SharedKey, c.BSLAccessKey.SecretKey) clusterLabelSvc := clustersvc.NewLabelService(db) c.ArtifactsService = artifacts.NewArtifactsService(db, clusterLabelSvc) return nil }