Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Resource: azurerm_api_management_api_diagnostic #7873

Merged
merged 17 commits into from
Sep 9, 2020
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion azurerm/helpers/azure/resourceid.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,5 @@ func (id *ResourceID) ValidateNoEmptySegments(sourceId string) error {
return nil
}

return fmt.Errorf("ID contained more segments than required: %q", sourceId)
return fmt.Errorf("ID contained more segments than required: %q, %v", sourceId, id.Path)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package apimanagement

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2019-12-01/apimanagement"
"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/tf"
helpersvalidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/apimanagement/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/apimanagement/validate"
azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmApiManagementApiDiagnostic() *schema.Resource {
return &schema.Resource{
Create: resourceArmApiManagementApiDiagnosticCreateUpdate,
Read: resourceArmApiManagementApiDiagnosticRead,
Update: resourceArmApiManagementApiDiagnosticCreateUpdate,
Delete: resourceArmApiManagementApiDiagnosticDelete,

Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error {
_, err := parse.ApiManagementApiDiagnosticID(id)
return err
}),

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{
"identifier": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
"applicationinsights",
"azuremonitor",
}, false),
},

"resource_group_name": azure.SchemaResourceGroupName(),

"api_management_name": azure.SchemaApiManagementName(),

"api_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: helpersvalidate.ApiManagementApiName,
},

"api_management_logger_id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validate.ApiManagementLoggerID,
},
},
}
}

func resourceArmApiManagementApiDiagnosticCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).ApiManagement.ApiDiagnosticClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

diagnosticId := d.Get("identifier").(string)
resourceGroup := d.Get("resource_group_name").(string)
serviceName := d.Get("api_management_name").(string)
apiName := d.Get("api_name").(string)

if d.IsNewResource() {
existing, err := client.Get(ctx, resourceGroup, serviceName, apiName, diagnosticId)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for presence of existing Diagnostic %q (Resource Group %q / API Management Service %q / API %q): %s", diagnosticId, resourceGroup, serviceName, apiName, err)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_api_management_api_diagnostic", *existing.ID)
}
}

parameters := apimanagement.DiagnosticContract{
DiagnosticContractProperties: &apimanagement.DiagnosticContractProperties{
LoggerID: utils.String(d.Get("api_management_logger_id").(string)),
},
}

if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, apiName, diagnosticId, parameters, ""); err != nil {
return fmt.Errorf("creating or updating Diagnostic %q (Resource Group %q / API Management Service %q / API %q): %+v", diagnosticId, resourceGroup, serviceName, apiName, err)
}

resp, err := client.Get(ctx, resourceGroup, serviceName, apiName, diagnosticId)
if err != nil {
return fmt.Errorf("retrieving Diagnostic %q (Resource Group %q / API Management Service %q / API %q): %+v", diagnosticId, resourceGroup, serviceName, apiName, err)
}
if resp.ID == nil || *resp.ID == "" {
return fmt.Errorf("reading ID for Diagnostic %q (Resource Group %q / API Management Service %q / API %q): ID is empty", diagnosticId, resourceGroup, serviceName, apiName)
}
d.SetId(*resp.ID)

return resourceArmApiManagementApiDiagnosticRead(d, meta)
}

func resourceArmApiManagementApiDiagnosticRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).ApiManagement.ApiDiagnosticClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

diagnosticId, err := parse.ApiManagementApiDiagnosticID(d.Id())
if err != nil {
return err
}

resp, err := client.Get(ctx, diagnosticId.ResourceGroup, diagnosticId.ServiceName, diagnosticId.ApiName, diagnosticId.Name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[DEBUG] Diagnostic %q (Resource Group %q / API Management Service %q / API %q) was not found - removing from state!", diagnosticId.Name, diagnosticId.ResourceGroup, diagnosticId.ServiceName, diagnosticId.ApiName)
d.SetId("")
return nil
}

return fmt.Errorf("making Read request for Diagnostic %q (Resource Group %q / API Management Service %q / API %q): %+v", diagnosticId.Name, diagnosticId.ResourceGroup, diagnosticId.ServiceName, diagnosticId.ApiName, err)
}

d.Set("api_name", diagnosticId.ApiName)
d.Set("identifier", resp.Name)
d.Set("resource_group_name", diagnosticId.ResourceGroup)
d.Set("api_management_name", diagnosticId.ServiceName)
if props := resp.DiagnosticContractProperties; props != nil {
d.Set("api_management_logger_id", props.LoggerID)
}

return nil
}

func resourceArmApiManagementApiDiagnosticDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).ApiManagement.ApiDiagnosticClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

diagnosticId, err := parse.ApiManagementApiDiagnosticID(d.Id())
if err != nil {
return err
}

if resp, err := client.Delete(ctx, diagnosticId.ResourceGroup, diagnosticId.ServiceName, diagnosticId.ApiName, diagnosticId.Name, ""); err != nil {
if !utils.ResponseWasNotFound(resp) {
return fmt.Errorf("deleting Diagnostic %q (Resource Group %q / API Management Service %q / API %q): %+v", diagnosticId.Name, diagnosticId.ResourceGroup, diagnosticId.ServiceName, diagnosticId.ApiName, err)
}
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func resourceArmApiManagementDiagnostic() *schema.Resource {
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
"applicationinsights",
"azuremonitor",
}, false),
},

Expand Down
5 changes: 5 additions & 0 deletions azurerm/internal/services/apimanagement/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

