Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 28 additions & 28 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ This project includes code licensed under the following terms:

----------
Module: cloud.google.com/go/artifactregistry
Version: v1.19.0
Version: v1.20.0
License: Apache-2.0
License URL: https://github.com/googleapis/google-cloud-go/blob/artifactregistry/v1.19.0/artifactregistry/LICENSE
License URL: https://github.com/googleapis/google-cloud-go/blob/artifactregistry/v1.20.0/artifactregistry/LICENSE

----------
Module: cloud.google.com/go/auth
Expand Down Expand Up @@ -95,9 +95,9 @@ License URL: https://github.com/clipperhouse/uax29/blob/v2.4.0/LICENSE

----------
Module: github.com/codesphere-cloud/cs-go
Version: v0.16.4
Version: v0.17.0
License: Apache-2.0
License URL: https://github.com/codesphere-cloud/cs-go/blob/v0.16.4/LICENSE
License URL: https://github.com/codesphere-cloud/cs-go/blob/v0.17.0/LICENSE

----------
Module: github.com/codesphere-cloud/oms/internal/tmpl
Expand Down Expand Up @@ -179,9 +179,9 @@ License URL: https://github.com/googleapis/enterprise-certificate-proxy/blob/v0.

----------
Module: github.com/googleapis/gax-go/v2
Version: v2.16.0
Version: v2.17.0
License: BSD-3-Clause
License URL: https://github.com/googleapis/gax-go/blob/v2.16.0/v2/LICENSE
License URL: https://github.com/googleapis/gax-go/blob/v2.17.0/v2/LICENSE

----------
Module: github.com/hashicorp/go-cleanhttp
Expand Down Expand Up @@ -353,21 +353,21 @@ License URL: https://github.com/yaml/go-yaml/blob/v3.0.4/LICENSE

----------
Module: golang.org/x/crypto
Version: v0.47.0
Version: v0.48.0
License: BSD-3-Clause
License URL: https://cs.opensource.google/go/x/crypto/+/v0.47.0:LICENSE
License URL: https://cs.opensource.google/go/x/crypto/+/v0.48.0:LICENSE

----------
Module: golang.org/x/net
Version: v0.49.0
Version: v0.50.0
License: BSD-3-Clause
License URL: https://cs.opensource.google/go/x/net/+/v0.49.0:LICENSE
License URL: https://cs.opensource.google/go/x/net/+/v0.50.0:LICENSE

----------
Module: golang.org/x/oauth2
Version: v0.34.0
Version: v0.35.0
License: BSD-3-Clause
License URL: https://cs.opensource.google/go/x/oauth2/+/v0.34.0:LICENSE
License URL: https://cs.opensource.google/go/x/oauth2/+/v0.35.0:LICENSE

----------
Module: golang.org/x/sync/semaphore
Expand All @@ -377,21 +377,21 @@ License URL: https://cs.opensource.google/go/x/sync/+/v0.19.0:LICENSE

----------
Module: golang.org/x/sys
Version: v0.40.0
Version: v0.41.0
License: BSD-3-Clause
License URL: https://cs.opensource.google/go/x/sys/+/v0.40.0:LICENSE
License URL: https://cs.opensource.google/go/x/sys/+/v0.41.0:LICENSE

----------
Module: golang.org/x/term
Version: v0.39.0
Version: v0.40.0
License: BSD-3-Clause
License URL: https://cs.opensource.google/go/x/term/+/v0.39.0:LICENSE
License URL: https://cs.opensource.google/go/x/term/+/v0.40.0:LICENSE

----------
Module: golang.org/x/text
Version: v0.33.0
Version: v0.34.0
License: BSD-3-Clause
License URL: https://cs.opensource.google/go/x/text/+/v0.33.0:LICENSE
License URL: https://cs.opensource.google/go/x/text/+/v0.34.0:LICENSE

----------
Module: golang.org/x/time/rate
Expand All @@ -401,15 +401,15 @@ License URL: https://cs.opensource.google/go/x/time/+/v0.14.0:LICENSE

----------
Module: google.golang.org/api
Version: v0.264.0
Version: v0.266.0
License: BSD-3-Clause
License URL: https://github.com/googleapis/google-api-go-client/blob/v0.264.0/LICENSE
License URL: https://github.com/googleapis/google-api-go-client/blob/v0.266.0/LICENSE

----------
Module: google.golang.org/api/internal/third_party/uritemplates
Version: v0.264.0
Version: v0.266.0
License: BSD-3-Clause
License URL: https://github.com/googleapis/google-api-go-client/blob/v0.264.0/internal/third_party/uritemplates/LICENSE
License URL: https://github.com/googleapis/google-api-go-client/blob/v0.266.0/internal/third_party/uritemplates/LICENSE

