|
| 1 | +// Copyright (c) HashiCorp, Inc. |
| 2 | +// SPDX-License-Identifier: MPL-2.0 |
| 3 | + |
| 4 | +package main |
| 5 | + |
| 6 | +import ( |
| 7 | + "bytes" |
| 8 | + "context" |
| 9 | + "encoding/csv" |
| 10 | + "fmt" |
| 11 | + "log" |
| 12 | + "time" |
| 13 | + |
| 14 | + tfe "github.com/hashicorp/go-tfe" |
| 15 | +) |
| 16 | + |
| 17 | +func main() { |
| 18 | + config := &tfe.Config{ |
| 19 | + Token: "insert-your-token-here", |
| 20 | + RetryServerErrors: true, |
| 21 | + } |
| 22 | + |
| 23 | + client, err := tfe.NewClient(config) |
| 24 | + if err != nil { |
| 25 | + log.Fatal(err) |
| 26 | + } |
| 27 | + |
| 28 | + // Create a context |
| 29 | + ctx := context.Background() |
| 30 | + |
| 31 | + organization := "insert-your-organization-name" |
| 32 | + |
| 33 | + // Note: The following queries may not yield any results as the data available to query is dependent on your organization. Also results are paginated so the initial response may not reflect the full query result. |
| 34 | + |
| 35 | + // (#1) Workspaces Example: Give me all the workspace names that have a |
| 36 | + // current run status of "errored" AND are in project "foo" |
| 37 | + wql, err := client.Explorer.QueryWorkspaces(ctx, organization, tfe.ExplorerQueryOptions{ |
| 38 | + Fields: []string{"workspace_name"}, |
| 39 | + Filters: []*tfe.ExplorerQueryFilter{ |
| 40 | + { |
| 41 | + Index: 0, |
| 42 | + Name: "current_run_status", |
| 43 | + Operator: tfe.OpIs, |
| 44 | + Value: "errored", |
| 45 | + }, |
| 46 | + { |
| 47 | + Index: 1, |
| 48 | + Name: "project_name", |
| 49 | + Operator: tfe.OpIs, |
| 50 | + Value: "foo", |
| 51 | + }, |
| 52 | + }, |
| 53 | + }) |
| 54 | + if err != nil { |
| 55 | + log.Fatal(err) |
| 56 | + } |
| 57 | + |
| 58 | + fmt.Println(wql.Items[0].WorkspaceName) |
| 59 | + |
| 60 | + // (#2) Modules Example: Give me all the modules that are being used by more than one workspace and sort them by number of workspaces DESC. |
| 61 | + mql, err := client.Explorer.QueryModules(ctx, organization, tfe.ExplorerQueryOptions{ |
| 62 | + Sort: "-workspace_count", |
| 63 | + Filters: []*tfe.ExplorerQueryFilter{ |
| 64 | + { |
| 65 | + Index: 0, |
| 66 | + Name: "workspace_count", |
| 67 | + Operator: tfe.OpGreaterThan, |
| 68 | + Value: "1", |
| 69 | + }, |
| 70 | + }, |
| 71 | + }) |
| 72 | + if err != nil { |
| 73 | + log.Fatal(err) |
| 74 | + } |
| 75 | + |
| 76 | + fmt.Println(mql.Items[0].Name) |
| 77 | + fmt.Println(mql.Items[0].WorkspaceCount) |
| 78 | + |
| 79 | + // (#3) Providers Example: Give me all the providers that are being used by the workspace "staging-us-east-1" |
| 80 | + pql, err := client.Explorer.QueryProviders(ctx, organization, tfe.ExplorerQueryOptions{ |
| 81 | + Filters: []*tfe.ExplorerQueryFilter{ |
| 82 | + { |
| 83 | + Index: 0, |
| 84 | + Name: "workspaces", |
| 85 | + Operator: tfe.OpContains, |
| 86 | + Value: "staging-us-east-1", |
| 87 | + }, |
| 88 | + }, |
| 89 | + }) |
| 90 | + if err != nil { |
| 91 | + log.Fatal(err) |
| 92 | + } |
| 93 | + |
| 94 | + fmt.Println(len(pql.Items)) |
| 95 | + |
| 96 | + // (#4) Terraform Versions Example: Give me all of the workspaces |
| 97 | + // that are not using Terraform version 1.10.0 |
| 98 | + tfql, err := client.Explorer.QueryTerraformVersions(ctx, organization, tfe.ExplorerQueryOptions{ |
| 99 | + Filters: []*tfe.ExplorerQueryFilter{ |
| 100 | + { |
| 101 | + Index: 0, |
| 102 | + Name: "version", |
| 103 | + Operator: tfe.OpIsNot, |
| 104 | + Value: "1.10.0", |
| 105 | + }, |
| 106 | + }, |
| 107 | + }) |
| 108 | + if err != nil { |
| 109 | + log.Fatal(err) |
| 110 | + } |
| 111 | + |
| 112 | + fmt.Println(tfql.Items[0].Version) |
| 113 | + fmt.Println(tfql.Items[0].WorkspaceCount) |
| 114 | + |
| 115 | + // (#5) Export to CSV: Give me all the workspaces where health checks have |
| 116 | + // succeeded and have been updated since 2 days ago. Note: This method can also |
| 117 | + // be used for modules, providers and terraform version queries. |
| 118 | + since := time.Now().AddDate(0, 0, -2).Format(time.RFC3339) |
| 119 | + data, err := client.Explorer.ExportToCSV(ctx, organization, tfe.ExplorerQueryOptions{ |
| 120 | + Filters: []*tfe.ExplorerQueryFilter{ |
| 121 | + { |
| 122 | + Index: 0, |
| 123 | + Name: "all_checks_succeeded", |
| 124 | + Operator: tfe.OpIs, |
| 125 | + Value: "true", |
| 126 | + }, |
| 127 | + { |
| 128 | + Index: 1, |
| 129 | + Name: "updated_at", |
| 130 | + Operator: tfe.OpIsAfter, |
| 131 | + Value: since, |
| 132 | + }, |
| 133 | + }, |
| 134 | + }) |
| 135 | + if err != nil { |
| 136 | + log.Fatal(err) |
| 137 | + } |
| 138 | + reader := csv.NewReader(bytes.NewReader(data)) |
| 139 | + rows, err := reader.ReadAll() |
| 140 | + if err != nil { |
| 141 | + log.Fatal(err) |
| 142 | + } |
| 143 | + |
| 144 | + for _, r := range rows { |
| 145 | + // Do something with each row in the CSV |
| 146 | + fmt.Println(r) |
| 147 | + } |
| 148 | +} |
0 commit comments