Skip to content

Commit f2e0f1d

Browse files
authored
feat(tftemplate): add datasource generation to tftemplate (#2017)
1 parent 072ea0c commit f2e0f1d

File tree

4 files changed

+160
-1
lines changed

4 files changed

+160
-1
lines changed

cmd/tftemplate/datasource.go.tmpl

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{{- /*gotype: tftemplate/models.ResourceTemplate*/ -}}
2+
package scaleway
3+
4+
import (
5+
"context"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
)
10+
11+
func dataSourceScaleway{{.Resource}}() *schema.Resource {
12+
// Generate datasource schema from resource
13+
dsSchema := datasourceSchemaFromResourceSchema(resourceScaleway{{.Resource}}().Schema)
14+
15+
addOptionalFieldsToSchema(dsSchema, "name", "{{.Locality}}")
16+
17+
dsSchema["{{.ResourceCleanLow}}_id"] = &schema.Schema{
18+
Type: schema.TypeString,
19+
Optional: true,
20+
Description: "The ID of the {{.ResourceCleanLow}}",
21+
ConflictsWith: []string{"name"},
22+
ValidateFunc: validationUUIDorUUIDWithLocality(),
23+
}
24+
25+
return &schema.Resource{
26+
ReadContext: dataSourceScaleway{{.Resource}}Read,
27+
Schema: dsSchema,
28+
}
29+
}
30+
31+
func dataSourceScaleway{{.Resource}}Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
32+
api, {{.Locality}}, err := {{.API}}APIWith{{.LocalityUpper}}(d, meta)
33+
if err != nil {
34+
return diag.FromErr(err)
35+
}
36+
37+
{{.ResourceCleanLow}}ID, {{.ResourceCleanLow}}IDExists := d.GetOk("{{.ResourceCleanLow}}_id")
38+
if !{{.ResourceCleanLow}}IDExists {
39+
res, err := api.List{{.ResourceClean}}s(&{{.API}}.List{{.ResourceClean}}sRequest{
40+
{{.LocalityUpper}}: {{.Locality}},
41+
Name: expandStringPtr(d.Get("name")),
42+
ProjectID: expandStringPtr(d.Get("project_id")),
43+
})
44+
if err != nil {
45+
return diag.FromErr(err)
46+
}
47+
for _, {{.ResourceCleanLow}} := range res.{{.ResourceClean}}s {
48+
if {{.ResourceCleanLow}}.Name == d.Get("name").(string) {
49+
if {{.ResourceCleanLow}}ID != "" {
50+
return diag.Errorf("more than 1 {{.ResourceCleanLow}} found with the same name %s", d.Get("name"))
51+
}
52+
{{.ResourceCleanLow}}ID = {{.ResourceCleanLow}}.ID
53+
}
54+
}
55+
if {{.ResourceCleanLow}}ID == "" {
56+
return diag.Errorf("no {{.ResourceCleanLow}} found with the name %s", d.Get("name"))
57+
}
58+
}
59+
60+
{{.Locality}}ID := datasourceNew{{.LocalityAdjectiveUpper}}ID({{.ResourceCleanLow}}ID, {{.Locality}})
61+
d.SetId({{.Locality}}ID)
62+
err = d.Set("{{.ResourceCleanLow}}_id", {{.Locality}}ID)
63+
if err != nil {
64+
return diag.FromErr(err)
65+
}
66+
67+
diags := resourceScaleway{{.Resource}}Read(ctx, d, meta)
68+
if diags != nil {
69+
return append(diags, diag.Errorf("failed to read {{.ResourceCleanLow}} state")...)
70+
}
71+
72+
if d.Id() == "" {
73+
return diag.Errorf("{{.ResourceCleanLow}} (%s) not found", {{.Locality}}ID)
74+
}
75+
76+
return nil
77+
}
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{{- /*gotype: tftemplate/models.ResourceTemplate*/ -}}
2+
package scaleway
3+
4+
import (
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
)
9+
10+
func TestAccScalewayDataSource{{.Resource}}_Basic(t *testing.T) {
11+
tt := NewTestTools(t)
12+
defer tt.Cleanup()
13+
resource.ParallelTest(t, resource.TestCase{
14+
PreCheck: func() { testAccPreCheck(t) },
15+
ProviderFactories: tt.ProviderFactories,
16+
CheckDestroy: resource.ComposeTestCheckFunc(
17+
testAccCheckScaleway{{.Resource}}Destroy(tt),
18+
),
19+
Steps: []resource.TestStep{
20+
{
21+
Config: `
22+
resource scaleway_{{.ResourceHCL}} main {
23+
name = "test-ds-{{.API}}-{{ .ResourceCleanLow}}-basic"
24+
}
25+
26+
data scaleway_{{.ResourceHCL}} find_by_name {
27+
name = scaleway_{{.ResourceHCL}}.main.name
28+
}
29+
30+
data scaleway_{{.ResourceHCL}} find_by_id {
31+
{{.ResourceCleanLow}}_id = scaleway_{{.ResourceHCL}}.main.id
32+
}
33+
`,
34+
Check: resource.ComposeTestCheckFunc(
35+
testAccCheckScaleway{{.Resource}}Exists(tt, "scaleway_{{.ResourceHCL}}.main"),
36+
37+
resource.TestCheckResourceAttrPair("scaleway_{{.ResourceHCL}}.main", "name", "data.scaleway_{{.ResourceHCL}}.find_by_name", "name"),
38+
resource.TestCheckResourceAttrPair("scaleway_{{.ResourceHCL}}.main", "name", "data.scaleway_{{.ResourceHCL}}.find_by_id", "name"),
39+
resource.TestCheckResourceAttrPair("scaleway_{{.ResourceHCL}}.main", "id", "data.scaleway_{{.ResourceHCL}}.find_by_name", "id"),
40+
resource.TestCheckResourceAttrPair("scaleway_{{.ResourceHCL}}.main", "id", "data.scaleway_{{.ResourceHCL}}.find_by_id", "id"),
41+
),
42+
},
43+
},
44+
})
45+
}

