-
Notifications
You must be signed in to change notification settings - Fork 251
/
Copy pathmain.go
175 lines (160 loc) · 5.71 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/grafana/terraform-provider-grafana/v3/pkg/generate"
"github.com/fatih/color"
"github.com/urfave/cli/v2"
)
var version = "" // set by ldflags
func main() {
err := run()
if err != nil {
log.Fatal(err)
}
}
func run() error {
msg := "WARNING: This tool is highly experimental and comes with no support or guarantees."
lines := strings.Repeat("-", len(msg))
color.New(color.FgRed, color.Bold).Fprintf(os.Stderr, "%[2]s\n%[1]s\n%[2]s\n", msg, lines)
app := &cli.App{
Name: "terraform-provider-grafana-generate",
Usage: "Generate `terraform-provider-grafana` resources from your Grafana instance or Grafana Cloud account.",
UsageText: "terraform-provider-grafana-generate [options]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "output-dir",
Aliases: []string{"o"},
Usage: "Output directory for generated resources",
Required: true,
EnvVars: []string{"TFGEN_OUTPUT_DIR"},
},
&cli.BoolFlag{
Name: "clobber",
Aliases: []string{"c"},
Usage: "Delete all files in the output directory before generating resources",
EnvVars: []string{"TFGEN_CLOBBER"},
},
&cli.StringFlag{
Name: "output-format",
Aliases: []string{"f"},
Usage: fmt.Sprintf("Output format for generated resources. "+
"Supported formats are: %v", generate.OutputFormats),
Value: string(generate.OutputFormatHCL),
EnvVars: []string{"TFGEN_OUTPUT_FORMAT"},
},
&cli.StringFlag{
Name: "terraform-provider-version",
Usage: "Version of the Grafana provider to generate resources for. Defaults to the release version (same as the generator version).",
EnvVars: []string{"TFGEN_TERRAFORM_PROVIDER_VERSION"},
Value: version,
},
&cli.StringSliceFlag{
Name: "include-resources",
Usage: `List of resources to include in the "resourceType.resourceName" format. If not set, all resources will be included
This supports a glob format. Examples:
* Generate all dashboards and folders: --resource-names 'grafana_dashboard.*' --resource-names 'grafana_folder.*'
* Generate all resources with "hello" in their ID (this is usually the resource UIDs): --resource-names '*.*hello*'
* Generate all resources (same as default behaviour): --resource-names '*.*'
`,
EnvVars: []string{"TFGEN_INCLUDE_RESOURCES"},
Required: false,
},
// Grafana OSS flags
&cli.StringFlag{
Name: "grafana-url",
Usage: "URL of the Grafana instance to generate resources from",
Category: "Grafana",
EnvVars: []string{"TF_GEN_GRAFANA_URL"},
},
&cli.StringFlag{
Name: "grafana-auth",
Usage: "Service account token or username:password for the Grafana instance",
Category: "Grafana",
EnvVars: []string{"TFGEN_GRAFANA_AUTH"},
},
// Grafana Cloud flags
&cli.StringFlag{
Name: "cloud-access-policy-token",
Usage: "Access policy token for Grafana Cloud",
Category: "Grafana Cloud",
EnvVars: []string{"TFGEN_CLOUD_ACCESS_POLICY_TOKEN"},
},
&cli.StringFlag{
Name: "cloud-org",
Usage: "Organization ID or name for Grafana Cloud",
Category: "Grafana Cloud",
EnvVars: []string{"TFGEN_CLOUD_ORG"},
},
&cli.BoolFlag{
Name: "cloud-create-stack-service-account",
Usage: "Create a service account for each Grafana Cloud stack, allowing generation and management of resources in that stack.",
Category: "Grafana Cloud",
EnvVars: []string{"TFGEN_CLOUD_CREATE_STACK_SERVICE_ACCOUNT"},
},
&cli.StringFlag{
Name: "cloud-stack-service-account-name",
Usage: "Name of the service account to create for each Grafana Cloud stack.",
Category: "Grafana Cloud",
EnvVars: []string{"TFGEN_CLOUD_STACK_SERVICE_ACCOUNT_NAME"},
Value: "tfgen-management",
},
},
InvalidFlagAccessHandler: func(ctx *cli.Context, s string) {
panic(fmt.Errorf("invalid flag access: %s", s))
},
Action: func(ctx *cli.Context) error {
cfg, err := parseFlags(ctx)
if err != nil {
return fmt.Errorf("failed to parse flags: %w", err)
}
return generate.Generate(ctx.Context, cfg)
},
}
return app.Run(os.Args)
}
func parseFlags(ctx *cli.Context) (*generate.Config, error) {
config := &generate.Config{
OutputDir: ctx.String("output-dir"),
Clobber: ctx.Bool("clobber"),
Format: generate.OutputFormat(ctx.String("output-format")),
ProviderVersion: ctx.String("terraform-provider-version"),
Grafana: &generate.GrafanaConfig{
URL: ctx.String("grafana-url"),
Auth: ctx.String("grafana-auth"),
},
Cloud: &generate.CloudConfig{
AccessPolicyToken: ctx.String("cloud-access-policy-token"),
Org: ctx.String("cloud-org"),
CreateStackServiceAccount: ctx.Bool("cloud-create-stack-service-account"),
StackServiceAccountName: ctx.String("cloud-stack-service-account-name"),
},
IncludeResources: ctx.StringSlice("include-resources"),
}
if config.ProviderVersion == "" {
return nil, fmt.Errorf("terraform-provider-version must be set")
}
// Validate flags
err := newFlagValidations().
atLeastOne("grafana-url", "cloud-access-policy-token").
conflicting(
[]string{"grafana-url", "grafana-auth"},
[]string{"cloud-access-policy-token", "cloud-org", "cloud-create-stack-service-account", "cloud-stack-service-account-name"},
).
requiredWhenSet("grafana-url", "grafana-auth").
requiredWhenSet("cloud-access-policy-token", "cloud-org").
requiredWhenSet("cloud-stack-service-account-name", "cloud-create-stack-service-account").
validate(ctx)
if err != nil {
return nil, err
}
if config.Grafana.Auth == "" {
config.Grafana = nil
}
if config.Cloud.AccessPolicyToken == "" {
config.Cloud = nil
}
return config, nil
}