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

Add App Service Environment resource and Data Source #5508

Merged
merged 26 commits into from
Feb 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
13e50e1
Adds new resource and datasource for App Serice Environment (v2 suppo…
jackofallops Jan 24, 2020
5beb2d2
Linter fixes
jackofallops Jan 24, 2020
e94e186
Added forgotten requiresImport test
jackofallops Jan 24, 2020
1a5f5f2
Refactor for 2.0
jackofallops Feb 12, 2020
522a17b
refactor tests, fix tflint issues
jackofallops Feb 12, 2020
260bd86
docs update
jackofallops Feb 12, 2020
f2d9067
fmt fix
jackofallops Feb 13, 2020
f659142
refactor validate to correct helper location
jackofallops Feb 17, 2020
3e21fb7
r/app_service_environment: fixing up the build errors
tombuildsstuff Feb 19, 2020
6ab4e1e
r/subnet: moving the subnet parser into the parse package
tombuildsstuff Feb 19, 2020
a6a4897
network: moving the virtual network parse/validaters into those packages
tombuildsstuff Feb 19, 2020
ef7dcaa
d/app_service_environment: fixing comments from code review
tombuildsstuff Feb 19, 2020
bbdfbcb
web: removing todos
tombuildsstuff Feb 19, 2020
a661838
d/app_service_environment: renaming the file to match the convention
tombuildsstuff Feb 19, 2020
b840fd4
r/app_service_environment: fixing comments from code review
tombuildsstuff Feb 19, 2020
5b5241e
r/app_service_environment: switching to use a custom update method/po…
tombuildsstuff Feb 19, 2020
f5d0c7c
tests: adding in missing checkdestroys for the data source tests
tombuildsstuff Feb 21, 2020
b190eff
r/app_service_environment: fixing up linting
tombuildsstuff Feb 21, 2020
8000bba
r/app_service_env: fixing the import test
tombuildsstuff Feb 21, 2020
afb1e60
r/app_service_environment: fixing the requires import test
tombuildsstuff Feb 21, 2020
08855d9
r/app_service_environment: converting from the display to actual sku
tombuildsstuff Feb 21, 2020
1c2eb08
r/app_service_environment: fixing the plan test
tombuildsstuff Feb 21, 2020
9187513
refactor: switching to the same client
tombuildsstuff Feb 21, 2020
26000c1
deps: fixing the vendor file
tombuildsstuff Feb 21, 2020
8bf7e31
r/app_service_plan: increasing the timeouts to 60m for ASE's
tombuildsstuff Feb 22, 2020
f9f006e
r/app_service_environment: checking the ID's from the state
tombuildsstuff Feb 23, 2020
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
38 changes: 38 additions & 0 deletions azurerm/internal/services/network/parse/subnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package parse

import (
"fmt"

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

type SubnetId struct {
ResourceGroup string
VirtualNetworkName string
Name string
}

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

subnet := SubnetId{
ResourceGroup: id.ResourceGroup,
}

if subnet.VirtualNetworkName, err = id.PopSegment("virtualNetworks"); err != nil {
return nil, err
}

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

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

return &subnet, nil
}
90 changes: 90 additions & 0 deletions azurerm/internal/services/network/parse/subnet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package parse

import (
"testing"
)

func TestSubnetID(t *testing.T) {
testData := []struct {
Name string
Input string
Error bool
Expect *SubnetId
}{
{
Name: "Empty",
Input: "",
Error: true,
},
{
Name: "No Resource Groups Segment",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000",
Error: true,
},
{
Name: "No Resource Groups Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/",
Error: true,
},
{
Name: "Resource Group ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/",
Error: true,
},
{
Name: "Missing Virtual Networks Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Network/virtualNetworks/",
Error: true,
},
{
Name: "Missing Subnets Key",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Network/virtualNetworks/network1",
Error: true,
},
{
Name: "Missing Subnets Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Network/virtualNetworks/network1/subnets/",
Error: true,
},
{
Name: "Subnet ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Network/virtualNetworks/network1/subnets/subnet1",
Error: false,
Expect: &SubnetId{
ResourceGroup: "resGroup1",
VirtualNetworkName: "network1",
Name: "subnet1",
},
},
{
Name: "Wrong Casing",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Network/virtualNetworks/network1/Subnets/subnet1",
Error: true,
},
}

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

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

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

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

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

if actual.ResourceGroup != v.Expect.ResourceGroup {
t.Fatalf("Expected %q but got %q for Resource Group", v.Expect.ResourceGroup, actual.ResourceGroup)
}
}
}
33 changes: 33 additions & 0 deletions azurerm/internal/services/network/parse/virtual_network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package parse

