Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/cli. OpenStatus CLI www.openstatus.dev
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178package terraform
import ( "context" "fmt" "os" "path/filepath"
"github.com/urfave/cli/v3"
"github.com/openstatusHQ/cli/internal/api" "github.com/openstatusHQ/cli/internal/auth" output "github.com/openstatusHQ/cli/internal/cli")
var generatedFileNames = []string{ "provider.tf", "monitors.tf", "notifications.tf", "status_pages.tf", "private_locations.tf", "imports.tf",}
func GetTerraformGenerateCmd() *cli.Command { return &cli.Command{ Name: "generate", Aliases: []string{"gen"}, Usage: "Generate Terraform configuration from workspace resources", UsageText: "openstatus terraform generate [--output-dir ./openstatus-terraform/]", Flags: []cli.Flag{ &cli.StringFlag{ Name: "access-token", Usage: "OpenStatus API Access Token", Aliases: []string{"t"}, Sources: cli.EnvVars("OPENSTATUS_API_TOKEN"), }, &cli.StringFlag{ Name: "output-dir", Usage: "Directory to write Terraform files into", Value: "./openstatus-terraform/", Aliases: []string{"o"}, }, &cli.BoolFlag{ Name: "force", Usage: "Overwrite existing files in --output-dir", Aliases: []string{"f"}, }, }, Action: func(ctx context.Context, cmd *cli.Command) error { apiKey, err := auth.ResolveAccessToken(cmd) if err != nil { return cli.Exit(err.Error(), 1) }
outputDir := cmd.String("output-dir") if err := checkExistingFiles(outputDir, cmd.Bool("force")); err != nil { return cli.Exit(err.Error(), 1) } if err := os.MkdirAll(outputDir, 0o755); err != nil { return cli.Exit(fmt.Sprintf("failed to create output directory: %v", err), 1) }
s := output.StartSpinner("Fetching workspace resources...") data, err := FetchWorkspaceData(ctx, apiKey) output.StopSpinner(s) if err != nil { return cli.Exit(err.Error(), 1) }
gen := NewGenerator(data)
// Always write provider.tf if err := writeFile(filepath.Join(outputDir, "provider.tf"), GenerateProviderFile(api.BaseURL)); err != nil { return cli.Exit(fmt.Sprintf("failed to write provider.tf: %v", err), 1) }
if gen.TotalResourceCount() == 0 { fmt.Printf("No resources found in workspace. Only provider.tf was generated in %s\n", outputDir) return nil }
if gen.HasMonitors() { if err := writeFile(filepath.Join(outputDir, "monitors.tf"), gen.GenerateMonitorsFile().Bytes()); err != nil { return cli.Exit(fmt.Sprintf("failed to write monitors.tf: %v", err), 1) } }
if gen.HasNotifications() { if err := writeFile(filepath.Join(outputDir, "notifications.tf"), gen.GenerateNotificationsFile().Bytes()); err != nil { return cli.Exit(fmt.Sprintf("failed to write notifications.tf: %v", err), 1) } }
if gen.HasStatusPages() { if err := writeFile(filepath.Join(outputDir, "status_pages.tf"), gen.GenerateStatusPagesFile().Bytes()); err != nil { return cli.Exit(fmt.Sprintf("failed to write status_pages.tf: %v", err), 1) } }
if gen.HasPrivateLocations() { if err := writeFile(filepath.Join(outputDir, "private_locations.tf"), gen.GeneratePrivateLocationsFile().Bytes()); err != nil { return cli.Exit(fmt.Sprintf("failed to write private_locations.tf: %v", err), 1) } }
if err := writeFile(filepath.Join(outputDir, "imports.tf"), gen.GenerateImportsFile().Bytes()); err != nil { return cli.Exit(fmt.Sprintf("failed to write imports.tf: %v", err), 1) }
printSummary(outputDir, data) return nil }, }}
func checkExistingFiles(outputDir string, force bool) error { if force { return nil } for _, name := range generatedFileNames { if _, err := os.Stat(filepath.Join(outputDir, name)); err == nil { return fmt.Errorf("refusing to overwrite existing file %s; pass --force to replace", name) } } return nil}
func writeFile(path string, content []byte) error { f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644) if err != nil { return err } defer f.Close() _, err = f.Write(content) return err}
func printSummary(outputDir string, data *WorkspaceData) { httpCount := len(data.HTTPMonitors) tcpCount := len(data.TCPMonitors) dnsCount := len(data.DNSMonitors) icmpCount := len(data.ICMPMonitors) monitorTotal := httpCount + tcpCount + dnsCount + icmpCount notifCount := len(data.Notifications) plCount := len(data.PrivateLocations)
pageCount := len(data.StatusPages) compCount := 0 groupCount := 0 for _, sp := range data.StatusPages { compCount += len(sp.Components) groupCount += len(sp.Groups) }
importCount := monitorTotal + notifCount + pageCount + compCount + groupCount + plCount
fmt.Printf("\nGenerated Terraform configuration in %s\n\n", outputDir) if monitorTotal > 0 { fmt.Printf(" %d monitors (%d HTTP, %d TCP, %d DNS, %d ICMP)\n", monitorTotal, httpCount, tcpCount, dnsCount, icmpCount) } if notifCount > 0 { fmt.Printf(" %d notifications\n", notifCount) } if pageCount > 0 { fmt.Printf(" %d status pages (%d components, %d groups)\n", pageCount, compCount, groupCount) } if plCount > 0 { fmt.Printf(" %d private locations\n", plCount) } fmt.Printf(" %d import blocks\n", importCount) fmt.Printf("\nNext steps:\n") fmt.Printf(" cd %s\n", outputDir) fmt.Printf(" terraform init\n") fmt.Printf(" terraform plan\n") fmt.Printf("\nNote: provider version pinned to ~> 0.4. Run 'terraform init -upgrade' if you previously ran this command.\n")}