Skip to content

Commit

Permalink
Merge pull request #27154 from hashicorp/td-tag-resource-generator-wi…
Browse files Browse the repository at this point in the history
…thout-timeout

Code generation: Generate `WithoutTimeout` CRUD handler variants for tag resources
  • Loading branch information
ewbankkit authored Oct 7, 2022
2 parents 488dac2 + bff6a8c commit 72c8d66
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 343 deletions.
201 changes: 5 additions & 196 deletions internal/generate/tagresource/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package main

import (
"bytes"
_ "embed"
"flag"
"fmt"
"go/format"
Expand Down Expand Up @@ -108,200 +109,8 @@ func generateTemplateFile(filename string, templateBody string, templateData int
return nil
}

const (
resourceTemplateBody = `
// Code generated by internal/generate/tagresource/main.go; DO NOT EDIT.
//go:embed resource.tmpl
var resourceTemplateBody string

package {{ .ServicePackage }}
import (
"fmt"
"log"
"github.com/aws/aws-sdk-go/service/{{ .AWSService }}"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)
func ResourceTag() *schema.Resource {
return &schema.Resource{
Create: resourceTagCreate,
Read: resourceTagRead,
Update: resourceTagUpdate,
Delete: resourceTagDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"{{ .IDAttribName }}": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
},
}
}
func resourceTagCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
identifier := d.Get("{{ .IDAttribName }}").(string)
key := d.Get("key").(string)
value := d.Get("value").(string)
{{ if eq .ServicePackage "ec2" }}
if err := CreateTags(conn, identifier, map[string]string{key: value}); err != nil {
{{- else }}
if err := UpdateTags(conn, identifier, nil, map[string]string{key: value}); err != nil {
{{- end }}
return fmt.Errorf("error creating %s resource (%s) tag (%s): %w", {{ .ServicePackage }}.ServiceID, identifier, key, err)
}
d.SetId(tftags.SetResourceID(identifier, key))
return resourceTagRead(d, meta)
}
func resourceTagRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
identifier, key, err := tftags.GetResourceID(d.Id())
if err != nil {
return err
}
value, err := GetTag(conn, identifier, key)
if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] %s resource (%s) tag (%s) not found, removing from state", {{ .ServicePackage }}.ServiceID, identifier, key)
d.SetId("")
return nil
}
if err != nil {
return fmt.Errorf("error reading %s resource (%s) tag (%s): %w", {{ .ServicePackage }}.ServiceID, identifier, key, err)
}
d.Set("{{ .IDAttribName }}", identifier)
d.Set("key", key)
d.Set("value", value)
return nil
}
func resourceTagUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
identifier, key, err := tftags.GetResourceID(d.Id())
if err != nil {
return err
}
if err := UpdateTags(conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil {
return fmt.Errorf("error updating %s resource (%s) tag (%s): %w", {{ .ServicePackage }}.ServiceID, identifier, key, err)
}
return resourceTagRead(d, meta)
}
func resourceTagDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
identifier, key, err := tftags.GetResourceID(d.Id())
if err != nil {
return err
}
if err := UpdateTags(conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil {
return fmt.Errorf("error deleting %s resource (%s) tag (%s): %w", {{ .ServicePackage }}.ServiceID, identifier, key, err)
}
return nil
}
`
resourceTestTemplateBody = `
// Code generated by internal/generate/tagresource/main.go; DO NOT EDIT.
package {{ .ServicePackage }}_test
import (
"fmt"
"github.com/aws/aws-sdk-go/service/{{ .AWSService }}"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
tf{{ .ServicePackage }} "github.com/hashicorp/terraform-provider-aws/internal/service/{{ .ServicePackage }}"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)
func testAccCheckTagDestroy(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_{{ .ServicePackage }}_tag" {
continue
}
identifier, key, err := tftags.GetResourceID(rs.Primary.ID)
if err != nil {
return err
}
_, err = tf{{ .ServicePackage }}.GetTag(conn, identifier, key)
if tfresource.NotFound(err) {
continue
}
if err != nil {
return err
}
return fmt.Errorf("%s resource (%s) tag (%s) still exists", {{ .ServicePackage }}.ServiceID, identifier, key)
}
return nil
}
func testAccCheckTagExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("not found: %s", resourceName)
}
if rs.Primary.ID == "" {
return fmt.Errorf("%s: missing resource ID", resourceName)
}
identifier, key, err := tftags.GetResourceID(rs.Primary.ID)
if err != nil {
return err
}
conn := acctest.Provider.Meta().(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
_, err = tf{{ .ServicePackage }}.GetTag(conn, identifier, key)
return err
}
}
`
)
//go:embed tests.tmpl
var resourceTestTemplateBody string
122 changes: 122 additions & 0 deletions internal/generate/tagresource/resource.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Code generated by internal/generate/tagresource/main.go; DO NOT EDIT.

package {{ .ServicePackage }}

import (
"context"
"log"

"github.com/aws/aws-sdk-go/service/{{ .AWSService }}"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)

func ResourceTag() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceTagCreate,
ReadWithoutTimeout: resourceTagRead,
UpdateWithoutTimeout: resourceTagUpdate,
DeleteWithoutTimeout: resourceTagDelete,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Schema: map[string]*schema.Schema{
"{{ .IDAttribName }}": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
},
}
}

func resourceTagCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).{{ .AWSServiceUpper }}Conn

identifier := d.Get("{{ .IDAttribName }}").(string)
key := d.Get("key").(string)
value := d.Get("value").(string)

{{ if eq .ServicePackage "ec2" }}
if err := CreateTagsWithContext(ctx, conn, identifier, map[string]string{key: value}); err != nil {
{{- else }}
if err := UpdateTagsWithContext(ctx, conn, identifier, nil, map[string]string{key: value}); err != nil {
{{- end }}
return diag.Errorf("creating %s resource (%s) tag (%s): %s", {{ .ServicePackage }}.ServiceID, identifier, key, err)
}

d.SetId(tftags.SetResourceID(identifier, key))

return resourceTagRead(ctx, d, meta)
}

func resourceTagRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
identifier, key, err := tftags.GetResourceID(d.Id())

if err != nil {
return diag.FromErr(err)
}

value, err := GetTagWithContext(ctx, conn, identifier, key)

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] %s resource (%s) tag (%s) not found, removing from state", {{ .ServicePackage }}.ServiceID, identifier, key)
d.SetId("")
return nil
}

if err != nil {
return diag.Errorf("reading %s resource (%s) tag (%s): %s", {{ .ServicePackage }}.ServiceID, identifier, key, err)
}

d.Set("{{ .IDAttribName }}", identifier)
d.Set("key", key)
d.Set("value", value)

return nil
}

func resourceTagUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
identifier, key, err := tftags.GetResourceID(d.Id())

if err != nil {
return diag.FromErr(err)
}

if err := UpdateTagsWithContext(ctx, conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil {
return diag.Errorf("updating %s resource (%s) tag (%s): %s", {{ .ServicePackage }}.ServiceID, identifier, key, err)
}

return resourceTagRead(ctx, d, meta)
}

func resourceTagDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).{{ .AWSServiceUpper }}Conn
identifier, key, err := tftags.GetResourceID(d.Id())

if err != nil {
return diag.FromErr(err)
}

if err := UpdateTagsWithContext(ctx, conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil {
return diag.Errorf("deleting %s resource (%s) tag (%s): %s", {{ .ServicePackage }}.ServiceID, identifier, key, err)
}

return nil
}
Loading

0 comments on commit 72c8d66

Please sign in to comment.