type Client struct {
ApiClient *apimanagement.APIClient
ApiDiagnosticClient *apimanagement.APIDiagnosticClient
sirlatrom marked this conversation as resolved.
Show resolved Hide resolved
ApiPoliciesClient *apimanagement.APIPolicyClient
ApiOperationsClient *apimanagement.APIOperationClient
ApiOperationPoliciesClient *apimanagement.APIOperationPolicyClient
Expand Down Expand Up @@ -38,6 +39,9 @@ func NewClient(o *common.ClientOptions) *Client {
apiClient := apimanagement.NewAPIClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&apiClient.Client, o.ResourceManagerAuthorizer)

apiDiagnosticClient := apimanagement.NewAPIDiagnosticClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&apiDiagnosticClient.Client, o.ResourceManagerAuthorizer)

apiPoliciesClient := apimanagement.NewAPIPolicyClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&apiPoliciesClient.Client, o.ResourceManagerAuthorizer)

Expand Down Expand Up @@ -115,6 +119,7 @@ func NewClient(o *common.ClientOptions) *Client {

return &Client{
ApiClient: &apiClient,
ApiDiagnosticClient: &apiDiagnosticClient,
ApiPoliciesClient: &apiPoliciesClient,
ApiOperationsClient: &apiOperationsClient,
ApiOperationPoliciesClient: &apiOperationPoliciesClient,
Expand Down
43 changes: 43 additions & 0 deletions azurerm/internal/services/apimanagement/parse/api_diagnostic_id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package parse

import (
"fmt"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
)

type ApiManagementApiDiagnosticId struct {
ResourceGroup string
ServiceName string
ApiName string
Name string
}

func ApiManagementApiDiagnosticID(input string) (*ApiManagementApiDiagnosticId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, fmt.Errorf("parsing Api Management Diagnostic ID %q: %+v", input, err)
}

diagnostic := ApiManagementApiDiagnosticId{
ResourceGroup: id.ResourceGroup,
}

if diagnostic.ServiceName, err = id.PopSegment("service"); err != nil {
return nil, err
}

if diagnostic.ApiName, err = id.PopSegment("apis"); err != nil {
return nil, err
}

if diagnostic.Name, err = id.PopSegment("diagnostics"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &diagnostic, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package parse

import "testing"

func TestApiManagementApiDiagnosticID(t *testing.T) {
testData := []struct {
Name string
Input string
Expected *ApiManagementApiDiagnosticId
}{
{
Name: "Empty",
Input: "",
Expected: nil,
},
{
Name: "No Resource Groups Segment",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000",
Expected: nil,
},
{
Name: "No Resource Groups Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/",
Expected: nil,
},
{
Name: "Resource Group ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/",
Expected: nil,
},
{
Name: "Missing Service Name",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/",
Expected: nil,
},
{
Name: "Missing APIs",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1",
Expected: nil,
},
{
Name: "Missing APIs Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/apis",
Expected: nil,
},
{
Name: "Missing Diagnostics",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/apis/api1",
Expected: nil,
},
{
Name: "Missing Diagnostics Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/apis/api1/diagnostics",
Expected: nil,
},
{
Name: "Diagnostic ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/apis/api1/diagnostics/applicationinsights",
Expected: &ApiManagementApiDiagnosticId{
Name: "applicationinsights",
ApiName: "api1",
ServiceName: "service1",
ResourceGroup: "resGroup1",
},
},
{
Name: "Wrong Casing",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.ApiManagement/service/service1/APIs/api1/diagnostics/applicationinsights",
Expected: nil,
},
{
Name: "From ACC test",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/acctestRG-200904094049117016/providers/Microsoft.ApiManagement/service/acctestAM-200904094049117016/apis/acctestAMA-200904094049117016/diagnostics/applicationinsights",
Expected: &ApiManagementApiDiagnosticId{
Name: "applicationinsights",
ApiName: "acctestAMA-200904094049117016",
ServiceName: "acctestAM-200904094049117016",
ResourceGroup: "acctestRG-200904094049117016",
},
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Name)

actual, err := ApiManagementApiDiagnosticID(v.Input)
if err != nil {
if v.Expected == nil {
continue
}

t.Fatalf("Expected a value but got an error: %s", err)
}

if actual.Name != v.Expected.Name {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}

if actual.ApiName != v.Expected.ApiName {
t.Fatalf("Expected %q but got %q for API Name", v.Expected.ApiName, actual.ApiName)
}

if actual.ServiceName != v.Expected.ServiceName {
t.Fatalf("Expected %q but got %q for Service Name", v.Expected.Name, actual.Name)
}

if actual.ResourceGroup != v.Expected.ResourceGroup {
t.Fatalf("Expected %q but got %q for Resource Group", v.Expected.ResourceGroup, actual.ResourceGroup)
}
}
}
1 change: 1 addition & 0 deletions azurerm/internal/services/apimanagement/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func (r Registration) SupportedResources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_api_management": resourceArmApiManagementService(),
"azurerm_api_management_api": resourceArmApiManagementApi(),
"azurerm_api_management_api_diagnostic": resourceArmApiManagementApiDiagnostic(),
"azurerm_api_management_api_operation": resourceArmApiManagementApiOperation(),
"azurerm_api_management_api_operation_policy": resourceArmApiManagementApiOperationPolicy(),
"azurerm_api_management_api_policy": resourceArmApiManagementApiPolicy(),
Expand Down
Loading