----------
Module: google.golang.org/genproto/googleapis
Expand All @@ -419,21 +419,21 @@ License URL: https://github.com/googleapis/go-genproto/blob/8636f8732409/LICENSE

----------
Module: google.golang.org/genproto/googleapis/api
Version: v0.0.0-20260128011058-8636f8732409
Version: v0.0.0-20260203192932-546029d2fa20
License: Apache-2.0
License URL: https://github.com/googleapis/go-genproto/blob/8636f8732409/googleapis/api/LICENSE
License URL: https://github.com/googleapis/go-genproto/blob/546029d2fa20/googleapis/api/LICENSE

----------
Module: google.golang.org/genproto/googleapis/rpc
Version: v0.0.0-20260128011058-8636f8732409
Version: v0.0.0-20260203192932-546029d2fa20
License: Apache-2.0
License URL: https://github.com/googleapis/go-genproto/blob/8636f8732409/googleapis/rpc/LICENSE
License URL: https://github.com/googleapis/go-genproto/blob/546029d2fa20/googleapis/rpc/LICENSE

----------
Module: google.golang.org/grpc
Version: v1.78.0
Version: v1.79.1
License: Apache-2.0
License URL: https://github.com/grpc/grpc-go/blob/v1.78.0/LICENSE
License URL: https://github.com/grpc/grpc-go/blob/v1.79.1/LICENSE

