From a9ebab23e77e904464ce0c6b52c1c2208ab3bfd4 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Fri, 3 Jun 2022 14:08:45 +0200 Subject: [PATCH 1/5] CDN: generating the Resource ID Parsers/Validators for Rule Sets/Rules --- .../services/cdn/parse/front_door_rule.go | 149 +++++++++ .../services/cdn/parse/front_door_rule_set.go | 131 ++++++++ .../cdn/parse/front_door_rule_set_test.go | 264 ++++++++++++++++ .../cdn/parse/front_door_rule_test.go | 299 ++++++++++++++++++ internal/services/cdn/resourceids.go | 2 + .../cdn/validate/front_door_rule_id.go | 23 ++ .../cdn/validate/front_door_rule_id_test.go | 100 ++++++ .../cdn/validate/front_door_rule_name.go | 20 ++ .../cdn/validate/front_door_rule_name_test.go | 74 +++++ .../cdn/validate/front_door_rule_set_id.go | 23 ++ .../validate/front_door_rule_set_id_test.go | 88 ++++++ .../cdn/validate/front_door_rule_set_name.go | 20 ++ .../validate/front_door_rule_set_name_test.go | 74 +++++ 13 files changed, 1267 insertions(+) create mode 100644 internal/services/cdn/parse/front_door_rule.go create mode 100644 internal/services/cdn/parse/front_door_rule_set.go create mode 100644 internal/services/cdn/parse/front_door_rule_set_test.go create mode 100644 internal/services/cdn/parse/front_door_rule_test.go create mode 100644 internal/services/cdn/validate/front_door_rule_id.go create mode 100644 internal/services/cdn/validate/front_door_rule_id_test.go create mode 100644 internal/services/cdn/validate/front_door_rule_name.go create mode 100644 internal/services/cdn/validate/front_door_rule_name_test.go create mode 100644 internal/services/cdn/validate/front_door_rule_set_id.go create mode 100644 internal/services/cdn/validate/front_door_rule_set_id_test.go create mode 100644 internal/services/cdn/validate/front_door_rule_set_name.go create mode 100644 internal/services/cdn/validate/front_door_rule_set_name_test.go diff --git a/internal/services/cdn/parse/front_door_rule.go b/internal/services/cdn/parse/front_door_rule.go new file mode 100644 index 000000000000..3f8a1c4ec0ea --- /dev/null +++ b/internal/services/cdn/parse/front_door_rule.go @@ -0,0 +1,149 @@ +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 FrontDoorRuleId struct { + SubscriptionId string + ResourceGroup string + ProfileName string + RuleSetName string + RuleName string +} + +func NewFrontDoorRuleID(subscriptionId, resourceGroup, profileName, ruleSetName, ruleName string) FrontDoorRuleId { + return FrontDoorRuleId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + ProfileName: profileName, + RuleSetName: ruleSetName, + RuleName: ruleName, + } +} + +func (id FrontDoorRuleId) String() string { + segments := []string{ + fmt.Sprintf("Rule Name %q", id.RuleName), + fmt.Sprintf("Rule Set Name %q", id.RuleSetName), + fmt.Sprintf("Profile Name %q", id.ProfileName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Front Door Rule", segmentsStr) +} + +func (id FrontDoorRuleId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Cdn/profiles/%s/ruleSets/%s/rules/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.ProfileName, id.RuleSetName, id.RuleName) +} + +// FrontDoorRuleID parses a FrontDoorRule ID into an FrontDoorRuleId struct +func FrontDoorRuleID(input string) (*FrontDoorRuleId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := FrontDoorRuleId{ + 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.ProfileName, err = id.PopSegment("profiles"); err != nil { + return nil, err + } + if resourceId.RuleSetName, err = id.PopSegment("ruleSets"); err != nil { + return nil, err + } + if resourceId.RuleName, err = id.PopSegment("rules"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} + +// FrontDoorRuleIDInsensitively parses an FrontDoorRule ID into an FrontDoorRuleId struct, insensitively +// This should only be used to parse an ID for rewriting, the FrontDoorRuleID +// method should be used instead for validation etc. +// +// Whilst this may seem strange, this enables Terraform have consistent casing +// which works around issues in Core, whilst handling broken API responses. +func FrontDoorRuleIDInsensitively(input string) (*FrontDoorRuleId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := FrontDoorRuleId{ + 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") + } + + // find the correct casing for the 'profiles' segment + profilesKey := "profiles" + for key := range id.Path { + if strings.EqualFold(key, profilesKey) { + profilesKey = key + break + } + } + if resourceId.ProfileName, err = id.PopSegment(profilesKey); err != nil { + return nil, err + } + + // find the correct casing for the 'ruleSets' segment + ruleSetsKey := "ruleSets" + for key := range id.Path { + if strings.EqualFold(key, ruleSetsKey) { + ruleSetsKey = key + break + } + } + if resourceId.RuleSetName, err = id.PopSegment(ruleSetsKey); err != nil { + return nil, err + } + + // find the correct casing for the 'rules' segment + rulesKey := "rules" + for key := range id.Path { + if strings.EqualFold(key, rulesKey) { + rulesKey = key + break + } + } + if resourceId.RuleName, err = id.PopSegment(rulesKey); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/internal/services/cdn/parse/front_door_rule_set.go b/internal/services/cdn/parse/front_door_rule_set.go new file mode 100644 index 000000000000..f8e35e3a57d1 --- /dev/null +++ b/internal/services/cdn/parse/front_door_rule_set.go @@ -0,0 +1,131 @@ +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 FrontDoorRuleSetId struct { + SubscriptionId string + ResourceGroup string + ProfileName string + RuleSetName string +} + +func NewFrontDoorRuleSetID(subscriptionId, resourceGroup, profileName, ruleSetName string) FrontDoorRuleSetId { + return FrontDoorRuleSetId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + ProfileName: profileName, + RuleSetName: ruleSetName, + } +} + +func (id FrontDoorRuleSetId) String() string { + segments := []string{ + fmt.Sprintf("Rule Set Name %q", id.RuleSetName), + fmt.Sprintf("Profile Name %q", id.ProfileName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Front Door Rule Set", segmentsStr) +} + +func (id FrontDoorRuleSetId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Cdn/profiles/%s/ruleSets/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.ProfileName, id.RuleSetName) +} + +// FrontDoorRuleSetID parses a FrontDoorRuleSet ID into an FrontDoorRuleSetId struct +func FrontDoorRuleSetID(input string) (*FrontDoorRuleSetId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := FrontDoorRuleSetId{ + 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.ProfileName, err = id.PopSegment("profiles"); err != nil { + return nil, err + } + if resourceId.RuleSetName, err = id.PopSegment("ruleSets"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} + +// FrontDoorRuleSetIDInsensitively parses an FrontDoorRuleSet ID into an FrontDoorRuleSetId struct, insensitively +// This should only be used to parse an ID for rewriting, the FrontDoorRuleSetID +// method should be used instead for validation etc. +// +// Whilst this may seem strange, this enables Terraform have consistent casing +// which works around issues in Core, whilst handling broken API responses. +func FrontDoorRuleSetIDInsensitively(input string) (*FrontDoorRuleSetId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := FrontDoorRuleSetId{ + 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") + } + + // find the correct casing for the 'profiles' segment + profilesKey := "profiles" + for key := range id.Path { + if strings.EqualFold(key, profilesKey) { + profilesKey = key + break + } + } + if resourceId.ProfileName, err = id.PopSegment(profilesKey); err != nil { + return nil, err + } + + // find the correct casing for the 'ruleSets' segment + ruleSetsKey := "ruleSets" + for key := range id.Path { + if strings.EqualFold(key, ruleSetsKey) { + ruleSetsKey = key + break + } + } + if resourceId.RuleSetName, err = id.PopSegment(ruleSetsKey); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/internal/services/cdn/parse/front_door_rule_set_test.go b/internal/services/cdn/parse/front_door_rule_set_test.go new file mode 100644 index 000000000000..45e91d416cf7 --- /dev/null +++ b/internal/services/cdn/parse/front_door_rule_set_test.go @@ -0,0 +1,264 @@ +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 = FrontDoorRuleSetId{} + +func TestFrontDoorRuleSetIDFormatter(t *testing.T) { + actual := NewFrontDoorRuleSetID("12345678-1234-9876-4563-123456789012", "resourceGroup1", "profile1", "ruleSet1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestFrontDoorRuleSetID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *FrontDoorRuleSetId + }{ + + { + // 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 ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/", + Error: true, + }, + + { + // missing value for ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/", + Error: true, + }, + + { + // missing RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/", + Error: true, + }, + + { + // missing value for RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1", + Expected: &FrontDoorRuleSetId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESOURCEGROUP1/PROVIDERS/MICROSOFT.CDN/PROFILES/PROFILE1/RULESETS/RULESET1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := FrontDoorRuleSetID(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.ProfileName != v.Expected.ProfileName { + t.Fatalf("Expected %q but got %q for ProfileName", v.Expected.ProfileName, actual.ProfileName) + } + if actual.RuleSetName != v.Expected.RuleSetName { + t.Fatalf("Expected %q but got %q for RuleSetName", v.Expected.RuleSetName, actual.RuleSetName) + } + } +} + +func TestFrontDoorRuleSetIDInsensitively(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *FrontDoorRuleSetId + }{ + + { + // 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 ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/", + Error: true, + }, + + { + // missing value for ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/", + Error: true, + }, + + { + // missing RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/", + Error: true, + }, + + { + // missing value for RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1", + Expected: &FrontDoorRuleSetId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + }, + }, + + { + // lower-cased segment names + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/rulesets/ruleSet1", + Expected: &FrontDoorRuleSetId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + }, + }, + + { + // upper-cased segment names + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/PROFILES/profile1/RULESETS/ruleSet1", + Expected: &FrontDoorRuleSetId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + }, + }, + + { + // mixed-cased segment names + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/PrOfIlEs/profile1/RuLeSeTs/ruleSet1", + Expected: &FrontDoorRuleSetId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + }, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := FrontDoorRuleSetIDInsensitively(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.ProfileName != v.Expected.ProfileName { + t.Fatalf("Expected %q but got %q for ProfileName", v.Expected.ProfileName, actual.ProfileName) + } + if actual.RuleSetName != v.Expected.RuleSetName { + t.Fatalf("Expected %q but got %q for RuleSetName", v.Expected.RuleSetName, actual.RuleSetName) + } + } +} diff --git a/internal/services/cdn/parse/front_door_rule_test.go b/internal/services/cdn/parse/front_door_rule_test.go new file mode 100644 index 000000000000..84e83c640e65 --- /dev/null +++ b/internal/services/cdn/parse/front_door_rule_test.go @@ -0,0 +1,299 @@ +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 = FrontDoorRuleId{} + +func TestFrontDoorRuleIDFormatter(t *testing.T) { + actual := NewFrontDoorRuleID("12345678-1234-9876-4563-123456789012", "resourceGroup1", "profile1", "ruleSet1", "rule1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/rules/rule1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestFrontDoorRuleID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *FrontDoorRuleId + }{ + + { + // 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 ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/", + Error: true, + }, + + { + // missing value for ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/", + Error: true, + }, + + { + // missing RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/", + Error: true, + }, + + { + // missing value for RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/", + Error: true, + }, + + { + // missing RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/", + Error: true, + }, + + { + // missing value for RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/rules/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/rules/rule1", + Expected: &FrontDoorRuleId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + RuleName: "rule1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESOURCEGROUP1/PROVIDERS/MICROSOFT.CDN/PROFILES/PROFILE1/RULESETS/RULESET1/RULES/RULE1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := FrontDoorRuleID(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.ProfileName != v.Expected.ProfileName { + t.Fatalf("Expected %q but got %q for ProfileName", v.Expected.ProfileName, actual.ProfileName) + } + if actual.RuleSetName != v.Expected.RuleSetName { + t.Fatalf("Expected %q but got %q for RuleSetName", v.Expected.RuleSetName, actual.RuleSetName) + } + if actual.RuleName != v.Expected.RuleName { + t.Fatalf("Expected %q but got %q for RuleName", v.Expected.RuleName, actual.RuleName) + } + } +} + +func TestFrontDoorRuleIDInsensitively(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *FrontDoorRuleId + }{ + + { + // 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 ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/", + Error: true, + }, + + { + // missing value for ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/", + Error: true, + }, + + { + // missing RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/", + Error: true, + }, + + { + // missing value for RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/", + Error: true, + }, + + { + // missing RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/", + Error: true, + }, + + { + // missing value for RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/rules/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/rules/rule1", + Expected: &FrontDoorRuleId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + RuleName: "rule1", + }, + }, + + { + // lower-cased segment names + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/rulesets/ruleSet1/rules/rule1", + Expected: &FrontDoorRuleId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + RuleName: "rule1", + }, + }, + + { + // upper-cased segment names + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/PROFILES/profile1/RULESETS/ruleSet1/RULES/rule1", + Expected: &FrontDoorRuleId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + RuleName: "rule1", + }, + }, + + { + // mixed-cased segment names + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/PrOfIlEs/profile1/RuLeSeTs/ruleSet1/RuLeS/rule1", + Expected: &FrontDoorRuleId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + ProfileName: "profile1", + RuleSetName: "ruleSet1", + RuleName: "rule1", + }, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := FrontDoorRuleIDInsensitively(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.ProfileName != v.Expected.ProfileName { + t.Fatalf("Expected %q but got %q for ProfileName", v.Expected.ProfileName, actual.ProfileName) + } + if actual.RuleSetName != v.Expected.RuleSetName { + t.Fatalf("Expected %q but got %q for RuleSetName", v.Expected.RuleSetName, actual.RuleSetName) + } + if actual.RuleName != v.Expected.RuleName { + t.Fatalf("Expected %q but got %q for RuleName", v.Expected.RuleName, actual.RuleName) + } + } +} diff --git a/internal/services/cdn/resourceids.go b/internal/services/cdn/resourceids.go index 2a424a87e207..8c08a9e353f7 100644 --- a/internal/services/cdn/resourceids.go +++ b/internal/services/cdn/resourceids.go @@ -8,3 +8,5 @@ package cdn // CDN FrontDoor //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=FrontDoorEndpoint -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/afdEndpoints/endpoint1 -rewrite=true //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=FrontDoorProfile -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1 -rewrite=true +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=FrontDoorRuleSet -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1 -rewrite=true +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=FrontDoorRule -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/rules/rule1 -rewrite=true diff --git a/internal/services/cdn/validate/front_door_rule_id.go b/internal/services/cdn/validate/front_door_rule_id.go new file mode 100644 index 000000000000..f52e6a7d74a3 --- /dev/null +++ b/internal/services/cdn/validate/front_door_rule_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/cdn/parse" +) + +func FrontDoorRuleID(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.FrontDoorRuleID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/internal/services/cdn/validate/front_door_rule_id_test.go b/internal/services/cdn/validate/front_door_rule_id_test.go new file mode 100644 index 000000000000..436e9526689d --- /dev/null +++ b/internal/services/cdn/validate/front_door_rule_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 TestFrontDoorRuleID(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 ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/", + Valid: false, + }, + + { + // missing value for ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/", + Valid: false, + }, + + { + // missing RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/", + Valid: false, + }, + + { + // missing value for RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/", + Valid: false, + }, + + { + // missing RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/", + Valid: false, + }, + + { + // missing value for RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/rules/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1/rules/rule1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESOURCEGROUP1/PROVIDERS/MICROSOFT.CDN/PROFILES/PROFILE1/RULESETS/RULESET1/RULES/RULE1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := FrontDoorRuleID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/internal/services/cdn/validate/front_door_rule_name.go b/internal/services/cdn/validate/front_door_rule_name.go new file mode 100644 index 000000000000..263440a42a1d --- /dev/null +++ b/internal/services/cdn/validate/front_door_rule_name.go @@ -0,0 +1,20 @@ +package validate + +import ( + "fmt" + + "github.com/hashicorp/terraform-provider-azurerm/helpers/validate" +) + +func FrontDoorRuleName(i interface{}, k string) (_ []string, errors []error) { + v, ok := i.(string) + if !ok { + return nil, []error{fmt.Errorf("expected type of %q to be string", k)} + } + + if m, _ := validate.RegExHelper(i, k, `^[a-zA-Z][\da-zA-Z]{0,259}$`); !m { + return nil, []error{fmt.Errorf(`%q must be between 1 and 260 characters in length, begin with a letter and may contain only letters and numbers, got %q`, k, v)} + } + + return nil, nil +} diff --git a/internal/services/cdn/validate/front_door_rule_name_test.go b/internal/services/cdn/validate/front_door_rule_name_test.go new file mode 100644 index 000000000000..85c6ff8a408d --- /dev/null +++ b/internal/services/cdn/validate/front_door_rule_name_test.go @@ -0,0 +1,74 @@ +package validate + +import "testing" + +func TestFrontDoorRuleName(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + { + // Empty + Input: "", + Valid: false, + }, + + { + // Starts invalid character + Input: "-foo", + Valid: false, + }, + + { + // Ends with invalid character + Input: "foo-", + Valid: false, + }, + + { + // Has embedded invalid character + Input: "foo-bar", + Valid: false, + }, + + { + // Starts with number + Input: "1foo", + Valid: false, + }, + + { + // Ends with number + Input: "foo1", + Valid: true, + }, + + { + // Min Len + Input: "f", + Valid: true, + }, + + { + // Max Len + Input: "AAAAAAAAAAAAAHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE", + Valid: true, + }, + + { + // Too Long + Input: "AAAAAAAAAAAAAHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE", + Valid: false, + }, + } + + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := FrontDoorRuleName(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/internal/services/cdn/validate/front_door_rule_set_id.go b/internal/services/cdn/validate/front_door_rule_set_id.go new file mode 100644 index 000000000000..624d790adaee --- /dev/null +++ b/internal/services/cdn/validate/front_door_rule_set_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/cdn/parse" +) + +func FrontDoorRuleSetID(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.FrontDoorRuleSetID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/internal/services/cdn/validate/front_door_rule_set_id_test.go b/internal/services/cdn/validate/front_door_rule_set_id_test.go new file mode 100644 index 000000000000..d08969e748a5 --- /dev/null +++ b/internal/services/cdn/validate/front_door_rule_set_id_test.go @@ -0,0 +1,88 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import "testing" + +func TestFrontDoorRuleSetID(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 ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/", + Valid: false, + }, + + { + // missing value for ProfileName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/", + Valid: false, + }, + + { + // missing RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/", + Valid: false, + }, + + { + // missing value for RuleSetName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESOURCEGROUP1/PROVIDERS/MICROSOFT.CDN/PROFILES/PROFILE1/RULESETS/RULESET1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := FrontDoorRuleSetID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/internal/services/cdn/validate/front_door_rule_set_name.go b/internal/services/cdn/validate/front_door_rule_set_name.go new file mode 100644 index 000000000000..400178b27913 --- /dev/null +++ b/internal/services/cdn/validate/front_door_rule_set_name.go @@ -0,0 +1,20 @@ +package validate + +import ( + "fmt" + + "github.com/hashicorp/terraform-provider-azurerm/helpers/validate" +) + +func FrontDoorRuleSetName(i interface{}, k string) (_ []string, errors []error) { + v, ok := i.(string) + if !ok { + return nil, []error{fmt.Errorf("expected type of %q to be string", k)} + } + + if m, _ := validate.RegExHelper(i, k, `^[a-zA-Z][\da-zA-Z]{0,59}$`); !m { + return nil, []error{fmt.Errorf(`%q must be between 1 and 60 characters in length, begin with a letter and may contain only letters and numbers, got %q`, k, v)} + } + + return nil, nil +} diff --git a/internal/services/cdn/validate/front_door_rule_set_name_test.go b/internal/services/cdn/validate/front_door_rule_set_name_test.go new file mode 100644 index 000000000000..7108e8c88b56 --- /dev/null +++ b/internal/services/cdn/validate/front_door_rule_set_name_test.go @@ -0,0 +1,74 @@ +package validate + +import "testing" + +func TestFrontDoorRuleSetName(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + { + // Empty + Input: "", + Valid: false, + }, + + { + // Starts invalid character + Input: "-foo", + Valid: false, + }, + + { + // Ends with invalid character + Input: "foo-", + Valid: false, + }, + + { + // Has embedded invalid character + Input: "foo-bar", + Valid: false, + }, + + { + // Starts with number + Input: "1foo", + Valid: false, + }, + + { + // Ends with number + Input: "foo1", + Valid: true, + }, + + { + // Min Len + Input: "f", + Valid: true, + }, + + { + // Max Len + Input: "AAAAAAAAAAAAAHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIEEEEEEEEEEEEEEE", + Valid: true, + }, + + { + // Too Long + Input: "AAAAAAAAAAAAAHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIEEEEEEEEEEEEEEEE", + Valid: false, + }, + } + + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := FrontDoorRuleSetName(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} From 2cc3a8c0564faf7a1d9dad380c64545cb67b8745 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Fri, 3 Jun 2022 14:12:36 +0200 Subject: [PATCH 2/5] New Resource: `azurerm_cdn_frontdoor_rule_set` Splitting out from #16671 Co-authored-by: Jeffrey Cline <20408400+WodansSon@users.noreply.github.com> --- .../cdn/cdn_frontdoor_rule_set_resource.go | 129 +++++++++++++++++ .../cdn_frontdoor_rule_set_resource_test.go | 134 ++++++++++++++++++ internal/services/cdn/registration.go | 1 + .../r/cdn_frontdoor_rule_set.html.markdown | 60 ++++++++ 4 files changed, 324 insertions(+) create mode 100644 internal/services/cdn/cdn_frontdoor_rule_set_resource.go create mode 100644 internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go create mode 100644 website/docs/r/cdn_frontdoor_rule_set.html.markdown diff --git a/internal/services/cdn/cdn_frontdoor_rule_set_resource.go b/internal/services/cdn/cdn_frontdoor_rule_set_resource.go new file mode 100644 index 000000000000..bbf6c411456b --- /dev/null +++ b/internal/services/cdn/cdn_frontdoor_rule_set_resource.go @@ -0,0 +1,129 @@ +package cdn + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cdn/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cdn/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 resourceCdnFrontDoorRuleSet() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Create: resourceCdnFrontDoorRuleSetCreate, + Read: resourceCdnFrontDoorRuleSetRead, + Delete: resourceCdnFrontDoorRuleSetDelete, + + 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), + }, + + Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { + _, err := parse.FrontDoorRuleSetID(id) + return err + }), + + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.FrontDoorRuleSetName, + }, + + "cdn_frontdoor_profile_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.FrontDoorProfileID, + }, + }, + } +} + +func resourceCdnFrontDoorRuleSetCreate(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Cdn.FrontDoorRuleSetsClient + ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) + defer cancel() + + profileId, err := parse.FrontDoorProfileID(d.Get("cdn_frontdoor_profile_id").(string)) + if err != nil { + return err + } + + id := parse.NewFrontDoorRuleSetID(profileId.SubscriptionId, profileId.ResourceGroup, profileId.ProfileName, d.Get("name").(string)) + if d.IsNewResource() { + existing, err := client.Get(ctx, id.ResourceGroup, id.ProfileName, id.RuleSetName) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for existing %s: %+v", id, err) + } + } + + if !utils.ResponseWasNotFound(existing.Response) { + return tf.ImportAsExistsError("azurerm_cdn_frontdoor_rule_set", id.ID()) + } + } + + if _, err = client.Create(ctx, id.ResourceGroup, id.ProfileName, id.RuleSetName); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + d.SetId(id.ID()) + return resourceCdnFrontDoorRuleSetRead(d, meta) +} + +func resourceCdnFrontDoorRuleSetRead(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Cdn.FrontDoorRuleSetsClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.FrontDoorRuleSetID(d.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.ResourceGroup, id.ProfileName, id.RuleSetName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + d.Set("name", id.RuleSetName) + d.Set("cdn_frontdoor_profile_id", parse.NewFrontDoorProfileID(id.SubscriptionId, id.ResourceGroup, id.ProfileName).ID()) + + return nil +} + +func resourceCdnFrontDoorRuleSetDelete(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Cdn.FrontDoorRuleSetsClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.FrontDoorRuleSetID(d.Id()) + if err != nil { + return err + } + + future, err := client.Delete(ctx, id.ResourceGroup, id.ProfileName, id.RuleSetName) + if err != nil { + return fmt.Errorf("deleting %s: %+v", *id, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("waiting for the deletion of %s: %+v", *id, err) + } + + return nil +} diff --git a/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go b/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go new file mode 100644 index 000000000000..b563a7ae1fcf --- /dev/null +++ b/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go @@ -0,0 +1,134 @@ +package cdn_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/cdn/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type CdnFrontDoorRuleSetResource struct{} + +func TestAccCdnFrontDoorRuleSet_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_rule_set", "test") + r := CdnFrontDoorRuleSetResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccCdnFrontDoorRuleSet_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_rule_set", "test") + r := CdnFrontDoorRuleSetResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.RequiresImportErrorStep(r.requiresImport), + }) +} + +func TestAccCdnFrontDoorRuleSet_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_rule_set", "test") + r := CdnFrontDoorRuleSetResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r CdnFrontDoorRuleSetResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := parse.FrontDoorRuleSetID(state.ID) + if err != nil { + return nil, err + } + + client := clients.Cdn.FrontDoorRuleSetsClient + resp, err := client.Get(ctx, id.ResourceGroup, id.ProfileName, id.RuleSetName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + + return utils.Bool(true), nil +} + +func (r CdnFrontDoorRuleSetResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +%s + +resource "azurerm_cdn_frontdoor_rule_set" "test" { + name = "acctest-fdruleset-%d" + cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.test.id +} +`, template, data.RandomIntOfLength(8)) +} + +func (r CdnFrontDoorRuleSetResource) requiresImport(data acceptance.TestData) string { + config := r.basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_cdn_frontdoor_rule_set" "import" { + name = azurerm_cdn_frontdoor_rule_set.test.name + cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.test.id +} +`, config) +} + +func (r CdnFrontDoorRuleSetResource) complete(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +%s + +resource "azurerm_cdn_frontdoor_rule_set" "test" { + name = "acctest-fdruleset-%d" + cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.test.id +} +`, template, data.RandomIntOfLength(8)) +} + +func (CdnFrontDoorRuleSetResource) template(data acceptance.TestData) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-cdn-afdx-%d" + location = "%s" +} + +resource "azurerm_cdn_frontdoor_profile" "test" { + name = "acctest-fdprofile-%d" + resource_group_name = azurerm_resource_group.test.name +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +} diff --git a/internal/services/cdn/registration.go b/internal/services/cdn/registration.go index 403cee90c09d..6730462ff90a 100644 --- a/internal/services/cdn/registration.go +++ b/internal/services/cdn/registration.go @@ -48,5 +48,6 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { // FrontDoor "azurerm_cdn_frontdoor_endpoint": resourceCdnFrontDoorEndpoint(), "azurerm_cdn_frontdoor_profile": resourceCdnFrontDoorProfile(), + "azurerm_cdn_frontdoor_rule_set": resourceCdnFrontDoorRuleSet(), } } diff --git a/website/docs/r/cdn_frontdoor_rule_set.html.markdown b/website/docs/r/cdn_frontdoor_rule_set.html.markdown new file mode 100644 index 000000000000..31d51f44d9dc --- /dev/null +++ b/website/docs/r/cdn_frontdoor_rule_set.html.markdown @@ -0,0 +1,60 @@ +--- +subcategory: "CDN" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cdn_frontdoor_rule_set" +description: |- + Manages a CDN FrontDoor Rule Set. +--- + +# azurerm_cdn_frontdoor_rule_set + +Manages a CDN FrontDoor Rule Set. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-cdn-frontdoor" + location = "West Europe" +} + +resource "azurerm_cdn_frontdoor_profile" "example" { + name = "example-profile" + resource_group_name = azurerm_resource_group.example.name +} + +resource "azurerm_cdn_frontdoor_rule_set" "example" { + name = "example-rule-set" + cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.example.id +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `name` - (Required) The name which should be used for this CDN FrontDoor Rule Set. Changing this forces a new CDN FrontDoor Rule Set to be created. + +* `cdn_frontdoor_profile_id` - (Required) The ID of the CDN FrontDoor Profile. Changing this forces a new CDN FrontDoor Rule Set to be created. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the CDN FrontDoor Rule Set. + +## 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 CDN FrontDoor Rule Set. +* `read` - (Defaults to 5 minutes) Used when retrieving the CDN FrontDoor Rule Set. +* `delete` - (Defaults to 30 minutes) Used when deleting the CDN FrontDoor Rule Set. + +## Import + +CDN FrontDoor Rule Sets can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_cdn_frontdoor_rule_set.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.Cdn/profiles/profile1/ruleSets/ruleSet1 +``` From 9703e7a2a48c7ecdf0be672b58cf6920bd52ce13 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Fri, 3 Jun 2022 14:47:00 +0200 Subject: [PATCH 3/5] New Data Source: `azurerm_cdn_frontdoor_rule_set` --- .../cdn/cdn_frontdoor_rule_set_data_source.go | 69 +++++++++++++++++++ ...cdn_frontdoor_rule_set_data_source_test.go | 37 ++++++++++ internal/services/cdn/registration.go | 1 + .../d/cdn_frontdoor_rule_set.html.markdown | 46 +++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 internal/services/cdn/cdn_frontdoor_rule_set_data_source.go create mode 100644 internal/services/cdn/cdn_frontdoor_rule_set_data_source_test.go create mode 100644 website/docs/d/cdn_frontdoor_rule_set.html.markdown diff --git a/internal/services/cdn/cdn_frontdoor_rule_set_data_source.go b/internal/services/cdn/cdn_frontdoor_rule_set_data_source.go new file mode 100644 index 000000000000..0994dfc6208e --- /dev/null +++ b/internal/services/cdn/cdn_frontdoor_rule_set_data_source.go @@ -0,0 +1,69 @@ +package cdn + +import ( + "fmt" + "time" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cdn/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cdn/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 dataSourceCdnFrontDoorRuleSet() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Read: dataSourceCdnFrontDoorRuleSetRead, + + Timeouts: &pluginsdk.ResourceTimeout{ + Read: pluginsdk.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validate.FrontDoorRuleSetName, + }, + + "profile_name": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validate.FrontDoorName, + }, + + "resource_group_name": commonschema.ResourceGroupNameForDataSource(), + + "cdn_frontdoor_profile_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceCdnFrontDoorRuleSetRead(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Cdn.FrontDoorRuleSetsClient + subscriptionId := meta.(*clients.Client).Account.SubscriptionId + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id := parse.NewFrontDoorRuleSetID(subscriptionId, d.Get("resource_group_name").(string), d.Get("profile_name").(string), d.Get("name").(string)) + resp, err := client.Get(ctx, id.ResourceGroup, id.ProfileName, id.RuleSetName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("%s was not found", id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + d.SetId(id.ID()) + d.Set("name", id.RuleSetName) + d.Set("profile_name", id.ProfileName) + d.Set("resource_group_name", id.ResourceGroup) + d.Set("cdn_frontdoor_profile_id", parse.NewFrontDoorProfileID(id.SubscriptionId, id.ResourceGroup, id.ProfileName).ID()) + + return nil +} diff --git a/internal/services/cdn/cdn_frontdoor_rule_set_data_source_test.go b/internal/services/cdn/cdn_frontdoor_rule_set_data_source_test.go new file mode 100644 index 000000000000..e8c1b47ccfb3 --- /dev/null +++ b/internal/services/cdn/cdn_frontdoor_rule_set_data_source_test.go @@ -0,0 +1,37 @@ +package cdn_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" +) + +type CdnFrontDoorRuleSetDataSource struct{} + +func TestAccCdnFrontDoorRuleSetDataSource_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_cdn_frontdoor_rule_set", "test") + d := CdnFrontDoorRuleSetDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: d.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("cdn_frontdoor_profile_id").MatchesOtherKey(check.That("azurerm_cdn_frontdoor_profile.test").Key("id")), + ), + }, + }) +} + +func (CdnFrontDoorRuleSetDataSource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_cdn_frontdoor_rule_set" "test" { + name = azurerm_cdn_frontdoor_rule_set.test.name + profile_name = azurerm_cdn_frontdoor_rule_set.test.profile_name + resource_group_name = azurerm_cdn_frontdoor_rule_set.test.resource_group_name +} +`, CdnFrontDoorRuleSetResource{}.complete(data)) +} diff --git a/internal/services/cdn/registration.go b/internal/services/cdn/registration.go index 6730462ff90a..daa1eff667fe 100644 --- a/internal/services/cdn/registration.go +++ b/internal/services/cdn/registration.go @@ -34,6 +34,7 @@ func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource { // FrontDoor "azurerm_cdn_frontdoor_endpoint": dataSourceCdnFrontDoorEndpoint(), "azurerm_cdn_frontdoor_profile": dataSourceCdnFrontDoorProfile(), + "azurerm_cdn_frontdoor_rule_set": dataSourceCdnFrontDoorRuleSet(), } } diff --git a/website/docs/d/cdn_frontdoor_rule_set.html.markdown b/website/docs/d/cdn_frontdoor_rule_set.html.markdown new file mode 100644 index 000000000000..e8cce661ddf3 --- /dev/null +++ b/website/docs/d/cdn_frontdoor_rule_set.html.markdown @@ -0,0 +1,46 @@ +--- +subcategory: "CDN" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cdn_frontdoor_rule_set" +description: |- + Gets information about an existing CDN FrontDoor Rule Set. +--- + +# Data Source: azurerm_cdn_frontdoor_rule_set + +Gets information about an existing CDN FrontDoor Rule Set. + +## Example Usage + +```hcl +data "azurerm_cdn_frontdoor_rule_set" "example" { + name = "existing-rule-set" + profile_name = "existing-profile" + resource_group_name = "existing-resources" +} +``` + +## Arguments Reference + +The following arguments are supported: + + +* `name` - (Required) Specifies the name of the CDN FrontDoor Rule Set to retrieve. + +* `profile_name` - (Required) Specifies the name of the CDN FrontDoor Profile where this CDN FrontDoor Rule Set exists. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group where the CDN FrontDoor Profile exists. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the CDN FrontDoor Rule Set. + +* `cdn_frontdoor_profile_id` - The ID of the CDN FrontDoor Profile within which this CDN FrontDoor Rule Set exists. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the CDN FrontDoor Rule Set. From 82c16835959d1b78069bcee3ba0f79cbe1769886 Mon Sep 17 00:00:00 2001 From: Matthew Frahry Date: Fri, 3 Jun 2022 10:50:39 -0700 Subject: [PATCH 4/5] Update cdn_frontdoor_rule_set_resource_test.go --- internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go b/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go index b563a7ae1fcf..dceeebf1bfe9 100644 --- a/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go +++ b/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go @@ -129,6 +129,7 @@ resource "azurerm_resource_group" "test" { resource "azurerm_cdn_frontdoor_profile" "test" { name = "acctest-fdprofile-%d" resource_group_name = azurerm_resource_group.test.name + sku_name = "Standard_AzureFrontDoor" } `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } From 3fd20332c56ab186f69fea04fa589534e3418873 Mon Sep 17 00:00:00 2001 From: Matthew Frahry Date: Fri, 3 Jun 2022 10:53:06 -0700 Subject: [PATCH 5/5] Update cdn_frontdoor_rule_set_resource_test.go --- internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go b/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go index dceeebf1bfe9..f16310b71244 100644 --- a/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go +++ b/internal/services/cdn/cdn_frontdoor_rule_set_resource_test.go @@ -85,7 +85,7 @@ provider "azurerm" { %s resource "azurerm_cdn_frontdoor_rule_set" "test" { - name = "acctest-fdruleset-%d" + name = "acctestfdruleset%d" cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.test.id } `, template, data.RandomIntOfLength(8)) @@ -113,7 +113,7 @@ provider "azurerm" { %s resource "azurerm_cdn_frontdoor_rule_set" "test" { - name = "acctest-fdruleset-%d" + name = "acctestfdruleset%d" cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.test.id } `, template, data.RandomIntOfLength(8))