diff --git a/internal/services/apimanagement/api_management_gateway_certificate_authority_resource.go b/internal/services/apimanagement/api_management_gateway_certificate_authority_resource.go new file mode 100644 index 000000000000..4fa00c2e78af --- /dev/null +++ b/internal/services/apimanagement/api_management_gateway_certificate_authority_resource.go @@ -0,0 +1,151 @@ +package apimanagement + +import ( + "fmt" + "log" + "time" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2021-08-01/apimanagement" + "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/schemaz" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +func resourceApiManagementGatewayCertificateAuthority() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Create: resourceApiManagementGatewayCertificateAuthorityCreateUpdate, + Read: resourceApiManagementGatewayCertificateAuthorityRead, + Update: resourceApiManagementGatewayCertificateAuthorityCreateUpdate, + Delete: resourceApiManagementGatewayCertificateAuthorityDelete, + + Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { + _, err := parse.GatewayCertificateAuthorityID(id) + return err + }), + + Timeouts: &pluginsdk.ResourceTimeout{ + Create: pluginsdk.DefaultTimeout(30 * time.Minute), + Read: pluginsdk.DefaultTimeout(5 * time.Minute), + Update: pluginsdk.DefaultTimeout(30 * time.Minute), + Delete: pluginsdk.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*pluginsdk.Schema{ + "api_management_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.ApiManagementID, + }, + + "certificate_name": schemaz.SchemaApiManagementChildName(), + + "gateway_name": schemaz.SchemaApiManagementChildName(), + + "is_trusted": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + }, + } +} + +func resourceApiManagementGatewayCertificateAuthorityCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).ApiManagement.GatewayCertificateAuthorityClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + apimId, err := parse.ApiManagementID(d.Get("api_management_id").(string)) + if err != nil { + return fmt.Errorf("parsing `api_management_id`: %v", err) + } + + id := parse.NewGatewayCertificateAuthorityID(apimId.SubscriptionId, apimId.ResourceGroup, apimId.ServiceName, d.Get("gateway_name").(string), d.Get("certificate_name").(string)) + + if d.IsNewResource() { + existing, err := client.Get(ctx, id.ResourceGroup, id.ServiceName, id.GatewayName, d.Get("certificate_name").(string)) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for presence of existing %s: %s", id, err) + } + } + + if !utils.ResponseWasNotFound(existing.Response) { + return tf.ImportAsExistsError("azurerm_api_management_gateway_certificate_authority", id.ID()) + } + } + + parameters := apimanagement.GatewayCertificateAuthorityContract{ + GatewayCertificateAuthorityContractProperties: &apimanagement.GatewayCertificateAuthorityContractProperties{ + IsTrusted: utils.Bool(d.Get("is_trusted").(bool)), + }, + } + + resp, err := client.CreateOrUpdate(ctx, id.ResourceGroup, id.ServiceName, d.Get("gateway_name").(string), d.Get("certificate_name").(string), parameters, "") + if err != nil { + return fmt.Errorf("creating or updating %s: %+v", id, err) + } + + d.SetId(*resp.ID) + + return resourceApiManagementGatewayCertificateAuthorityRead(d, meta) +} + +func resourceApiManagementGatewayCertificateAuthorityRead(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).ApiManagement.GatewayCertificateAuthorityClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.GatewayCertificateAuthorityID(d.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.ResourceGroup, id.ServiceName, id.GatewayName, id.CertificateAuthorityName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("%s was not found - removing from state!", *id) + d.SetId("") + return nil + } + + return fmt.Errorf("making read request for %s: %+v", *id, err) + } + + apimId := parse.NewApiManagementID(id.SubscriptionId, id.ResourceGroup, id.ServiceName) + + d.Set("certificate_name", resp.Name) + d.Set("api_management_id", apimId.ID()) + d.Set("gateway_name", id.GatewayName) + + if properties := resp.GatewayCertificateAuthorityContractProperties; properties != nil { + d.Set("is_trusted", properties.IsTrusted) + } + + return nil +} + +func resourceApiManagementGatewayCertificateAuthorityDelete(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).ApiManagement.GatewayCertificateAuthorityClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.GatewayCertificateAuthorityID(d.Id()) + if err != nil { + return err + } + + log.Printf("[DEBUG] Deleting %s", *id) + if resp, err := client.Delete(ctx, id.ResourceGroup, id.ServiceName, id.GatewayName, id.CertificateAuthorityName, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("deleting %s: %+v", *id, err) + } + } + + return nil +} diff --git a/internal/services/apimanagement/api_management_gateway_certificate_authority_resource_test.go b/internal/services/apimanagement/api_management_gateway_certificate_authority_resource_test.go new file mode 100644 index 000000000000..5b162c86518d --- /dev/null +++ b/internal/services/apimanagement/api_management_gateway_certificate_authority_resource_test.go @@ -0,0 +1,254 @@ +package apimanagement_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type ApiManagementGatewayCertificateAuthorityResource struct{} + +func TestAccApiManagementGatewayCertificateAuthority_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_gateway_certificate_authority", "test") + r := ApiManagementGatewayCertificateAuthorityResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApiManagementGatewayCertificateAuthority_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_gateway_certificate_authority", "test") + r := ApiManagementGatewayCertificateAuthorityResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.RequiresImportErrorStep(r.requiresImport), + }) +} + +func TestAccApiManagementGatewayCertificateAuthority_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_gateway_certificate_authority", "test") + r := ApiManagementGatewayCertificateAuthorityResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApiManagementGatewayCertificateAuthority_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_gateway_certificate_authority", "test") + r := ApiManagementGatewayCertificateAuthorityResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + { + Config: r.update(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + }) +} + +func (ApiManagementGatewayCertificateAuthorityResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := parse.GatewayCertificateAuthorityID(state.ID) + if err != nil { + return nil, err + } + + resp, err := clients.ApiManagement.GatewayCertificateAuthorityClient.Get(ctx, id.ResourceGroup, id.ServiceName, id.GatewayName, id.CertificateAuthorityName) + if err != nil { + return nil, fmt.Errorf("reading Api Management Gateway Certificate Authority (%s): %+v", id, err) + } + + return utils.Bool(resp.ID != nil), nil +} + +func (ApiManagementGatewayCertificateAuthorityResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku_name = "Developer_1" +} + +resource "azurerm_api_management_gateway" "test" { + name = "acctestAMGateway-%d" + api_management_id = azurerm_api_management.test.id + + location_data { + name = "test" + } +} + +resource "azurerm_api_management_certificate" "test" { + name = "example-cert" + api_management_name = azurerm_api_management.test.name + resource_group_name = azurerm_resource_group.test.name + data = filebase64("testdata/keyvaultcert.pfx") + password = "" +} + +resource "azurerm_api_management_gateway_certificate_authority" "test" { + api_management_id = azurerm_api_management.test.id + certificate_name = azurerm_api_management_certificate.test.name + gateway_name = azurerm_api_management_gateway.test.name +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) +} + +func (r ApiManagementGatewayCertificateAuthorityResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_gateway_certificate_authority" "import" { + api_management_id = azurerm_api_management_gateway_certificate_authority.test.api_management_id + certificate_name = azurerm_api_management_gateway_certificate_authority.test.certificate_name + gateway_name = azurerm_api_management_gateway_certificate_authority.test.gateway_name +} +`, r.basic(data)) +} + +func (ApiManagementGatewayCertificateAuthorityResource) update(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku_name = "Developer_1" +} + +resource "azurerm_api_management_gateway" "test" { + name = "acctestAMGateway-%d" + api_management_id = azurerm_api_management.test.id + + location_data { + name = "test" + } +} + +resource "azurerm_api_management_certificate" "test" { + name = "example-cert" + api_management_name = azurerm_api_management.test.name + resource_group_name = azurerm_resource_group.test.name + data = filebase64("testdata/keyvaultcert.pfx") + password = "" +} + +resource "azurerm_api_management_gateway_certificate_authority" "test" { + api_management_id = azurerm_api_management.test.id + certificate_name = azurerm_api_management_certificate.test.name + gateway_name = azurerm_api_management_gateway.test.name + is_trusted = true +} + +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) +} + +func (ApiManagementGatewayCertificateAuthorityResource) complete(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku_name = "Developer_1" +} + +resource "azurerm_api_management_gateway" "test" { + name = "acctestAMGateway-%d" + api_management_id = azurerm_api_management.test.id + + location_data { + name = "test" + } +} + +resource "azurerm_api_management_certificate" "test" { + name = "example-cert" + api_management_name = azurerm_api_management.test.name + resource_group_name = azurerm_resource_group.test.name + data = filebase64("testdata/keyvaultcert.pfx") + password = "" +} + +resource "azurerm_api_management_gateway_certificate_authority" "test" { + api_management_id = azurerm_api_management.test.id + certificate_name = azurerm_api_management_certificate.test.name + gateway_name = azurerm_api_management_gateway.test.name + is_trusted = false +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) +} diff --git a/internal/services/apimanagement/client/client.go b/internal/services/apimanagement/client/client.go index 12c09025c667..8fb138b155cb 100644 --- a/internal/services/apimanagement/client/client.go +++ b/internal/services/apimanagement/client/client.go @@ -6,43 +6,44 @@ import ( ) type Client struct { - ApiClient *apimanagement.APIClient - ApiDiagnosticClient *apimanagement.APIDiagnosticClient - ApiPoliciesClient *apimanagement.APIPolicyClient - ApiOperationsClient *apimanagement.APIOperationClient - ApiOperationPoliciesClient *apimanagement.APIOperationPolicyClient - ApiReleasesClient *apimanagement.APIReleaseClient - ApiSchemasClient *apimanagement.APISchemaClient - ApiVersionSetClient *apimanagement.APIVersionSetClient - AuthorizationServersClient *apimanagement.AuthorizationServerClient - BackendClient *apimanagement.BackendClient - CacheClient *apimanagement.CacheClient - CertificatesClient *apimanagement.CertificateClient - DiagnosticClient *apimanagement.DiagnosticClient - DeletedServicesClient *apimanagement.DeletedServicesClient - EmailTemplateClient *apimanagement.EmailTemplateClient - GatewayClient *apimanagement.GatewayClient - GatewayApisClient *apimanagement.GatewayAPIClient - GroupClient *apimanagement.GroupClient - GroupUsersClient *apimanagement.GroupUserClient - IdentityProviderClient *apimanagement.IdentityProviderClient - LoggerClient *apimanagement.LoggerClient - NamedValueClient *apimanagement.NamedValueClient - NotificationRecipientEmailClient *apimanagement.NotificationRecipientEmailClient - NotificationRecipientUserClient *apimanagement.NotificationRecipientUserClient - OpenIdConnectClient *apimanagement.OpenIDConnectProviderClient - PolicyClient *apimanagement.PolicyClient - ProductsClient *apimanagement.ProductClient - ProductApisClient *apimanagement.ProductAPIClient - ProductGroupsClient *apimanagement.ProductGroupClient - ProductPoliciesClient *apimanagement.ProductPolicyClient - ServiceClient *apimanagement.ServiceClient - SignInClient *apimanagement.SignInSettingsClient - SignUpClient *apimanagement.SignUpSettingsClient - SubscriptionsClient *apimanagement.SubscriptionClient - TagClient *apimanagement.TagClient - TenantAccessClient *apimanagement.TenantAccessClient - UsersClient *apimanagement.UserClient + ApiClient *apimanagement.APIClient + ApiDiagnosticClient *apimanagement.APIDiagnosticClient + ApiPoliciesClient *apimanagement.APIPolicyClient + ApiOperationsClient *apimanagement.APIOperationClient + ApiOperationPoliciesClient *apimanagement.APIOperationPolicyClient + ApiReleasesClient *apimanagement.APIReleaseClient + ApiSchemasClient *apimanagement.APISchemaClient + ApiVersionSetClient *apimanagement.APIVersionSetClient + AuthorizationServersClient *apimanagement.AuthorizationServerClient + BackendClient *apimanagement.BackendClient + CacheClient *apimanagement.CacheClient + CertificatesClient *apimanagement.CertificateClient + DiagnosticClient *apimanagement.DiagnosticClient + DeletedServicesClient *apimanagement.DeletedServicesClient + EmailTemplateClient *apimanagement.EmailTemplateClient + GatewayClient *apimanagement.GatewayClient + GatewayCertificateAuthorityClient *apimanagement.GatewayCertificateAuthorityClient + GatewayApisClient *apimanagement.GatewayAPIClient + GroupClient *apimanagement.GroupClient + GroupUsersClient *apimanagement.GroupUserClient + IdentityProviderClient *apimanagement.IdentityProviderClient + LoggerClient *apimanagement.LoggerClient + NamedValueClient *apimanagement.NamedValueClient + NotificationRecipientEmailClient *apimanagement.NotificationRecipientEmailClient + NotificationRecipientUserClient *apimanagement.NotificationRecipientUserClient + OpenIdConnectClient *apimanagement.OpenIDConnectProviderClient + PolicyClient *apimanagement.PolicyClient + ProductsClient *apimanagement.ProductClient + ProductApisClient *apimanagement.ProductAPIClient + ProductGroupsClient *apimanagement.ProductGroupClient + ProductPoliciesClient *apimanagement.ProductPolicyClient + ServiceClient *apimanagement.ServiceClient + SignInClient *apimanagement.SignInSettingsClient + SignUpClient *apimanagement.SignUpSettingsClient + SubscriptionsClient *apimanagement.SubscriptionClient + TagClient *apimanagement.TagClient + TenantAccessClient *apimanagement.TenantAccessClient + UsersClient *apimanagement.UserClient } func NewClient(o *common.ClientOptions) *Client { @@ -94,6 +95,9 @@ func NewClient(o *common.ClientOptions) *Client { gatewayClient := apimanagement.NewGatewayClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&gatewayClient.Client, o.ResourceManagerAuthorizer) + gatewayCertificateAuthorityClient := apimanagement.NewGatewayCertificateAuthorityClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&gatewayCertificateAuthorityClient.Client, o.ResourceManagerAuthorizer) + gatewayApisClient := apimanagement.NewGatewayAPIClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&gatewayApisClient.Client, o.ResourceManagerAuthorizer) @@ -158,42 +162,43 @@ func NewClient(o *common.ClientOptions) *Client { o.ConfigureClient(&usersClient.Client, o.ResourceManagerAuthorizer) return &Client{ - ApiClient: &apiClient, - ApiDiagnosticClient: &apiDiagnosticClient, - ApiPoliciesClient: &apiPoliciesClient, - ApiOperationsClient: &apiOperationsClient, - ApiOperationPoliciesClient: &apiOperationPoliciesClient, - ApiReleasesClient: &apiReleasesClient, - ApiSchemasClient: &apiSchemasClient, - ApiVersionSetClient: &apiVersionSetClient, - AuthorizationServersClient: &authorizationServersClient, - BackendClient: &backendClient, - CacheClient: &cacheClient, - CertificatesClient: &certificatesClient, - DiagnosticClient: &diagnosticClient, - DeletedServicesClient: &deletedServicesClient, - EmailTemplateClient: &emailTemplateClient, - GatewayClient: &gatewayClient, - GatewayApisClient: &gatewayApisClient, - GroupClient: &groupClient, - GroupUsersClient: &groupUsersClient, - IdentityProviderClient: &identityProviderClient, - LoggerClient: &loggerClient, - NamedValueClient: &namedValueClient, - NotificationRecipientEmailClient: ¬ificationRecipientEmailClient, - NotificationRecipientUserClient: ¬ificationRecipientUserClient, - OpenIdConnectClient: &openIdConnectClient, - PolicyClient: &policyClient, - ProductsClient: &productsClient, - ProductApisClient: &productApisClient, - ProductGroupsClient: &productGroupsClient, - ProductPoliciesClient: &productPoliciesClient, - ServiceClient: &serviceClient, - SignInClient: &signInClient, - SignUpClient: &signUpClient, - SubscriptionsClient: &subscriptionsClient, - TagClient: &tagClient, - TenantAccessClient: &tenantAccessClient, - UsersClient: &usersClient, + ApiClient: &apiClient, + ApiDiagnosticClient: &apiDiagnosticClient, + ApiPoliciesClient: &apiPoliciesClient, + ApiOperationsClient: &apiOperationsClient, + ApiOperationPoliciesClient: &apiOperationPoliciesClient, + ApiReleasesClient: &apiReleasesClient, + ApiSchemasClient: &apiSchemasClient, + ApiVersionSetClient: &apiVersionSetClient, + AuthorizationServersClient: &authorizationServersClient, + BackendClient: &backendClient, + CacheClient: &cacheClient, + CertificatesClient: &certificatesClient, + DiagnosticClient: &diagnosticClient, + DeletedServicesClient: &deletedServicesClient, + EmailTemplateClient: &emailTemplateClient, + GatewayClient: &gatewayClient, + GatewayCertificateAuthorityClient: &gatewayCertificateAuthorityClient, + GatewayApisClient: &gatewayApisClient, + GroupClient: &groupClient, + GroupUsersClient: &groupUsersClient, + IdentityProviderClient: &identityProviderClient, + LoggerClient: &loggerClient, + NamedValueClient: &namedValueClient, + NotificationRecipientEmailClient: ¬ificationRecipientEmailClient, + NotificationRecipientUserClient: ¬ificationRecipientUserClient, + OpenIdConnectClient: &openIdConnectClient, + PolicyClient: &policyClient, + ProductsClient: &productsClient, + ProductApisClient: &productApisClient, + ProductGroupsClient: &productGroupsClient, + ProductPoliciesClient: &productPoliciesClient, + ServiceClient: &serviceClient, + SignInClient: &signInClient, + SignUpClient: &signUpClient, + SubscriptionsClient: &subscriptionsClient, + TagClient: &tagClient, + TenantAccessClient: &tenantAccessClient, + UsersClient: &usersClient, } } diff --git a/internal/services/apimanagement/parse/gateway_certificate_authority.go b/internal/services/apimanagement/parse/gateway_certificate_authority.go new file mode 100644 index 000000000000..d8a8f530f78d --- /dev/null +++ b/internal/services/apimanagement/parse/gateway_certificate_authority.go @@ -0,0 +1,81 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type GatewayCertificateAuthorityId struct { + SubscriptionId string + ResourceGroup string + ServiceName string + GatewayName string + CertificateAuthorityName string +} + +func NewGatewayCertificateAuthorityID(subscriptionId, resourceGroup, serviceName, gatewayName, certificateAuthorityName string) GatewayCertificateAuthorityId { + return GatewayCertificateAuthorityId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + ServiceName: serviceName, + GatewayName: gatewayName, + CertificateAuthorityName: certificateAuthorityName, + } +} + +func (id GatewayCertificateAuthorityId) String() string { + segments := []string{ + fmt.Sprintf("Certificate Authority Name %q", id.CertificateAuthorityName), + fmt.Sprintf("Gateway Name %q", id.GatewayName), + fmt.Sprintf("Service Name %q", id.ServiceName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Gateway Certificate Authority", segmentsStr) +} + +func (id GatewayCertificateAuthorityId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.ApiManagement/service/%s/gateways/%s/certificateAuthorities/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.ServiceName, id.GatewayName, id.CertificateAuthorityName) +} + +// GatewayCertificateAuthorityID parses a GatewayCertificateAuthority ID into an GatewayCertificateAuthorityId struct +func GatewayCertificateAuthorityID(input string) (*GatewayCertificateAuthorityId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := GatewayCertificateAuthorityId{ + SubscriptionId: id.SubscriptionID, + ResourceGroup: id.ResourceGroup, + } + + if resourceId.SubscriptionId == "" { + return nil, fmt.Errorf("ID was missing the 'subscriptions' element") + } + + if resourceId.ResourceGroup == "" { + return nil, fmt.Errorf("ID was missing the 'resourceGroups' element") + } + + if resourceId.ServiceName, err = id.PopSegment("service"); err != nil { + return nil, err + } + if resourceId.GatewayName, err = id.PopSegment("gateways"); err != nil { + return nil, err + } + if resourceId.CertificateAuthorityName, err = id.PopSegment("certificateAuthorities"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/internal/services/apimanagement/parse/gateway_certificate_authority_test.go b/internal/services/apimanagement/parse/gateway_certificate_authority_test.go new file mode 100644 index 000000000000..ab5b9ab7fbf7 --- /dev/null +++ b/internal/services/apimanagement/parse/gateway_certificate_authority_test.go @@ -0,0 +1,144 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.Id = GatewayCertificateAuthorityId{} + +func TestGatewayCertificateAuthorityIDFormatter(t *testing.T) { + actual := NewGatewayCertificateAuthorityID("12345678-1234-9876-4563-123456789012", "resGroup1", "service1", "gateway1", "cert1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/certificateAuthorities/cert1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestGatewayCertificateAuthorityID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *GatewayCertificateAuthorityId + }{ + + { + // empty + Input: "", + Error: true, + }, + + { + // missing SubscriptionId + Input: "/", + Error: true, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Error: true, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Error: true, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Error: true, + }, + + { + // missing ServiceName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/", + Error: true, + }, + + { + // missing value for ServiceName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/", + Error: true, + }, + + { + // missing GatewayName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/", + Error: true, + }, + + { + // missing value for GatewayName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/", + Error: true, + }, + + { + // missing CertificateAuthorityName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/", + Error: true, + }, + + { + // missing value for CertificateAuthorityName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/certificateAuthorities/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/certificateAuthorities/cert1", + Expected: &GatewayCertificateAuthorityId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resGroup1", + ServiceName: "service1", + GatewayName: "gateway1", + CertificateAuthorityName: "cert1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.APIMANAGEMENT/SERVICE/SERVICE1/GATEWAYS/GATEWAY1/CERTIFICATEAUTHORITIES/CERT1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := GatewayCertificateAuthorityID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %s", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + if actual.ServiceName != v.Expected.ServiceName { + t.Fatalf("Expected %q but got %q for ServiceName", v.Expected.ServiceName, actual.ServiceName) + } + if actual.GatewayName != v.Expected.GatewayName { + t.Fatalf("Expected %q but got %q for GatewayName", v.Expected.GatewayName, actual.GatewayName) + } + if actual.CertificateAuthorityName != v.Expected.CertificateAuthorityName { + t.Fatalf("Expected %q but got %q for CertificateAuthorityName", v.Expected.CertificateAuthorityName, actual.CertificateAuthorityName) + } + } +} diff --git a/internal/services/apimanagement/registration.go b/internal/services/apimanagement/registration.go index 8e3672c4a859..272ef9c4e33b 100644 --- a/internal/services/apimanagement/registration.go +++ b/internal/services/apimanagement/registration.go @@ -41,46 +41,47 @@ func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource { // SupportedResources returns the supported Resources supported by this Service func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { return map[string]*pluginsdk.Resource{ - "azurerm_api_management": resourceApiManagementService(), - "azurerm_api_management_api": resourceApiManagementApi(), - "azurerm_api_management_api_diagnostic": resourceApiManagementApiDiagnostic(), - "azurerm_api_management_api_operation": resourceApiManagementApiOperation(), - "azurerm_api_management_api_operation_tag": resourceApiManagementApiOperationTag(), - "azurerm_api_management_api_operation_policy": resourceApiManagementApiOperationPolicy(), - "azurerm_api_management_api_policy": resourceApiManagementApiPolicy(), - "azurerm_api_management_api_release": resourceApiManagementApiRelease(), - "azurerm_api_management_api_schema": resourceApiManagementApiSchema(), - "azurerm_api_management_api_tag": resourceApiManagementApiTag(), - "azurerm_api_management_api_version_set": resourceApiManagementApiVersionSet(), - "azurerm_api_management_authorization_server": resourceApiManagementAuthorizationServer(), - "azurerm_api_management_backend": resourceApiManagementBackend(), - "azurerm_api_management_certificate": resourceApiManagementCertificate(), - "azurerm_api_management_custom_domain": resourceApiManagementCustomDomain(), - "azurerm_api_management_diagnostic": resourceApiManagementDiagnostic(), - "azurerm_api_management_email_template": resourceApiManagementEmailTemplate(), - "azurerm_api_management_gateway": resourceApiManagementGateway(), - "azurerm_api_management_gateway_api": resourceApiManagementGatewayApi(), - "azurerm_api_management_group": resourceApiManagementGroup(), - "azurerm_api_management_group_user": resourceApiManagementGroupUser(), - "azurerm_api_management_identity_provider_aad": resourceApiManagementIdentityProviderAAD(), - "azurerm_api_management_identity_provider_aadb2c": resourceArmApiManagementIdentityProviderAADB2C(), - "azurerm_api_management_identity_provider_facebook": resourceApiManagementIdentityProviderFacebook(), - "azurerm_api_management_identity_provider_google": resourceApiManagementIdentityProviderGoogle(), - "azurerm_api_management_identity_provider_microsoft": resourceApiManagementIdentityProviderMicrosoft(), - "azurerm_api_management_identity_provider_twitter": resourceApiManagementIdentityProviderTwitter(), - "azurerm_api_management_logger": resourceApiManagementLogger(), - "azurerm_api_management_named_value": resourceApiManagementNamedValue(), - "azurerm_api_management_openid_connect_provider": resourceApiManagementOpenIDConnectProvider(), - "azurerm_api_management_policy": resourceApiManagementPolicy(), - "azurerm_api_management_product": resourceApiManagementProduct(), - "azurerm_api_management_product_tag": resourceApiManagementProductTag(), - "azurerm_api_management_product_api": resourceApiManagementProductApi(), - "azurerm_api_management_product_group": resourceApiManagementProductGroup(), - "azurerm_api_management_product_policy": resourceApiManagementProductPolicy(), - "azurerm_api_management_redis_cache": resourceApiManagementRedisCache(), - "azurerm_api_management_subscription": resourceApiManagementSubscription(), - "azurerm_api_management_tag": resourceApiManagementTag(), - "azurerm_api_management_user": resourceApiManagementUser(), + "azurerm_api_management": resourceApiManagementService(), + "azurerm_api_management_api": resourceApiManagementApi(), + "azurerm_api_management_api_diagnostic": resourceApiManagementApiDiagnostic(), + "azurerm_api_management_api_operation": resourceApiManagementApiOperation(), + "azurerm_api_management_api_operation_tag": resourceApiManagementApiOperationTag(), + "azurerm_api_management_api_operation_policy": resourceApiManagementApiOperationPolicy(), + "azurerm_api_management_api_policy": resourceApiManagementApiPolicy(), + "azurerm_api_management_api_release": resourceApiManagementApiRelease(), + "azurerm_api_management_api_schema": resourceApiManagementApiSchema(), + "azurerm_api_management_api_tag": resourceApiManagementApiTag(), + "azurerm_api_management_api_version_set": resourceApiManagementApiVersionSet(), + "azurerm_api_management_authorization_server": resourceApiManagementAuthorizationServer(), + "azurerm_api_management_backend": resourceApiManagementBackend(), + "azurerm_api_management_certificate": resourceApiManagementCertificate(), + "azurerm_api_management_custom_domain": resourceApiManagementCustomDomain(), + "azurerm_api_management_diagnostic": resourceApiManagementDiagnostic(), + "azurerm_api_management_email_template": resourceApiManagementEmailTemplate(), + "azurerm_api_management_gateway": resourceApiManagementGateway(), + "azurerm_api_management_gateway_api": resourceApiManagementGatewayApi(), + "azurerm_api_management_gateway_certificate_authority": resourceApiManagementGatewayCertificateAuthority(), + "azurerm_api_management_group": resourceApiManagementGroup(), + "azurerm_api_management_group_user": resourceApiManagementGroupUser(), + "azurerm_api_management_identity_provider_aad": resourceApiManagementIdentityProviderAAD(), + "azurerm_api_management_identity_provider_aadb2c": resourceArmApiManagementIdentityProviderAADB2C(), + "azurerm_api_management_identity_provider_facebook": resourceApiManagementIdentityProviderFacebook(), + "azurerm_api_management_identity_provider_google": resourceApiManagementIdentityProviderGoogle(), + "azurerm_api_management_identity_provider_microsoft": resourceApiManagementIdentityProviderMicrosoft(), + "azurerm_api_management_identity_provider_twitter": resourceApiManagementIdentityProviderTwitter(), + "azurerm_api_management_logger": resourceApiManagementLogger(), + "azurerm_api_management_named_value": resourceApiManagementNamedValue(), + "azurerm_api_management_openid_connect_provider": resourceApiManagementOpenIDConnectProvider(), + "azurerm_api_management_policy": resourceApiManagementPolicy(), + "azurerm_api_management_product": resourceApiManagementProduct(), + "azurerm_api_management_product_tag": resourceApiManagementProductTag(), + "azurerm_api_management_product_api": resourceApiManagementProductApi(), + "azurerm_api_management_product_group": resourceApiManagementProductGroup(), + "azurerm_api_management_product_policy": resourceApiManagementProductPolicy(), + "azurerm_api_management_redis_cache": resourceApiManagementRedisCache(), + "azurerm_api_management_subscription": resourceApiManagementSubscription(), + "azurerm_api_management_tag": resourceApiManagementTag(), + "azurerm_api_management_user": resourceApiManagementUser(), } } diff --git a/internal/services/apimanagement/resourceids.go b/internal/services/apimanagement/resourceids.go index 457dc3c6cb84..a9cfc97f3952 100644 --- a/internal/services/apimanagement/resourceids.go +++ b/internal/services/apimanagement/resourceids.go @@ -38,3 +38,4 @@ package apimanagement //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=ApiRelease -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/apis/api1/releases/release1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=Tag -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/tags/tag1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=ApiTag -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/apis/api1/tags/tag1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=GatewayCertificateAuthority -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/certificateAuthorities/cert1 diff --git a/internal/services/apimanagement/validate/gateway_certificate_authority_id.go b/internal/services/apimanagement/validate/gateway_certificate_authority_id.go new file mode 100644 index 000000000000..f12688afa3fe --- /dev/null +++ b/internal/services/apimanagement/validate/gateway_certificate_authority_id.go @@ -0,0 +1,23 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + + "github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/parse" +) + +func GatewayCertificateAuthorityID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := parse.GatewayCertificateAuthorityID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/internal/services/apimanagement/validate/gateway_certificate_authority_id_test.go b/internal/services/apimanagement/validate/gateway_certificate_authority_id_test.go new file mode 100644 index 000000000000..a467e6f53c6f --- /dev/null +++ b/internal/services/apimanagement/validate/gateway_certificate_authority_id_test.go @@ -0,0 +1,100 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import "testing" + +func TestGatewayCertificateAuthorityID(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + + { + // empty + Input: "", + Valid: false, + }, + + { + // missing SubscriptionId + Input: "/", + Valid: false, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Valid: false, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Valid: false, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Valid: false, + }, + + { + // missing ServiceName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/", + Valid: false, + }, + + { + // missing value for ServiceName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/", + Valid: false, + }, + + { + // missing GatewayName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/", + Valid: false, + }, + + { + // missing value for GatewayName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/", + Valid: false, + }, + + { + // missing CertificateAuthorityName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/", + Valid: false, + }, + + { + // missing value for CertificateAuthorityName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/certificateAuthorities/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/certificateAuthorities/cert1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.APIMANAGEMENT/SERVICE/SERVICE1/GATEWAYS/GATEWAY1/CERTIFICATEAUTHORITIES/CERT1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := GatewayCertificateAuthorityID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/website/docs/r/api_management_gateway_certificate_authority.html.markdown b/website/docs/r/api_management_gateway_certificate_authority.html.markdown new file mode 100644 index 000000000000..f96150101190 --- /dev/null +++ b/website/docs/r/api_management_gateway_certificate_authority.html.markdown @@ -0,0 +1,91 @@ +--- +subcategory: "API Management" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_gateway_certificate_authority" +description: |- + Manages an API Management Gateway Certificate Authority. +--- + +# azurerm_api_management_gateway_certificate_authority + +Manages an API Management Gateway Certificate Authority. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_api_management" "example" { + name = "example-apim" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + publisher_name = "pub1" + publisher_email = "pub1@email.com" + sku_name = "Consumption_0" +} + +resource "azurerm_api_management_gateway" "example" { + name = "example-gateway" + api_management_id = azurerm_api_management.example.id + description = "Example API Management gateway" + + location_data { + name = "example name" + city = "example city" + district = "example district" + region = "example region" + } +} + +resource "azurerm_api_management_certificate" "example" { + name = "example-cert" + api_management_name = azurerm_api_management.example.name + resource_group_name = azurerm_resource_group.example.name + data = filebase64("example.pfx") +} + +resource "azurerm_api_management_gateway_certificate_authority" "example" { + api_management_id = azurerm_api_management.example.id + certificate_name = azurerm_api_management_certificate.example.name + gateway_name = azurerm_api_management_gateway.example.name + is_trusted = true +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `api_management_id` - (Required) The ID of the API Management Service. Changing this forces a new resource to be created. + +* `certificate_name` - (Required) The name of the API Management Certificate. Changing this forces a new resource to be created. + +* `gateway_name` - (Required) The name of the API Management Gateway. Changing this forces a new resource to be created. + +* `is_trusted` - (Optional) Whether the API Management Gateway Certificate Authority is trusted. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the API Management Gateway Certificate Authority. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the API Management Gateway Certificate Authority. +* `read` - (Defaults to 5 minutes) Used when retrieving the API Management Gateway Certificate Authority. +* `update` - (Defaults to 30 minutes) Used when updating the API Management Gateway Certificate Authority. +* `delete` - (Defaults to 30 minutes) Used when deleting the API Management Gateway Certificate Authority. + +## Import + +API Management Gateway Certificate Authority can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_gateway_certificate_authority.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.ApiManagement/service/service1/gateways/gateway1/certificateAuthorities/cert1 +```