diff --git a/NOTICE b/NOTICE index c40568e..df833f3 100644 --- a/NOTICE +++ b/NOTICE @@ -267,12 +267,6 @@ Version: v0.5.15 License: BSD-3-Clause License URL: https://github.com/ulikunitz/xz/blob/v0.5.15/LICENSE ----------- -Module: github.com/yaml/go-yaml -Version: v2.1.0 -License: Apache-2.0 -License URL: https://github.com/yaml/go-yaml/blob/v2.1.0/LICENSE - ---------- Module: go.opentelemetry.io/auto/sdk Version: v1.2.1 diff --git a/cli/cmd/update_install_config.go b/cli/cmd/update_install_config.go index 9cf6bc9..95f427c 100644 --- a/cli/cmd/update_install_config.go +++ b/cli/cmd/update_install_config.go @@ -5,6 +5,7 @@ package cmd import ( "fmt" + "log" "strings" csio "github.com/codesphere-cloud/cs-go/pkg/io" @@ -283,7 +284,8 @@ func (c *UpdateInstallConfigCmd) applyUpdates(config *files.RootConfig, tracker func (c *UpdateInstallConfigCmd) regenerateSecrets(config *files.RootConfig, tracker *SecretDependencyTracker) error { if tracker.NeedsPostgresPrimaryCertRegen() { - fmt.Println(" - Regenerating PostgreSQL primary server certificate...") + log.Println(" - Regenerating PostgreSQL primary server certificate...") + var err error config.Postgres.Primary.PrivateKey, config.Postgres.Primary.SSLConfig.ServerCertPem, err = installer.GenerateServerCertificate( config.Postgres.CaCertPrivateKey, @@ -297,7 +299,8 @@ func (c *UpdateInstallConfigCmd) regenerateSecrets(config *files.RootConfig, tra } if tracker.NeedsPostgresReplicaCertRegen() && config.Postgres.Replica != nil { - fmt.Println(" - Regenerating PostgreSQL replica server certificate...") + log.Println(" - Regenerating PostgreSQL replica server certificate...") + var err error config.Postgres.ReplicaPrivateKey, config.Postgres.Replica.SSLConfig.ServerCertPem, err = installer.GenerateServerCertificate( config.Postgres.CaCertPrivateKey, diff --git a/internal/bootstrap/gcp.go b/internal/bootstrap/gcp.go index e1f4eb9..439f2d2 100644 --- a/internal/bootstrap/gcp.go +++ b/internal/bootstrap/gcp.go @@ -78,8 +78,9 @@ func NewGCPBootstrapper(env env.Env, CodesphereEnv *CodesphereEnvironment, gcpCl FileIO: fw, KeyPath: CodesphereEnv.SSHPrivateKeyPath, } + if fw.Exists(CodesphereEnv.InstallConfig) { - fmt.Printf("Reading install config file: %s\n", CodesphereEnv.InstallConfig) + log.Printf("Reading install config file: %s", CodesphereEnv.InstallConfig) err := icg.LoadInstallConfigFromFile(CodesphereEnv.InstallConfig) if err != nil { return nil, fmt.Errorf("failed to load config file: %w", err) @@ -94,17 +95,19 @@ func NewGCPBootstrapper(env env.Env, CodesphereEnv *CodesphereEnvironment, gcpCl } if fw.Exists(CodesphereEnv.SecretsFile) { - fmt.Printf("Reading vault file: %s\n", CodesphereEnv.SecretsFile) + log.Printf("Reading vault file: %s", CodesphereEnv.SecretsFile) err := icg.LoadVaultFromFile(CodesphereEnv.SecretsFile) if err != nil { return nil, fmt.Errorf("failed to load vault file: %w", err) } - fmt.Println("Merging vault secrets into configuration...") + + log.Println("Merging vault secrets into configuration...") err = icg.MergeVaultIntoConfig() if err != nil { return nil, fmt.Errorf("failed to merge vault into config: %w", err) } } + return &GCPBootstrapper{ env: CodesphereEnv, InstallConfig: icg.GetInstallConfig(), @@ -259,7 +262,8 @@ func (b *GCPBootstrapper) EnsureBilling() error { if err != nil { return fmt.Errorf("failed to enable billing: %w", err) } - log.Printf("Billing enabled for project %s with account %s\n", b.env.ProjectID, b.env.BillingAccount) + log.Printf("Billing enabled for project %s with account %s", b.env.ProjectID, b.env.BillingAccount) + return nil } @@ -276,7 +280,7 @@ func (b *GCPBootstrapper) EnsureAPIsEnabled() error { return fmt.Errorf("failed to enable APIs: %w", err) } - log.Printf("Required APIs enabled for project %s\n", b.env.ProjectID) + log.Printf("Required APIs enabled for project %s", b.env.ProjectID) return nil } @@ -299,7 +303,7 @@ func (b *GCPBootstrapper) EnsureArtifactRegistry() error { b.InstallConfig.Registry.Server = repo.GetRegistryUri() - log.Printf("Artifact Registry repository %s ensured\n", b.InstallConfig.Registry.Server) + log.Printf("Artifact Registry repository %s ensured", b.InstallConfig.Registry.Server) return nil } @@ -325,13 +329,17 @@ func (b *GCPBootstrapper) EnsureServiceAccounts() error { if retries > 3 { return fmt.Errorf("failed to create service account key: %w", err) } + log.Printf("got response %d trying to create service account key for %s, retrying...", status.Code(err), sa) + time.Sleep(5 * time.Second) continue } - fmt.Printf("Service account key for %s ensured\n", sa) + + log.Printf("Service account key for %s ensured", sa) b.InstallConfig.Registry.Password = string(privateKey) b.InstallConfig.Registry.Username = "_json_key_base64" + break } @@ -362,7 +370,8 @@ func (b *GCPBootstrapper) EnsureVPC() error { if err != nil { return fmt.Errorf("failed to ensure VPC: %w", err) } - fmt.Printf("VPC %s ensured\n", networkName) + + log.Printf("VPC %s ensured", networkName) return nil } @@ -460,7 +469,7 @@ func (b *GCPBootstrapper) EnsureFirewallRules() error { return fmt.Errorf("failed to create postgres firewall rule: %w", err) } - fmt.Println("Firewall rules ensured") + log.Println("Firewall rules ensured") return nil } @@ -591,7 +600,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { errCh <- fmt.Errorf("failed to wait for instance %s creation: %w", vm.Name, err) } } - fmt.Printf("Instance %s ensured\n", vm.Name) + log.Printf("Instance %s ensured", vm.Name) //find out the IP addresses of the created instance resp, err := instancesClient.Get(ctx, &computepb.GetInstanceRequest{ @@ -692,7 +701,8 @@ func (b *GCPBootstrapper) EnsureExternalIP(name string) (string, error) { address, err := addressesClient.Get(b.ctx, req) if err == nil && address != nil { - fmt.Printf("Address %s already exists\n", name) + log.Printf("Address %s already exists", name) + return address.GetAddress(), nil } @@ -707,7 +717,7 @@ func (b *GCPBootstrapper) EnsureExternalIP(name string) (string, error) { if err := op.Wait(b.ctx); err != nil { return "", fmt.Errorf("failed to wait for address %s creation: %w", name, err) } - fmt.Printf("Address %s ensured\n", name) + log.Printf("Address %s ensured", name) address, err = addressesClient.Get(b.ctx, req) @@ -723,13 +733,14 @@ func (b *GCPBootstrapper) EnsureRootLoginEnabled() error { if err != nil { return fmt.Errorf("timed out waiting for SSH service to start on jumpbox: %w", err) } + hasRootLogin := b.env.Jumpbox.HasRootLoginEnabled(nil, b.NodeManager) if !hasRootLogin { err := b.env.Jumpbox.EnableRootLogin(nil, b.NodeManager) if err != nil { return fmt.Errorf("failed to enable root login on %s: %w", b.env.Jumpbox.Name, err) } - fmt.Printf("Root login enabled on %s\n", b.env.Jumpbox.Name) + log.Printf("Root login enabled on %s", b.env.Jumpbox.Name) } allNodes := append(b.env.ControlPlaneNodes, b.env.PostgreSQLNode) @@ -742,7 +753,8 @@ func (b *GCPBootstrapper) EnsureRootLoginEnabled() error { } hasRootLogin := node.HasRootLoginEnabled(&b.env.Jumpbox, b.NodeManager) if hasRootLogin { - fmt.Printf("Root login already enabled on %s\n", node.Name) + log.Printf("Root login already enabled on %s", node.Name) + continue } for i := range 3 { @@ -757,7 +769,7 @@ func (b *GCPBootstrapper) EnsureRootLoginEnabled() error { time.Sleep(10 * time.Second) } - fmt.Printf("Root login enabled on %s\n", node.Name) + log.Printf("Root login enabled on %s", node.Name) } return nil } @@ -771,7 +783,7 @@ func (b *GCPBootstrapper) EnsureJumpboxConfigured() error { } hasOms := b.env.Jumpbox.HasCommand(b.NodeManager, "oms-cli") if hasOms { - fmt.Println("OMS already installed on jumpbox") + log.Println("OMS already installed on jumpbox") return nil } err := b.env.Jumpbox.InstallOms(b.NodeManager) @@ -779,7 +791,7 @@ func (b *GCPBootstrapper) EnsureJumpboxConfigured() error { return fmt.Errorf("failed to install OMS on jumpbox: %w", err) } - fmt.Println("OMS installed on jumpbox") + log.Println("OMS installed on jumpbox") return nil } @@ -801,7 +813,7 @@ func (b *GCPBootstrapper) EnsureHostsConfigured() error { return fmt.Errorf("failed to configure memory map on %s: %w", node.Name, err) } } - fmt.Printf("Host %s configured\n", node.Name) + log.Printf("Host %s configured", node.Name) } return nil } @@ -1061,7 +1073,7 @@ func (b *GCPBootstrapper) UpdateInstallConfig() error { func (b *GCPBootstrapper) EnsureAgeKey() error { hasKey := b.env.Jumpbox.HasFile(nil, b.NodeManager, b.env.SecretsDir+"/age_key.txt") if hasKey { - fmt.Println("Age key already present on jumpbox") + log.Println("Age key already present on jumpbox") return nil } @@ -1070,7 +1082,7 @@ func (b *GCPBootstrapper) EnsureAgeKey() error { return fmt.Errorf("failed to generate age key on jumpbox: %w", err) } - fmt.Println("Age key generated on jumpbox") + log.Println("Age key generated on jumpbox") return nil } @@ -1085,7 +1097,7 @@ func (b *GCPBootstrapper) EncryptVault() error { return fmt.Errorf("failed to encrypt vault on jumpbox: %w", err) } - fmt.Println("Vault encrypted on jumpbox") + log.Println("Vault encrypted on jumpbox") return nil } @@ -1171,7 +1183,7 @@ func (b *GCPBootstrapper) EnsureDNSRecords() error { return fmt.Errorf("failed to create DNS records: %w", err) } - fmt.Printf("DNS records created in project %s zone %s\n", gcpProject, zoneName) + log.Printf("DNS records created in project %s zone %s", gcpProject, zoneName) return nil } @@ -1186,7 +1198,7 @@ func (b *GCPBootstrapper) InstallCodesphere() error { return fmt.Errorf("failed to install Codesphere from jumpbox: %w", err) } - fmt.Println("Codesphere installed from jumpbox") + log.Println("Codesphere installed from jumpbox") return nil } diff --git a/internal/bootstrap/gcp_client.go b/internal/bootstrap/gcp_client.go index 96a5764..9e93e03 100644 --- a/internal/bootstrap/gcp_client.go +++ b/internal/bootstrap/gcp_client.go @@ -151,12 +151,16 @@ func (c *RealGCPClient) EnableAPIs(ctx context.Context, projectID string, apis [ for _, api := range apis { serviceName := fmt.Sprintf("projects/%s/services/%s", projectID, api) wg.Add(1) + go func(serviceName, api string) { defer wg.Done() - log.Printf("Enabling API %s\n", api) + + log.Printf("Enabling API %s", api) + op, err := client.EnableService(ctx, &serviceusagepb.EnableServiceRequest{Name: serviceName}) if status.Code(err) == codes.AlreadyExists { - log.Printf("API %s already enabled\n", api) + log.Printf("API %s already enabled", api) + return } if err != nil { @@ -165,9 +169,11 @@ func (c *RealGCPClient) EnableAPIs(ctx context.Context, projectID string, apis [ if _, err := op.Wait(ctx); err != nil { errCh <- fmt.Errorf("failed to enable API %s: %w", api, err) } - log.Printf("API %s enabled\n", api) + + log.Printf("API %s enabled", api) }(serviceName, api) } + wg.Wait() close(errCh) errStr := "" @@ -375,7 +381,8 @@ func (c *RealGCPClient) CreateVPC(ctx context.Context, projectID, region, networ return fmt.Errorf("failed to wait for router creation: %w", err) } } - fmt.Printf("Router %s ensured\n", routerName) + + log.Printf("Router %s ensured", routerName) // Create NAT Gateway natsClient, err := compute.NewRoutersRESTClient(ctx) @@ -406,7 +413,9 @@ func (c *RealGCPClient) CreateVPC(ctx context.Context, projectID, region, networ if err != nil && !isAlreadyExistsError(err) { return fmt.Errorf("failed to create NAT gateway: %w", err) } - fmt.Printf("NAT gateway %s ensured\n", natName) + + log.Printf("NAT gateway %s ensured", natName) + return nil } diff --git a/internal/installer/config_manager_profile.go b/internal/installer/config_manager_profile.go index d2f9d1a..3912683 100644 --- a/internal/installer/config_manager_profile.go +++ b/internal/installer/config_manager_profile.go @@ -5,6 +5,7 @@ package installer import ( "fmt" + "log" "github.com/codesphere-cloud/oms/internal/installer/files" ) @@ -119,7 +120,7 @@ func (g *InstallConfig) ApplyProfile(profile string) error { g.Config.Codesphere.WorkspaceHostingBaseDomain = "ws.local" g.Config.Codesphere.CustomDomains.CNameBaseDomain = "custom.local" g.Config.Codesphere.DNSServers = []string{"8.8.8.8", "1.1.1.1"} - fmt.Println("Applied 'dev' profile: single-node development setup") + log.Println("Applied 'dev' profile: single-node development setup") case PROFILE_PROD, PROFILE_PRODUCTION: g.Config.Datacenter.Name = "production" @@ -158,7 +159,7 @@ func (g *InstallConfig) ApplyProfile(profile string) error { OnDemand: true, }, } - fmt.Println("Applied 'production' profile: HA multi-node setup") + log.Println("Applied 'production' profile: HA multi-node setup") case PROFILE_MINIMAL: g.Config.Datacenter.Name = "minimal" @@ -182,7 +183,7 @@ func (g *InstallConfig) ApplyProfile(profile string) error { OnDemand: true, }, } - fmt.Println("Applied 'minimal' profile: minimal single-node setup") + log.Println("Applied 'minimal' profile: minimal single-node setup") default: return fmt.Errorf("unknown profile: %s, available profiles: dev, prod, minimal", profile) diff --git a/internal/installer/config_manager_secrets.go b/internal/installer/config_manager_secrets.go index a46f477..f9f1744 100644 --- a/internal/installer/config_manager_secrets.go +++ b/internal/installer/config_manager_secrets.go @@ -5,25 +5,27 @@ package installer import ( "fmt" + "log" "github.com/codesphere-cloud/oms/internal/installer/files" ) func (g *InstallConfig) GenerateSecrets() error { - fmt.Println("Generating domain authentication keys...") + log.Println("Generating domain authentication keys...") + var err error g.Config.Codesphere.DomainAuthPublicKey, g.Config.Codesphere.DomainAuthPrivateKey, err = GenerateECDSAKeyPair() if err != nil { return fmt.Errorf("failed to generate domain auth keys: %w", err) } - fmt.Println("Generating ingress CA certificate...") + log.Println("Generating ingress CA certificate...") g.Config.Cluster.IngressCAKey, g.Config.Cluster.Certificates.CA.CertPem, err = GenerateCA("Cluster Ingress CA", "DE", "Karlsruhe", "Codesphere") if err != nil { return fmt.Errorf("failed to generate ingress CA: %w", err) } - fmt.Println("Generating Ceph SSH keys...") + log.Println("Generating Ceph SSH keys...") g.Config.Ceph.SshPrivateKey, g.Config.Ceph.CephAdmSSHKey.PublicKey, err = GenerateSSHKeyPair() if err != nil { return fmt.Errorf("failed to generate Ceph SSH keys: %w", err) @@ -39,7 +41,8 @@ func (g *InstallConfig) GenerateSecrets() error { } func (g *InstallConfig) generatePostgresSecrets(config *files.RootConfig) error { - fmt.Println("Generating PostgreSQL certificates and passwords...") + log.Println("Generating PostgreSQL certificates and passwords...") + var err error config.Postgres.CaCertPrivateKey, config.Postgres.CACertPem, err = GenerateCA("PostgreSQL CA", "DE", "Karlsruhe", "Codesphere") if err != nil { diff --git a/internal/tmpl/NOTICE b/internal/tmpl/NOTICE index c40568e..df833f3 100644 --- a/internal/tmpl/NOTICE +++ b/internal/tmpl/NOTICE @@ -267,12 +267,6 @@ Version: v0.5.15 License: BSD-3-Clause License URL: https://github.com/ulikunitz/xz/blob/v0.5.15/LICENSE ----------- -Module: github.com/yaml/go-yaml -Version: v2.1.0 -License: Apache-2.0 -License URL: https://github.com/yaml/go-yaml/blob/v2.1.0/LICENSE - ---------- Module: go.opentelemetry.io/auto/sdk Version: v1.2.1 diff --git a/internal/util/filewriter.go b/internal/util/filewriter.go index 2f9552c..8872282 100644 --- a/internal/util/filewriter.go +++ b/internal/util/filewriter.go @@ -5,6 +5,7 @@ package util import ( "fmt" + "log" "os" ) @@ -43,7 +44,7 @@ func (fs *FilesystemWriter) CreateAndWrite(filePath string, data []byte, fileTyp return fmt.Errorf("failed to write %s file: %w", fileType, err) } - fmt.Printf("\n%s file created: %s\n", fileType, filePath) + log.Printf("\n%s file created: %s", fileType, filePath) return nil }