Skip to content

Commit

Permalink
New data source: azurerm_app_configuration_keys (#17053)
Browse files Browse the repository at this point in the history
  • Loading branch information
favoretti authored Jun 2, 2022
1 parent 862ac3a commit fee5ddb
Show file tree
Hide file tree
Showing 5 changed files with 420 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

type AppConfigurationKeyDataSource struct{}

func TestAccAppServicePlanDataSource_basic(t *testing.T) {
func TestAccAppConfigurationKeyDataSource_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_app_configuration_key", "test")
d := AppConfigurationKeyDataSource{}

Expand All @@ -31,7 +31,7 @@ func TestAccAppServicePlanDataSource_basic(t *testing.T) {
})
}

func TestAccAppServicePlanDataSource_basicNoLabel(t *testing.T) {
func TestAccAppConfigurationKeyDataSource_basicNoLabel(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_app_configuration_key", "test")
d := AppConfigurationKeyDataSource{}

Expand All @@ -51,7 +51,7 @@ func TestAccAppServicePlanDataSource_basicNoLabel(t *testing.T) {
})
}

func TestAccAppServicePlanDataSource_basicVault(t *testing.T) {
func TestAccAppConfigurationKeyDataSource_basicVault(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_app_configuration_key", "test")
d := AppConfigurationKeyDataSource{}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
package appconfiguration

import (
"context"
"encoding/json"
"fmt"
"net/url"
"time"

"github.com/Azure/go-autorest/autorest"
"github.com/hashicorp/terraform-provider-azurerm/helpers/azure"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/appconfiguration/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

type KeysDataSource struct{}

var _ sdk.DataSource = KeysDataSource{}

type KeyDataSourceModel struct {
Key string `tfschema:"key"`
ContentType string `tfschema:"content_type"`
Etag string `tfschema:"etag"`
Label string `tfschema:"label"`
Value string `tfschema:"value"`
Locked bool `tfschema:"locked"`
Tags map[string]interface{} `tfschema:"tags"`
Type string `tfschema:"type"`
VaultKeyReference string `tfschema:"vault_key_reference"`
}

type KeysDataSourceModel struct {
ConfigurationStoreId string `tfschema:"configuration_store_id"`
Key string `tfschema:"key"`
Label string `tfschema:"label"`
Items []KeyDataSourceModel `tfschema:"items"`
}

func (k KeysDataSource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"configuration_store_id": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: azure.ValidateResourceID,
},
"key": {
Type: pluginsdk.TypeString,
Optional: true,
Default: "",
},
"label": {
Type: pluginsdk.TypeString,
Optional: true,
Default: "",
},
}
}

func (k KeysDataSource) Attributes() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"items": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"key": {
Type: pluginsdk.TypeString,
Computed: true,
},
"label": {
Type: pluginsdk.TypeString,
Computed: true,
},
"content_type": {
Type: pluginsdk.TypeString,
Computed: true,
},
"etag": {
Type: pluginsdk.TypeString,
Computed: true,
},
"value": {
Type: pluginsdk.TypeString,
Computed: true,
},
"locked": {
Type: pluginsdk.TypeBool,
Computed: true,
},
"type": {
Type: pluginsdk.TypeString,
Computed: true,
},
"vault_key_reference": {
Type: pluginsdk.TypeString,
Computed: true,
},
"tags": tags.SchemaDataSource(),
},
},
},
}
}

func (k KeysDataSource) ModelObject() interface{} {
return &KeysDataSourceModel{}
}

func (k KeysDataSource) ResourceType() string {
return "azurerm_app_configuration_keys"
}

