Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/cli. OpenStatus CLI www.openstatus.dev
Something went wrong. Try again.
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246//go:build smoke
// Run with: go test -tags=smoke ./internal/terraform///// This smoke test exercises the generator's output against a real terraform// binary and the live openstatusHQ/openstatus provider from the public// registry. It does NOT require an API token and does NOT call any// OpenStatus RPC — only `terraform init` (which fetches the provider) and// `terraform validate` (which checks schema/syntax fit).//// Skipped automatically when the terraform binary is not on PATH.
package terraform
import ( "os" "os/exec" "path/filepath" "testing"
monitorv1 "buf.build/gen/go/openstatus/api/protocolbuffers/go/openstatus/monitor/v1" notificationv1 "buf.build/gen/go/openstatus/api/protocolbuffers/go/openstatus/notification/v1" private_locationv1 "buf.build/gen/go/openstatus/api/protocolbuffers/go/openstatus/private_location/v1" status_pagev1 "buf.build/gen/go/openstatus/api/protocolbuffers/go/openstatus/status_page/v1"
"github.com/openstatusHQ/cli/internal/api")
func TestSmokeValidate(t *testing.T) { if _, err := exec.LookPath("terraform"); err != nil { t.Skipf("terraform binary not in PATH; install terraform 1.0+ to run this test") }
dir := t.TempDir() data := smokeFixture() gen := NewGenerator(data)
files := map[string][]byte{ "provider.tf": GenerateProviderFile(api.DefaultBaseURL), "monitors.tf": gen.GenerateMonitorsFile().Bytes(), "notifications.tf": gen.GenerateNotificationsFile().Bytes(), "status_pages.tf": gen.GenerateStatusPagesFile().Bytes(), "private_locations.tf": gen.GeneratePrivateLocationsFile().Bytes(), "imports.tf": gen.GenerateImportsFile().Bytes(), } for name, content := range files { if err := os.WriteFile(filepath.Join(dir, name), content, 0o644); err != nil { t.Fatalf("writing %s: %v", name, err) } }
// Force registry-only installation. A dev_overrides block in ~/.terraformrc or // a legacy ~/.terraform.d/plugins mirror would otherwise resolve the provider // locally and validate the config against a stale schema. cliConfig := filepath.Join(dir, "registry.tfrc") if err := os.WriteFile(cliConfig, []byte("provider_installation {\n direct {}\n}\n"), 0o644); err != nil { t.Fatalf("writing terraform CLI config: %v", err) } env := append(os.Environ(), "TF_CLI_CONFIG_FILE="+cliConfig)
initCmd := exec.Command("terraform", "init", "-upgrade", "-no-color") initCmd.Dir = dir initCmd.Env = env if out, err := initCmd.CombinedOutput(); err != nil { t.Fatalf("terraform init failed: %v\noutput:\n%s", err, out) }
validateCmd := exec.Command("terraform", "validate", "-no-color") validateCmd.Dir = dir validateCmd.Env = env if out, err := validateCmd.CombinedOutput(); err != nil { t.Fatalf("terraform validate failed: %v\noutput:\n%s", err, out) }}
func smokeFixture() *WorkspaceData { httpMon := &monitorv1.HTTPMonitor{} httpMon.SetId("mon-http") httpMon.SetName("API Health") httpMon.SetUrl("https://api.example.com/health") httpMon.SetPeriodicity(monitorv1.Periodicity_PERIODICITY_5M) httpMon.SetMethod(monitorv1.HTTPMethod_HTTP_METHOD_GET) httpMon.SetTimeout(45000) httpMon.SetRetry(3) httpMon.SetFollowRedirects(true) httpMon.SetActive(true) httpMon.SetRegions([]monitorv1.Region{monitorv1.Region_REGION_FLY_IAD})
otelConfig := &monitorv1.OpenTelemetryConfig{} otelConfig.SetEndpoint("https://otel.example.com/v1/metrics") otelHeader := &monitorv1.Headers{} otelHeader.SetKey("X-Api-Key") otelHeader.SetValue("secret") otelConfig.SetHeaders([]*monitorv1.Headers{otelHeader}) httpMon.SetOpenTelemetry(otelConfig)
statusAssertion := &monitorv1.StatusCodeAssertion{} statusAssertion.SetTarget(200) statusAssertion.SetComparator(monitorv1.NumberComparator_NUMBER_COMPARATOR_EQUAL) httpMon.SetStatusCodeAssertions([]*monitorv1.StatusCodeAssertion{statusAssertion})
tcpMon := &monitorv1.TCPMonitor{} tcpMon.SetId("mon-tcp") tcpMon.SetName("DB TCP") tcpMon.SetUri("db.example.com:5432") tcpMon.SetPeriodicity(monitorv1.Periodicity_PERIODICITY_5M) tcpMon.SetTimeout(45000) tcpMon.SetRetry(3) tcpMon.SetActive(true)
dnsMon := &monitorv1.DNSMonitor{} dnsMon.SetId("mon-dns") dnsMon.SetName("DNS Check") dnsMon.SetUri("example.com") dnsMon.SetPeriodicity(monitorv1.Periodicity_PERIODICITY_10M) dnsMon.SetTimeout(45000) dnsMon.SetRetry(3) dnsMon.SetActive(true) dnsRecord := &monitorv1.RecordAssertion{} dnsRecord.SetRecord("A") dnsRecord.SetTarget("93.184.216.34") dnsRecord.SetComparator(monitorv1.RecordComparator_RECORD_COMPARATOR_EQUAL) dnsMon.SetRecordAssertions([]*monitorv1.RecordAssertion{dnsRecord})
icmpMon := &monitorv1.ICMPMonitor{} icmpMon.SetId("mon-icmp") icmpMon.SetName("Gateway Ping") icmpMon.SetUri("8.8.8.8") icmpMon.SetPeriodicity(monitorv1.Periodicity_PERIODICITY_1M) icmpMon.SetTimeout(45000) icmpMon.SetRetry(3) icmpMon.SetActive(true) icmpMon.SetRegions([]monitorv1.Region{monitorv1.Region_REGION_FLY_IAD})
slackNotif := newNotification("notif-slack", "Slack Alerts", []string{"mon-http"}, func(d *notificationv1.NotificationData) { sd := ¬ificationv1.SlackData{} sd.SetWebhookUrl("https://hooks.example.com/slack") d.SetSlack(sd) }) teamsNotif := newNotification("notif-teams", "Teams Alerts", nil, func(d *notificationv1.NotificationData) { td := ¬ificationv1.MsTeamsData{} td.SetWebhookUrl("https://example.com/teams") d.SetMsTeams(td) }) webhookNotif := newNotification("notif-webhook", "Webhook Alerts", nil, func(d *notificationv1.NotificationData) { wd := ¬ificationv1.WebhookData{} wd.SetEndpoint("https://example.com/hook") h := ¬ificationv1.WebhookHeader{} h.SetKey("Authorization") h.SetValue("Bearer xyz") wd.SetHeaders([]*notificationv1.WebhookHeader{h}) d.SetWebhook(wd) })
page := &status_pagev1.StatusPage{} page.SetId("page-1") page.SetTitle("Public Status") page.SetSlug("public-status") page.SetTheme(status_pagev1.PageTheme_PAGE_THEME_DARK) page.SetDefaultLocale(status_pagev1.Locale_LOCALE_EN) page.SetLocales([]status_pagev1.Locale{ status_pagev1.Locale_LOCALE_EN, status_pagev1.Locale_LOCALE_FR, }) page.SetAllowIndex(true)
// Variable names must come from the provider's allowlist or validate fails. customTheme := &status_pagev1.CustomTheme{} customTheme.SetLight(map[string]string{ "--primary": "hsl(24 94% 50%)", "--radius": "0.5rem", }) customTheme.SetDark(map[string]string{ "--primary": "hsl(24 94% 60%)", "--background": "hsl(240 10% 4%)", }) page.SetCustomTheme(customTheme)
group := &status_pagev1.PageComponentGroup{} group.SetId("group-1") group.SetPageId("page-1") group.SetName("Infrastructure") group.SetDefaultOpen(true)
component := &status_pagev1.PageComponent{} component.SetId("comp-1") component.SetPageId("page-1") component.SetName("API") component.SetType(status_pagev1.PageComponentType_PAGE_COMPONENT_TYPE_MONITOR) component.SetMonitorId("mon-http") component.SetOrder(1) component.SetGroupId("group-1") component.SetGroupOrder(1)
ipPage := &status_pagev1.StatusPage{} ipPage.SetId("page-2") ipPage.SetTitle("Internal") ipPage.SetSlug("internal") ipPage.SetAccessType(status_pagev1.PageAccessType_PAGE_ACCESS_TYPE_IP_RESTRICTED) ipPage.SetAllowedIpRanges("10.0.0.0/8,192.168.0.0/16")
attachedLocation := &private_locationv1.PrivateLocation{} attachedLocation.SetId("pl-office") attachedLocation.SetName("office-paris") attachedLocation.SetMonitorIds([]string{"mon-http", "mon-tcp"}) attachedLocation.SetMetadata(map[string]string{ "env": "prod", "k8s.cluster": "eu-1", }) attachedLocation.SetToken("smoke-token")
bareLocation := &private_locationv1.PrivateLocation{} bareLocation.SetId("pl-spare") bareLocation.SetName("spare-agent")
return &WorkspaceData{ HTTPMonitors: []*monitorv1.HTTPMonitor{httpMon}, TCPMonitors: []*monitorv1.TCPMonitor{tcpMon}, DNSMonitors: []*monitorv1.DNSMonitor{dnsMon}, ICMPMonitors: []*monitorv1.ICMPMonitor{icmpMon}, Notifications: []*notificationv1.Notification{slackNotif, teamsNotif, webhookNotif}, StatusPages: []StatusPageData{ { Page: page, Groups: []*status_pagev1.PageComponentGroup{group}, Components: []*status_pagev1.PageComponent{component}, }, {Page: ipPage}, }, PrivateLocations: []*private_locationv1.PrivateLocation{attachedLocation, bareLocation}, }}
func newNotification(id, name string, monitorIDs []string, setData func(*notificationv1.NotificationData)) *notificationv1.Notification { n := ¬ificationv1.Notification{} n.SetId(id) n.SetName(name) if len(monitorIDs) > 0 { n.SetMonitorIds(monitorIDs) } nd := ¬ificationv1.NotificationData{} setData(nd) n.SetData(nd) return n}