Skip to content

feat: cleanup bootstrapped infra#185

Open
OliverTrautvetter wants to merge 40 commits intomainfrom
cleanup_bootstrapped_infra
Open

feat: cleanup bootstrapped infra#185
OliverTrautvetter wants to merge 40 commits intomainfrom
cleanup_bootstrapped_infra

Conversation

@OliverTrautvetter
Copy link
Member

@OliverTrautvetter OliverTrautvetter commented Feb 10, 2026

Add the ability to clean up the infrastructure I created with oms beta bootstrap-gcp , so that no manual cleanup is required.

Clickup

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new bootstrap-gcp cleanup CLI subcommand to delete OMS-bootstrapped GCP projects (optionally cleaning up OMS-created DNS records), aiming to remove the need for manual teardown.

Changes:

  • Add oms beta bootstrap-gcp cleanup command with --project-id, --force, and --skip-dns-cleanup flags.
  • Label newly created GCP projects with oms-managed=true and add client methods to verify/delete OMS-managed projects and delete OMS DNS records.
  • Add docs and initial test scaffolding for the cleanup functionality.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/bootstrap/gcp/gcp_client.go Adds OMS-managed labeling on project creation and implements delete/verification/DNS cleanup client methods.
internal/bootstrap/gcp/mocks.go Updates generated mock to include new GCP client manager methods.
internal/bootstrap/gcp/gcp_client_cleanup_test.go Adds new tests around constants/formatting (currently not exercising new production code paths).
cli/cmd/bootstrap_gcp_cleanup.go Implements the new cleanup subcommand behavior (infra file loading, verification/prompt, DNS cleanup, project deletion).
cli/cmd/bootstrap_gcp_cleanup_test.go Adds tests for opts defaults and flag wiring for the new command.
cli/cmd/bootstrap_gcp.go Registers the new cleanup subcommand under bootstrap-gcp.
docs/oms-cli_beta_bootstrap-gcp_cleanup.md Documents the new cleanup command and flags.
docs/oms-cli_beta_bootstrap-gcp.md Adds the cleanup subcommand to the bootstrap-gcp docs index.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@OliverTrautvetter OliverTrautvetter requested review from a team and siherrmann and removed request for a team February 11, 2026 12:14
@OliverTrautvetter OliverTrautvetter marked this pull request as ready for review February 16, 2026 10:07
@OliverTrautvetter OliverTrautvetter removed the request for review from siherrmann February 24, 2026 09:43
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

OliverTrautvetter and others added 8 commits February 26, 2026 11:58
Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com>
Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com>
Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com>
Comment on lines +224 to +238
Example: ` # Clean up using project ID from the local infra file
oms-cli beta bootstrap-gcp cleanup

# Clean up a specific project
oms-cli beta bootstrap-gcp cleanup --project-id my-project-abc123

# Force cleanup without confirmation (skips OMS-managed check)
oms-cli beta bootstrap-gcp cleanup --project-id my-project-abc123 --force

# Skip DNS record cleanup
oms-cli beta bootstrap-gcp cleanup --skip-dns-cleanup

# Clean up with manual DNS settings (when infra file is not available)
oms-cli beta bootstrap-gcp cleanup --project-id my-project --base-domain example.com --dns-zone-name my-zone --dns-project-id dns-project`,
},
Copy link
Member

Choose a reason for hiding this comment

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

should use the example util so you don't need to think about the oms-cli or oms binary name

Comment on lines +73 to +108
state, err := c.resolveCleanupConfig(deps)
if err != nil {
return fmt.Errorf("failed to resolve cleanup configuration: %w", err)
}

err = c.verifyAndConfirm(deps, state)
if err != nil {
return err
}

if !c.Opts.SkipDNSCleanup && state.baseDomain != "" && state.dnsZoneName != "" {
err = deps.StepLogger.Step("Clean up DNS records", func() error {
return deps.GCPClient.DeleteDNSRecordSets(state.dnsProjectID, state.dnsZoneName, state.baseDomain)
})
if err != nil {
log.Printf("Warning: DNS cleanup failed: %v", err)
log.Printf("You may need to manually delete DNS records for %s in project %s", state.baseDomain, state.dnsProjectID)
}
} else if !c.Opts.SkipDNSCleanup {
log.Printf("Skipping DNS cleanup: missing base domain or DNS zone name (provide --base-domain/--dns-zone-name or use --skip-dns-cleanup)")
}

err = deps.StepLogger.Step("Delete GCP project", func() error {
return deps.GCPClient.DeleteProject(state.projectID)
})
if err != nil {
return fmt.Errorf("failed to delete project: %w", err)
}

c.removeLocalInfraFile(deps, state)

log.Println("\nGCP project cleanup completed successfully!")
log.Printf("Project '%s' has been scheduled for deletion.", state.projectID)
log.Printf("Note: GCP projects are retained for 30 days before permanent deletion. You can restore the project within this period from the GCP Console.")

return nil
Copy link
Member

Choose a reason for hiding this comment

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

I think this function could look a bit simpler if you moved the 3 steps verify, dns cleanup, project deletion in their own functions each, in the best case each not taking an argument but instead on a struct that knows the "state", or as methods of the state struct. Then each step would become something like

err = deps.StepLogger.Step("Delete GCP project", state.DeleteProject)
if err != nil {
...
}


if !c.Opts.SkipDNSCleanup && state.baseDomain != "" && state.dnsZoneName != "" {
err = deps.StepLogger.Step("Clean up DNS records", func() error {
return deps.GCPClient.DeleteDNSRecordSets(state.dnsProjectID, state.dnsZoneName, state.baseDomain)
Copy link
Member

Choose a reason for hiding this comment

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

this part is now missing the service account of the project that became permissions to do DNS stuff on the dnsproject


// resolveCleanupConfig loads the infra file (if needed) and determines the project ID
// and DNS settings from flags and/or the infra file.
func (c *BootstrapGcpCleanupCmd) resolveCleanupConfig(deps *CleanupDeps) (*cleanupState, error) {
Copy link
Member

Choose a reason for hiding this comment

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

lots of else ifs in this function, I think it would be helpful to split it up so you can turn some of them into returns and reduce the complexity. (cyclomatic complexity here is 16)

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