diff --git a/consul/data_source_consul_config_entry_v2_exported_services.go b/consul/data_source_consul_config_entry_v2_exported_services.go index 0bc211c1..af7706a0 100644 --- a/consul/data_source_consul_config_entry_v2_exported_services.go +++ b/consul/data_source_consul_config_entry_v2_exported_services.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" - "github.com/hashicorp/consul/api" pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" @@ -84,12 +83,12 @@ func dataSourceConsulV2ExportedServicesRead(d *schema.ResourceData, meta interfa client, qOpts, _ := getClient(d, meta) name := d.Get("name").(string) kind := d.Get("kind").(string) - gvk := &api.GVK{ + gvk := &GVK{ //&api.GVK{ Group: "multicluster", Version: "v2", Kind: kind, } - resp, err := client.Resource().Read(gvk, name, qOpts) + resp, err := v2MulticlusterRead(client, gvk, name, qOpts) if err != nil || resp == nil { return fmt.Errorf("exported services config not found: %s", name) } diff --git a/consul/data_source_consul_config_entry_v2_exported_services_test.go b/consul/data_source_consul_config_entry_v2_exported_services_test.go index e6e7124a..dc011f0e 100644 --- a/consul/data_source_consul_config_entry_v2_exported_services_test.go +++ b/consul/data_source_consul_config_entry_v2_exported_services_test.go @@ -8,17 +8,20 @@ import ( ) func TestAccDataExportedServicesV2_basic(t *testing.T) { - providers, _ := startTestServer(t) + providers, client := startTestServer(t) resource.Test(t, resource.TestCase{ Providers: providers, + PreCheck: func() { skipTestOnConsulCommunityEdition(t) }, Steps: []resource.TestStep{ { Config: testAccDataSourceExportedServicesV2ConfigNotFound, + SkipFunc: skipIfConsulVersionLT(client, "1.18.0"), ExpectError: regexp.MustCompile(`exported services config not found: not-found`), }, { - Config: testAccDataSourceExportedServicesV2ConfigBasic, + Config: testAccDataSourceExportedServicesV2ConfigBasic, + SkipFunc: skipIfConsulVersionLT(client, "1.18.0"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "name", "test"), resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "kind", "ExportedServices"), @@ -29,33 +32,59 @@ func TestAccDataExportedServicesV2_basic(t *testing.T) { ), }, { - Config: testAccDataSourceComputedExportedServicesV2ConfigBasic, + Config: testAccDataSourceNamespaceExportedServicesV2ConfigBasic, + SkipFunc: skipIfConsulVersionLT(client, "1.18.0"), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "name", "default"), - resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "kind", "ComputedExportedServices"), + resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "name", "test"), + resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "kind", "NamespaceExportedServices"), resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "partition", "default"), - resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "services.0", "s1"), - resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "sameness_group_consumers.0", "sg1"), + resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "partition_consumers.0", "default"), + ), + }, + { + Config: testAccDataSourcePartitionExportedServicesV2ConfigBasic, + SkipFunc: skipIfConsulVersionLT(client, "1.18.0"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "name", "test"), + resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "kind", "PartitionExportedServices"), + resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "partition", "default"), + resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "peer_consumers.0", "peer1"), ), }, }, }) } -const testAccDataSourceComputedExportedServicesV2ConfigBasic = ` +const testAccDataSourcePartitionExportedServicesV2ConfigBasic = ` resource "consul_config_entry_v2_exported_services" "test" { name = "test" - kind = "ExportedServices" + kind = "PartitionExportedServices" + partition = "default" + peer_consumers = ["peer1"] +} + +data "consul_config_entry_v2_exported_services" "read" { + name = consul_config_entry_v2_exported_services.test.name + kind = consul_config_entry_v2_exported_services.test.kind + namespace = consul_config_entry_v2_exported_services.test.namespace + partition = consul_config_entry_v2_exported_services.test.partition +} +` + +const testAccDataSourceNamespaceExportedServicesV2ConfigBasic = ` +resource "consul_config_entry_v2_exported_services" "test" { + name = "test" + kind = "NamespaceExportedServices" namespace = "default" partition = "default" - services = ["s1"] partition_consumers = ["default"] } data "consul_config_entry_v2_exported_services" "read" { - name = "default" - kind = "ComputedExportedServices" - partition = "default" + name = consul_config_entry_v2_exported_services.test.name + kind = consul_config_entry_v2_exported_services.test.kind + namespace = consul_config_entry_v2_exported_services.test.namespace + partition = consul_config_entry_v2_exported_services.test.partition } ` diff --git a/consul/resource_consul_config_entry_v2_exported_services.go b/consul/resource_consul_config_entry_v2_exported_services.go index 9ad4bf34..cc68ff45 100644 --- a/consul/resource_consul_config_entry_v2_exported_services.go +++ b/consul/resource_consul_config_entry_v2_exported_services.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" - "github.com/hashicorp/consul/api" pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" @@ -94,10 +93,10 @@ func resourceConsulV2ExportedServicesCreate(d *schema.ResourceData, meta interfa } func resourceConsulV2ExportedServicesUpdate(d *schema.ResourceData, meta interface{}) error { - client, qOpts, _ := getClient(d, meta) + client, _, wOpts := getClient(d, meta) name := d.Get("name").(string) kind := d.Get("kind").(string) - gvk := &api.GVK{ + gvk := &GVK{ Group: "multicluster", Version: "v2", Kind: kind, @@ -112,20 +111,20 @@ func resourceConsulV2ExportedServicesUpdate(d *schema.ResourceData, meta interfa consumers = append(consumers, map[string]any{"partition": ap}) } samenessConsumers := d.Get("sameness_group_consumers").([]interface{}) - for _, ap := range samenessConsumers { - consumers = append(consumers, map[string]any{"sameness_group": ap}) + for _, sg := range samenessConsumers { + consumers = append(consumers, map[string]any{"sameness_group": sg}) } data := map[string]any{"consumers": consumers} services := d.Get("services").([]interface{}) if len(services) > 0 { data["services"] = services } - wReq := &api.WriteRequest{ + wReq := &V2WriteRequest{ Metadata: nil, Data: data, Owner: nil, } - resp, _, err := client.Resource().Apply(gvk, name, qOpts, wReq) + resp, _, err := v2MulticlusterApply(client, gvk, name, wOpts, wReq) if err != nil || resp == nil { return fmt.Errorf("failed to write exported services config '%s': %v", name, err) } @@ -142,12 +141,12 @@ func resourceConsulV2ExportedServicesRead(d *schema.ResourceData, meta interface client, qOpts, _ := getClient(d, meta) name := d.Get("name").(string) kind := d.Get("kind").(string) - gvk := &api.GVK{ + gvk := &GVK{ Group: "multicluster", Version: "v2", Kind: kind, } - resp, err := client.Resource().Read(gvk, name, qOpts) + resp, err := v2MulticlusterRead(client, gvk, name, qOpts) if err != nil || resp == nil { return fmt.Errorf("exported services config not found: %s", name) } @@ -196,11 +195,11 @@ func resourceConsulV2ExportedServicesRead(d *schema.ResourceData, meta interface func resourceConsulV2ExportedServicesDelete(d *schema.ResourceData, meta interface{}) error { client, qOpts, _ := getClient(d, meta) - gvk := &api.GVK{ + gvk := &GVK{ Group: "multicluster", Version: "v2", Kind: "ExportedServices", } name := d.Get("name").(string) - return client.Resource().Delete(gvk, name, qOpts) + return v2MulticlusterDelete(client, gvk, name, qOpts) } diff --git a/consul/resource_consul_config_entry_v2_exported_services_test.go b/consul/resource_consul_config_entry_v2_exported_services_test.go index ddfe4ad2..083d8afb 100644 --- a/consul/resource_consul_config_entry_v2_exported_services_test.go +++ b/consul/resource_consul_config_entry_v2_exported_services_test.go @@ -10,13 +10,15 @@ import ( ) func TestAccConsulExportedServicesV2_basic(t *testing.T) { - providers, _ := startTestServer(t) + providers, client := startTestServer(t) resource.Test(t, resource.TestCase{ Providers: providers, + PreCheck: func() { skipTestOnConsulCommunityEdition(t) }, Steps: []resource.TestStep{ { - Config: testAccConsulExportedServicesV2Basic, + Config: testAccConsulExportedServicesV2Basic, + SkipFunc: skipIfConsulVersionLT(client, "1.18.0"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry_v2_exported_services.test", "name", "test"), resource.TestCheckResourceAttr("consul_config_entry_v2_exported_services.test", "kind", "ExportedServices"), @@ -29,7 +31,8 @@ func TestAccConsulExportedServicesV2_basic(t *testing.T) { ), }, { - Config: testAccConsulNamespaceExportedServicesV2Basic, + Config: testAccConsulNamespaceExportedServicesV2Basic, + SkipFunc: skipIfConsulVersionLT(client, "1.18.0"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry_v2_exported_services.nstest", "name", "nstest"), resource.TestCheckResourceAttr("consul_config_entry_v2_exported_services.nstest", "kind", "NamespaceExportedServices"), @@ -42,7 +45,8 @@ func TestAccConsulExportedServicesV2_basic(t *testing.T) { ), }, { - Config: testAccConsulPartitionExportedServicesV2Basic, + Config: testAccConsulPartitionExportedServicesV2Basic, + SkipFunc: skipIfConsulVersionLT(client, "1.18.0"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry_v2_exported_services.ptest", "name", "ptest"), resource.TestCheckResourceAttr("consul_config_entry_v2_exported_services.ptest", "kind", "PartitionExportedServices"), diff --git a/consul/v2_resource_provider_helper.go b/consul/v2_resource_provider_helper.go new file mode 100644 index 00000000..342cba35 --- /dev/null +++ b/consul/v2_resource_provider_helper.go @@ -0,0 +1,63 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package consul + +import ( + "fmt" + "strings" + + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/proto-public/pbresource" +) + +type GVK struct { + Group string + Version string + Kind string +} + +type V2WriteRequest struct { + Metadata map[string]string `json:"metadata"` + Data map[string]any `json:"data"` + Owner *pbresource.ID `json:"owner"` +} + +type V2WriteResponse struct { + Metadata map[string]string `json:"metadata"` + Data map[string]any `json:"data"` + Owner *pbresource.ID `json:"owner,omitempty"` + ID *pbresource.ID `json:"id"` + Version string `json:"version"` + Generation string `json:"generation"` + Status map[string]any `json:"status"` +} + +func v2MulticlusterRead(client *api.Client, gvk *GVK, resourceName string, q *api.QueryOptions) (map[string]interface{}, error) { + endpoint := strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName)) + var out map[string]interface{} + _, err := client.Raw().Query(endpoint, &out, q) + if err != nil { + return nil, err + } + return out, nil +} + +func v2MulticlusterDelete(client *api.Client, gvk *GVK, resourceName string, q *api.QueryOptions) error { + endpoint := strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName)) + _, err := client.Raw().Delete(endpoint, q) + if err != nil { + return err + } + return nil +} + +func v2MulticlusterApply(client *api.Client, gvk *GVK, resourceName string, w *api.WriteOptions, payload *V2WriteRequest) (*V2WriteResponse, *api.WriteMeta, error) { + endpoint := strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName)) + out := &V2WriteResponse{} + wm, err := client.Raw().Write(endpoint, payload, out, w) + if err != nil { + return nil, nil, err + } + return out, wm, nil +} diff --git a/docs/data-sources/config_entry_v2_exported_services.md b/docs/data-sources/config_entry_v2_exported_services.md new file mode 100644 index 00000000..6b0e6665 --- /dev/null +++ b/docs/data-sources/config_entry_v2_exported_services.md @@ -0,0 +1,34 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "consul_config_entry_v2_exported_services Data Source - terraform-provider-consul" +subcategory: "" +description: |- + +--- + +# consul_config_entry_v2_exported_services (Data Source) + + + + + + +## Schema + +### Required + +- `kind` (String) The kind of exported services config (ExportedServices, NamespaceExportedServices, PartitionExportedServices). +- `name` (String) The name of the config entry to read. + +### Optional + +- `namespace` (String) The namespace the config entry is associated with. +- `partition` (String) The partition the config entry is associated with. +- `partition_consumers` (List of String) The exported service partition consumers. +- `peer_consumers` (List of String) The exported service peer consumers. +- `sameness_group_consumers` (List of String) The exported service sameness group consumers. +- `services` (List of String) The exported services. + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/docs/resources/config_entry_v2_exported_services.md b/docs/resources/config_entry_v2_exported_services.md new file mode 100644 index 00000000..5e65e799 --- /dev/null +++ b/docs/resources/config_entry_v2_exported_services.md @@ -0,0 +1,34 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "consul_config_entry_v2_exported_services Resource - terraform-provider-consul" +subcategory: "" +description: |- + +--- + +# consul_config_entry_v2_exported_services (Resource) + + + + + + +## Schema + +### Required + +- `kind` (String) The kind of exported services config (ExportedServices, NamespaceExportedServices, PartitionExportedServices). +- `name` (String) The name of the config entry to read. +- `partition` (String) The partition the config entry is associated with. + +### Optional + +- `namespace` (String) The namespace the config entry is associated with. +- `partition_consumers` (List of String) The exported service partition consumers. +- `peer_consumers` (List of String) The exported service peer consumers. +- `sameness_group_consumers` (List of String) The exported service sameness group consumers. +- `services` (List of String) The exported services. + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/go.mod b/go.mod index 1512e815..f21f9af5 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ module github.com/hashicorp/terraform-provider-consul replace github.com/hashicorp/consul/proto-public => github.com/hashicorp/consul/proto-public v0.1.2-0.20240208173503-e72afa654d22 require ( - github.com/hashicorp/consul/api v1.10.1-0.20240209095413-ae9fb4c83d42 + github.com/hashicorp/consul/api v1.10.1-0.20240227042019-fd46676f3cb7 github.com/hashicorp/consul/proto-public v0.5.2 github.com/hashicorp/errwrap v1.1.0 github.com/hashicorp/terraform-plugin-sdk v1.17.2 @@ -101,7 +101,7 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.56.3 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.32.0 ) go 1.21 diff --git a/go.sum b/go.sum index 0f4fd6f1..bb8685d5 100644 --- a/go.sum +++ b/go.sum @@ -410,12 +410,8 @@ github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6c github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.10.1-0.20240122152324-758ddf84e9c9 h1:qaS6rE768dt5hGPl2y4DIABXF4eA23BNSmWFpEr3kWQ= -github.com/hashicorp/consul/api v1.10.1-0.20240122152324-758ddf84e9c9/go.mod h1:gInwZGrnWlE1Vvq6rSD5pUf6qwNa69NTLLknbdwQRUk= -github.com/hashicorp/consul/api v1.10.1-0.20240209045659-981288e4082a h1:j2KLnImjuFUjhYK7Ly63dMVW7GWRFuPn5L1RIFoDye0= -github.com/hashicorp/consul/api v1.10.1-0.20240209045659-981288e4082a/go.mod h1:gInwZGrnWlE1Vvq6rSD5pUf6qwNa69NTLLknbdwQRUk= -github.com/hashicorp/consul/api v1.10.1-0.20240209095413-ae9fb4c83d42 h1:72SNfzBZccnJQ6diaGmUT6vHHzG5lcb4GiYAaED9kcM= -github.com/hashicorp/consul/api v1.10.1-0.20240209095413-ae9fb4c83d42/go.mod h1:XOFRmXaFsTMJIU9jGh0iZQs54SizswiA7lIGfOOX0j0= +github.com/hashicorp/consul/api v1.10.1-0.20240227042019-fd46676f3cb7 h1:SAnmime+Oi0TUG6q4uf0J9K/qgA5zmlvQCLxLO/hpGs= +github.com/hashicorp/consul/api v1.10.1-0.20240227042019-fd46676f3cb7/go.mod h1:kAuXnZ0r0y/uLXcy8+aexlGVonsgt3nR552fwkbBnMc= github.com/hashicorp/consul/proto-public v0.1.2-0.20240208173503-e72afa654d22 h1:PQQfwXeitSSyeXffKDTB/pOpxOKodgXEiNYcEFpgEMI= github.com/hashicorp/consul/proto-public v0.1.2-0.20240208173503-e72afa654d22/go.mod h1:JF6983XNCzvw4wDNOLEwLqOq2IPw7iyT+pkswHSz08U= github.com/hashicorp/consul/sdk v0.15.0 h1:2qK9nDrr4tiJKRoxPGhm6B7xJjLVIQqkjiab2M4aKjU= @@ -1232,8 +1228,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=