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: api_management_api #2073

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
97cde54
Added basic support for API Management API
torresdal Oct 9, 2018
19d3895
Cleaned up unused schema elements of API Management API
torresdal Oct 11, 2018
ad9c3b1
Added docs for api_management_api resource
torresdal Oct 12, 2018
091bed3
Added missing fields to schema
torresdal Oct 12, 2018
b7be791
Cleaned up, tested and added data to schema fields
torresdal Oct 12, 2018
9ada8fe
Cleanup:
torresdal Oct 13, 2018
dfe6909
Updated docs for API Management API resource and data to reflect rece…
torresdal Oct 13, 2018
bf8f2d7
Fixed sidebar issues in doc
torresdal Oct 13, 2018
469322b
Removed display_name option - name works for both
torresdal Oct 13, 2018
74f443f
Add simple test for data source
torresdal Oct 13, 2018
f2b49b6
Add simple test for API Management API
torresdal Oct 13, 2018
b5e03aa
Testing:
torresdal Oct 13, 2018
c523a99
Fixed error found in integration tests:
torresdal Oct 13, 2018
e4ac886
Check for generated name in test. Use local swagger file instead of url.
torresdal Oct 13, 2018
22fef3c
Output APIM Service name on error
tombuildsstuff Oct 23, 2018
9726bb1
Output APIM Service name on error
tombuildsstuff Oct 23, 2018
054d311
Added debug line when APIM API does not exist
tombuildsstuff Oct 23, 2018
dffbd80
Grammar improvement
tombuildsstuff Oct 23, 2018
fd6f773
Grammar improvement
tombuildsstuff Oct 23, 2018
23329de
Grammar improvement
tombuildsstuff Oct 23, 2018
b8450e6
Group together to match other registrations
torresdal Oct 23, 2018
bdac7e8
Fixed and made changes according to review
torresdal Oct 25, 2018
2b1ae0e
Fixed failing test by removing Computed on revision for api-managemen…
torresdal Oct 25, 2018
f46d630
Replaced ip's with int.test url in example wsdl using for int.test
torresdal Oct 25, 2018
ff71c76
Fixed issues after running int.tests.
torresdal Oct 26, 2018
2e0cf0c
Don't mix name and display_name, seperate them as in azure api
torresdal Nov 22, 2018
04815da
Simplyfied create/update with/without import api
torresdal Nov 22, 2018
86a2ac6
Documented display name. Removed defaults for header and query
torresdal Nov 22, 2018
671d344
Fixed empty return statements
torresdal Nov 22, 2018
55753ef
Removed unused props var
torresdal Nov 22, 2018
67cecd0
Proper fmt
torresdal Nov 22, 2018
a00e099
Fixed issue where display_name is a mandatory value for the Azure API
torresdal Nov 23, 2018
6849e82
Added missing display_name to int. tests
torresdal Nov 23, 2018
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
6 changes: 6 additions & 0 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ type ArmClient struct {

// API Management
apiManagementServiceClient apimanagement.ServiceClient
apiManagementApiClient apimanagement.APIClient

// Application Insights
appInsightsClient appinsights.ComponentsClient
Expand Down Expand Up @@ -458,6 +459,11 @@ func (c *ArmClient) registerApiManagementServiceClients(endpoint, subscriptionId
ams := apimanagement.NewServiceClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&ams.Client, auth)
c.apiManagementServiceClient = ams

api := apimanagement.NewAPIClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&api.Client, auth)
c.apiManagementApiClient = api
torresdal marked this conversation as resolved.
Show resolved Hide resolved

}

func (c *ArmClient) registerAppInsightsClients(endpoint, subscriptionId string, auth autorest.Authorizer) {
Expand Down
151 changes: 151 additions & 0 deletions azurerm/data_source_api_management_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package azurerm

import (
"fmt"

"github.com/Azure/azure-sdk-for-go/services/preview/apimanagement/mgmt/2018-06-01-preview/apimanagement"
"github.com/hashicorp/terraform/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceApiManagementApi() *schema.Resource {
return &schema.Resource{
Read: dataSourceApiManagementApiRead,

Schema: map[string]*schema.Schema{
"service_name": {
Type: schema.TypeString,
Required: true,
},

"name": {
Type: schema.TypeString,
Required: true,
},

"resource_group_name": resourceGroupNameForDataSourceSchema(),

"location": locationForDataSourceSchema(),

"path": {
Type: schema.TypeString,
Computed: true,
},

"service_url": {
Type: schema.TypeString,
Computed: true,
},

"description": {
Type: schema.TypeString,
Computed: true,
},

"protocols": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Computed: true,
},

"subscription_key_parameter_names": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"header": {
Type: schema.TypeString,
Computed: true,
},
"query": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"soap_pass_through": {
Type: schema.TypeBool,
Computed: true,
},

"revision": {
Type: schema.TypeInt,
Optional: true,
Default: nil,
Computed: true,
},

"api_version": {
Type: schema.TypeString,
Computed: true,
},

"api_version_set_id": {
Type: schema.TypeString,
Computed: true,
},

"is_current": {
Type: schema.TypeBool,
Computed: true,
},

"is_online": {
Type: schema.TypeBool,
Computed: true,
},
},
}
}

func dataSourceApiManagementApiRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).apiManagementApiClient
ctx := meta.(*ArmClient).StopContext

resGroup := d.Get("resource_group_name").(string)
serviceName := d.Get("service_name").(string)
name := d.Get("name").(string)
revision := int32(d.Get("revision").(int))

apiId := fmt.Sprintf("%s;rev=%d", name, revision)

resp, err := client.Get(ctx, resGroup, serviceName, apiId)

if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("API Management API %q (Service %q / Resource Group %q) was not found", name, serviceName, resGroup)
}

return fmt.Errorf("Error retrieving API Management API %q (Service %q / Resource Group %q): %+v", name, serviceName, resGroup, err)
}

d.SetId(*resp.ID)

d.Set("name", name)
d.Set("service_name", serviceName)
d.Set("resource_group_name", resGroup)

if props := resp.APIContractProperties; props != nil {
d.Set("service_url", props.ServiceURL)
d.Set("path", props.Path)
d.Set("description", props.Description)
d.Set("revision", props.APIRevision)
d.Set("api_version", props.APIVersion)
d.Set("api_version_set_id", props.APIVersionSetID)
d.Set("is_current", props.IsCurrent)
d.Set("is_online", props.IsOnline)
d.Set("protocols", props.Protocols)
d.Set("soap_pass_through", string(props.APIType) == string(apimanagement.SoapPassThrough))
torresdal marked this conversation as resolved.
Show resolved Hide resolved

if err := d.Set("subscription_key_parameter_names", flattenApiManagementApiSubscriptionKeyParamNames(props.SubscriptionKeyParameterNames)); err != nil {
return fmt.Errorf("Error setting `subscription_key_parameter_names`: %+v", err)
}
}

return nil
}
84 changes: 84 additions & 0 deletions azurerm/data_source_api_management_api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package azurerm

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceAzureRMApiManagementApi_basic(t *testing.T) {
dataSourceName := "data.azurerm_api_management_api.test"
rInt := acctest.RandInt()
location := testLocation()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceApiManagementApi_basic(rInt, location),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "is_current", "true"),
resource.TestCheckResourceAttr(dataSourceName, "is_online", "false"),
resource.TestCheckResourceAttr(dataSourceName, "name", fmt.Sprintf("acctestAMA-%d", rInt)),
resource.TestCheckResourceAttr(dataSourceName, "path", "api1"),
resource.TestCheckResourceAttr(dataSourceName, "protocols.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "protocols.0", "https"),
resource.TestCheckResourceAttr(dataSourceName, "service_name", fmt.Sprintf("acctestAM-%d", rInt)),
resource.TestCheckResourceAttr(dataSourceName, "soap_pass_through", "false"),
resource.TestCheckResourceAttr(dataSourceName, "subscription_key_parameter_names.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "subscription_key_parameter_names.0.header", "Ocp-Apim-Subscription-Key"),
resource.TestCheckResourceAttr(dataSourceName, "subscription_key_parameter_names.0.query", "subscription-key"),
resource.TestCheckResourceAttr(dataSourceName, "api_version", ""),
resource.TestCheckResourceAttr(dataSourceName, "api_version_set_id", ""),
),
},
},
})
}

func testAccDataSourceApiManagementApi_basic(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "amtestRG-%d"
location = "%s"
}

resource "azurerm_api_management" "test" {
name = "acctestAM-%d"
publisher_name = "pub1"
publisher_email = "[email protected]"

sku {
name = "Developer"
capacity = 1
}

location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
}

resource "azurerm_api_management_api" "test" {
name = "acctestAMA-%d"
display_name = "api1"
service_name = "${azurerm_api_management.test.name}"
path = "api1"
protocols = ["https"]

import {
content_value = "${file("testdata/api_management_api_swagger.json")}"
content_format = "swagger-json"
}

resource_group_name = "${azurerm_resource_group.test.name}"
}

