Skip to content

Commit

Permalink
add v2 exported service config resources
Browse files Browse the repository at this point in the history
  • Loading branch information
skpratt committed Feb 11, 2024
1 parent ec9cd0a commit 0e99850
Show file tree
Hide file tree
Showing 7 changed files with 591 additions and 64 deletions.
134 changes: 134 additions & 0 deletions consul/data_source_consul_config_entry_v2_exported_services.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package consul

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"
"google.golang.org/protobuf/encoding/protojson"
)

func dataSourceConsulConfigEntryV2ExportedServices() *schema.Resource {
return &schema.Resource{
Read: dataSourceConsulV2ExportedServicesRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "The name of the config entry to read.",
},

"kind": {
Type: schema.TypeString,
Required: true,
Description: "The kind of exported services config (ExportedServices, NamespaceExportedServices, PartitionExportedServices).",
},

"partition": {
Type: schema.TypeString,
Optional: true,
Description: "The partition the config entry is associated with.",
},

"namespace": {
Type: schema.TypeString,
Optional: true,
Description: "The namespace the config entry is associated with.",
},

"services": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Description: "The exported services.",
},

"partition_consumers": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Description: "The exported service partition consumers.",
},
"peer_consumers": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Description: "The exported service peer consumers.",
},
"sameness_group_consumers": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Description: "The exported service sameness group consumers.",
},
},
}
}

func dataSourceConsulV2ExportedServicesRead(d *schema.ResourceData, meta interface{}) error {
client, qOpts, _ := getClient(d, meta)
name := d.Get("name").(string)
kind := d.Get("kind").(string)
gvk := &api.GVK{
Group: "multicluster",
Version: "v2",
Kind: kind,
}
resp, err := client.Resource().Read(gvk, name, qOpts)
if err != nil || resp == nil {
return fmt.Errorf("exported services config not found: %s", name)
}
respData, err := json.Marshal(resp["data"])
if err != nil {
return fmt.Errorf("failed to unmarshal response data: %v", err)
}
data := &pbmulticluster.ExportedServices{}
if err = protojson.Unmarshal(respData, data); err != nil {
return fmt.Errorf("failed to unmarshal to proto message: %v", err)
}
respID, err := json.Marshal(resp["id"])
if err != nil {
return fmt.Errorf("failed to unmarshal response id: %v", err)
}
id := &pbresource.ID{}
if err = protojson.Unmarshal(respID, id); err != nil {
return fmt.Errorf("Failed to unmarshal to proto message: %v", err)
}
var partitions []string
var peers []string
var samenessgroups []string
for _, e := range data.Consumers {
switch v := e.ConsumerTenancy.(type) {
case *pbmulticluster.ExportedServicesConsumer_Peer:
peers = append(peers, v.Peer)
case *pbmulticluster.ExportedServicesConsumer_Partition:
partitions = append(partitions, v.Partition)
case *pbmulticluster.ExportedServicesConsumer_SamenessGroup:
samenessgroups = append(samenessgroups, v.SamenessGroup)
default:
return fmt.Errorf("unknown exported service consumer type: %T", v)
}
}
d.SetId(id.Uid)
sw := newStateWriter(d)
sw.set("services", data.Services)
sw.set("partition_consumers", partitions)
sw.set("peer_consumers", peers)
sw.set("sameness_group_consumers", samenessgroups)
return sw.error()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package consul

import (
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccDataExportedServicesV2_basic(t *testing.T) {
providers, _ := startTestServer(t)

resource.Test(t, resource.TestCase{
Providers: providers,
Steps: []resource.TestStep{
{
Config: testAccDataSourceExportedServicesV2ConfigNotFound,
ExpectError: regexp.MustCompile(`exported services config not found: not-found`),
},
{
Config: testAccDataSourceExportedServicesV2ConfigBasic,
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"),
resource.TestCheckResourceAttr("data.consul_config_entry_v2_exported_services.read", "namespace", "default"),
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"),
),
},
{
Config: testAccDataSourceComputedExportedServicesV2ConfigBasic,
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", "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"),
),
},
},
})
}

const testAccDataSourceComputedExportedServicesV2ConfigBasic = `
resource "consul_config_entry_v2_exported_services" "test" {
name = "test"
kind = "ExportedServices"
namespace = "default"
partition = "default"
services = ["s1"]
partition_consumers = ["default"]
}
data "consul_config_entry_v2_exported_services" "read" {
name = "default"
kind = "ComputedExportedServices"
partition = "default"
}
`

const testAccDataSourceExportedServicesV2ConfigBasic = `
resource "consul_config_entry_v2_exported_services" "test" {
name = "test"
kind = "ExportedServices"
namespace = "default"
partition = "default"
services = ["s1"]
sameness_group_consumers = ["sg1"]
}
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 testAccDataSourceExportedServicesV2ConfigNotFound = `
data "consul_config_entry_v2_exported_services" "test" {
name = "not-found"
kind = "ExportedServices"
namespace = "default"
partition = "default"
}
`
Loading

0 comments on commit 0e99850

Please sign in to comment.