Skip to content

feat(fga): Cluster Admin Email assignment gets part of bootstrap command#555

Open
nbrodnicke wants to merge 1 commit into
mainfrom
niklas/cluster-admin-bootstrap
Open

feat(fga): Cluster Admin Email assignment gets part of bootstrap command#555
nbrodnicke wants to merge 1 commit into
mainfrom
niklas/cluster-admin-bootstrap

Conversation

@nbrodnicke

@nbrodnicke nbrodnicke commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

CU-869dz4umw

Cluster admin email as part of bootstrap-gcp

Previously, the cluster admin email was set manually in a separate SSH step after bootstrap. This PR makes it a regular, optional part of the bootstrap and install flow instead.

What changes:

New --cluster-admin-email flag on oms beta bootstrap-gcp (optional, no behavior change when unset).
The email is now stored in the install config (codesphere.clusterAdminEmail) instead of only being set temporarily via SSH — it therefore survives re-runs with --write-config/--recover-config.
oms install codesphere automatically creates the cluster-admin-email secret before the platform phase (auth-service) starts — no manual extra step, no service restart needed.
Reuses the existing add-cluster-admin logic instead of duplicating it.
Why: So integration tests (and production bootstraps) get the cluster admin set consistently and reproducibly from the start, instead of relying on a fragile, separate SSH step in the CI workflow.

@nbrodnicke nbrodnicke self-assigned this Jul 3, 2026
@jonas-zipprick

Copy link
Copy Markdown

Signed-off-by: Niklas Brodnicke <niklas@codesphere.com>
@nbrodnicke nbrodnicke force-pushed the niklas/cluster-admin-bootstrap branch from 2b48970 to 865f0b3 Compare July 3, 2026 13:39

@OliverTrautvetter OliverTrautvetter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments and questions 👍

Comment on lines +40 to +42
if err := ensureClusterAdminSecret(context.Background(), opts, cfg); err != nil {
return fmt.Errorf("failed to set cluster admin email: %w", err)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we thread a context.Context through installCodespherePlatform instead of using a fixed context.Background()?

Comment on lines +451 to +469
func (b *GCPBootstrapper) validateClusterAdminEmail() error {
if b.Env.ClusterAdminEmail == "" {
return nil
}

// The email reaches the cluster via the install config, which is only
// updated when the config is written.
if !b.Env.WriteConfig {
return fmt.Errorf("cluster admin email requires write-config to be enabled")
}

email, err := clusteradmin.NormalizeEmail(b.Env.ClusterAdminEmail)
if err != nil {
return fmt.Errorf("invalid cluster admin email: %w", err)
}
b.Env.ClusterAdminEmail = email

return nil
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we allow the flag without --write-config when --recover-config is also set?

// codesphere.clusterAdminEmail to the cluster-admin-email secret before the
// platform is installed, so the auth-service finds it on first start.
// It is a no-op when the config does not set an email.
func ensureClusterAdminSecret(ctx context.Context, opts *InstallCodesphereOpts, cfg files.RootConfig) error {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it duplicates the vault-loading and kubeconfig-extraction pattern that already exists in loadVaultData in install_codesphere_dependencies.go

extract a shared helper maybe?

Comment on lines +106 to +114
func ensureNamespace(ctx context.Context, clientset kubernetes.Interface, namespace string) error {
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{Name: namespace},
}
if _, err := clientset.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) {
return fmt.Errorf("creating namespace %s: %w", namespace, err)
}
return nil
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't wait for the namespace, so the namespace might not be visible yet when secrets.Create is called. Is that a problem?

// codesphere.clusterAdminEmail to the cluster-admin-email secret before the
// platform is installed, so the auth-service finds it on first start.
// It is a no-op when the config does not set an email.
func ensureClusterAdminSecret(ctx context.Context, opts *InstallCodesphereOpts, cfg files.RootConfig) error {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this function does a lot of infrastructure stuff. So maybe this function would make more sense in the installer or clusteradmin package and not the cli command layer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants