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

App Service: Adding Import-Time Validation #5107

Merged
merged 9 commits into from
Dec 10, 2019
10 changes: 4 additions & 6 deletions azurerm/helpers/azure/app_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -1320,12 +1320,11 @@ func ExpandAppServiceLogs(input interface{}) web.SiteLogsConfigProperties {
return logs
}

func ExpandAppServiceIdentity(d *schema.ResourceData) *web.ManagedServiceIdentity {
identities := d.Get("identity").([]interface{})
if len(identities) == 0 {
func ExpandAppServiceIdentity(input []interface{}) *web.ManagedServiceIdentity {
if len(input) == 0 {
return nil
}
identity := identities[0].(map[string]interface{})
identity := input[0].(map[string]interface{})
identityType := web.ManagedServiceIdentityType(identity["type"].(string))

identityIds := make(map[string]*web.ManagedServiceIdentityUserAssignedIdentitiesValue)
Expand Down Expand Up @@ -1657,8 +1656,7 @@ func FlattenAppServiceSiteConfig(input *web.SiteConfig) []interface{} {
return append(results, result)
}

func ExpandAppServiceStorageAccounts(d *schema.ResourceData) map[string]*web.AzureStorageInfoValue {
input := d.Get("storage_account").(*schema.Set).List()
func ExpandAppServiceStorageAccounts(input []interface{}) map[string]*web.AzureStorageInfoValue {
output := make(map[string]*web.AzureStorageInfoValue, len(input))

for _, v := range input {
Expand Down
53 changes: 53 additions & 0 deletions azurerm/internal/services/web/app_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package web

import (
"fmt"

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

type AppServiceResourceID struct {
Base azure.ResourceID

Name string
}

func ParseAppServiceID(input string) (*AppServiceResourceID, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, fmt.Errorf("[ERROR] Unable to parse App Service ID %q: %+v", input, err)
}

group := AppServiceResourceID{
Base: *id,
Name: id.Path["sites"],
}

if group.Name == "" {
return nil, fmt.Errorf("ID was missing the `sites` element")
}

pathWithoutElements := group.Base.Path
delete(pathWithoutElements, "sites")
if len(pathWithoutElements) != 0 {
return nil, fmt.Errorf("ID contained more segments than a Resource ID requires: %q", input)
}

return &group, nil
}

// ValidateAppServiceID validates that the specified ID is a valid App Service ID
func ValidateAppServiceID(i interface{}, k string) (warnings []string, errors []error) {
v, ok := i.(string)
if !ok {
errors = append(errors, fmt.Errorf("expected type of %q to be string", k))
return
}

if _, err := ParseAppServiceID(v); err != nil {
errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err))
return
}

return warnings, errors
}
53 changes: 53 additions & 0 deletions azurerm/internal/services/web/app_service_certificate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package web

import (
"fmt"

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

type AppServiceCertificateResourceID struct {
Base azure.ResourceID

Name string
}

func ParseAppServiceCertificateID(input string) (*AppServiceCertificateResourceID, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, fmt.Errorf("[ERROR] Unable to parse App Service Certificate ID %q: %+v", input, err)
}

group := AppServiceCertificateResourceID{
Base: *id,
Name: id.Path["certificates"],
}

if group.Name == "" {
return nil, fmt.Errorf("ID was missing the `certificates` element")
}

pathWithoutElements := group.Base.Path
delete(pathWithoutElements, "certificates")
if len(pathWithoutElements) != 0 {
return nil, fmt.Errorf("ID contained more segments than a Resource ID requires: %q", input)
}

return &group, nil
}

// ValidateAppServiceCertificateID validates that the specified ID is a valid App Service Certificate ID
func ValidateAppServiceCertificateID(i interface{}, k string) (warnings []string, errors []error) {
v, ok := i.(string)
if !ok {
errors = append(errors, fmt.Errorf("expected type of %q to be string", k))
return
}

if _, err := ParseAppServiceCertificateID(v); err != nil {
errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err))
return
}

return warnings, errors
}
37 changes: 37 additions & 0 deletions azurerm/internal/services/web/app_service_certificate_order.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package web

import (
"fmt"

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

type AppServiceCertificateOrderResourceID struct {
Base azure.ResourceID

Name string
}

func ParseAppServiceCertificateOrderID(input string) (*AppServiceCertificateOrderResourceID, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, fmt.Errorf("[ERROR] Unable to parse App Service Certificate Order ID %q: %+v", input, err)
}

group := AppServiceCertificateOrderResourceID{
Base: *id,
Name: id.Path["certificateOrders"],
}

if group.Name == "" {
return nil, fmt.Errorf("ID was missing the `certificateOrders` element")
}

pathWithoutElements := group.Base.Path
delete(pathWithoutElements, "certificateOrders")
if len(pathWithoutElements) != 0 {
return nil, fmt.Errorf("ID contained more segments than a Resource ID requires: %q", input)
}

return &group, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package web

import (
"testing"

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

func TestParseAppServiceCertificateOrder(t *testing.T) {
testData := []struct {
Name string
Input string
Expected *AppServiceCertificateOrderResourceID
}{
{
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 Sites Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/sites/",
Expected: nil,
},
{
Name: "App Service Resource ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/sites/site1",
Expected: nil,
},
{
Name: "App Service Certificate Order Resource ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/certificateOrders/order1",
Expected: &AppServiceCertificateOrderResourceID{
Name: "order1",
Base: azure.ResourceID{
ResourceGroup: "mygroup1",
},
},
},
{
Name: "Wrong Casing",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/CertificateOrders/order1",
Expected: nil,
},
}

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

actual, err := ParseAppServiceCertificateOrderID(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.Base.ResourceGroup != v.Expected.Base.ResourceGroup {
t.Fatalf("Expected %q but got %q for Resource Group", v.Expected.Base.ResourceGroup, actual.Base.ResourceGroup)
}
}
}
128 changes: 128 additions & 0 deletions azurerm/internal/services/web/app_service_certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package web

import (
"testing"

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

func TestParseAppServiceCertificate(t *testing.T) {
testData := []struct {
Name string
Input string
Expected *AppServiceCertificateResourceID
}{
{
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 Sites Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/sites/",
Expected: nil,
},
{
Name: "App Service Resource ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/sites/site1",
Expected: nil,
},
{
Name: "App Service Certificate Resource ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/certificates/cert1",
Expected: &AppServiceCertificateResourceID{
Name: "cert1",
Base: azure.ResourceID{
ResourceGroup: "mygroup1",
},
},
},
{
Name: "Wrong Casing",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/Certificates/cert1",
Expected: nil,
},
}

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

actual, err := ParseAppServiceCertificateID(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.Base.ResourceGroup != v.Expected.Base.ResourceGroup {
t.Fatalf("Expected %q but got %q for Resource Group", v.Expected.Base.ResourceGroup, actual.Base.ResourceGroup)
}
}
}

func TestValidateAppServiceCertificateID(t *testing.T) {
cases := []struct {
ID string
Valid bool
}{
{
ID: "",
Valid: false,
},
{
ID: "nonsense",
Valid: false,
},
{
ID: "/subscriptions/00000000-0000-0000-0000-000000000000",
Valid: false,
},
{
ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo",
Valid: false,
},
{
ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/providers/Microsoft.Web",
Valid: false,
},
{
ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/providers/Microsoft.Web/certificates/cert1",
Valid: true,
},
{
ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/providers/Microsoft.Web/Certificates/cert1",
Valid: false,
},
}

for _, tc := range cases {
t.Logf("[DEBUG] Testing Value %q", tc.ID)
_, errors := ValidateAppServiceCertificateID(tc.ID, "test")
valid := len(errors) == 0

if tc.Valid != valid {
t.Fatalf("Expected %t but got %t", tc.Valid, valid)
}
}
}
Loading