import (
"fmt"

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

type VirtualNetworkId struct {
ResourceGroup string
Name string
}

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

vnet := VirtualNetworkId{
ResourceGroup: id.ResourceGroup,
}

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

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

return &vnet, nil
}
70 changes: 70 additions & 0 deletions azurerm/internal/services/network/parse/virtual_network_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package parse

import (
"testing"
)

func TestVirtualNetworkID(t *testing.T) {
testData := []struct {
Name string
Input string
Error bool
Expect *VirtualNetworkId
}{
{
Name: "Empty",
Input: "",
Error: true,
},
{
Name: "No Resource Groups Segment",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000",
Error: true,
},
{
Name: "No Resource Groups Value",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/",
Error: true,
},
{
Name: "Resource Group ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/",
Error: true,
},
{
Name: "Virtual Network ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Network/virtualNetworks/network1",
Error: false,
Expect: &VirtualNetworkId{
ResourceGroup: "resGroup1",
Name: "network1",
},
},
{
Name: "Wrong Casing",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Network/VirtualNetworks/network1",
Error: true,
},
}

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

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

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

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

if actual.ResourceGroup != v.Expect.ResourceGroup {
t.Fatalf("Expected %q but got %q for Resource Group", v.Expect.ResourceGroup, actual.ResourceGroup)
}
}
}
23 changes: 23 additions & 0 deletions azurerm/internal/services/network/validate/subnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package validate

import (
"fmt"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/network/parse"
)

// SubnetID validates that the specified ID is a valid Subnet ID
func SubnetID(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 := parse.SubnetID(v); err != nil {
errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err))
return
}

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

import (
"fmt"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/network/parse"
)

// VirtualNetworkID validates that the specified ID is a valid Virtual Network ID
func VirtualNetworkID(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 := parse.VirtualNetworkID(v); err != nil {
errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err))
return
}

return warnings, errors
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package web

import (
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmAppServiceEnvironment() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmAppServiceEnvironmentRead,

Timeouts: &schema.ResourceTimeout{
Read: schema.DefaultTimeout(5 * time.Minute),
},

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

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

"front_end_scale_factor": {
Type: schema.TypeInt,
Computed: true,
},

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

"tags": tags.SchemaDataSource(),
},
}
}

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

resourceGroup := d.Get("resource_group_name").(string)
name := d.Get("name").(string)

resp, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error: App Service Environment %q (Resource Group %q) was not found", name, resourceGroup)
}
return fmt.Errorf("Error retrieving App Service Environment %q (Resource Group %q): %+v", name, resourceGroup, err)
}

d.SetId(*resp.ID)

d.Set("name", name)
d.Set("resource_group_name", resourceGroup)

if loc := resp.Location; loc != nil {
d.Set("location", azure.NormalizeLocation(*loc))
}

if props := resp.AppServiceEnvironment; props != nil {
frontendScaleFactor := 0
if props.FrontEndScaleFactor != nil {
frontendScaleFactor = int(*props.FrontEndScaleFactor)
}
d.Set("front_end_scale_factor", frontendScaleFactor)

pricingTier := ""
if props.MultiSize != nil {
pricingTier = convertFromIsolatedSKU(*props.MultiSize)
}
d.Set("pricing_tier", pricingTier)
}

return tags.FlattenAndSet(d, resp.Tags)
}
Loading