From e1ada855eff3d4ee241a1704328c508b4359b6b1 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Thu, 7 Nov 2019 00:26:12 +0100 Subject: [PATCH 01/19] add resource azurerm_app_configuration --- azurerm/config.go | 2 + .../services/appconfiguration/client.go | 19 + azurerm/provider.go | 1 + azurerm/resource_arm_app_configuration.go | 325 ++++++++++++++++++ 4 files changed, 347 insertions(+) create mode 100644 azurerm/internal/services/appconfiguration/client.go create mode 100644 azurerm/resource_arm_app_configuration.go diff --git a/azurerm/config.go b/azurerm/config.go index 3b7c38ca0ba9..93652ae3b852 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -12,6 +12,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/analysisservices" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/apimanagement" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/appconfiguration" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/applicationinsights" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/authorization" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/automation" @@ -217,6 +218,7 @@ func getArmClient(authConfig *authentication.Config, skipProviderRegistration bo client.AnalysisServices = analysisservices.BuildClient(o) client.ApiManagement = apimanagement.BuildClient(o) + client.AppConfiguration = appconfiguration.BuildClient(o) client.AppInsights = applicationinsights.BuildClient(o) client.Automation = automation.BuildClient(o) client.Authorization = authorization.BuildClient(o) diff --git a/azurerm/internal/services/appconfiguration/client.go b/azurerm/internal/services/appconfiguration/client.go new file mode 100644 index 000000000000..ab871f6ebbc0 --- /dev/null +++ b/azurerm/internal/services/appconfiguration/client.go @@ -0,0 +1,19 @@ +package appconfiguration + +import ( + appconf "github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AppConfigurationsClient *appconf.ConfigurationStoresClient +} + +func BuildClient(o *common.ClientOptions) *Client { + AppConfigurationsClient := appconf.NewConfigurationStoresClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AppConfigurationsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AppConfigurationsClient: &AppConfigurationsClient, + } +} diff --git a/azurerm/provider.go b/azurerm/provider.go index f8af16943280..f56bf2e7ca4b 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -177,6 +177,7 @@ func Provider() terraform.ResourceProvider { "azurerm_api_management_property": resourceArmApiManagementProperty(), "azurerm_api_management_subscription": resourceArmApiManagementSubscription(), "azurerm_api_management_user": resourceArmApiManagementUser(), + "azurerm_app_configuration": resourceArmAppConfiguration(), "azurerm_app_service_active_slot": resourceArmAppServiceActiveSlot(), "azurerm_app_service_certificate": resourceArmAppServiceCertificate(), "azurerm_app_service_certificate_order": resourceArmAppServiceCertificateOrder(), diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go new file mode 100644 index 000000000000..232e1d1de217 --- /dev/null +++ b/azurerm/resource_arm_app_configuration.go @@ -0,0 +1,325 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + "strings" + "time" + + appconf "github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +var appConfigurationResourceName = "azurerm_app_configuration" + +func resourceArmAppConfiguration() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAppConfigurationCreate, + Read: resourceArmAppConfigurationRead, + Update: resourceArmAppConfigurationUpdate, + Delete: resourceArmAppConfigurationDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + SchemaVersion: 2, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAppConfigurationName, + }, + + "location": azure.SchemaLocation(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "sku": { + Type: schema.TypeString, + Optional: true, + Default: "free", + ValidateFunc: validation.StringInSlice([]string{ + "free", + "standard", + }, false), + }, + + "endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "primary_read_key": { + Type: schema.TypeMap, + Computed: true, + Sensitive: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "secondary_read_key": { + Type: schema.TypeMap, + Computed: true, + Sensitive: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "primary_write_key": { + Type: schema.TypeMap, + Computed: true, + Sensitive: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "secondary_write_key": { + Type: schema.TypeMap, + Computed: true, + Sensitive: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmAppConfigurationCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).AppConfiguration.AppConfigurationsClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*ArmClient).StopContext, d) + defer cancel() + + log.Printf("[INFO] preparing arguments for Azure ARM App Configuration creation.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing App Configuration %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_app_configuration", *existing.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) + skuName := d.Get("sku").(string) + sku := appconf.Sku{ + Name: &skuName, + } + + parameters := appconf.ConfigurationStore{ + Location: &location, + Sku: &sku, + Tags: tags.Expand(t), + } + + future, err := client.Create(ctx, resourceGroup, name, parameters) + if err != nil { + return fmt.Errorf("Error creating App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + if read.ID == nil { + return fmt.Errorf("Cannot read App Configuration %s (resource Group %q) ID", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmAppConfigurationRead(d, meta) +} + +func resourceArmAppConfigurationUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).AppConfiguration.AppConfigurationsClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*ArmClient).StopContext, d) + defer cancel() + + log.Printf("[INFO] preparing arguments for Azure ARM App Configuration update.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + t := d.Get("tags").(map[string]interface{}) + skuName := d.Get("sku").(string) + sku := appconf.Sku{ + Name: &skuName, + } + + parameters := appconf.ConfigurationStoreUpdateParameters{ + Sku: &sku, + Tags: tags.Expand(t), + } + + future, err := client.Update(ctx, resourceGroup, name, parameters) + if err != nil { + return fmt.Errorf("Error updating App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for update of App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + if read.ID == nil { + return fmt.Errorf("Cannot read App Configuration %s (resource Group %q) ID", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmAppConfigurationRead(d, meta) +} + +func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).AppConfiguration.AppConfigurationsClient + ctx, cancel := timeouts.ForRead(meta.(*ArmClient).StopContext, d) + defer cancel() + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["configurationStores"] + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] App Configuration %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if endpoint := resp.Endpoint; endpoint != nil { + d.Set("endpoint", resp.Endpoint) + } + + resultPage, err := client.ListKeys(ctx, resourceGroup, name, "") + if err != nil { + return fmt.Errorf("Failed to receive access keys for App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + values := resultPage.Values() + for _, value := range values { + var index string + var permission string + + if strings.HasPrefix(*value.Name, "Primary") { + index = "primary" + } else { + index = "secondary" + } + + if *value.ReadOnly { + permission = "read" + } else { + permission = "write" + } + + d.Set( + fmt.Sprintf("%s_%s_key", index, permission), + makeAccessKeyMap(value), + ) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmAppConfigurationDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).AppConfiguration.AppConfigurationsClient + ctx, cancel := timeouts.ForDelete(meta.(*ArmClient).StopContext, d) + defer cancel() + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["configurationStores"] + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + return nil + } + + return fmt.Errorf("Error retrieving App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + fut, err := client.Delete(ctx, resourceGroup, name) + resp, err := fut.Result(*client) + if err != nil { + if !response.WasNotFound(resp.Response) { + return fmt.Errorf("Error retrieving App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + return nil +} + +func validateAppConfigurationName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + if matched := regexp.MustCompile(`^[a-zA-Z0-9-]{5,50}$`).Match([]byte(value)); !matched { + errors = append(errors, fmt.Errorf("%q may only contain alphanumeric characters and dashes and must be between 5-50 chars", k)) + } + + return warnings, errors +} + +func makeAccessKeyMap(value appconf.APIKey) map[string]string { + m := make(map[string]string) + + m["id"] = *value.ID + m["secret"] = *value.Value + m["connectionString"] = *value.ConnectionString + + return m +} From d3fd5b98e16f8dcc7bd1d8e0613dcbd3d85aa2c5 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 13 Nov 2019 00:04:23 +0100 Subject: [PATCH 02/19] add appconfiguration dependency --- .../2019-10-01/appconfiguration/client.go | 51 + .../appconfiguration/configurationstores.go | 933 +++++++++++++++++ .../2019-10-01/appconfiguration/models.go | 937 ++++++++++++++++++ .../2019-10-01/appconfiguration/operations.go | 238 +++++ .../2019-10-01/appconfiguration/version.go | 30 + vendor/modules.txt | 1 + 6 files changed, 2190 insertions(+) create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/configurationstores.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/models.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/operations.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/version.go diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/client.go new file mode 100644 index 000000000000..ca729e4e34ff --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/client.go @@ -0,0 +1,51 @@ +// Package appconfiguration implements the Azure ARM Appconfiguration service API version 2019-10-01. +// +// +package appconfiguration + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // DefaultBaseURI is the default URI used for the service Appconfiguration + DefaultBaseURI = "https://management.azure.com" +) + +// BaseClient is the base client for Appconfiguration. +type BaseClient struct { + autorest.Client + BaseURI string + SubscriptionID string +} + +// New creates an instance of the BaseClient client. +func New(subscriptionID string) BaseClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the BaseClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient { + return BaseClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/configurationstores.go b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/configurationstores.go new file mode 100644 index 000000000000..40daddce716f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/configurationstores.go @@ -0,0 +1,933 @@ +package appconfiguration + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// ConfigurationStoresClient is the client for the ConfigurationStores methods of the Appconfiguration service. +type ConfigurationStoresClient struct { + BaseClient +} + +// NewConfigurationStoresClient creates an instance of the ConfigurationStoresClient client. +func NewConfigurationStoresClient(subscriptionID string) ConfigurationStoresClient { + return NewConfigurationStoresClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewConfigurationStoresClientWithBaseURI creates an instance of the ConfigurationStoresClient client. +func NewConfigurationStoresClientWithBaseURI(baseURI string, subscriptionID string) ConfigurationStoresClient { + return ConfigurationStoresClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Create creates a configuration store with the specified parameters. +// Parameters: +// resourceGroupName - the name of the resource group to which the container registry belongs. +// configStoreName - the name of the configuration store. +// configStoreCreationParameters - the parameters for creating a configuration store. +func (client ConfigurationStoresClient) Create(ctx context.Context, resourceGroupName string, configStoreName string, configStoreCreationParameters ConfigurationStore) (result ConfigurationStoresCreateFuture, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.Create") + defer func() { + sc := -1 + if result.Response() != nil { + sc = result.Response().StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: configStoreName, + Constraints: []validation.Constraint{{Target: "configStoreName", Name: validation.MaxLength, Rule: 50, Chain: nil}, + {Target: "configStoreName", Name: validation.MinLength, Rule: 5, Chain: nil}, + {Target: "configStoreName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9_-]*$`, Chain: nil}}}, + {TargetValue: configStoreCreationParameters, + Constraints: []validation.Constraint{{Target: "configStoreCreationParameters.Sku", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "configStoreCreationParameters.Sku.Name", Name: validation.Null, Rule: true, Chain: nil}}}}}}); err != nil { + return result, validation.NewError("appconfiguration.ConfigurationStoresClient", "Create", err.Error()) + } + + req, err := client.CreatePreparer(ctx, resourceGroupName, configStoreName, configStoreCreationParameters) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Create", nil, "Failure preparing request") + return + } + + result, err = client.CreateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Create", result.Response(), "Failure sending request") + return + } + + return +} + +// CreatePreparer prepares the Create request. +func (client ConfigurationStoresClient) CreatePreparer(ctx context.Context, resourceGroupName string, configStoreName string, configStoreCreationParameters ConfigurationStore) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "configStoreName": autorest.Encode("path", configStoreName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AppConfiguration/configurationStores/{configStoreName}", pathParameters), + autorest.WithJSON(configStoreCreationParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateSender sends the Create request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) CreateSender(req *http.Request) (future ConfigurationStoresCreateFuture, err error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, sd...) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// CreateResponder handles the response to the Create request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) CreateResponder(resp *http.Response) (result ConfigurationStore, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a configuration store. +// Parameters: +// resourceGroupName - the name of the resource group to which the container registry belongs. +// configStoreName - the name of the configuration store. +func (client ConfigurationStoresClient) Delete(ctx context.Context, resourceGroupName string, configStoreName string) (result ConfigurationStoresDeleteFuture, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.Delete") + defer func() { + sc := -1 + if result.Response() != nil { + sc = result.Response().StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: configStoreName, + Constraints: []validation.Constraint{{Target: "configStoreName", Name: validation.MaxLength, Rule: 50, Chain: nil}, + {Target: "configStoreName", Name: validation.MinLength, Rule: 5, Chain: nil}, + {Target: "configStoreName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9_-]*$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("appconfiguration.ConfigurationStoresClient", "Delete", err.Error()) + } + + req, err := client.DeletePreparer(ctx, resourceGroupName, configStoreName) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = client.DeleteSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Delete", result.Response(), "Failure sending request") + return + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ConfigurationStoresClient) DeletePreparer(ctx context.Context, resourceGroupName string, configStoreName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "configStoreName": autorest.Encode("path", configStoreName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AppConfiguration/configurationStores/{configStoreName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) DeleteSender(req *http.Request) (future ConfigurationStoresDeleteFuture, err error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, sd...) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets the properties of the specified configuration store. +// Parameters: +// resourceGroupName - the name of the resource group to which the container registry belongs. +// configStoreName - the name of the configuration store. +func (client ConfigurationStoresClient) Get(ctx context.Context, resourceGroupName string, configStoreName string) (result ConfigurationStore, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.Get") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: configStoreName, + Constraints: []validation.Constraint{{Target: "configStoreName", Name: validation.MaxLength, Rule: 50, Chain: nil}, + {Target: "configStoreName", Name: validation.MinLength, Rule: 5, Chain: nil}, + {Target: "configStoreName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9_-]*$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("appconfiguration.ConfigurationStoresClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, resourceGroupName, configStoreName) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ConfigurationStoresClient) GetPreparer(ctx context.Context, resourceGroupName string, configStoreName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "configStoreName": autorest.Encode("path", configStoreName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AppConfiguration/configurationStores/{configStoreName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) GetSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) GetResponder(resp *http.Response) (result ConfigurationStore, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists the configuration stores for a given subscription. +// Parameters: +// skipToken - a skip token is used to continue retrieving items after an operation returns a partial result. +// If a previous response contains a nextLink element, the value of the nextLink element will include a +// skipToken parameter that specifies a starting point to use for subsequent calls. +func (client ConfigurationStoresClient) List(ctx context.Context, skipToken string) (result ConfigurationStoreListResultPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.List") + defer func() { + sc := -1 + if result.cslr.Response.Response != nil { + sc = result.cslr.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, skipToken) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.cslr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "List", resp, "Failure sending request") + return + } + + result.cslr, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ConfigurationStoresClient) ListPreparer(ctx context.Context, skipToken string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(skipToken) > 0 { + queryParameters["$skipToken"] = autorest.Encode("query", skipToken) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.AppConfiguration/configurationStores", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) ListSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) ListResponder(resp *http.Response) (result ConfigurationStoreListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client ConfigurationStoresClient) listNextResults(ctx context.Context, lastResults ConfigurationStoreListResult) (result ConfigurationStoreListResult, err error) { + req, err := lastResults.configurationStoreListResultPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client ConfigurationStoresClient) ListComplete(ctx context.Context, skipToken string) (result ConfigurationStoreListResultIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.List") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.List(ctx, skipToken) + return +} + +// ListByResourceGroup lists the configuration stores for a given resource group. +// Parameters: +// resourceGroupName - the name of the resource group to which the container registry belongs. +// skipToken - a skip token is used to continue retrieving items after an operation returns a partial result. +// If a previous response contains a nextLink element, the value of the nextLink element will include a +// skipToken parameter that specifies a starting point to use for subsequent calls. +func (client ConfigurationStoresClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, skipToken string) (result ConfigurationStoreListResultPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.ListByResourceGroup") + defer func() { + sc := -1 + if result.cslr.Response.Response != nil { + sc = result.cslr.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName, skipToken) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.cslr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result.cslr, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client ConfigurationStoresClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string, skipToken string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(skipToken) > 0 { + queryParameters["$skipToken"] = autorest.Encode("query", skipToken) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AppConfiguration/configurationStores", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) ListByResourceGroupResponder(resp *http.Response) (result ConfigurationStoreListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client ConfigurationStoresClient) listByResourceGroupNextResults(ctx context.Context, lastResults ConfigurationStoreListResult) (result ConfigurationStoreListResult, err error) { + req, err := lastResults.configurationStoreListResultPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client ConfigurationStoresClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, skipToken string) (result ConfigurationStoreListResultIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.ListByResourceGroup") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName, skipToken) + return +} + +// ListKeys lists the access key for the specified configuration store. +// Parameters: +// resourceGroupName - the name of the resource group to which the container registry belongs. +// configStoreName - the name of the configuration store. +// skipToken - a skip token is used to continue retrieving items after an operation returns a partial result. +// If a previous response contains a nextLink element, the value of the nextLink element will include a +// skipToken parameter that specifies a starting point to use for subsequent calls. +func (client ConfigurationStoresClient) ListKeys(ctx context.Context, resourceGroupName string, configStoreName string, skipToken string) (result APIKeyListResultPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.ListKeys") + defer func() { + sc := -1 + if result.aklr.Response.Response != nil { + sc = result.aklr.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: configStoreName, + Constraints: []validation.Constraint{{Target: "configStoreName", Name: validation.MaxLength, Rule: 50, Chain: nil}, + {Target: "configStoreName", Name: validation.MinLength, Rule: 5, Chain: nil}, + {Target: "configStoreName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9_-]*$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("appconfiguration.ConfigurationStoresClient", "ListKeys", err.Error()) + } + + result.fn = client.listKeysNextResults + req, err := client.ListKeysPreparer(ctx, resourceGroupName, configStoreName, skipToken) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListKeys", nil, "Failure preparing request") + return + } + + resp, err := client.ListKeysSender(req) + if err != nil { + result.aklr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListKeys", resp, "Failure sending request") + return + } + + result.aklr, err = client.ListKeysResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListKeys", resp, "Failure responding to request") + } + + return +} + +// ListKeysPreparer prepares the ListKeys request. +func (client ConfigurationStoresClient) ListKeysPreparer(ctx context.Context, resourceGroupName string, configStoreName string, skipToken string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "configStoreName": autorest.Encode("path", configStoreName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(skipToken) > 0 { + queryParameters["$skipToken"] = autorest.Encode("query", skipToken) + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AppConfiguration/configurationStores/{configStoreName}/ListKeys", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListKeysSender sends the ListKeys request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) ListKeysSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListKeysResponder handles the response to the ListKeys request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) ListKeysResponder(resp *http.Response) (result APIKeyListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listKeysNextResults retrieves the next set of results, if any. +func (client ConfigurationStoresClient) listKeysNextResults(ctx context.Context, lastResults APIKeyListResult) (result APIKeyListResult, err error) { + req, err := lastResults.aPIKeyListResultPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listKeysNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListKeysSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listKeysNextResults", resp, "Failure sending next results request") + } + result, err = client.ListKeysResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "listKeysNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListKeysComplete enumerates all values, automatically crossing page boundaries as required. +func (client ConfigurationStoresClient) ListKeysComplete(ctx context.Context, resourceGroupName string, configStoreName string, skipToken string) (result APIKeyListResultIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.ListKeys") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.ListKeys(ctx, resourceGroupName, configStoreName, skipToken) + return +} + +// ListKeyValue lists a configuration store key-value. +// Parameters: +// resourceGroupName - the name of the resource group to which the container registry belongs. +// configStoreName - the name of the configuration store. +// listKeyValueParameters - the parameters for retrieving a key-value. +func (client ConfigurationStoresClient) ListKeyValue(ctx context.Context, resourceGroupName string, configStoreName string, listKeyValueParameters ListKeyValueParameters) (result KeyValue, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.ListKeyValue") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: configStoreName, + Constraints: []validation.Constraint{{Target: "configStoreName", Name: validation.MaxLength, Rule: 50, Chain: nil}, + {Target: "configStoreName", Name: validation.MinLength, Rule: 5, Chain: nil}, + {Target: "configStoreName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9_-]*$`, Chain: nil}}}, + {TargetValue: listKeyValueParameters, + Constraints: []validation.Constraint{{Target: "listKeyValueParameters.Key", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewError("appconfiguration.ConfigurationStoresClient", "ListKeyValue", err.Error()) + } + + req, err := client.ListKeyValuePreparer(ctx, resourceGroupName, configStoreName, listKeyValueParameters) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListKeyValue", nil, "Failure preparing request") + return + } + + resp, err := client.ListKeyValueSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListKeyValue", resp, "Failure sending request") + return + } + + result, err = client.ListKeyValueResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "ListKeyValue", resp, "Failure responding to request") + } + + return +} + +// ListKeyValuePreparer prepares the ListKeyValue request. +func (client ConfigurationStoresClient) ListKeyValuePreparer(ctx context.Context, resourceGroupName string, configStoreName string, listKeyValueParameters ListKeyValueParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "configStoreName": autorest.Encode("path", configStoreName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AppConfiguration/configurationStores/{configStoreName}/listKeyValue", pathParameters), + autorest.WithJSON(listKeyValueParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListKeyValueSender sends the ListKeyValue request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) ListKeyValueSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListKeyValueResponder handles the response to the ListKeyValue request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) ListKeyValueResponder(resp *http.Response) (result KeyValue, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RegenerateKey regenerates an access key for the specified configuration store. +// Parameters: +// resourceGroupName - the name of the resource group to which the container registry belongs. +// configStoreName - the name of the configuration store. +// regenerateKeyParameters - the parameters for regenerating an access key. +func (client ConfigurationStoresClient) RegenerateKey(ctx context.Context, resourceGroupName string, configStoreName string, regenerateKeyParameters RegenerateKeyParameters) (result APIKey, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.RegenerateKey") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: configStoreName, + Constraints: []validation.Constraint{{Target: "configStoreName", Name: validation.MaxLength, Rule: 50, Chain: nil}, + {Target: "configStoreName", Name: validation.MinLength, Rule: 5, Chain: nil}, + {Target: "configStoreName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9_-]*$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("appconfiguration.ConfigurationStoresClient", "RegenerateKey", err.Error()) + } + + req, err := client.RegenerateKeyPreparer(ctx, resourceGroupName, configStoreName, regenerateKeyParameters) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "RegenerateKey", nil, "Failure preparing request") + return + } + + resp, err := client.RegenerateKeySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "RegenerateKey", resp, "Failure sending request") + return + } + + result, err = client.RegenerateKeyResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "RegenerateKey", resp, "Failure responding to request") + } + + return +} + +// RegenerateKeyPreparer prepares the RegenerateKey request. +func (client ConfigurationStoresClient) RegenerateKeyPreparer(ctx context.Context, resourceGroupName string, configStoreName string, regenerateKeyParameters RegenerateKeyParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "configStoreName": autorest.Encode("path", configStoreName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AppConfiguration/configurationStores/{configStoreName}/RegenerateKey", pathParameters), + autorest.WithJSON(regenerateKeyParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// RegenerateKeySender sends the RegenerateKey request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) RegenerateKeySender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// RegenerateKeyResponder handles the response to the RegenerateKey request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) RegenerateKeyResponder(resp *http.Response) (result APIKey, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Update updates a configuration store with the specified parameters. +// Parameters: +// resourceGroupName - the name of the resource group to which the container registry belongs. +// configStoreName - the name of the configuration store. +// configStoreUpdateParameters - the parameters for updating a configuration store. +func (client ConfigurationStoresClient) Update(ctx context.Context, resourceGroupName string, configStoreName string, configStoreUpdateParameters ConfigurationStoreUpdateParameters) (result ConfigurationStoresUpdateFuture, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoresClient.Update") + defer func() { + sc := -1 + if result.Response() != nil { + sc = result.Response().StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: configStoreName, + Constraints: []validation.Constraint{{Target: "configStoreName", Name: validation.MaxLength, Rule: 50, Chain: nil}, + {Target: "configStoreName", Name: validation.MinLength, Rule: 5, Chain: nil}, + {Target: "configStoreName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9_-]*$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("appconfiguration.ConfigurationStoresClient", "Update", err.Error()) + } + + req, err := client.UpdatePreparer(ctx, resourceGroupName, configStoreName, configStoreUpdateParameters) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Update", nil, "Failure preparing request") + return + } + + result, err = client.UpdateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresClient", "Update", result.Response(), "Failure sending request") + return + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client ConfigurationStoresClient) UpdatePreparer(ctx context.Context, resourceGroupName string, configStoreName string, configStoreUpdateParameters ConfigurationStoreUpdateParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "configStoreName": autorest.Encode("path", configStoreName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AppConfiguration/configurationStores/{configStoreName}", pathParameters), + autorest.WithJSON(configStoreUpdateParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client ConfigurationStoresClient) UpdateSender(req *http.Request) (future ConfigurationStoresUpdateFuture, err error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, sd...) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client ConfigurationStoresClient) UpdateResponder(resp *http.Response) (result ConfigurationStore, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/models.go new file mode 100644 index 000000000000..66ce6f2bd531 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/models.go @@ -0,0 +1,937 @@ +package appconfiguration + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "encoding/json" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/autorest/to" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// The package's fully qualified name. +const fqdn = "github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration" + +// IdentityType enumerates the values for identity type. +type IdentityType string + +const ( + // None ... + None IdentityType = "None" + // SystemAssigned ... + SystemAssigned IdentityType = "SystemAssigned" + // SystemAssignedUserAssigned ... + SystemAssignedUserAssigned IdentityType = "SystemAssigned, UserAssigned" + // UserAssigned ... + UserAssigned IdentityType = "UserAssigned" +) + +// PossibleIdentityTypeValues returns an array of possible values for the IdentityType const type. +func PossibleIdentityTypeValues() []IdentityType { + return []IdentityType{None, SystemAssigned, SystemAssignedUserAssigned, UserAssigned} +} + +// ProvisioningState enumerates the values for provisioning state. +type ProvisioningState string + +const ( + // Canceled ... + Canceled ProvisioningState = "Canceled" + // Creating ... + Creating ProvisioningState = "Creating" + // Deleting ... + Deleting ProvisioningState = "Deleting" + // Failed ... + Failed ProvisioningState = "Failed" + // Succeeded ... + Succeeded ProvisioningState = "Succeeded" + // Updating ... + Updating ProvisioningState = "Updating" +) + +// PossibleProvisioningStateValues returns an array of possible values for the ProvisioningState const type. +func PossibleProvisioningStateValues() []ProvisioningState { + return []ProvisioningState{Canceled, Creating, Deleting, Failed, Succeeded, Updating} +} + +// APIKey an API key used for authenticating with a configuration store endpoint. +type APIKey struct { + autorest.Response `json:"-"` + // ID - READ-ONLY; The key ID. + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; A name for the key describing its usage. + Name *string `json:"name,omitempty"` + // Value - READ-ONLY; The value of the key that is used for authentication purposes. + Value *string `json:"value,omitempty"` + // ConnectionString - READ-ONLY; A connection string that can be used by supporting clients for authentication. + ConnectionString *string `json:"connectionString,omitempty"` + // LastModified - READ-ONLY; The last time any of the key's properties were modified. + LastModified *date.Time `json:"lastModified,omitempty"` + // ReadOnly - READ-ONLY; Whether this key can only be used for read operations. + ReadOnly *bool `json:"readOnly,omitempty"` +} + +// APIKeyListResult the result of a request to list API keys. +type APIKeyListResult struct { + autorest.Response `json:"-"` + // Value - The collection value. + Value *[]APIKey `json:"value,omitempty"` + // NextLink - The URI that can be used to request the next set of paged results. + NextLink *string `json:"nextLink,omitempty"` +} + +// APIKeyListResultIterator provides access to a complete listing of APIKey values. +type APIKeyListResultIterator struct { + i int + page APIKeyListResultPage +} + +// NextWithContext advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *APIKeyListResultIterator) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/APIKeyListResultIterator.NextWithContext") + defer func() { + sc := -1 + if iter.Response().Response.Response != nil { + sc = iter.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err = iter.page.NextWithContext(ctx) + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (iter *APIKeyListResultIterator) Next() error { + return iter.NextWithContext(context.Background()) +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter APIKeyListResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter APIKeyListResultIterator) Response() APIKeyListResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter APIKeyListResultIterator) Value() APIKey { + if !iter.page.NotDone() { + return APIKey{} + } + return iter.page.Values()[iter.i] +} + +// Creates a new instance of the APIKeyListResultIterator type. +func NewAPIKeyListResultIterator(page APIKeyListResultPage) APIKeyListResultIterator { + return APIKeyListResultIterator{page: page} +} + +// IsEmpty returns true if the ListResult contains no values. +func (aklr APIKeyListResult) IsEmpty() bool { + return aklr.Value == nil || len(*aklr.Value) == 0 +} + +// aPIKeyListResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (aklr APIKeyListResult) aPIKeyListResultPreparer(ctx context.Context) (*http.Request, error) { + if aklr.NextLink == nil || len(to.String(aklr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare((&http.Request{}).WithContext(ctx), + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(aklr.NextLink))) +} + +// APIKeyListResultPage contains a page of APIKey values. +type APIKeyListResultPage struct { + fn func(context.Context, APIKeyListResult) (APIKeyListResult, error) + aklr APIKeyListResult +} + +// NextWithContext advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *APIKeyListResultPage) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/APIKeyListResultPage.NextWithContext") + defer func() { + sc := -1 + if page.Response().Response.Response != nil { + sc = page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + next, err := page.fn(ctx, page.aklr) + if err != nil { + return err + } + page.aklr = next + return nil +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (page *APIKeyListResultPage) Next() error { + return page.NextWithContext(context.Background()) +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page APIKeyListResultPage) NotDone() bool { + return !page.aklr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page APIKeyListResultPage) Response() APIKeyListResult { + return page.aklr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page APIKeyListResultPage) Values() []APIKey { + if page.aklr.IsEmpty() { + return nil + } + return *page.aklr.Value +} + +// Creates a new instance of the APIKeyListResultPage type. +func NewAPIKeyListResultPage(getNextPage func(context.Context, APIKeyListResult) (APIKeyListResult, error)) APIKeyListResultPage { + return APIKeyListResultPage{fn: getNextPage} +} + +// CheckNameAvailabilityParameters parameters used for checking whether a resource name is available. +type CheckNameAvailabilityParameters struct { + // Name - The name to check for availability. + Name *string `json:"name,omitempty"` + // Type - The resource type to check for name availability. + Type *string `json:"type,omitempty"` +} + +// ConfigurationStore the configuration store along with all resource properties. The Configuration Store +// will have all information to begin utilizing it. +type ConfigurationStore struct { + autorest.Response `json:"-"` + // Identity - The managed identity information, if configured. + Identity *ResourceIdentity `json:"identity,omitempty"` + // ConfigurationStoreProperties - The properties of a configuration store. + *ConfigurationStoreProperties `json:"properties,omitempty"` + // Sku - The sku of the configuration store. + Sku *Sku `json:"sku,omitempty"` + // ID - READ-ONLY; The resource ID. + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; The name of the resource. + Name *string `json:"name,omitempty"` + // Type - READ-ONLY; The type of the resource. + Type *string `json:"type,omitempty"` + // Location - The location of the resource. This cannot be changed after the resource is created. + Location *string `json:"location,omitempty"` + // Tags - The tags of the resource. + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for ConfigurationStore. +func (cs ConfigurationStore) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if cs.Identity != nil { + objectMap["identity"] = cs.Identity + } + if cs.ConfigurationStoreProperties != nil { + objectMap["properties"] = cs.ConfigurationStoreProperties + } + if cs.Sku != nil { + objectMap["sku"] = cs.Sku + } + if cs.Location != nil { + objectMap["location"] = cs.Location + } + if cs.Tags != nil { + objectMap["tags"] = cs.Tags + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for ConfigurationStore struct. +func (cs *ConfigurationStore) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "identity": + if v != nil { + var identity ResourceIdentity + err = json.Unmarshal(*v, &identity) + if err != nil { + return err + } + cs.Identity = &identity + } + case "properties": + if v != nil { + var configurationStoreProperties ConfigurationStoreProperties + err = json.Unmarshal(*v, &configurationStoreProperties) + if err != nil { + return err + } + cs.ConfigurationStoreProperties = &configurationStoreProperties + } + case "sku": + if v != nil { + var sku Sku + err = json.Unmarshal(*v, &sku) + if err != nil { + return err + } + cs.Sku = &sku + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + cs.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + cs.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + cs.Type = &typeVar + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + cs.Location = &location + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + cs.Tags = tags + } + } + } + + return nil +} + +// ConfigurationStoreListResult the result of a request to list configuration stores. +type ConfigurationStoreListResult struct { + autorest.Response `json:"-"` + // Value - The collection value. + Value *[]ConfigurationStore `json:"value,omitempty"` + // NextLink - The URI that can be used to request the next set of paged results. + NextLink *string `json:"nextLink,omitempty"` +} + +// ConfigurationStoreListResultIterator provides access to a complete listing of ConfigurationStore values. +type ConfigurationStoreListResultIterator struct { + i int + page ConfigurationStoreListResultPage +} + +// NextWithContext advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *ConfigurationStoreListResultIterator) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoreListResultIterator.NextWithContext") + defer func() { + sc := -1 + if iter.Response().Response.Response != nil { + sc = iter.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err = iter.page.NextWithContext(ctx) + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (iter *ConfigurationStoreListResultIterator) Next() error { + return iter.NextWithContext(context.Background()) +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter ConfigurationStoreListResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter ConfigurationStoreListResultIterator) Response() ConfigurationStoreListResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter ConfigurationStoreListResultIterator) Value() ConfigurationStore { + if !iter.page.NotDone() { + return ConfigurationStore{} + } + return iter.page.Values()[iter.i] +} + +// Creates a new instance of the ConfigurationStoreListResultIterator type. +func NewConfigurationStoreListResultIterator(page ConfigurationStoreListResultPage) ConfigurationStoreListResultIterator { + return ConfigurationStoreListResultIterator{page: page} +} + +// IsEmpty returns true if the ListResult contains no values. +func (cslr ConfigurationStoreListResult) IsEmpty() bool { + return cslr.Value == nil || len(*cslr.Value) == 0 +} + +// configurationStoreListResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (cslr ConfigurationStoreListResult) configurationStoreListResultPreparer(ctx context.Context) (*http.Request, error) { + if cslr.NextLink == nil || len(to.String(cslr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare((&http.Request{}).WithContext(ctx), + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(cslr.NextLink))) +} + +// ConfigurationStoreListResultPage contains a page of ConfigurationStore values. +type ConfigurationStoreListResultPage struct { + fn func(context.Context, ConfigurationStoreListResult) (ConfigurationStoreListResult, error) + cslr ConfigurationStoreListResult +} + +// NextWithContext advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *ConfigurationStoreListResultPage) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ConfigurationStoreListResultPage.NextWithContext") + defer func() { + sc := -1 + if page.Response().Response.Response != nil { + sc = page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + next, err := page.fn(ctx, page.cslr) + if err != nil { + return err + } + page.cslr = next + return nil +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (page *ConfigurationStoreListResultPage) Next() error { + return page.NextWithContext(context.Background()) +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page ConfigurationStoreListResultPage) NotDone() bool { + return !page.cslr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page ConfigurationStoreListResultPage) Response() ConfigurationStoreListResult { + return page.cslr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page ConfigurationStoreListResultPage) Values() []ConfigurationStore { + if page.cslr.IsEmpty() { + return nil + } + return *page.cslr.Value +} + +// Creates a new instance of the ConfigurationStoreListResultPage type. +func NewConfigurationStoreListResultPage(getNextPage func(context.Context, ConfigurationStoreListResult) (ConfigurationStoreListResult, error)) ConfigurationStoreListResultPage { + return ConfigurationStoreListResultPage{fn: getNextPage} +} + +// ConfigurationStoreProperties the properties of a configuration store. +type ConfigurationStoreProperties struct { + // ProvisioningState - READ-ONLY; The provisioning state of the configuration store. Possible values include: 'Creating', 'Updating', 'Deleting', 'Succeeded', 'Failed', 'Canceled' + ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` + // CreationDate - READ-ONLY; The creation date of configuration store. + CreationDate *date.Time `json:"creationDate,omitempty"` + // Endpoint - READ-ONLY; The DNS endpoint where the configuration store API will be available. + Endpoint *string `json:"endpoint,omitempty"` +} + +// ConfigurationStoresCreateFuture an abstraction for monitoring and retrieving the results of a +// long-running operation. +type ConfigurationStoresCreateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *ConfigurationStoresCreateFuture) Result(client ConfigurationStoresClient) (cs ConfigurationStore, err error) { + var done bool + done, err = future.DoneWithContext(context.Background(), client) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresCreateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("appconfiguration.ConfigurationStoresCreateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if cs.Response.Response, err = future.GetResult(sender); err == nil && cs.Response.Response.StatusCode != http.StatusNoContent { + cs, err = client.CreateResponder(cs.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresCreateFuture", "Result", cs.Response.Response, "Failure responding to request") + } + } + return +} + +// ConfigurationStoresDeleteFuture an abstraction for monitoring and retrieving the results of a +// long-running operation. +type ConfigurationStoresDeleteFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *ConfigurationStoresDeleteFuture) Result(client ConfigurationStoresClient) (ar autorest.Response, err error) { + var done bool + done, err = future.DoneWithContext(context.Background(), client) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresDeleteFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("appconfiguration.ConfigurationStoresDeleteFuture") + return + } + ar.Response = future.Response() + return +} + +// ConfigurationStoresUpdateFuture an abstraction for monitoring and retrieving the results of a +// long-running operation. +type ConfigurationStoresUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *ConfigurationStoresUpdateFuture) Result(client ConfigurationStoresClient) (cs ConfigurationStore, err error) { + var done bool + done, err = future.DoneWithContext(context.Background(), client) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("appconfiguration.ConfigurationStoresUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if cs.Response.Response, err = future.GetResult(sender); err == nil && cs.Response.Response.StatusCode != http.StatusNoContent { + cs, err = client.UpdateResponder(cs.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.ConfigurationStoresUpdateFuture", "Result", cs.Response.Response, "Failure responding to request") + } + } + return +} + +// ConfigurationStoreUpdateParameters the parameters for updating a configuration store. +type ConfigurationStoreUpdateParameters struct { + // Properties - The properties for updating a configuration store. + Properties interface{} `json:"properties,omitempty"` + // Identity - The managed identity information for the configuration store. + Identity *ResourceIdentity `json:"identity,omitempty"` + // Sku - The SKU of the configuration store. + Sku *Sku `json:"sku,omitempty"` + // Tags - The ARM resource tags. + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for ConfigurationStoreUpdateParameters. +func (csup ConfigurationStoreUpdateParameters) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if csup.Properties != nil { + objectMap["properties"] = csup.Properties + } + if csup.Identity != nil { + objectMap["identity"] = csup.Identity + } + if csup.Sku != nil { + objectMap["sku"] = csup.Sku + } + if csup.Tags != nil { + objectMap["tags"] = csup.Tags + } + return json.Marshal(objectMap) +} + +// Error appConfiguration error object. +type Error struct { + // Code - Error code. + Code *string `json:"code,omitempty"` + // Message - Error message. + Message *string `json:"message,omitempty"` +} + +// KeyValue the result of a request to retrieve a key-value from the specified configuration store. +type KeyValue struct { + autorest.Response `json:"-"` + // Key - READ-ONLY; The primary identifier of a key-value. + // The key is used in unison with the label to uniquely identify a key-value. + Key *string `json:"key,omitempty"` + // Label - READ-ONLY; A value used to group key-values. + // The label is used in unison with the key to uniquely identify a key-value. + Label *string `json:"label,omitempty"` + // Value - READ-ONLY; The value of the key-value. + Value *string `json:"value,omitempty"` + // ContentType - READ-ONLY; The content type of the key-value's value. + // Providing a proper content-type can enable transformations of values when they are retrieved by applications. + ContentType *string `json:"contentType,omitempty"` + // ETag - READ-ONLY; An ETag indicating the state of a key-value within a configuration store. + ETag *string `json:"eTag,omitempty"` + // LastModified - READ-ONLY; The last time a modifying operation was performed on the given key-value. + LastModified *date.Time `json:"lastModified,omitempty"` + // Locked - READ-ONLY; A value indicating whether the key-value is locked. + // A locked key-value may not be modified until it is unlocked. + Locked *bool `json:"locked,omitempty"` + // Tags - READ-ONLY; A dictionary of tags that can help identify what a key-value may be applicable for. + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for KeyValue. +func (kv KeyValue) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + return json.Marshal(objectMap) +} + +// ListKeyValueParameters the parameters used to list a configuration store key-value +type ListKeyValueParameters struct { + // Key - The key to retrieve. + Key *string `json:"key,omitempty"` + // Label - The label of the key. + Label *string `json:"label,omitempty"` +} + +// NameAvailabilityStatus the result of a request to check the availability of a resource name. +type NameAvailabilityStatus struct { + autorest.Response `json:"-"` + // NameAvailable - READ-ONLY; The value indicating whether the resource name is available. + NameAvailable *bool `json:"nameAvailable,omitempty"` + // Message - READ-ONLY; If any, the error message that provides more detail for the reason that the name is not available. + Message *string `json:"message,omitempty"` + // Reason - READ-ONLY; If any, the reason that the name is not available. + Reason *string `json:"reason,omitempty"` +} + +// OperationDefinition the definition of a configuration store operation. +type OperationDefinition struct { + // Name - Operation name: {provider}/{resource}/{operation}. + Name *string `json:"name,omitempty"` + // Display - The display information for the configuration store operation. + Display *OperationDefinitionDisplay `json:"display,omitempty"` +} + +// OperationDefinitionDisplay the display information for a configuration store operation. +type OperationDefinitionDisplay struct { + // Provider - READ-ONLY; The resource provider name: Microsoft App Configuration." + Provider *string `json:"provider,omitempty"` + // Resource - The resource on which the operation is performed. + Resource *string `json:"resource,omitempty"` + // Operation - The operation that users can perform. + Operation *string `json:"operation,omitempty"` + // Description - The description for the operation. + Description *string `json:"description,omitempty"` +} + +// OperationDefinitionListResult the result of a request to list configuration store operations. +type OperationDefinitionListResult struct { + autorest.Response `json:"-"` + // Value - The collection value. + Value *[]OperationDefinition `json:"value,omitempty"` + // NextLink - The URI that can be used to request the next set of paged results. + NextLink *string `json:"nextLink,omitempty"` +} + +// OperationDefinitionListResultIterator provides access to a complete listing of OperationDefinition +// values. +type OperationDefinitionListResultIterator struct { + i int + page OperationDefinitionListResultPage +} + +// NextWithContext advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *OperationDefinitionListResultIterator) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/OperationDefinitionListResultIterator.NextWithContext") + defer func() { + sc := -1 + if iter.Response().Response.Response != nil { + sc = iter.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err = iter.page.NextWithContext(ctx) + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (iter *OperationDefinitionListResultIterator) Next() error { + return iter.NextWithContext(context.Background()) +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter OperationDefinitionListResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter OperationDefinitionListResultIterator) Response() OperationDefinitionListResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter OperationDefinitionListResultIterator) Value() OperationDefinition { + if !iter.page.NotDone() { + return OperationDefinition{} + } + return iter.page.Values()[iter.i] +} + +// Creates a new instance of the OperationDefinitionListResultIterator type. +func NewOperationDefinitionListResultIterator(page OperationDefinitionListResultPage) OperationDefinitionListResultIterator { + return OperationDefinitionListResultIterator{page: page} +} + +// IsEmpty returns true if the ListResult contains no values. +func (odlr OperationDefinitionListResult) IsEmpty() bool { + return odlr.Value == nil || len(*odlr.Value) == 0 +} + +// operationDefinitionListResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (odlr OperationDefinitionListResult) operationDefinitionListResultPreparer(ctx context.Context) (*http.Request, error) { + if odlr.NextLink == nil || len(to.String(odlr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare((&http.Request{}).WithContext(ctx), + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(odlr.NextLink))) +} + +// OperationDefinitionListResultPage contains a page of OperationDefinition values. +type OperationDefinitionListResultPage struct { + fn func(context.Context, OperationDefinitionListResult) (OperationDefinitionListResult, error) + odlr OperationDefinitionListResult +} + +// NextWithContext advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *OperationDefinitionListResultPage) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/OperationDefinitionListResultPage.NextWithContext") + defer func() { + sc := -1 + if page.Response().Response.Response != nil { + sc = page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + next, err := page.fn(ctx, page.odlr) + if err != nil { + return err + } + page.odlr = next + return nil +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (page *OperationDefinitionListResultPage) Next() error { + return page.NextWithContext(context.Background()) +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page OperationDefinitionListResultPage) NotDone() bool { + return !page.odlr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page OperationDefinitionListResultPage) Response() OperationDefinitionListResult { + return page.odlr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page OperationDefinitionListResultPage) Values() []OperationDefinition { + if page.odlr.IsEmpty() { + return nil + } + return *page.odlr.Value +} + +// Creates a new instance of the OperationDefinitionListResultPage type. +func NewOperationDefinitionListResultPage(getNextPage func(context.Context, OperationDefinitionListResult) (OperationDefinitionListResult, error)) OperationDefinitionListResultPage { + return OperationDefinitionListResultPage{fn: getNextPage} +} + +// RegenerateKeyParameters the parameters used to regenerate an API key. +type RegenerateKeyParameters struct { + // ID - The id of the key to regenerate. + ID *string `json:"id,omitempty"` +} + +// Resource an Azure resource. +type Resource struct { + // ID - READ-ONLY; The resource ID. + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; The name of the resource. + Name *string `json:"name,omitempty"` + // Type - READ-ONLY; The type of the resource. + Type *string `json:"type,omitempty"` + // Location - The location of the resource. This cannot be changed after the resource is created. + Location *string `json:"location,omitempty"` + // Tags - The tags of the resource. + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for Resource. +func (r Resource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if r.Location != nil { + objectMap["location"] = r.Location + } + if r.Tags != nil { + objectMap["tags"] = r.Tags + } + return json.Marshal(objectMap) +} + +// ResourceIdentity ... +type ResourceIdentity struct { + // Type - The type of managed identity used. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user-assigned identities. The type 'None' will remove any identities. Possible values include: 'None', 'SystemAssigned', 'UserAssigned', 'SystemAssignedUserAssigned' + Type IdentityType `json:"type,omitempty"` + // UserAssignedIdentities - The list of user-assigned identities associated with the resource. The user-assigned identity dictionary keys will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'. + UserAssignedIdentities map[string]*UserIdentity `json:"userAssignedIdentities"` + // PrincipalID - READ-ONLY; The principal id of the identity. This property will only be provided for a system-assigned identity. + PrincipalID *string `json:"principalId,omitempty"` + // TenantID - READ-ONLY; The tenant id associated with the resource's identity. This property will only be provided for a system-assigned identity. + TenantID *string `json:"tenantId,omitempty"` +} + +// MarshalJSON is the custom marshaler for ResourceIdentity. +func (ri ResourceIdentity) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if ri.Type != "" { + objectMap["type"] = ri.Type + } + if ri.UserAssignedIdentities != nil { + objectMap["userAssignedIdentities"] = ri.UserAssignedIdentities + } + return json.Marshal(objectMap) +} + +// Sku describes a configuration store SKU. +type Sku struct { + // Name - The SKU name of the configuration store. + Name *string `json:"name,omitempty"` +} + +// UserIdentity ... +type UserIdentity struct { + // PrincipalID - READ-ONLY; The principal ID of the user-assigned identity. + PrincipalID *string `json:"principalId,omitempty"` + // ClientID - READ-ONLY; The client ID of the user-assigned identity. + ClientID *string `json:"clientId,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/operations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/operations.go new file mode 100644 index 000000000000..8840f7d4abdc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/operations.go @@ -0,0 +1,238 @@ +package appconfiguration + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// OperationsClient is the client for the Operations methods of the Appconfiguration service. +type OperationsClient struct { + BaseClient +} + +// NewOperationsClient creates an instance of the OperationsClient client. +func NewOperationsClient(subscriptionID string) OperationsClient { + return NewOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewOperationsClientWithBaseURI creates an instance of the OperationsClient client. +func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string) OperationsClient { + return OperationsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CheckNameAvailability checks whether the configuration store name is available for use. +// Parameters: +// checkNameAvailabilityParameters - the object containing information for the availability request. +func (client OperationsClient) CheckNameAvailability(ctx context.Context, checkNameAvailabilityParameters CheckNameAvailabilityParameters) (result NameAvailabilityStatus, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/OperationsClient.CheckNameAvailability") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: checkNameAvailabilityParameters, + Constraints: []validation.Constraint{{Target: "checkNameAvailabilityParameters.Name", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "checkNameAvailabilityParameters.Type", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewError("appconfiguration.OperationsClient", "CheckNameAvailability", err.Error()) + } + + req, err := client.CheckNameAvailabilityPreparer(ctx, checkNameAvailabilityParameters) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "CheckNameAvailability", nil, "Failure preparing request") + return + } + + resp, err := client.CheckNameAvailabilitySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "CheckNameAvailability", resp, "Failure sending request") + return + } + + result, err = client.CheckNameAvailabilityResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "CheckNameAvailability", resp, "Failure responding to request") + } + + return +} + +// CheckNameAvailabilityPreparer prepares the CheckNameAvailability request. +func (client OperationsClient) CheckNameAvailabilityPreparer(ctx context.Context, checkNameAvailabilityParameters CheckNameAvailabilityParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.AppConfiguration/checkNameAvailability", pathParameters), + autorest.WithJSON(checkNameAvailabilityParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CheckNameAvailabilitySender sends the CheckNameAvailability request. The method will close the +// http.Response Body if it receives an error. +func (client OperationsClient) CheckNameAvailabilitySender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// CheckNameAvailabilityResponder handles the response to the CheckNameAvailability request. The method always +// closes the http.Response Body. +func (client OperationsClient) CheckNameAvailabilityResponder(resp *http.Response) (result NameAvailabilityStatus, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists the operations available from this provider. +// Parameters: +// skipToken - a skip token is used to continue retrieving items after an operation returns a partial result. +// If a previous response contains a nextLink element, the value of the nextLink element will include a +// skipToken parameter that specifies a starting point to use for subsequent calls. +func (client OperationsClient) List(ctx context.Context, skipToken string) (result OperationDefinitionListResultPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/OperationsClient.List") + defer func() { + sc := -1 + if result.odlr.Response.Response != nil { + sc = result.odlr.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, skipToken) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.odlr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "List", resp, "Failure sending request") + return + } + + result.odlr, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client OperationsClient) ListPreparer(ctx context.Context, skipToken string) (*http.Request, error) { + const APIVersion = "2019-10-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(skipToken) > 0 { + queryParameters["$skipToken"] = autorest.Encode("query", skipToken) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.AppConfiguration/operations"), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client OperationsClient) ListSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client OperationsClient) ListResponder(resp *http.Response) (result OperationDefinitionListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client OperationsClient) listNextResults(ctx context.Context, lastResults OperationDefinitionListResult) (result OperationDefinitionListResult, err error) { + req, err := lastResults.operationDefinitionListResultPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "appconfiguration.OperationsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client OperationsClient) ListComplete(ctx context.Context, skipToken string) (result OperationDefinitionListResultIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/OperationsClient.List") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.List(ctx, skipToken) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/version.go new file mode 100644 index 000000000000..122ce7758d0a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration/version.go @@ -0,0 +1,30 @@ +package appconfiguration + +import "github.com/Azure/azure-sdk-for-go/version" + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return "Azure-SDK-For-Go/" + version.Number + " appconfiguration/2019-10-01" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return version.Number +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 76cec7ee9230..9ed3ee6699f7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -10,6 +10,7 @@ cloud.google.com/go/storage github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources github.com/Azure/azure-sdk-for-go/services/analysisservices/mgmt/2017-08-01/analysisservices github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement +github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch From 053b7e2a669e0e9edcf79514598fdcc492c126b1 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 13 Nov 2019 00:35:22 +0100 Subject: [PATCH 03/19] fix error handling in deletion method --- azurerm/resource_arm_app_configuration.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index 232e1d1de217..e7a229a5423e 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -285,21 +285,20 @@ func resourceArmAppConfigurationDelete(d *schema.ResourceData, meta interface{}) resourceGroup := id.ResourceGroup name := id.Path["configurationStores"] - read, err := client.Get(ctx, resourceGroup, name) + fut, err := client.Delete(ctx, resourceGroup, name) if err != nil { - if utils.ResponseWasNotFound(read.Response) { + if response.WasNotFound(fut.Response()) { return nil } - - return fmt.Errorf("Error retrieving App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("Error deleting App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) } - fut, err := client.Delete(ctx, resourceGroup, name) resp, err := fut.Result(*client) if err != nil { if !response.WasNotFound(resp.Response) { - return fmt.Errorf("Error retrieving App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + return nil } + return fmt.Errorf("Error deleting App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) } return nil From 7d1d6c4e04fa715d8d4c6e2f375d9a635ea92ffd Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 13 Nov 2019 00:47:41 +0100 Subject: [PATCH 04/19] adjust fetching of access keys - Terraform provider linters only allow string literals for ResourceData.Set() - switched to nested if-statements instead of string interpolation --- azurerm/resource_arm_app_configuration.go | 28 +++++++++++------------ 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index e7a229a5423e..4c94b0f45320 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -249,25 +249,23 @@ func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) e values := resultPage.Values() for _, value := range values { - var index string - var permission string + accessKey := makeAccessKeyMap(value) if strings.HasPrefix(*value.Name, "Primary") { - index = "primary" - } else { - index = "secondary" - } - - if *value.ReadOnly { - permission = "read" + if *value.ReadOnly { + d.Set("primary_read_key", accessKey) + } else { + d.Set("primary_write_key", accessKey) + } + } else if strings.HasPrefix(*value.Name, "Secondary") { + if *value.ReadOnly { + d.Set("secondary_read_key", accessKey) + } else { + d.Set("secondary_write_key", accessKey) + } } else { - permission = "write" + log.Printf("[WARN] Received unknown App Configuration access key '%s', ignoring...", value.Name) } - - d.Set( - fmt.Sprintf("%s_%s_key", index, permission), - makeAccessKeyMap(value), - ) } return tags.FlattenAndSet(d, resp.Tags) From 605e96e52a4c7e77fa8215d2674e4f652b1e8e72 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 13 Nov 2019 00:51:32 +0100 Subject: [PATCH 05/19] remove unused variable --- azurerm/resource_arm_app_configuration.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index 4c94b0f45320..e6defb8d3e8d 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -19,8 +19,6 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -var appConfigurationResourceName = "azurerm_app_configuration" - func resourceArmAppConfiguration() *schema.Resource { return &schema.Resource{ Create: resourceArmAppConfigurationCreate, From 02194f679ef07cac2fd3b254ea23b64aa35b8097 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 13 Nov 2019 01:06:25 +0100 Subject: [PATCH 06/19] fix log statement --- azurerm/resource_arm_app_configuration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index e6defb8d3e8d..9b09c9dd5001 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -262,7 +262,7 @@ func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) e d.Set("secondary_write_key", accessKey) } } else { - log.Printf("[WARN] Received unknown App Configuration access key '%s', ignoring...", value.Name) + log.Printf("[WARN] Received unknown App Configuration access key '%s', ignoring...", *value.Name) } } From 2a9a681605a554596822d2d59fe3ab5a8444863e Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 13 Nov 2019 20:33:22 +0100 Subject: [PATCH 07/19] use create instead of create/update timeout Co-Authored-By: Matthew Frahry --- azurerm/resource_arm_app_configuration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index 9b09c9dd5001..9ce74baed406 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -109,7 +109,7 @@ func resourceArmAppConfiguration() *schema.Resource { func resourceArmAppConfigurationCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient).AppConfiguration.AppConfigurationsClient - ctx, cancel := timeouts.ForCreateUpdate(meta.(*ArmClient).StopContext, d) + ctx, cancel := timeouts.ForCreate(meta.(*ArmClient).StopContext, d) defer cancel() log.Printf("[INFO] preparing arguments for Azure ARM App Configuration creation.") From 5c7d877da86f045bafe0723e5a80ac6a9ce7fc20 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 13 Nov 2019 20:42:05 +0100 Subject: [PATCH 08/19] align future handling in deletion method --- azurerm/resource_arm_app_configuration.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index 9ce74baed406..112e846555a2 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -289,9 +289,8 @@ func resourceArmAppConfigurationDelete(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error deleting App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) } - resp, err := fut.Result(*client) - if err != nil { - if !response.WasNotFound(resp.Response) { + if err = fut.WaitForCompletionRef(ctx, client.Client); err != nil { + if response.WasNotFound(fut.Response()) { return nil } return fmt.Errorf("Error deleting App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) From 5807463196086df8062d660454f724df6b058e9c Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 13 Nov 2019 22:14:11 +0100 Subject: [PATCH 09/19] add missing nil check --- azurerm/resource_arm_app_configuration.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index 112e846555a2..baac00894c1f 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -247,6 +247,10 @@ func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) e values := resultPage.Values() for _, value := range values { + if &value == nil { + continue + } + accessKey := makeAccessKeyMap(value) if strings.HasPrefix(*value.Name, "Primary") { From eea91fbd0742f99b501b4ac41f54a1bd5bdf16d1 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Fri, 15 Nov 2019 21:24:29 +0100 Subject: [PATCH 10/19] make access key of schema type list --- azurerm/resource_arm_app_configuration.go | 120 ++++++++++++++++------ 1 file changed, 89 insertions(+), 31 deletions(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index baac00894c1f..6eb33e4296c3 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -67,38 +67,102 @@ func resourceArmAppConfiguration() *schema.Resource { }, "primary_read_key": { - Type: schema.TypeMap, - Computed: true, - Sensitive: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeList, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "connection_string": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, }, }, "secondary_read_key": { - Type: schema.TypeMap, - Computed: true, - Sensitive: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeList, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "connection_string": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, }, }, "primary_write_key": { - Type: schema.TypeMap, - Computed: true, - Sensitive: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeList, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "connection_string": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, }, }, "secondary_write_key": { - Type: schema.TypeMap, - Computed: true, - Sensitive: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeList, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "connection_string": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, }, }, @@ -251,7 +315,11 @@ func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) e continue } - accessKey := makeAccessKeyMap(value) + accessKey := []interface{}{map[string]string{ + "id": *value.ID, + "secret": *value.Value, + "connection_string": *value.ConnectionString, + }} if strings.HasPrefix(*value.Name, "Primary") { if *value.ReadOnly { @@ -311,13 +379,3 @@ func validateAppConfigurationName(v interface{}, k string) (warnings []string, e return warnings, errors } - -func makeAccessKeyMap(value appconf.APIKey) map[string]string { - m := make(map[string]string) - - m["id"] = *value.ID - m["secret"] = *value.Value - m["connectionString"] = *value.ConnectionString - - return m -} From bf3b4d95dc31397a66d953a8c1f085f7fa98de07 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Mon, 18 Nov 2019 22:06:04 +0100 Subject: [PATCH 11/19] add app_configuration resource doc --- .../docs/r/app_configuration.html.markdown | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 website/docs/r/app_configuration.html.markdown diff --git a/website/docs/r/app_configuration.html.markdown b/website/docs/r/app_configuration.html.markdown new file mode 100644 index 000000000000..05d0b6db85bd --- /dev/null +++ b/website/docs/r/app_configuration.html.markdown @@ -0,0 +1,77 @@ +--- +subcategory: "App Configuration" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_app_configuration" +sidebar_current: "docs-azurerm-resource-app-configuration" +description: |- + Manages an Azure App Configuration. + +--- + +# azurerm_container_registry + +Manages an Azure App Configuration. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "rg" { + name = "resourceGroup1" + location = "West Europe" +} + +resource "azurerm_app_configuration" "appconf" { + name = "appConf1" + resource_group_name = "${azurerm_resource_group.rg.name}" + location = "${azurerm_resource_group.rg.location}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the App Configuration. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the App Configuration. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `sku` - (Optional) The SKU name of the the App Configuration. Possible values are `free` and `standard`. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- +## Attributes Reference + +The following attributes are exported: + +* `id` - The App Configuration ID. + +* `endpoint` - The URL that can be used to log into the container registry. + +* `primary_write_key` - An `access_key` block as defined below containing the primary write access key. + +* `secondary_write_key` - An `access_key` block as defined below containing the secondary write access key. + +* `primary_read_key` - An `access_key` block as defined below containing the primary read access key. + +* `secondary_read_key` - An `access_key` block as defined below containing the secondary read access key. + +--- + +A `access_key` block exports the following: + +* `id` - The ID of the access key. + +* `secret` - The secret of the access key. + +* `connection_string` - The connection string including the endpoint, id and secret. + +## Import + +App Configurations can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_app_configuration.appconf /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/resourceGroup1/providers/Microsoft.AppConfiguration/configurationStores/appConf1 +``` From 242024edabfa7523a8d98b9af511a5ae0dcf29df Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 20 Nov 2019 00:01:43 +0100 Subject: [PATCH 12/19] add tests for app_configuration resource --- .../resource_arm_app_configuration_test.go | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 azurerm/resource_arm_app_configuration_test.go diff --git a/azurerm/resource_arm_app_configuration_test.go b/azurerm/resource_arm_app_configuration_test.go new file mode 100644 index 000000000000..830739f93b18 --- /dev/null +++ b/azurerm/resource_arm_app_configuration_test.go @@ -0,0 +1,340 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMAppConfigurationName_validation(t *testing.T) { + cases := []struct { + Value string + ErrCount int + }{ + { + Value: "four", + ErrCount: 1, + }, + { + Value: "5five", + ErrCount: 0, + }, + { + Value: "hello-world", + ErrCount: 0, + }, + { + Value: "hello_world", + ErrCount: 1, + }, + { + Value: "helloWorld", + ErrCount: 0, + }, + { + Value: "helloworld12", + ErrCount: 0, + }, + { + Value: "hello@world", + ErrCount: 1, + }, + { + Value: "qfvbdsbvipqdbwsbddbdcwqffewsqwcdw21ddwqwd3324120", + ErrCount: 0, + }, + { + Value: "qfvbdsbvipqdbwsbddbdcwqffewsqwcdw21ddwqwd332412020", + ErrCount: 0, + }, + { + Value: "qfvbdsbvipqdbwsbddbdcwqfjjfewsqwcdw21ddwqwd33241201", + ErrCount: 1, + }, + } + + for _, tc := range cases { + _, errors := validateAppConfigurationName(tc.Value, "azurerm_app_configuration") + + if len(errors) != tc.ErrCount { + t.Fatalf("Expected the Azure App Configuration Name to trigger a validation error: %v", tc) + } + } +} + +func TestAccAzureAppConfiguration_free(t *testing.T) { + rn := "azurerm_app_configuration.test" + ri := tf.AccRandTimeInt() + l := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureAppConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureAppConfiguration_free(ri, l), + Check: resource.ComposeTestCheckFunc( + testCheckAzureAppConfigurationExists(rn), + ), + }, + { + ResourceName: rn, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureAppConfiguration_standard(t *testing.T) { + rn := "azurerm_app_configuration.test" + ri := tf.AccRandTimeInt() + l := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureAppConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureAppConfiguration_standard(ri, l), + Check: resource.ComposeTestCheckFunc( + testCheckAzureAppConfigurationExists(rn), + ), + }, + { + ResourceName: rn, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureAppConfiguration_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + rn := "azurerm_app_configuration.test" + ri := tf.AccRandTimeInt() + l := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureAppConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureAppConfiguration_free(ri, l), + Check: resource.ComposeTestCheckFunc( + testCheckAzureAppConfigurationExists(rn), + ), + }, + { + Config: testAccAzureAppConfiguration_requiresImport(ri, l), + ExpectError: testRequiresImportError("azurerm_app_configuration"), + }, + }, + }) +} + +func TestAccAzureAppConfiguration_complete(t *testing.T) { + rn := "azurerm_app_configuration.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureAppConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureAppConfiguration_complete(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureAppConfigurationExists(rn), + ), + }, + { + ResourceName: rn, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureAppConfiguration_update(t *testing.T) { + rn := "azurerm_app_configuration.test" + ri := tf.AccRandTimeInt() + l := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureAppConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureAppConfiguration_complete(ri, l), + Check: resource.ComposeTestCheckFunc( + testCheckAzureAppConfigurationExists(rn), + ), + }, + { + Config: testAccAzureAppConfiguration_completeUpdated(ri, l), + Check: resource.ComposeTestCheckFunc( + testCheckAzureAppConfigurationExists(rn), + ), + }, + }, + }) +} + +func testCheckAzureAppConfigurationDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).AppConfiguration.AppConfigurationsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_app_configuration" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + + return nil +} + +func testCheckAzureAppConfigurationExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for App Configuration: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).AppConfiguration.AppConfigurationsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Bad: Get on appConfigurationsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: App Configuration %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testAccAzureAppConfiguration_free(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" +} + +resource "azurerm_app_configuration" "test" { + name = "testaccappconf%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + sku = "free" +} +`, rInt, location, rInt) +} + +func testAccAzureAppConfiguration_standard(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" +} + +resource "azurerm_app_configuration" "test" { + name = "testaccappconf%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + sku = "standard" +} +`, rInt, location, rInt) +} + +func testAccAzureAppConfiguration_requiresImport(rInt int, location string) string { + template := testAccAzureAppConfiguration_free(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_app_configuration" "import" { + name = "${azurerm_app_configuration.test.name}" + resource_group_name = "${azurerm_app_configuration.test.resource_group_name}" + location = "${azurerm_app_configuration.test.location}" + sku = "${azurerm_app_configuration.test.sku}" + +} +`, template) +} + +func testAccAzureAppConfiguration_complete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" +} + +resource "azurerm_app_configuration" "test" { + name = "testaccappconf%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + sku = "free" + + tags = { + environment = "development" + } +} +`, rInt, location, rInt) +} + +func testAccAzureAppConfiguration_completeUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" +} + +resource "azurerm_app_configuration" "test" { + name = "testaccappconf%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + sku = "free" + + tags = { + environment = "production" + } +} +`, rInt, location, rInt) +} From f7b4ebf64a5671126f9f5025e97143a202222071 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 20 Nov 2019 00:10:35 +0100 Subject: [PATCH 13/19] add app configuration to new client struct --- azurerm/internal/clients/client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azurerm/internal/clients/client.go b/azurerm/internal/clients/client.go index 8be46af3d270..a7be96479441 100644 --- a/azurerm/internal/clients/client.go +++ b/azurerm/internal/clients/client.go @@ -5,6 +5,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/analysisservices" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/apimanagement" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/appconfiguration" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/applicationinsights" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/authorization" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/automation" @@ -22,6 +23,7 @@ type Client struct { AnalysisServices *analysisservices.Client ApiManagement *apimanagement.Client + AppConfiguration *appconfiguration.Client AppInsights *applicationinsights.Client Automation *automation.Client Authorization *authorization.Client From 423a277d50d75b8aa06c3d23c7444a7342460650 Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Wed, 20 Nov 2019 20:12:56 +0100 Subject: [PATCH 14/19] add hint about SKU downgrade --- website/docs/r/app_configuration.html.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/r/app_configuration.html.markdown b/website/docs/r/app_configuration.html.markdown index 05d0b6db85bd..281b64a01563 100644 --- a/website/docs/r/app_configuration.html.markdown +++ b/website/docs/r/app_configuration.html.markdown @@ -39,6 +39,8 @@ The following arguments are supported: * `sku` - (Optional) The SKU name of the the App Configuration. Possible values are `free` and `standard`. +~> **NOTE:** Azure does not allow a downgrade from `standard` to `free`. + * `tags` - (Optional) A mapping of tags to assign to the resource. --- From 60eb5c444d274d46d471c65e1151bed985f90eac Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Thu, 28 Nov 2019 21:51:22 +0100 Subject: [PATCH 15/19] extract sku name in read method --- azurerm/resource_arm_app_configuration.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index 6eb33e4296c3..62eb4c03ea71 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -300,6 +300,10 @@ func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) e d.Set("location", azure.NormalizeLocation(*location)) } + if sku := resp.Sku; sku != nil { + d.Set("sku", sku.Name) + } + if endpoint := resp.Endpoint; endpoint != nil { d.Set("endpoint", resp.Endpoint) } From ea7d0fbf7e3982d42b57ae1406b9641741e3227b Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Thu, 5 Dec 2019 19:27:26 +0100 Subject: [PATCH 16/19] remove MaxItems from access key fields --- azurerm/resource_arm_app_configuration.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index 62eb4c03ea71..eec6e7ed5ccb 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -68,7 +68,6 @@ func resourceArmAppConfiguration() *schema.Resource { "primary_read_key": { Type: schema.TypeList, - MaxItems: 1, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -93,7 +92,6 @@ func resourceArmAppConfiguration() *schema.Resource { "secondary_read_key": { Type: schema.TypeList, - MaxItems: 1, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -118,7 +116,6 @@ func resourceArmAppConfiguration() *schema.Resource { "primary_write_key": { Type: schema.TypeList, - MaxItems: 1, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -143,7 +140,6 @@ func resourceArmAppConfiguration() *schema.Resource { "secondary_write_key": { Type: schema.TypeList, - MaxItems: 1, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ From 5a12c39f76b8101aab5476c0714afa6377084cbe Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Thu, 5 Dec 2019 19:34:14 +0100 Subject: [PATCH 17/19] fix APIKey nil check --- azurerm/resource_arm_app_configuration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index eec6e7ed5ccb..c65115ecc2f8 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -311,7 +311,7 @@ func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) e values := resultPage.Values() for _, value := range values { - if &value == nil { + if value.ID == nil || value.Value == nil || value.ConnectionString == nil || value.Name == nil || value.ReadOnly == nil { continue } From 41fe134a681ac96609e6ea0500d9ada64a95decb Mon Sep 17 00:00:00 2001 From: Max Brenner Date: Thu, 5 Dec 2019 19:38:32 +0100 Subject: [PATCH 18/19] remove SchemaVersion --- azurerm/resource_arm_app_configuration.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index c65115ecc2f8..697d7f7405f7 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -30,8 +30,6 @@ func resourceArmAppConfiguration() *schema.Resource { State: schema.ImportStatePassthrough, }, - SchemaVersion: 2, - Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), Read: schema.DefaultTimeout(5 * time.Minute), From f26fcb7493e1af26afa09aa7464170a580f3b749 Mon Sep 17 00:00:00 2001 From: Matthew Frahry Date: Mon, 9 Dec 2019 13:57:10 -0800 Subject: [PATCH 19/19] Updating with master and fixing nil check --- azurerm/internal/clients/client.go | 5 +- .../appconfiguration/{ => client}/client.go | 4 +- azurerm/resource_arm_app_configuration.go | 50 +++++++++++-------- 3 files changed, 34 insertions(+), 25 deletions(-) rename azurerm/internal/services/appconfiguration/{ => client}/client.go (87%) diff --git a/azurerm/internal/clients/client.go b/azurerm/internal/clients/client.go index 48a05c31da6b..cc5616fb4338 100644 --- a/azurerm/internal/clients/client.go +++ b/azurerm/internal/clients/client.go @@ -3,10 +3,10 @@ package clients import ( "context" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" analysisServices "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/analysisservices/client" apiManagement "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/apimanagement/client" + appConfiguration "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/appconfiguration/client" applicationInsights "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/applicationinsights/client" authorization "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/authorization/client" automation "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/automation/client" @@ -73,9 +73,9 @@ type Client struct { Account *ResourceManagerAccount - AnalysisServices *analysisServices.Client ApiManagement *apiManagement.Client + AppConfiguration *appConfiguration.Client AppInsights *applicationInsights.Client Authorization *authorization.Client Automation *automation.Client @@ -147,6 +147,7 @@ type Client struct { func (client *Client) Build(o *common.ClientOptions) error { client.AnalysisServices = analysisServices.NewClient(o) client.ApiManagement = apiManagement.NewClient(o) + client.AppConfiguration = appConfiguration.NewClient(o) client.AppInsights = applicationInsights.NewClient(o) client.Authorization = authorization.NewClient(o) client.Automation = automation.NewClient(o) diff --git a/azurerm/internal/services/appconfiguration/client.go b/azurerm/internal/services/appconfiguration/client/client.go similarity index 87% rename from azurerm/internal/services/appconfiguration/client.go rename to azurerm/internal/services/appconfiguration/client/client.go index ab871f6ebbc0..b1354e75280a 100644 --- a/azurerm/internal/services/appconfiguration/client.go +++ b/azurerm/internal/services/appconfiguration/client/client.go @@ -1,4 +1,4 @@ -package appconfiguration +package client import ( appconf "github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration" @@ -9,7 +9,7 @@ type Client struct { AppConfigurationsClient *appconf.ConfigurationStoresClient } -func BuildClient(o *common.ClientOptions) *Client { +func NewClient(o *common.ClientOptions) *Client { AppConfigurationsClient := appconf.NewConfigurationStoresClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&AppConfigurationsClient.Client, o.ResourceManagerAuthorizer) diff --git a/azurerm/resource_arm_app_configuration.go b/azurerm/resource_arm_app_configuration.go index 697d7f7405f7..76a95545b1cd 100644 --- a/azurerm/resource_arm_app_configuration.go +++ b/azurerm/resource_arm_app_configuration.go @@ -8,10 +8,10 @@ import ( "time" appconf "github.com/Azure/azure-sdk-for-go/services/appconfiguration/mgmt/2019-10-01/appconfiguration" + "github.com/hashicorp/go-azure-helpers/response" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" @@ -309,30 +309,38 @@ func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) e values := resultPage.Values() for _, value := range values { - if value.ID == nil || value.Value == nil || value.ConnectionString == nil || value.Name == nil || value.ReadOnly == nil { - continue + accessKeyParams := map[string]string{} + if id := value.ID; id != nil { + accessKeyParams["id"] = *id + } + if value := value.Value; value != nil { + accessKeyParams["secret"] = *value + } + if connectionString := value.ConnectionString; connectionString != nil { + accessKeyParams["connection_string"] = *value.ConnectionString } - accessKey := []interface{}{map[string]string{ - "id": *value.ID, - "secret": *value.Value, - "connection_string": *value.ConnectionString, - }} - - if strings.HasPrefix(*value.Name, "Primary") { - if *value.ReadOnly { - d.Set("primary_read_key", accessKey) - } else { - d.Set("primary_write_key", accessKey) - } - } else if strings.HasPrefix(*value.Name, "Secondary") { - if *value.ReadOnly { - d.Set("secondary_read_key", accessKey) + accessKey := []interface{}{accessKeyParams} + if name := value.Name; name != nil { + if strings.HasPrefix(*name, "Primary") { + if readOnly := value.ReadOnly; readOnly != nil { + if *readOnly { + d.Set("primary_read_key", accessKey) + } else { + d.Set("primary_write_key", accessKey) + } + } + } else if strings.HasPrefix(*name, "Secondary") { + if readOnly := value.ReadOnly; readOnly != nil { + if *readOnly { + d.Set("secondary_read_key", accessKey) + } else { + d.Set("secondary_write_key", accessKey) + } + } } else { - d.Set("secondary_write_key", accessKey) + log.Printf("[WARN] Received unknown App Configuration access key '%s', ignoring...", *name) } - } else { - log.Printf("[WARN] Received unknown App Configuration access key '%s', ignoring...", *value.Name) } }