data "azurerm_api_management_api" "test" {
name = "${azurerm_api_management_api.test.name}"
service_name = "${azurerm_api_management.test.name}"
resource_group_name = "${azurerm_api_management_api.test.resource_group_name}"
}
`, rInt, location, rInt, rInt)
torresdal marked this conversation as resolved.
Show resolved Hide resolved
}
18 changes: 18 additions & 0 deletions azurerm/helpers/validate/api_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,21 @@ func ApiManagementServicePublisherEmail(v interface{}, k string) (warnings []str

return warnings, errors
}

func ApiManagementApiName(v interface{}, k string) (ws []string, es []error) {
value := v.(string)

if matched := regexp.MustCompile(`^[^*#&+]{1,256}$`).Match([]byte(value)); !matched {
es = append(es, fmt.Errorf("%q may only be up to 256 characters in length and not include the characters `*`, `#`, `&` or `+`", k))
}
return ws, es
}

func ApiManagementApiPath(v interface{}, k string) (ws []string, es []error) {
value := v.(string)

if matched := regexp.MustCompile(`^[\w][\w-/.]+[\w-]$`).Match([]byte(value)); !matched {
es = append(es, fmt.Errorf("%q may only be up to 256 characters in length, not start or end with `/` and only contain valid url characters", k))
}
return ws, es
}
84 changes: 84 additions & 0 deletions azurerm/helpers/validate/api_management_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,87 @@ func TestAzureRMApiManagementPublisherName_validation(t *testing.T) {
}
}
}

func TestAzureRMApiManagementApiPath_validation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{
Value: "",
ErrCount: 1,
},
{
Value: "/",
ErrCount: 1,
},
{
Value: "/abc",
ErrCount: 1,
},
{
Value: "api1",
ErrCount: 0,
},
{
Value: "api1/",
ErrCount: 1,
},
{
Value: "api1/sub",
ErrCount: 0,
},
}

for _, tc := range cases {
_, errors := ApiManagementApiPath(tc.Value, "azurerm_api_management_api")

if len(errors) != tc.ErrCount {
t.Fatalf("Expected the Api Management Api Path to trigger a validation error for '%s'", tc.Value)
}
}
}

func TestAzureRMApiManagementApiName_validation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{
Value: "",
ErrCount: 1,
},
{
Value: "asdf+",
ErrCount: 1,
},
{
Value: "adsf&",
ErrCount: 1,
},
{
Value: "asdfasdf#",
ErrCount: 1,
},
{
Value: "asdf*",
ErrCount: 1,
},
{
Value: "alksdjl asdlfj laskdjflkjasdlfj lasdf",
ErrCount: 0,
},
{
Value: "ddlfj laskdjflkjasdlfj lasdf alksdjflka sdlfjalsdjflajdsflkjasd alsdkjflaksjd flajksdl fjasldkjf lasjdflkajs dfljas ldfjj aljds fljasldkf jalsdjf lakjsdf ljasldkfjalskdjf lakjsd flkajs dlfkja lsdkjf laksdjf lkasjdf lkajsdlfk jasldkfj asldkjfal ksdjf laksjdf",
ErrCount: 1,
},
}

for _, tc := range cases {
_, errors := ApiManagementApiName(tc.Value, "azurerm_api_management_api")

if len(errors) != tc.ErrCount {
t.Fatalf("Expected the Api Management Api Name to trigger a validation error for '%s'", tc.Value)
}
}
}
2 changes: 2 additions & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_azuread_application": dataSourceArmAzureADApplication(),
"azurerm_azuread_service_principal": dataSourceArmActiveDirectoryServicePrincipal(),
"azurerm_api_management": dataSourceApiManagementService(),
"azurerm_api_management_api": dataSourceApiManagementApi(),
"azurerm_application_security_group": dataSourceArmApplicationSecurityGroup(),
"azurerm_app_service": dataSourceArmAppService(),
"azurerm_app_service_plan": dataSourceAppServicePlan(),
Expand Down Expand Up @@ -130,6 +131,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_azuread_service_principal": resourceArmActiveDirectoryServicePrincipal(),
"azurerm_azuread_service_principal_password": resourceArmActiveDirectoryServicePrincipalPassword(),
"azurerm_api_management": resourceArmApiManagementService(),
"azurerm_api_management_api": resourceArmApiManagementApi(),
"azurerm_application_gateway": resourceArmApplicationGateway(),
"azurerm_application_insights": resourceArmApplicationInsights(),
"azurerm_application_security_group": resourceArmApplicationSecurityGroup(),
Expand Down
Loading