cmd/tftemplate/main.go

+36-1
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,21 @@ var (
1919
resourceHelpersTemplateFile string
2020
//go:embed waiters.go.tmpl
2121
resourceWaitersTemplateFile string
22+
//go:embed datasource.go.tmpl
23+
datasourceTemplateFile string
24+
//go:embed datasource_test.go.tmpl
25+
datasourceTestTemplateFile string
2226
)
2327

2428
var resourceQS = []*survey.Question{
29+
{
30+
Name: "targets",
31+
Prompt: &survey.MultiSelect{
32+
Message: "Select targets to generate",
33+
Options: []string{"resource", "datasource"},
34+
Default: []string{"resource"},
35+
},
36+
},
2537
{
2638
Name: "api",
2739
Prompt: &survey.Input{Message: "API name (function, instance, container)"},
@@ -49,14 +61,25 @@ var resourceQS = []*survey.Question{
4961
{
5062
Name: "waiters",
5163
Prompt: &survey.Confirm{
52-
Message: "Generate helpers ? Will be added to scaleway/helpers_{api}.go",
64+
Message: "Generate waiters ? Will be added to scaleway/helpers_{api}.go",
5365
Default: true,
5466
},
5567
},
5668
}
5769

70+
func contains[T comparable](slice []T, expected T) bool {
71+
for _, elem := range slice {
72+
if elem == expected {
73+
return true
74+
}
75+
}
76+
77+
return false
78+
}
79+
5880
func main() {
5981
resourceInput := struct {
82+
Targets []string
6083
API string
6184
Resource string
6285
Locality string
@@ -73,10 +96,22 @@ func main() {
7396
{
7497
FileName: fmt.Sprintf("../../scaleway/resource_%s.go", resourceData.ResourceHCL),
7598
TemplateFile: resourceTemplateFile,
99+
Skip: !contains(resourceInput.Targets, "resource"),
76100
},
77101
{
78102
FileName: fmt.Sprintf("../../scaleway/resource_%s_test.go", resourceData.ResourceHCL),
79103
TemplateFile: resourceTestTemplateFile,
104+
Skip: !contains(resourceInput.Targets, "resource"),
105+
},
106+
{
107+
FileName: fmt.Sprintf("../../scaleway/data_source_%s.go", resourceData.ResourceHCL),
108+
TemplateFile: datasourceTemplateFile,
109+
Skip: !contains(resourceInput.Targets, "datasource"),
110+
},
111+
{
112+
FileName: fmt.Sprintf("../../scaleway/data_source_%s_test.go", resourceData.ResourceHCL),
113+
TemplateFile: datasourceTestTemplateFile,
114+
Skip: !contains(resourceInput.Targets, "datasource"),
80115
},
81116
{
82117
FileName: fmt.Sprintf("../../scaleway/helpers_%s.go", resourceData.API),

cmd/tftemplate/resource.go.tmpl

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ func resourceScaleway{{ .Resource }}Read(ctx context.Context, d *schema.Resource
7474
}
7575

7676
_ = d.Set("name", {{ .ResourceCleanLow }}.Name)
77+
_ = d.Set("{{.Locality}}", {{.ResourceCleanLow}}.{{.LocalityUpper}})
78+
_ = d.Set("project_id", {{.ResourceCleanLow}}.ProjectID)
7779

7880
return nil
7981
}

0 commit comments

Comments
 (0)