func (k KeysDataSource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
var model KeysDataSourceModel
if err := metadata.Decode(&model); err != nil {
return err
}

decodedKey, err := url.QueryUnescape(model.Key)
if err != nil {
return fmt.Errorf("while decoding key of resource ID: %+v", err)
}

id := parse.AppConfigurationKeyId{
ConfigurationStoreId: model.ConfigurationStoreId,
Key: decodedKey,
Label: model.Label,
}

client, err := metadata.Client.AppConfiguration.DataPlaneClient(ctx, model.ConfigurationStoreId)
if client == nil {
return fmt.Errorf("building data plane client: app configuration %q was not found", model.ConfigurationStoreId)
}
if err != nil {
return err
}

iter, err := client.GetKeyValuesComplete(ctx, decodedKey, model.Label, "", "", []string{})
if err != nil {
if v, ok := err.(autorest.DetailedError); ok {
if utils.ResponseWasNotFound(autorest.Response{Response: v.Response}) {
return fmt.Errorf("key %s was not found", decodedKey)
}
} else {
return fmt.Errorf("while checking for key's %q existence: %+v", decodedKey, err)
}
return fmt.Errorf("while checking for key's %q existence: %+v", decodedKey, err)
}

for iter.NotDone() {
kv := iter.Value()
var krmodel KeyDataSourceModel
krmodel.Key = *kv.Key
krmodel.Label = *kv.Label
if contentType := utils.NormalizeNilableString(kv.ContentType); contentType != VaultKeyContentType {
krmodel.Type = KeyTypeKV
krmodel.ContentType = contentType
krmodel.Value = utils.NormalizeNilableString(kv.Value)
} else {
var ref VaultKeyReference
refBytes := []byte(utils.NormalizeNilableString(kv.Value))
err := json.Unmarshal(refBytes, &ref)
if err != nil {
return fmt.Errorf("while unmarshalling vault reference: %+v", err)
}

krmodel.Type = KeyTypeVault
krmodel.VaultKeyReference = ref.URI
krmodel.ContentType = VaultKeyContentType
krmodel.Value = ref.URI
}

if kv.Locked != nil {
krmodel.Locked = *kv.Locked
}
krmodel.Etag = utils.NormalizeNilableString(kv.Etag)
if id.Label == "" {
// We set an empty label as %00 in the resource ID
// Otherwise it breaks the ID parsing logic
id.Label = "%00"
}
model.Items = append(model.Items, krmodel)
if err := iter.NextWithContext(ctx); err != nil {
return fmt.Errorf("fetching keys for %q: %+v", id, err)
}
}
metadata.SetID(id)
return metadata.Encode(&model)
},
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package appconfiguration_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
)

type AppConfigurationKeysDataSource struct{}

func TestAccAppConfigurationKeysDataSource_allkeys(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_app_configuration_keys", "test")
d := AppConfigurationKeysDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: d.allKeys(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("items.#").HasValue("4"),
),
},
})
}

func TestAccAppConfigurationKeysDataSource_key(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_app_configuration_keys", "test")
d := AppConfigurationKeysDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: d.key(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("items.#").HasValue("2"),
),
},
})
}

func TestAccAppConfigurationKeysDataSource_label(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_app_configuration_keys", "test")
d := AppConfigurationKeysDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: d.label(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("items.#").HasValue("2"),
),
},
})
}

func (t AppConfigurationKeysDataSource) keys() string {
return fmt.Sprintf(`
resource "azurerm_app_configuration_key" "test" {
configuration_store_id = azurerm_app_configuration.test.id
key = "key1"
content_type = "test"
label = "label1"
value = "a test"
}
resource "azurerm_app_configuration_key" "test2" {
configuration_store_id = azurerm_app_configuration.test.id
key = "key1"
content_type = "test"
label = "label2"
value = "a test"
}
resource "azurerm_app_configuration_key" "test3" {
configuration_store_id = azurerm_app_configuration.test.id
key = "key2"
content_type = "test"
label = "testlabel"
value = "a test"
}
resource "azurerm_app_configuration_key" "test4" {
configuration_store_id = azurerm_app_configuration.test.id
key = "key3"
content_type = "test"
label = "testlabel"
value = "a test"
}
`)
}

func (t AppConfigurationKeysDataSource) allKeys(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
%s
data "azurerm_app_configuration_keys" "test" {
configuration_store_id = azurerm_app_configuration.test.id
depends_on = [
azurerm_app_configuration_key.test,
azurerm_app_configuration_key.test2,
azurerm_app_configuration_key.test3,
azurerm_app_configuration_key.test4
]
}
`, AppConfigurationKeyResource{}.base(data), t.keys())
}

func (t AppConfigurationKeysDataSource) key(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
%s
data "azurerm_app_configuration_keys" "test" {
configuration_store_id = azurerm_app_configuration.test.id
key = "key1"
depends_on = [
azurerm_app_configuration_key.test,
azurerm_app_configuration_key.test2,
azurerm_app_configuration_key.test3,
azurerm_app_configuration_key.test4
]
}
`, AppConfigurationKeyResource{}.base(data), t.keys())
}

func (t AppConfigurationKeysDataSource) label(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
%s
data "azurerm_app_configuration_keys" "test" {
configuration_store_id = azurerm_app_configuration.test.id
label = "testlabel"
depends_on = [
azurerm_app_configuration_key.test,
azurerm_app_configuration_key.test2,
azurerm_app_configuration_key.test3,
azurerm_app_configuration_key.test4
]
}
`, AppConfigurationKeyResource{}.base(data), t.keys())
}
1 change: 1 addition & 0 deletions internal/services/appconfiguration/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func (r Registration) AssociatedGitHubLabel() string {
func (r Registration) DataSources() []sdk.DataSource {
return []sdk.DataSource{
KeyDataSource{},
KeysDataSource{},
}
}

Expand Down
Loading

0 comments on commit fee5ddb

Please sign in to comment.