----------
Module: google.golang.org/protobuf
Expand Down
5 changes: 2 additions & 3 deletions cli/cmd/bootstrap_gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ func AddBootstrapGcpCmd(parent *cobra.Command, opts *GlobalOptions) {
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.BaseDomain, "base-domain", "", "Base domain for Codesphere (required)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.GithubAppClientID, "github-app-client-id", "", "Github App Client ID (required)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.GithubAppClientSecret, "github-app-client-secret", "", "Github App Client Secret (required)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.GitHubPAT, "github-pat", "", "GitHub Personal Access Token to use for direct image access. Scope required: package read (optional)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.GitHubAppName, "github-app-name", "", "Github App Name (optional)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.SecretsDir, "secrets-dir", "/etc/codesphere/secrets", "Directory for secrets (default: /etc/codesphere/secrets)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.FolderID, "folder-id", "", "GCP Folder ID (optional)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.SSHPublicKeyPath, "ssh-public-key-path", "~/.ssh/id_rsa.pub", "SSH Public Key Path (default: ~/.ssh/id_rsa.pub)")
Expand All @@ -74,16 +76,13 @@ func AddBootstrapGcpCmd(parent *cobra.Command, opts *GlobalOptions) {
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.Region, "region", "europe-west4", "GCP Region (default: europe-west4)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.Zone, "zone", "europe-west4-a", "GCP Zone (default: europe-west4-a)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.DNSProjectID, "dns-project-id", "", "GCP Project ID for Cloud DNS (optional)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.DNSProjectServiceAccount, "dns-project-sa", "", "GCP Project Service Account for Cloud DNS (optional)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.DNSZoneName, "dns-zone-name", "oms-testing", "Cloud DNS Zone Name (optional)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.InstallVersion, "install-version", "", "Codesphere version to install (default: none)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.InstallHash, "install-hash", "", "Codesphere package hash to install (default: none)")
flags.StringArrayVarP(&bootstrapGcpCmd.CodesphereEnv.InstallSkipSteps, "install-skip-steps", "s", []string{}, "Installation steps to skip during Codesphere installation (optional)")

flags.StringVar(&bootstrapGcpCmd.InputRegistryType, "registry-type", "local-container", "Container registry type to use (options: local-container, artifact-registry) (default: artifact-registry)")
flags.BoolVar(&bootstrapGcpCmd.CodesphereEnv.WriteConfig, "write-config", true, "Write generated install config to file (default: true)")
flags.BoolVar(&bootstrapGcpCmd.SSHQuiet, "ssh-quiet", true, "Suppress SSH command output (default: true)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.GitHubPAT, "github-pat", "", "GitHub Personal Access Token to use for direct image access. Scope required: package read (optional)")
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.RegistryUser, "registry-user", "", "Custom Registry username (only for GitHub registry type) (optional)")
flags.StringArrayVar(&bootstrapGcpCmd.CodesphereEnv.Experiments, "experiments", gcp.DefaultExperiments, "Experiments to enable in Codesphere installation (optional)")
flags.StringArrayVar(&bootstrapGcpCmd.CodesphereEnv.FeatureFlags, "feature-flags", []string{}, "Feature flags to enable in Codesphere installation (optional)")
Expand Down
2 changes: 1 addition & 1 deletion docs/oms-cli_beta_bootstrap-gcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ oms-cli beta bootstrap-gcp [flags]
--custom-pg-ip string Custom PostgreSQL IP (optional)
--datacenter-id int Datacenter ID (default: 1) (default 1)
--dns-project-id string GCP Project ID for Cloud DNS (optional)
--dns-project-sa string GCP Project Service Account for Cloud DNS (optional)
--dns-zone-name string Cloud DNS Zone Name (optional) (default "oms-testing")
--experiments stringArray Experiments to enable in Codesphere installation (optional) (default [managed-services,vcluster,custom-service-image,ms-in-ls,secret-management,sub-path-mount])
--feature-flags stringArray Feature flags to enable in Codesphere installation (optional)
--folder-id string GCP Folder ID (optional)
--github-app-client-id string Github App Client ID (required)
--github-app-client-secret string Github App Client Secret (required)
--github-app-name string Github App Name (optional)
--github-pat string GitHub Personal Access Token to use for direct image access. Scope required: package read (optional)
-h, --help help for bootstrap-gcp
--install-config string Path to install config file (optional) (default "config.yaml")
Expand Down
89 changes: 47 additions & 42 deletions internal/bootstrap/gcp/gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"errors"
"fmt"
"slices"
"sort"
"strings"
"sync"
Expand Down Expand Up @@ -78,28 +79,28 @@ type GCPBootstrapper struct {
}

type CodesphereEnvironment struct {
ProjectID string `json:"project_id"`
ProjectName string `json:"project_name"`
DNSProjectID string `json:"dns_project_id"`
DNSProjectServiceAccount string `json:"dns_project_service_account"`
Jumpbox *node.Node `json:"jumpbox"`
PostgreSQLNode *node.Node `json:"postgres_node"`
ControlPlaneNodes []*node.Node `json:"control_plane_nodes"`
CephNodes []*node.Node `json:"ceph_nodes"`
ContainerRegistryURL string `json:"-"`
ExistingConfigUsed bool `json:"-"`
InstallVersion string `json:"install_version"`
InstallHash string `json:"install_hash"`
InstallSkipSteps []string `json:"install_skip_steps"`
Preemptible bool `json:"preemptible"`
WriteConfig bool `json:"-"`
GatewayIP string `json:"gateway_ip"`
PublicGatewayIP string `json:"public_gateway_ip"`
RegistryType RegistryType `json:"registry_type"`
GitHubPAT string `json:"-"`
RegistryUser string `json:"-"`
Experiments []string `json:"experiments"`
FeatureFlags []string `json:"feature_flags"`
ProjectID string `json:"project_id"`
ProjectName string `json:"project_name"`
DNSProjectID string `json:"dns_project_id"`
Jumpbox *node.Node `json:"jumpbox"`
PostgreSQLNode *node.Node `json:"postgres_node"`
ControlPlaneNodes []*node.Node `json:"control_plane_nodes"`
CephNodes []*node.Node `json:"ceph_nodes"`
ContainerRegistryURL string `json:"-"`
ExistingConfigUsed bool `json:"-"`
InstallVersion string `json:"install_version"`
InstallHash string `json:"install_hash"`
InstallSkipSteps []string `json:"install_skip_steps"`
Preemptible bool `json:"preemptible"`
WriteConfig bool `json:"-"`
GatewayIP string `json:"gateway_ip"`
PublicGatewayIP string `json:"public_gateway_ip"`
RegistryType RegistryType `json:"registry_type"`
GitHubPAT string `json:"-"`
GitHubAppName string `json:"-"`
RegistryUser string `json:"-"`
Experiments []string `json:"experiments"`
FeatureFlags []string `json:"feature_flags"`

// Config
InstallConfigPath string `json:"-"`
Expand Down Expand Up @@ -154,9 +155,9 @@ func GetInfraFilePath() string {

func (b *GCPBootstrapper) Bootstrap() error {
if b.Env.InstallVersion != "" {
err := b.stlog.Step("Validate package to install", b.ValidatePackageName)
err := b.stlog.Step("Validate input", b.ValidateInput)
if err != nil {
return fmt.Errorf("invalid package name: %w", err)
return fmt.Errorf("invalid input: %w", err)
}

}
Expand Down Expand Up @@ -293,7 +294,7 @@ func (b *GCPBootstrapper) Bootstrap() error {
return nil
}

func (b *GCPBootstrapper) ValidatePackageName() error {
func (b *GCPBootstrapper) ValidateInput() error {
build, err := b.PortalClient.GetBuild(portal.CodesphereProduct, b.Env.InstallVersion, b.Env.InstallHash)
if err != nil {
return fmt.Errorf("failed to get codesphere package: %w", err)
Expand All @@ -312,6 +313,11 @@ func (b *GCPBootstrapper) ValidatePackageName() error {
}
}

ghParams := []string{b.Env.GitHubAppName, b.Env.GithubAppClientID, b.Env.GithubAppClientSecret}
if slices.Contains(ghParams, "") && strings.Join(ghParams, "") != "" {
return fmt.Errorf("GitHub app credentials are not fully specified (all or none of GitHubAppName, GithubAppClientID, GithubAppClientSecret must be set)")
}

return fmt.Errorf("specified package does not contain required installer artifact %s. Existing artifacts: %s", requiredFilename, strings.Join(filenames, ", "))
}

Expand Down Expand Up @@ -467,7 +473,7 @@ func (b *GCPBootstrapper) EnsureServiceAccounts() error {
}

func (b *GCPBootstrapper) EnsureIAMRoles() error {
err := b.ensureIAMRoleWithRetry("cloud-controller", []string{"roles/compute.admin"})
err := b.ensureIAMRoleWithRetry(b.Env.ProjectID, "cloud-controller", b.Env.ProjectID, []string{"roles/compute.admin"})
if err != nil {
return err
}
Expand All @@ -481,14 +487,14 @@ func (b *GCPBootstrapper) EnsureIAMRoles() error {
return nil
}

err = b.ensureIAMRoleWithRetry("artifact-registry-writer", []string{"roles/artifactregistry.writer"})
err = b.ensureIAMRoleWithRetry(b.Env.ProjectID, "artifact-registry-writer", b.Env.ProjectID, []string{"roles/artifactregistry.writer"})
return err
}

func (b *GCPBootstrapper) ensureIAMRoleWithRetry(serviceAccount string, roles []string) error {
func (b *GCPBootstrapper) ensureIAMRoleWithRetry(projectID string, serviceAccount string, serviceAccountProjectID string, roles []string) error {
var err error
for retries := range 5 {
err = b.GCPClient.AssignIAMRole(b.Env.ProjectID, serviceAccount, roles)
err = b.GCPClient.AssignIAMRole(projectID, serviceAccount, serviceAccountProjectID, roles)
if err == nil {
return nil
}
Expand All @@ -501,17 +507,11 @@ func (b *GCPBootstrapper) ensureIAMRoleWithRetry(serviceAccount string, roles []
}

func (b *GCPBootstrapper) ensureDnsPermissions() error {
if b.Env.DNSProjectID != "" {
if b.Env.DNSProjectServiceAccount == "" {
return errors.New("dns project service account with role roles/dns.admin must be provided when dns project id is set")
}
err := b.GCPClient.GrantImpersonation("cloud-controller", b.Env.ProjectID, b.Env.DNSProjectServiceAccount, b.Env.DNSProjectID)
if err != nil {
return fmt.Errorf("failed to grant impersonization on dns project %s to cloud-controller service account: %w", b.Env.DNSProjectID, err)
}
return nil
dnsProject := b.Env.DNSProjectID
if b.Env.DNSProjectID == "" {
dnsProject = b.Env.ProjectID
}
err := b.ensureIAMRoleWithRetry("cloud-controller", []string{"roles/dns.admin"})
err := b.ensureIAMRoleWithRetry(dnsProject, "cloud-controller", b.Env.ProjectID, []string{"roles/dns.admin"})
if err != nil {
return err
}
Expand Down Expand Up @@ -1218,8 +1218,10 @@ func (b *GCPBootstrapper) UpdateInstallConfig() error {
},
},
}
b.Env.InstallConfig.Codesphere.GitProviders = &files.GitProvidersConfig{
GitHub: &files.GitProviderConfig{

b.Env.InstallConfig.Codesphere.GitProviders = &files.GitProvidersConfig{}
if b.Env.GitHubAppName != "" && b.Env.GithubAppClientID != "" && b.Env.GithubAppClientSecret != "" {
b.Env.InstallConfig.Codesphere.GitProviders.GitHub = &files.GitProviderConfig{
Enabled: true,
URL: "https://github.com",
API: files.APIConfig{
Expand All @@ -1229,11 +1231,14 @@ func (b *GCPBootstrapper) UpdateInstallConfig() error {
Issuer: "https://github.com",
AuthorizationEndpoint: "https://github.com/login/oauth/authorize",
TokenEndpoint: "https://github.com/login/oauth/access_token",
ClientAuthMethod: "client_secret_post",
RedirectURI: "https://cs." + b.Env.BaseDomain + "/ide/auth/github/callback",
InstallationURI: "https://github.com/apps/" + b.Env.GitHubAppName + "/installations/new",

ClientID: b.Env.GithubAppClientID,
ClientSecret: b.Env.GithubAppClientSecret,
},
},
}
}
b.Env.InstallConfig.Codesphere.Experiments = b.Env.Experiments
b.Env.InstallConfig.Codesphere.Features = b.Env.FeatureFlags
Expand Down
Loading