From 5177bb35b3290942c0c12235ffd5ed31adc74d01 Mon Sep 17 00:00:00 2001 From: Julien Duchesne Date: Thu, 21 Mar 2024 11:27:53 -0400 Subject: [PATCH] Remove global resources var (#1432) * Remove global resources var The `provider` package now has a function that will expose all the resources from all subcategories of the provider This list is used to: - Used in the import docs generation command - Sent to both provider servers - Used in the tf code generation command * ML + SLO: Use common resource framework (#1433) Paving the way for TF code generation --- docs/resources/machine_learning_holiday.md | 8 ++++ docs/resources/machine_learning_job.md | 8 ++++ .../machine_learning_outlier_detector.md | 8 ++++ docs/resources/slo.md | 10 +++- .../import.sh | 1 + .../grafana_machine_learning_job/import.sh | 1 + .../import.sh | 1 + examples/resources/grafana_slo/import.sh | 1 + internal/common/resource.go | 27 ----------- internal/resources/cloud/resources.go | 8 ---- .../machinelearning/resource_holiday.go | 8 +++- .../resources/machinelearning/resource_job.go | 8 +++- .../resource_outlier_detector.go | 8 +++- .../resources/machinelearning/resources.go | 8 ++-- internal/resources/slo/data_source_slo.go | 2 +- internal/resources/slo/resource_slo.go | 8 +++- internal/resources/slo/resources.go | 4 +- pkg/provider/legacy_provider.go | 19 +------- pkg/provider/resources.go | 47 +++++++++++++++++++ templates/resources/slo.md.tmpl | 8 +++- tools/genimports/main.go | 28 +++++++++-- 21 files changed, 147 insertions(+), 74 deletions(-) create mode 100644 examples/resources/grafana_machine_learning_holiday/import.sh create mode 100644 examples/resources/grafana_machine_learning_job/import.sh create mode 100644 examples/resources/grafana_machine_learning_outlier_detector/import.sh create mode 100644 examples/resources/grafana_slo/import.sh create mode 100644 pkg/provider/resources.go diff --git a/docs/resources/machine_learning_holiday.md b/docs/resources/machine_learning_holiday.md index 7ad574731..8347e737a 100644 --- a/docs/resources/machine_learning_holiday.md +++ b/docs/resources/machine_learning_holiday.md @@ -60,3 +60,11 @@ Required: Optional: - `name` (String) The name of the custom period. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import grafana_machine_learning_holiday.name "{{ id }}" +``` diff --git a/docs/resources/machine_learning_job.md b/docs/resources/machine_learning_job.md index 7518e9624..62e6675be 100644 --- a/docs/resources/machine_learning_job.md +++ b/docs/resources/machine_learning_job.md @@ -36,3 +36,11 @@ A job defines the queries and model parameters for a machine learning task. ### Read-Only - `id` (String) The ID of the job. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import grafana_machine_learning_job.name "{{ id }}" +``` diff --git a/docs/resources/machine_learning_outlier_detector.md b/docs/resources/machine_learning_outlier_detector.md index 21707d38b..59beb847e 100644 --- a/docs/resources/machine_learning_outlier_detector.md +++ b/docs/resources/machine_learning_outlier_detector.md @@ -58,3 +58,11 @@ Optional: Required: - `epsilon` (Number) Specify the epsilon parameter (positive float) + +## Import + +Import is supported using the following syntax: + +```shell +terraform import grafana_machine_learning_outlier_detector.name "{{ id }}" +``` diff --git a/docs/resources/slo.md b/docs/resources/slo.md index 4573303f0..a4fbf5112 100644 --- a/docs/resources/slo.md +++ b/docs/resources/slo.md @@ -289,4 +289,12 @@ Optional: Required: - `key` (String) -- `value` (String) \ No newline at end of file +- `value` (String) + +## Import + +Import is supported using the following syntax: + +```shell +terraform import grafana_slo.name "{{ uuid }}" +``` diff --git a/examples/resources/grafana_machine_learning_holiday/import.sh b/examples/resources/grafana_machine_learning_holiday/import.sh new file mode 100644 index 000000000..ce3351c42 --- /dev/null +++ b/examples/resources/grafana_machine_learning_holiday/import.sh @@ -0,0 +1 @@ +terraform import grafana_machine_learning_holiday.name "{{ id }}" diff --git a/examples/resources/grafana_machine_learning_job/import.sh b/examples/resources/grafana_machine_learning_job/import.sh new file mode 100644 index 000000000..549955e44 --- /dev/null +++ b/examples/resources/grafana_machine_learning_job/import.sh @@ -0,0 +1 @@ +terraform import grafana_machine_learning_job.name "{{ id }}" diff --git a/examples/resources/grafana_machine_learning_outlier_detector/import.sh b/examples/resources/grafana_machine_learning_outlier_detector/import.sh new file mode 100644 index 000000000..841f19e70 --- /dev/null +++ b/examples/resources/grafana_machine_learning_outlier_detector/import.sh @@ -0,0 +1 @@ +terraform import grafana_machine_learning_outlier_detector.name "{{ id }}" diff --git a/examples/resources/grafana_slo/import.sh b/examples/resources/grafana_slo/import.sh new file mode 100644 index 000000000..62fd3b68b --- /dev/null +++ b/examples/resources/grafana_slo/import.sh @@ -0,0 +1 @@ +terraform import grafana_slo.name "{{ uuid }}" diff --git a/internal/common/resource.go b/internal/common/resource.go index 03d4d9455..186c623fb 100644 --- a/internal/common/resource.go +++ b/internal/common/resource.go @@ -2,16 +2,11 @@ package common import ( "fmt" - "log" - "os" - "path/filepath" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -var allResources = []*Resource{} - type Resource struct { Name string IDType *ResourceID @@ -24,7 +19,6 @@ func NewResource(name string, idType *ResourceID, schema *schema.Resource) *Reso IDType: idType, Schema: schema, } - allResources = append(allResources, r) return r } @@ -37,24 +31,3 @@ func (r *Resource) ImportExample() string { return fmt.Sprintf(`terraform import %s.name %q `, r.Name, strings.Join(fields, defaultSeparator)) } - -// GenerateImportFiles generates import files for all resources that use a helper defined in this package -func GenerateImportFiles(path string) error { - for _, r := range allResources { - resourcePath := filepath.Join(path, "resources", r.Name, "import.sh") - if err := os.RemoveAll(resourcePath); err != nil { // Remove the file if it exists - return err - } - - if r.IDType == nil { - log.Printf("Skipping import file generation for %s because it does not have an ID type\n", r.Name) - continue - } - - log.Printf("Generating import file for %s (writing to %s)\n", r.Name, resourcePath) - if err := os.WriteFile(resourcePath, []byte(r.ImportExample()), 0600); err != nil { - return err - } - } - return nil -} diff --git a/internal/resources/cloud/resources.go b/internal/resources/cloud/resources.go index fa5f9b205..66e4d4477 100644 --- a/internal/resources/cloud/resources.go +++ b/internal/resources/cloud/resources.go @@ -22,11 +22,3 @@ var Resources = []*common.Resource{ resourceStackServiceAccountToken(), resourceSyntheticMonitoringInstallation(), } - -func ResourcesMap() map[string]*schema.Resource { - m := make(map[string]*schema.Resource) - for _, r := range Resources { - m[r.Name] = r.Schema - } - return m -} diff --git a/internal/resources/machinelearning/resource_holiday.go b/internal/resources/machinelearning/resource_holiday.go index 5b9a45b6b..6c22cb6bb 100644 --- a/internal/resources/machinelearning/resource_holiday.go +++ b/internal/resources/machinelearning/resource_holiday.go @@ -13,8 +13,10 @@ import ( "github.com/grafana/terraform-provider-grafana/internal/common" ) -func resourceHoliday() *schema.Resource { - return &schema.Resource{ +var resourceHolidayID = common.NewResourceID(common.StringIDField("id")) + +func resourceHoliday() *common.Resource { + schema := &schema.Resource{ Description: ` A holiday describes time periods where a time series is expected to behave differently to normal. @@ -101,6 +103,8 @@ resource "grafana_machine_learning_job" "test_job" { }, }, } + + return common.NewResource("grafana_machine_learning_holiday", resourceHolidayID, schema) } func resourceHolidayCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { diff --git a/internal/resources/machinelearning/resource_job.go b/internal/resources/machinelearning/resource_job.go index f9f2796d0..c792af398 100644 --- a/internal/resources/machinelearning/resource_job.go +++ b/internal/resources/machinelearning/resource_job.go @@ -12,8 +12,10 @@ import ( "github.com/grafana/terraform-provider-grafana/internal/common" ) -func resourceJob() *schema.Resource { - return &schema.Resource{ +var resourceJobID = common.NewResourceID(common.StringIDField("id")) + +func resourceJob() *common.Resource { + schema := &schema.Resource{ Description: ` A job defines the queries and model parameters for a machine learning task. @@ -102,6 +104,8 @@ A job defines the queries and model parameters for a machine learning task. }, }, } + + return common.NewResource("grafana_machine_learning_job", resourceJobID, schema) } func resourceJobCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { diff --git a/internal/resources/machinelearning/resource_outlier_detector.go b/internal/resources/machinelearning/resource_outlier_detector.go index 223ebf4f8..0b46e6d3b 100644 --- a/internal/resources/machinelearning/resource_outlier_detector.go +++ b/internal/resources/machinelearning/resource_outlier_detector.go @@ -12,8 +12,10 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) -func resourceOutlierDetector() *schema.Resource { - return &schema.Resource{ +var resourceOutlierDetectorID = common.NewResourceID(common.StringIDField("id")) + +func resourceOutlierDetector() *common.Resource { + schema := &schema.Resource{ Description: ` An outlier detector monitors the results of a query and reports when its values are outside normal bands. @@ -120,6 +122,8 @@ Visit https://grafana.com/docs/grafana-cloud/machine-learning/outlier-detection/ }, }, } + + return common.NewResource("grafana_machine_learning_outlier_detector", resourceOutlierDetectorID, schema) } func resourceOutlierCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { diff --git a/internal/resources/machinelearning/resources.go b/internal/resources/machinelearning/resources.go index c01dcb3fd..3e6db8313 100644 --- a/internal/resources/machinelearning/resources.go +++ b/internal/resources/machinelearning/resources.go @@ -20,8 +20,8 @@ func checkClient(f func(ctx context.Context, d *schema.ResourceData, meta interf var DatasourcesMap = map[string]*schema.Resource{} -var ResourcesMap = map[string]*schema.Resource{ - "grafana_machine_learning_job": resourceJob(), - "grafana_machine_learning_holiday": resourceHoliday(), - "grafana_machine_learning_outlier_detector": resourceOutlierDetector(), +var Resources = []*common.Resource{ + resourceJob(), + resourceHoliday(), + resourceOutlierDetector(), } diff --git a/internal/resources/slo/data_source_slo.go b/internal/resources/slo/data_source_slo.go index 2433ae1d1..70fe30998 100644 --- a/internal/resources/slo/data_source_slo.go +++ b/internal/resources/slo/data_source_slo.go @@ -25,7 +25,7 @@ Datasource for retrieving all SLOs. Computed: true, Description: `Returns a list of all SLOs"`, Elem: &schema.Resource{ - Schema: common.CloneResourceSchemaForDatasource(resourceSlo(), map[string]*schema.Schema{ + Schema: common.CloneResourceSchemaForDatasource(resourceSlo().Schema, map[string]*schema.Schema{ "uuid": { Type: schema.TypeString, Description: `A unique, random identifier. This value will also be the name of the resource stored in the API server. This value is read-only.`, diff --git a/internal/resources/slo/resource_slo.go b/internal/resources/slo/resource_slo.go index 370832b5b..eb5ad5dc7 100644 --- a/internal/resources/slo/resource_slo.go +++ b/internal/resources/slo/resource_slo.go @@ -20,8 +20,10 @@ const ( QueryTypeThreshold string = "threshold" ) -func resourceSlo() *schema.Resource { - return &schema.Resource{ +var resourceSloID = common.NewResourceID(common.StringIDField("uuid")) + +func resourceSlo() *common.Resource { + schema := &schema.Resource{ Description: ` Resource manages Grafana SLOs. @@ -219,6 +221,8 @@ Resource manages Grafana SLOs. }, }, } + + return common.NewResource("grafana_slo", resourceSloID, schema) } var keyvalueSchema = &schema.Resource{ diff --git a/internal/resources/slo/resources.go b/internal/resources/slo/resources.go index 2d08b82e8..4f411edcd 100644 --- a/internal/resources/slo/resources.go +++ b/internal/resources/slo/resources.go @@ -25,6 +25,6 @@ var DatasourcesMap = map[string]*schema.Resource{ "grafana_slos": datasourceSlo(), } -var ResourcesMap = map[string]*schema.Resource{ - "grafana_slo": resourceSlo(), +var Resources = []*common.Resource{ + resourceSlo(), } diff --git a/pkg/provider/legacy_provider.go b/pkg/provider/legacy_provider.go index afeed6ab7..a07f6b479 100644 --- a/pkg/provider/legacy_provider.go +++ b/pkg/provider/legacy_provider.go @@ -151,14 +151,7 @@ func Provider(version string) *schema.Provider { }, }, - ResourcesMap: mergeResourceMaps( - grafana.ResourcesMap, - machinelearning.ResourcesMap, - slo.ResourcesMap, - syntheticmonitoring.ResourcesMap, - oncall.ResourcesMap, - cloud.ResourcesMap(), - ), + ResourcesMap: resourceMap(), DataSourcesMap: mergeResourceMaps( grafana.DatasourcesMap, @@ -249,13 +242,3 @@ func int64ValueOrNull(d *schema.ResourceData, key string) types.Int64 { } return types.Int64Null() } - -func mergeResourceMaps(maps ...map[string]*schema.Resource) map[string]*schema.Resource { - result := make(map[string]*schema.Resource) - for _, m := range maps { - for k, v := range m { - result[k] = v - } - } - return result -} diff --git a/pkg/provider/resources.go b/pkg/provider/resources.go new file mode 100644 index 000000000..b04774f9c --- /dev/null +++ b/pkg/provider/resources.go @@ -0,0 +1,47 @@ +// This file contains + +package provider + +import ( + "github.com/grafana/terraform-provider-grafana/internal/common" + "github.com/grafana/terraform-provider-grafana/internal/resources/cloud" + "github.com/grafana/terraform-provider-grafana/internal/resources/grafana" + "github.com/grafana/terraform-provider-grafana/internal/resources/machinelearning" + "github.com/grafana/terraform-provider-grafana/internal/resources/oncall" + "github.com/grafana/terraform-provider-grafana/internal/resources/slo" + "github.com/grafana/terraform-provider-grafana/internal/resources/syntheticmonitoring" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func Resources() []*common.Resource { + var resources []*common.Resource + resources = append(resources, cloud.Resources...) + resources = append(resources, machinelearning.Resources...) + resources = append(resources, slo.Resources...) + return resources +} + +func resourceMap() map[string]*schema.Resource { + result := make(map[string]*schema.Resource) + for _, r := range Resources() { + result[r.Name] = r.Schema + } + + // TODO: Migrate to common.Resource instances (in Resources function) + return mergeResourceMaps( + result, + grafana.ResourcesMap, + syntheticmonitoring.ResourcesMap, + oncall.ResourcesMap, + ) +} + +func mergeResourceMaps(maps ...map[string]*schema.Resource) map[string]*schema.Resource { + result := make(map[string]*schema.Resource) + for _, m := range maps { + for k, v := range m { + result[k] = v + } + } + return result +} diff --git a/templates/resources/slo.md.tmpl b/templates/resources/slo.md.tmpl index 387c28155..330801ef3 100644 --- a/templates/resources/slo.md.tmpl +++ b/templates/resources/slo.md.tmpl @@ -20,4 +20,10 @@ description: |- {{ tffile "examples/resources/grafana_slo/resource_complex.tf" }} -{{ .SchemaMarkdown | trimspace }} \ No newline at end of file +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" "examples/resources/grafana_slo/import.sh" }} diff --git a/tools/genimports/main.go b/tools/genimports/main.go index 495142a8e..7b0a63d14 100644 --- a/tools/genimports/main.go +++ b/tools/genimports/main.go @@ -1,19 +1,39 @@ package main import ( + "log" "os" + "path/filepath" - "github.com/grafana/terraform-provider-grafana/internal/common" "github.com/grafana/terraform-provider-grafana/pkg/provider" ) -// TODO: Move to cmd, and remove global var in common - func main() { p := provider.Provider("genimports") // Instantiate the provider so that all resources are registered _ = p - if err := common.GenerateImportFiles(os.Args[1]); err != nil { + if err := generateImportFiles(os.Args[1]); err != nil { panic(err) } } + +// GenerateImportFiles generates import files for all resources that use a helper defined in this package +func generateImportFiles(path string) error { + for _, r := range provider.Resources() { + resourcePath := filepath.Join(path, "resources", r.Name, "import.sh") + if err := os.RemoveAll(resourcePath); err != nil { // Remove the file if it exists + return err + } + + if r.IDType == nil { + log.Printf("Skipping import file generation for %s because it does not have an ID type\n", r.Name) + continue + } + + log.Printf("Generating import file for %s (writing to %s)\n", r.Name, resourcePath) + if err := os.WriteFile(resourcePath, []byte(r.ImportExample()), 0600); err != nil { + return err + } + } + return nil +}