diff --git a/.travis.yml b/.travis.yml index 54d2758..052fe6b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ sudo: false language: go go: - - 1.14 - 1.15 cache: diff --git a/go.mod b/go.mod index 9f33f5b..64cc1ae 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/kjmkznr/terraform-provider-mackerel -go 1.14 +go 1.15 require ( - github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform v0.13.5 - github.com/hashicorp/terraform-plugin-sdk v1.16.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.3 github.com/mackerelio/mackerel-client-go v0.12.0 golang.org/x/tools v0.0.0-20200904185747-39188db58858 // indirect ) diff --git a/go.sum b/go.sum index 6537c8a..135a654 100644 --- a/go.sum +++ b/go.sum @@ -295,6 +295,8 @@ github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuD github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= +github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02 h1:l1KB3bHVdvegcIf5upQ5mjcHjs2qsWnKh4Yr9xgIuu8= github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= @@ -330,9 +332,8 @@ github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= github.com/hashicorp/hcl/v2 v2.3.0/go.mod h1:d+FwDBbOLvpAM3Z6J7gPj/VoAGkNe/gm352ZhjJ/Zv8= github.com/hashicorp/hcl/v2 v2.6.0 h1:3krZOfGY6SziUXa6H9PJU6TyohHn7I+ARYnhbeNBz+o= @@ -346,15 +347,14 @@ github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb h1:ZbgmOQt8DOg796fi github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= github.com/hashicorp/terraform v0.13.5 h1:QgPgb/pOBclUMymDji9255FlseySf9dRcUMzJws9BAQ= github.com/hashicorp/terraform v0.13.5/go.mod h1:1H1qcnppNc/bBGc7poOfnmmBeQMlF0stEN3haY3emCU= -github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 h1:Pc5TCv9mbxFN6UVX0LH6CpQrdTM5YjbVI2w15237Pjk= github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= github.com/hashicorp/terraform-exec v0.10.0 h1:3nh/1e3u9gYRUQGOKWp/8wPR7ABlL2F14sZMZBrp+dM= github.com/hashicorp/terraform-exec v0.10.0/go.mod h1:tOT8j1J8rP05bZBGWXfMyU3HkLi1LWyqL3Bzsc3CJjo= github.com/hashicorp/terraform-json v0.5.0 h1:7TV3/F3y7QVSuN4r9BEXqnWqrAyeOtON8f0wvREtyzs= github.com/hashicorp/terraform-json v0.5.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= -github.com/hashicorp/terraform-plugin-sdk v1.16.0 h1:NrkXMRjHErUPPTHQkZ6JIn6bByiJzGnlJzH1rVdNEuE= -github.com/hashicorp/terraform-plugin-sdk v1.16.0/go.mod h1:5sVxrwW6/xzFhZyql+Q9zXCUEJaGWcBIxBbZFLpVXOI= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.3 h1:X7VmKpcIxq+rIbuqe5TPN27KLzbO9aXQcjG4c5iC3tk= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.3/go.mod h1:oz4kkpfTJ/hA2VMD0WpITTd3yPDGpT4uN7CiKdre/YI= github.com/hashicorp/terraform-plugin-test/v2 v2.1.2 h1:p96IIn+XpvVjw7AtN8y9MKxn0x69S7wtbGf7JgDJoIk= github.com/hashicorp/terraform-plugin-test/v2 v2.1.2/go.mod h1:jerO5mrd+jVNALy8aiq+VZOg/CR8T2T1QR3jd6JKGOI= github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596 h1:hjyO2JsNZUKT1ym+FAdlBEkGPevazYsmVgIMw7dVELg= @@ -582,8 +582,6 @@ github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.5.1 h1:oALUZX+aJeEBUe2a1+uD2+UTaYfEjnKFDEMRydkGvWE= github.com/zclconf/go-cty v1.5.1/go.mod h1:nHzOclRkoj++EU9ZjSrZvRG0BXIWt8c7loYc0qXAFGQ= -github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8= -github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0= github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 37914d4..282f3cd 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1,8 +1,10 @@ package provider import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) const ( @@ -10,7 +12,7 @@ const ( ) // Provider returns a terraform.ResourceProvider. -func Provider() terraform.ResourceProvider { +func Provider() *schema.Provider { return &schema.Provider{ Schema: map[string]*schema.Schema{ "api_key": { @@ -29,14 +31,19 @@ func Provider() terraform.ResourceProvider { "mackerel_service": resourceMackerelService(), "mackerel_channel": resourceMackerelChannel(), }, - ConfigureFunc: providerConfigure, + ConfigureContextFunc: providerConfigure, } } -func providerConfigure(d *schema.ResourceData) (interface{}, error) { +func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { + var diags diag.Diagnostics config := Config{ ApiKey: d.Get("api_key").(string), } - return config.NewClient() + c, err := config.NewClient() + if err != nil { + diag.FromErr(err) + } + return c, diags } diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 5ff11f9..0316cf9 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -1,35 +1,45 @@ package provider import ( + "context" "os" + "sync" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) -var testAccProviders map[string]terraform.ResourceProvider +const providerName = "mackerel" + var testAccProvider *schema.Provider +var testAccProviderFactories map[string]func() (*schema.Provider, error) + +var testAccProviderConfigure sync.Once func init() { - testAccProvider = Provider().(*schema.Provider) - testAccProviders = map[string]terraform.ResourceProvider{ - "mackerel": testAccProvider, + testAccProvider = Provider() + testAccProviderFactories = map[string]func() (*schema.Provider, error){ + providerName: func() (*schema.Provider, error) { + return Provider(), nil + }, } } func TestProvider(t *testing.T) { - if err := Provider().(*schema.Provider).InternalValidate(); err != nil { + if err := Provider().InternalValidate(); err != nil { t.Fatalf("err: %s", err) } } -func TestProvider_impl(t *testing.T) { - var _ terraform.ResourceProvider = Provider() -} - func testAccPreCheck(t *testing.T) { - if v := os.Getenv("MACKEREL_API_KEY"); v == "" { - t.Fatal("MACKEREL_API_KEY must be set for acceptance tests") - } + testAccProviderConfigure.Do(func() { + if v := os.Getenv("MACKEREL_API_KEY"); v == "" { + t.Fatal("MACKEREL_API_KEY must be set for acceptance tests") + } + err := testAccProvider.Configure(context.Background(), terraform.NewResourceConfigRaw(nil)) + if err != nil { + t.Fatal(err) + } + }) } diff --git a/internal/provider/resource_mackerel_channel.go b/internal/provider/resource_mackerel_channel.go index f844a80..acbd6ed 100644 --- a/internal/provider/resource_mackerel_channel.go +++ b/internal/provider/resource_mackerel_channel.go @@ -1,23 +1,23 @@ package provider import ( + "context" "encoding/json" "fmt" "log" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/mackerelio/mackerel-client-go" ) func resourceMackerelChannel() *schema.Resource { return &schema.Resource{ - Create: resourceMackerelChannelCreate, - Read: resourceMackerelChannelRead, - Delete: resourceMackerelChannelDelete, - Exists: resourceMackerelChannelExists, + CreateContext: resourceMackerelChannelCreate, + ReadContext: resourceMackerelChannelRead, + DeleteContext: resourceMackerelChannelDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ @@ -25,7 +25,7 @@ func resourceMackerelChannel() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{ + ValidateDiagFunc: stringInSliceDiag([]string{ "email", "slack", "webhook", @@ -76,77 +76,77 @@ func resourceMackerelChannel() *schema.Resource { } } -func resourceMackerelChannelCreate(d *schema.ResourceData, meta interface{}) error { +func resourceMackerelChannelCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client := meta.(*mackerel.Client) input, err := buildChannelParameter(d) if err != nil { - return err + return diag.FromErr(fmt.Errorf("error build channel parameter %w", err)) } channel, err := client.CreateChannel(input) if err != nil { - return err + return diag.FromErr(fmt.Errorf("error create channel %w", err)) } log.Printf("[DEBUG] mackerel channel %q created.", channel.ID) d.SetId(channel.ID) - return resourceMackerelChannelRead(d, meta) + return resourceMackerelChannelRead(ctx, d, meta) } -func resourceMackerelChannelRead(d *schema.ResourceData, meta interface{}) error { +func resourceMackerelChannelRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client := meta.(*mackerel.Client) log.Printf("[DEBUG] Reading mackerel channel: %q", d.Id()) channels, err := client.FindChannels() if err != nil { - return err + return diag.FromErr(fmt.Errorf("error read channel %w", err)) } + exists := false for _, channel := range channels { if channel.ID == d.Id() { - _ = d.Set("id", channel.ID) + exists = true _ = d.Set("name", channel.Name) _ = d.Set("type", channel.Type) _ = d.Set("url", channel.URL) _ = d.Set("enabled_graph_image", channel.EnabledGraphImage) _ = d.Set("user_ids", channel.UserIDs) - _ = d.Set("mentions", channel.Mentions) + + var mentions = map[string]string{} + if ok := channel.Mentions.OK; ok != "" { + mentions["ok"] = ok + } + if crit := channel.Mentions.Critical; crit != "" { + mentions["critical"] = crit + } + if warn := channel.Mentions.Warning; warn != "" { + mentions["warning"] = warn + } + _ = d.Set("mentions", mentions) _ = d.Set("events", channel.Events) break } - } - - return nil -} -func resourceMackerelChannelExists(d *schema.ResourceData, meta interface{}) (b bool, e error) { - client := meta.(*mackerel.Client) - channels, err := client.FindChannels() - if err != nil { - return false, err - } - - for _, c := range channels { - if c.ID == d.Id() { - return true, nil + if !exists { + // channel is gone + d.SetId("") } } - return false, nil + return nil } -func resourceMackerelChannelDelete(d *schema.ResourceData, meta interface{}) error { +func resourceMackerelChannelDelete(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client := meta.(*mackerel.Client) _, err := client.DeleteChannel(d.Id()) if err != nil { - return err + return diag.FromErr(fmt.Errorf("error delete channel %w", err)) } log.Printf("[DEBUG] mackerel channel %q deleted.", d.Id()) - d.SetId("") return nil } diff --git a/internal/provider/resource_mackerel_channel_test.go b/internal/provider/resource_mackerel_channel_test.go index 930a90d..44e02a0 100644 --- a/internal/provider/resource_mackerel_channel_test.go +++ b/internal/provider/resource_mackerel_channel_test.go @@ -6,9 +6,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/mackerelio/mackerel-client-go" ) @@ -17,9 +17,9 @@ func TestAccMackerelChannelEmail_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestChannelEmail-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelChannelDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelChannelDestroy, Steps: []resource.TestStep{ { Config: testAccMackerelChannelEmailConfigBasic(rName), @@ -40,9 +40,9 @@ func TestAccMackerelChannelEmail_Invalid(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestChannelEmail-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelChannelDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelChannelDestroy, Steps: []resource.TestStep{ { Config: testAccMackerelChannelEmailConfigInvalid(rName), @@ -57,9 +57,9 @@ func TestAccMackerelChannelSlack_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestChannelSlack-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelChannelDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelChannelDestroy, Steps: []resource.TestStep{ { Config: testAccMackerelChannelSlackConfigBasic(rName), @@ -83,9 +83,9 @@ func TestAccMackerelChannelWebhook_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestChannelWebhook-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelChannelDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelChannelDestroy, Steps: []resource.TestStep{ { Config: testAccMackerelChannelWebhookConfigBasic(rName), @@ -125,7 +125,7 @@ func testAccCheckMackerelChannelDestroy(s *terraform.State) error { return nil } -func testAccCheckMackerelChannelExists(resouceName string) resource.TestCheckFunc { +func testAccCheckMackerelChannelExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := testAccProvider.Meta().(*mackerel.Client) @@ -144,7 +144,7 @@ func testAccCheckMackerelChannelExists(resouceName string) resource.TestCheckFun } } } - return fmt.Errorf("channel (%s) not found", resouceName) + return fmt.Errorf("channel (%s) not found", resourceName) } } diff --git a/internal/provider/resource_mackerel_dashboard.go b/internal/provider/resource_mackerel_dashboard.go index c70c681..5620a48 100644 --- a/internal/provider/resource_mackerel_dashboard.go +++ b/internal/provider/resource_mackerel_dashboard.go @@ -3,7 +3,7 @@ package provider import ( "log" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/mackerelio/mackerel-client-go" ) @@ -15,7 +15,7 @@ func resourceMackerelDashboard() *schema.Resource { Delete: resourceMackerelDashboardDelete, Exists: resourceMackerelDashboardExists, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ @@ -28,9 +28,9 @@ func resourceMackerelDashboard() *schema.Resource { Required: true, }, "url_path": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validateUrlPathWord, + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validateUrlPathWordDiag(), }, }, } @@ -116,7 +116,6 @@ func resourceMackerelDashboardDelete(d *schema.ResourceData, meta interface{}) e } log.Printf("[DEBUG] mackerel dashboard %q deleted.", d.Id()) - d.SetId("") return nil } diff --git a/internal/provider/resource_mackerel_dashboard_test.go b/internal/provider/resource_mackerel_dashboard_test.go index 279e456..b10d272 100644 --- a/internal/provider/resource_mackerel_dashboard_test.go +++ b/internal/provider/resource_mackerel_dashboard_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/mackerelio/mackerel-client-go" ) @@ -14,9 +14,9 @@ func TestAccMackerelDashboard_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestDashboard-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelDashboardDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelDashboardDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelDashboardConfigBasic(rName), @@ -37,9 +37,9 @@ func TestAccMackerelDashboard_Update(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestDashboard-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelDashboardDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelDashboardDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelDashboardConfigBasic(rName), diff --git a/internal/provider/resource_mackerel_expression_monitor.go b/internal/provider/resource_mackerel_expression_monitor.go index 857d84c..c6b00d6 100644 --- a/internal/provider/resource_mackerel_expression_monitor.go +++ b/internal/provider/resource_mackerel_expression_monitor.go @@ -3,7 +3,7 @@ package provider import ( "log" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/mackerelio/mackerel-client-go" ) @@ -15,7 +15,7 @@ func resourceMackerelExpressionMonitor() *schema.Resource { Delete: resourceMackerelExpressionMonitorDelete, Exists: resourceMackerelExpressionMonitorExists, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ @@ -88,7 +88,6 @@ func resourceMackerelExpressionMonitorRead(d *schema.ResourceData, meta interfac for _, monitor := range monitors { if monitor.MonitorType() == "expression" && monitor.MonitorID() == d.Id() { mon := monitor.(*mackerel.MonitorExpression) - _ = d.Set("id", mon.MonitorID()) _ = d.Set("name", mon.MonitorName()) _ = d.Set("expression", mon.Expression) _ = d.Set("operator", mon.Operator) @@ -151,7 +150,6 @@ func resourceMackerelExpressionMonitorDelete(d *schema.ResourceData, meta interf } log.Printf("[DEBUG] mackerel monitor %q deleted.", d.Id()) - d.SetId("") return nil } diff --git a/internal/provider/resource_mackerel_expression_monitor_test.go b/internal/provider/resource_mackerel_expression_monitor_test.go index dcec8ab..0e82924 100644 --- a/internal/provider/resource_mackerel_expression_monitor_test.go +++ b/internal/provider/resource_mackerel_expression_monitor_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/mackerelio/mackerel-client-go" ) @@ -14,9 +14,9 @@ func TestAccMackerelExpressionMonitor_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestExpressionMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelExpressionMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelExpressionMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelExpressionMonitorConfigBasic(rName), @@ -43,9 +43,9 @@ func TestAccMackerelExpressionMonitor_Update(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestExpressionMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelExpressionMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelExpressionMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelExpressionMonitorConfigBasic(rName), @@ -89,9 +89,9 @@ func TestAccMackerelExpressionMonitor_Minimum(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestExpressionMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelExpressionMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelExpressionMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelExpressionMonitorConfigMinimum(rName), diff --git a/internal/provider/resource_mackerel_external_monitor.go b/internal/provider/resource_mackerel_external_monitor.go index 3839b2f..e02b46c 100644 --- a/internal/provider/resource_mackerel_external_monitor.go +++ b/internal/provider/resource_mackerel_external_monitor.go @@ -4,8 +4,8 @@ import ( "log" "net/http" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/mackerelio/mackerel-client-go" ) @@ -17,7 +17,7 @@ func resourceMackerelExternalMonitor() *schema.Resource { Delete: resourceMackerelExternalMonitorDelete, Exists: resourceMackerelExternalMonitorExists, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ @@ -77,15 +77,15 @@ func resourceMackerelExternalMonitor() *schema.Resource { Optional: true, }, "method": { - Type: schema.TypeString, - Default: http.MethodGet, - Optional: true, - ValidateFunc: validateMethodWord, + Type: schema.TypeString, + Default: http.MethodGet, + Optional: true, + ValidateDiagFunc: validateMethodWordDiag(), }, "memo": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringLenBetween(0, 250), + Type: schema.TypeString, + Optional: true, + ValidateDiagFunc: validateDiagFunc(validation.StringLenBetween(0, 250)), }, "request_body": { Type: schema.TypeString, @@ -127,7 +127,6 @@ func resourceMackerelExternalMonitorRead(d *schema.ResourceData, meta interface{ for _, monitor := range monitors { if monitor.MonitorType() == "external" && monitor.MonitorID() == d.Id() { mon := monitor.(*mackerel.MonitorExternalHTTP) - _ = d.Set("id", mon.MonitorID()) _ = d.Set("name", mon.MonitorName()) _ = d.Set("url", mon.URL) _ = d.Set("service", mon.Service) @@ -144,7 +143,7 @@ func resourceMackerelExternalMonitorRead(d *schema.ResourceData, meta interface{ _ = d.Set("method", mon.Method) _ = d.Set("memo", mon.Memo) _ = d.Set("request_body", mon.RequestBody) - _ = d.Set("headers", mon.Headers) + _ = d.Set("headers", expandHeaders(mon.Headers)) break } } @@ -190,7 +189,6 @@ func resourceMackerelExternalMonitorDelete(d *schema.ResourceData, meta interfac } log.Printf("[DEBUG] mackerel monitor %q deleted.", d.Id()) - d.SetId("") return nil } @@ -246,6 +244,8 @@ func getMackerelExternalMonitorInput(d *schema.ResourceData) *mackerel.MonitorEx } if v, ok := d.GetOk("headers"); ok { input.Headers = readHeaders(v.(map[string]interface{})) + } else { + input.Headers = []mackerel.HeaderField{} } return input @@ -263,3 +263,12 @@ func readHeaders(h map[string]interface{}) []mackerel.HeaderField { return headers } + +func expandHeaders(headerFields []mackerel.HeaderField) map[string]string { + var headers = map[string]string{} + for _, h := range headerFields { + headers[h.Name] = h.Value + } + + return headers +} diff --git a/internal/provider/resource_mackerel_external_monitor_test.go b/internal/provider/resource_mackerel_external_monitor_test.go index 67a9340..51b99c5 100644 --- a/internal/provider/resource_mackerel_external_monitor_test.go +++ b/internal/provider/resource_mackerel_external_monitor_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/mackerelio/mackerel-client-go" ) @@ -14,9 +14,9 @@ func TestAccMackerelExternalMonitor_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestExternalMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelExternalMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelExternalMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelExternalMonitorConfigBasic(rName), @@ -63,9 +63,9 @@ func TestAccMackerelExternalMonitor_Update(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestExternalMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelExternalMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelExternalMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelExternalMonitorConfigBasic(rName), @@ -139,9 +139,9 @@ func TestAccMackerelExternalMonitor_Minimum(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestExternalMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelExternalMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelExternalMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelExternalMonitorConfigMinimum(rName), @@ -170,7 +170,7 @@ func testAccCheckMackerelExternalMonitorDestroy(s *terraform.State) error { } for _, monitor := range monitors { if monitor.MonitorID() == rs.Primary.ID { - return fmt.Errorf("Monitor still exists") + return fmt.Errorf("monitor still exists") } } } diff --git a/internal/provider/resource_mackerel_host_monitor.go b/internal/provider/resource_mackerel_host_monitor.go index 855b6f7..e7f8d92 100644 --- a/internal/provider/resource_mackerel_host_monitor.go +++ b/internal/provider/resource_mackerel_host_monitor.go @@ -3,8 +3,8 @@ package provider import ( "log" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/mackerelio/mackerel-client-go" ) @@ -17,7 +17,7 @@ func resourceMackerelHostMonitor() *schema.Resource { Delete: resourceMackerelHostMonitorDelete, Exists: resourceMackerelHostMonitorExists, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ @@ -50,10 +50,10 @@ func resourceMackerelHostMonitor() *schema.Resource { Optional: true, }, "max_check_attempts": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: validation.IntBetween(1, 10), - Default: 1, + Type: schema.TypeInt, + Optional: true, + ValidateDiagFunc: validateDiagFunc(validation.IntBetween(1, 10)), + Default: 1, }, "scopes": { Type: schema.TypeList, @@ -120,7 +120,6 @@ func resourceMackerelHostMonitorRead(d *schema.ResourceData, meta interface{}) e for _, monitor := range monitors { if monitor.MonitorType() == "host" && monitor.MonitorID() == d.Id() { mon := monitor.(*mackerel.MonitorHostMetric) - _ = d.Set("id", mon.ID) _ = d.Set("name", mon.Name) _ = d.Set("duration", mon.Duration) _ = d.Set("metric", mon.Metric) @@ -197,7 +196,6 @@ func resourceMackerelHostMonitorDelete(d *schema.ResourceData, meta interface{}) } log.Printf("[DEBUG] mackerel monitor %q deleted.", d.Id()) - d.SetId("") return nil } diff --git a/internal/provider/resource_mackerel_host_monitor_test.go b/internal/provider/resource_mackerel_host_monitor_test.go index 89fda0a..331f758 100644 --- a/internal/provider/resource_mackerel_host_monitor_test.go +++ b/internal/provider/resource_mackerel_host_monitor_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/mackerelio/mackerel-client-go" ) @@ -14,9 +14,9 @@ func TestAccMackerelHostMonitor_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestHostMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelHostMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelHostMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelHostMonitorConfigBasic(rName), @@ -51,9 +51,9 @@ func TestAccMackerelHostMonitor_Update(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestHostMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelHostMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelHostMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelHostMonitorConfigBasic(rName), @@ -113,9 +113,9 @@ func TestAccMackerelHostMonitor_Minimum(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestHostMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelHostMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelHostMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccCheckMackerelHostMonitorConfigMinimum(rName), diff --git a/internal/provider/resource_mackerel_service.go b/internal/provider/resource_mackerel_service.go index 5eeca99..eec2967 100644 --- a/internal/provider/resource_mackerel_service.go +++ b/internal/provider/resource_mackerel_service.go @@ -4,8 +4,8 @@ import ( "log" "regexp" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/mackerelio/mackerel-client-go" ) @@ -16,15 +16,17 @@ func resourceMackerelService() *schema.Resource { Delete: resourceMackerelServiceDelete, Exists: resourceMackerelServiceExists, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9\-\_]+$`), "must contain only alphanumeric characters, dashes, and underscores"), + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateDiagFunc: validateDiagFunc( + validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9\-\_]+$`), + "must contain only alphanumeric characters, dashes, and underscores")), }, "memo": { Type: schema.TypeString, @@ -99,7 +101,6 @@ func resourceMackerelServiceDelete(d *schema.ResourceData, meta interface{}) err } log.Printf("[DEBUG] mackerel service %q deleted.", d.Id()) - d.SetId("") return nil } diff --git a/internal/provider/resource_mackerel_service_monitor.go b/internal/provider/resource_mackerel_service_monitor.go index 3af0bdd..1d9b989 100644 --- a/internal/provider/resource_mackerel_service_monitor.go +++ b/internal/provider/resource_mackerel_service_monitor.go @@ -3,8 +3,8 @@ package provider import ( "log" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/mackerelio/mackerel-client-go" ) @@ -16,7 +16,7 @@ func resourceMackerelServiceMonitor() *schema.Resource { Delete: resourceMackerelServiceMonitorDelete, Exists: resourceMackerelServiceMonitorExists, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ @@ -61,10 +61,10 @@ func resourceMackerelServiceMonitor() *schema.Resource { Optional: true, }, "max_check_attempts": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: validation.IntBetween(1, 10), - Default: 1, + Type: schema.TypeInt, + Optional: true, + ValidateDiagFunc: validateDiagFunc(validation.IntBetween(1, 10)), + Default: 1, }, "is_mute": { Type: schema.TypeBool, @@ -116,7 +116,6 @@ func resourceMackerelServiceMonitorRead(d *schema.ResourceData, meta interface{} for _, monitor := range monitors { if monitor.MonitorType() == "service" && monitor.MonitorID() == d.Id() { mon := monitor.(*mackerel.MonitorServiceMetric) - _ = d.Set("id", mon.ID) _ = d.Set("name", mon.Name) _ = d.Set("service", mon.Service) _ = d.Set("duration", mon.Duration) @@ -189,7 +188,6 @@ func resourceMackerelServiceMonitorDelete(d *schema.ResourceData, meta interface } log.Printf("[DEBUG] mackerel monitor %q deleted.", d.Id()) - d.SetId("") return nil } diff --git a/internal/provider/resource_mackerel_service_monitor_test.go b/internal/provider/resource_mackerel_service_monitor_test.go index 0d3bce1..f821297 100644 --- a/internal/provider/resource_mackerel_service_monitor_test.go +++ b/internal/provider/resource_mackerel_service_monitor_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/mackerelio/mackerel-client-go" ) @@ -14,9 +14,9 @@ func TestAccMackerelServiceMonitor_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestServiceMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelServiceMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelServiceMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccMackerelServiceMonitorConfigBasic(rName), @@ -53,9 +53,9 @@ func TestAccMackerelServiceMonitor_Update(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestServiceMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelServiceMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelServiceMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccMackerelServiceMonitorConfigBasic(rName), @@ -119,9 +119,9 @@ func TestAccMackerelServiceMonitor_Minimum(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestServiceMonitor-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelServiceMonitorDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelServiceMonitorDestroy, Steps: []resource.TestStep{ { Config: testAccMackerelServiceMonitorConfigMinimum(rName), diff --git a/internal/provider/resource_mackerel_service_test.go b/internal/provider/resource_mackerel_service_test.go index 1e74bfd..01d2a97 100644 --- a/internal/provider/resource_mackerel_service_test.go +++ b/internal/provider/resource_mackerel_service_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/mackerelio/mackerel-client-go" ) @@ -14,9 +14,9 @@ func TestAccMackerelService_Basic(t *testing.T) { rName := acctest.RandomWithPrefix("TerraformTestService-") resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckMackerelServiceDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckMackerelServiceDestroy, Steps: []resource.TestStep{ { Config: testAccMackerelServiceConfigBasic(rName), diff --git a/internal/provider/validators.go b/internal/provider/validators.go index 44f3798..fe629d2 100644 --- a/internal/provider/validators.go +++ b/internal/provider/validators.go @@ -4,46 +4,113 @@ import ( "fmt" "net/http" "regexp" + "strings" + + "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func validateUrlPathWord(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - pattern := `^([A-Za-z0-9_][-A-Za-z0-9_]*)(/[A-Za-z0-9_][-A-Za-z0-9_]*)*$` - if !regexp.MustCompile(pattern).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q doesn't comply with restrictions (%q): %q", - k, pattern, value)) +func validateUrlPathWordDiag() schema.SchemaValidateDiagFunc { + return func(v interface{}, path cty.Path) diag.Diagnostics { + diagnostics := stringDiag()(v, path) + value, _ := v.(string) + pattern := `^([A-Za-z0-9_][-A-Za-z0-9_]*)(/[A-Za-z0-9_][-A-Za-z0-9_]*)*$` + if !regexp.MustCompile(pattern).MatchString(value) { + diagnostics = append(diagnostics, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Value must be alphabet, number, '_', '-' or '/'", + Detail: fmt.Sprintf("value doesn't comply with restrictions (%q): %q", pattern, value), + AttributePath: path, + }) + } + return diagnostics } - return } -func validateMethodWord(v interface{}, k string) (warns []string, errors []error) { - value := v.(string) - switch value { - case http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete: - return - default: - errors = append(errors, fmt.Errorf( - "%q doesn't comply with restrictions (GET, POST, PUT, DELETE): %q", - k, value)) +func validateMethodWordDiag() schema.SchemaValidateDiagFunc { + return func(v interface{}, path cty.Path) diag.Diagnostics { + diagnostics := stringDiag()(v, path) + value, _ := v.(string) + if !stringInSlice(value, []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete}, false) { + diagnostics = append(diagnostics, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Value must be HTTP Method", + Detail: fmt.Sprintf("value doesn't comply with restrictions (GET, POST, PUT, DELETE): %q", value), + AttributePath: path, + }) + } + return diagnostics } - return } func validateChannelEvent(events []string, validEvents []string) error { for _, e := range events { - if !isStringInSlice(e, validEvents) { + if !stringInSlice(e, validEvents, true) { return fmt.Errorf("%s is not valid event", e) } } return nil } -func isStringInSlice(target string, strings []string) bool { - for _, s := range strings { - if target == s { +func stringDiag() schema.SchemaValidateDiagFunc { + return func(v interface{}, path cty.Path) diag.Diagnostics { + var diagnostics diag.Diagnostics + if val, ok := v.(string); !ok { + diagnostics = append(diagnostics, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Value must be string", + Detail: fmt.Sprintf("Value is not a string (type = %T)", val), + AttributePath: path, + }) + } + return diagnostics + } +} + +func stringInSliceDiag(valid []string, ignoreCase bool) schema.SchemaValidateDiagFunc { + return func(v interface{}, path cty.Path) diag.Diagnostics { + diagnostics := stringDiag()(v, path) + value, _ := v.(string) + if len(diagnostics) == 0 { + if !stringInSlice(value, valid, ignoreCase) { + diagnostics = append(diagnostics, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Value has incorrect value", + Detail: fmt.Sprintf("expected value to be one of %v, got %s", strings.Join(valid, ","), value), + AttributePath: path, + }) + } + } + return diagnostics + } +} + +func stringInSlice(target string, valid []string, ignoreCase bool) bool { + for _, s := range valid { + if target == s || (ignoreCase && strings.ToLower(target) == strings.ToLower(s)) { return true } } return false } + +func validateDiagFunc(validateFunc func(interface{}, string) ([]string, []error)) schema.SchemaValidateDiagFunc { + return func(i interface{}, path cty.Path) diag.Diagnostics { + warnings, errs := validateFunc(i, fmt.Sprintf("%+v", path)) + var diagnostics diag.Diagnostics + for _, warning := range warnings { + diagnostics = append(diagnostics, diag.Diagnostic{ + Severity: diag.Warning, + Summary: warning, + }) + } + for _, err := range errs { + diagnostics = append(diagnostics, diag.Diagnostic{ + Severity: diag.Error, + Summary: err.Error(), + }) + } + return diagnostics + } +} diff --git a/internal/provider/validators_test.go b/internal/provider/validators_test.go index 27542b1..885cacc 100644 --- a/internal/provider/validators_test.go +++ b/internal/provider/validators_test.go @@ -1,8 +1,10 @@ package provider import ( - "reflect" "testing" + + "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" ) func Test_validateMethodWord(t *testing.T) { @@ -45,11 +47,21 @@ func Test_validateMethodWord(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotWarns, gotErrors := validateMethodWord(tt.arg, "method") - if !reflect.DeepEqual(len(gotWarns), tt.wantWarnCount) { + diagnostics := validateMethodWordDiag()(tt.arg, (cty.Path)(nil).Index(cty.StringVal("method"))) + gotWarns := 0 + gotErrors := 0 + for _, d := range diagnostics { + if d.Severity == diag.Error { + gotErrors++ + } + if d.Severity == diag.Warning { + gotWarns++ + } + } + if gotWarns != tt.wantWarnCount { t.Errorf("validateMethodWord() gotWarns = %v, want %v", gotWarns, tt.wantWarnCount) } - if !reflect.DeepEqual(len(gotErrors), tt.wantErrorCount) { + if gotErrors != tt.wantErrorCount { t.Errorf("validateMethodWord() gotErrors = %v, want %v", gotErrors, tt.wantErrorCount) } }) diff --git a/main.go b/main.go index c958682..bfca8e2 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/hashicorp/terraform-plugin-sdk/plugin" + "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" "github.com/kjmkznr/terraform-provider-mackerel/internal/provider" )