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/Data Source: azurerm_nat_gateway and azurerm_subnet_nat_gateway_association #4449

Merged
merged 24 commits into from
Dec 5, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a9415d6
Add nat-gateway and subnet-nat-gateway-association
ArcturusZhang Nov 15, 2019
700345b
Resolve comments
ArcturusZhang Nov 15, 2019
f753d24
Fix CI
ArcturusZhang Nov 15, 2019
35d22ad
Rebased to master and update api-version of network package
ArcturusZhang Nov 21, 2019
41083b1
Rebased to master again
ArcturusZhang Nov 27, 2019
790a4f0
Resolved comments and fix bad tests
ArcturusZhang Dec 3, 2019
1f690a5
Adding more information to doc
WodansSon Dec 4, 2019
56c9b8d
Update test location to use alt location
WodansSon Dec 4, 2019
2698122
Add nat-gateway and subnet-nat-gateway-association
ArcturusZhang Nov 15, 2019
8d7a841
Resolve comments
ArcturusZhang Nov 15, 2019
7bf8142
Fix CI
ArcturusZhang Nov 15, 2019
573b7c4
Rebased to master and update api-version of network package
ArcturusZhang Nov 21, 2019
8183da0
Rebased to master again
ArcturusZhang Nov 27, 2019
cd658cb
Resolved comments and fix bad tests
ArcturusZhang Dec 3, 2019
d04ec02
Adding more information to doc
WodansSon Dec 4, 2019
9725cd1
Update test location to use alt location
WodansSon Dec 4, 2019
dc970e5
Resolving comments
ArcturusZhang Dec 5, 2019
9d69ef7
Change comments in test to clarify the context of using alt location
ArcturusZhang Dec 5, 2019
8f695e1
More official note
ArcturusZhang Dec 5, 2019
de571fe
More refine on private preview note
ArcturusZhang Dec 5, 2019
b63b48e
Merge branch 'nat-gateway' of https://github.com/ArcturusZhang/terraf…
WodansSon Dec 5, 2019
b591f59
Remove duplicate func
WodansSon Dec 5, 2019
3e8f457
Update per PR comments
WodansSon Dec 5, 2019
7dbafca
Updates per PR review
WodansSon Dec 5, 2019
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
136 changes: 136 additions & 0 deletions azurerm/data_source_nat_gateway.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package azurerm

import (
"fmt"

"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/services/network"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmNatGateway() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmNatGatewayRead,

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

"location": azure.SchemaLocationForDataSource(),

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

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

"public_ip_address_ids": {
Type: schema.TypeList,
Optional: true,
ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},

"public_ip_prefix_ids": {
Type: schema.TypeList,
Optional: true,
ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},

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

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

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

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

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

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

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

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

resp, err := client.Get(ctx, resourceGroup, name, "")
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error: Nat Gateway %q (Resource Group %q) was not found", name, resourceGroup)
}
return fmt.Errorf("Error reading Nat Gateway %q (Resource Group %q): %+v", name, resourceGroup, err)
}
if resp.ID == nil {
return fmt.Errorf("Cannot read NAT Gateway %q (Resource Group %q) ID", name, resourceGroup)
}
d.SetId(*resp.ID)
ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved

d.Set("name", resp.Name)
d.Set("sku_name", resp.Sku.Name)
d.Set("resource_group_name", resourceGroup)

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

if props := resp.NatGatewayPropertiesFormat; props != nil {
ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved
d.Set("idle_timeout_in_minutes", props.IdleTimeoutInMinutes)
d.Set("resource_guid", props.ResourceGUID)

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

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

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

if err := d.Set("zones", utils.FlattenStringSlice(resp.Zones)); err != nil {
ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("Error setting `zones`: %+v", err)
}

return tags.FlattenAndSet(d, resp.Tags)
ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved
}
73 changes: 73 additions & 0 deletions azurerm/data_source_nat_gateway_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package azurerm

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
)

func TestAccDataSourceAzureRMNatGateway_basic(t *testing.T) {
ri := tf.AccRandTimeInt()
// It is hard-coded because this resource currently only available in eastus2.
location := "eastus2"
ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceNatGateway_basic(ri, location),
Check: resource.ComposeTestCheckFunc(),
},
},
})
}

func TestAccDataSourceAzureRMNatGateway_complete(t *testing.T) {
dataSourceName := "data.azurerm_nat_gateway.test"
ri := tf.AccRandTimeInt()
// It is hard-coded because this resource currently only available in eastus2.
location := "eastus2"
ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceNatGateway_complete(ri, location),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "public_ip_address_ids.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "public_ip_prefix_ids.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "sku_name", "Standard"),
resource.TestCheckResourceAttr(dataSourceName, "idle_timeout_in_minutes", "10"),
),
},
},
})
}

func testAccDataSourceNatGateway_basic(rInt int, location string) string {
config := testAccAzureRMNatGateway_basic(rInt, location)
return fmt.Sprintf(`
%s

data "azurerm_nat_gateway" "test" {
resource_group_name = "${azurerm_nat_gateway.test.resource_group_name}"
name = "${azurerm_nat_gateway.test.name}"
}
`, config)
}

func testAccDataSourceNatGateway_complete(rInt int, location string) string {
config := testAccAzureRMNatGateway_complete(rInt, location)
return fmt.Sprintf(`
%s

data "azurerm_nat_gateway" "test" {
resource_group_name = "${azurerm_nat_gateway.test.resource_group_name}"
name = "${azurerm_nat_gateway.test.name}"
}
`, config)
}
5 changes: 5 additions & 0 deletions azurerm/internal/services/network/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Client struct {
SecurityGroupClient *network.SecurityGroupsClient
SecurityRuleClient *network.SecurityRulesClient
SubnetsClient *network.SubnetsClient
NatGatewayClient *network.NatGatewaysClient
VnetGatewayConnectionsClient *network.VirtualNetworkGatewayConnectionsClient
VnetGatewayClient *network.VirtualNetworkGatewaysClient
VnetClient *network.VirtualNetworksClient
Expand Down Expand Up @@ -123,6 +124,9 @@ func BuildClient(o *common.ClientOptions) *Client {
VnetGatewayClient := network.NewVirtualNetworkGatewaysClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&VnetGatewayClient.Client, o.ResourceManagerAuthorizer)

NatGatewayClient := network.NewNatGatewaysClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&NatGatewayClient.Client, o.ResourceManagerAuthorizer)

ArcturusZhang marked this conversation as resolved.
Show resolved Hide resolved
VnetGatewayConnectionsClient := network.NewVirtualNetworkGatewayConnectionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&VnetGatewayConnectionsClient.Client, o.ResourceManagerAuthorizer)

Expand Down Expand Up @@ -164,6 +168,7 @@ func BuildClient(o *common.ClientOptions) *Client {
SecurityGroupClient: &SecurityGroupClient,
SecurityRuleClient: &SecurityRuleClient,
SubnetsClient: &SubnetsClient,
NatGatewayClient: &NatGatewayClient,
VnetGatewayConnectionsClient: &VnetGatewayConnectionsClient,
VnetGatewayClient: &VnetGatewayClient,
VnetClient: &VnetClient,
Expand Down
28 changes: 28 additions & 0 deletions azurerm/internal/services/network/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,31 @@ func ValidateVirtualHubName(v interface{}, k string) (warnings []string, errors

return warnings, errors
}

func ValidateNatGatewayName(i interface{}, k string) (warnings []string, errors []error) {
v, ok := i.(string)
if !ok {
errors = append(errors, fmt.Errorf("expected type of %s to be string", k))
return warnings, errors
}

// The name attribute rules per the Nat Gateway service team are (Friday, October 18, 2019 4:20 PM):
// 1. Must not be empty.
// 2. Must be between 1 and 80 characters.
// 3. The attribute must:
// a) begin with a letter or number
// b) end with a letter, number or underscore
// c) may contain only letters, numbers, underscores, periods, or hyphens.

if len(v) == 1 {
if matched := regexp.MustCompile(`^([a-zA-Z\d])`).Match([]byte(v)); !matched {
errors = append(errors, fmt.Errorf("%s must begin with a letter or number", k))
}
} else {
if matched := regexp.MustCompile(`^([a-zA-Z\d])([a-zA-Z\d-\_\.]{0,78})([a-zA-Z\d\_])$`).Match([]byte(v)); !matched {
errors = append(errors, fmt.Errorf("%s must be between 1 - 80 characters long, begin with a letter or number, end with a letter, number or underscore, and may contain only letters, numbers, underscores, periods, or hyphens", k))
}
}

return warnings, errors
}
3 changes: 3 additions & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_monitor_diagnostic_categories": dataSourceArmMonitorDiagnosticCategories(),
"azurerm_monitor_log_profile": dataSourceArmMonitorLogProfile(),
"azurerm_mssql_elasticpool": dataSourceArmMsSqlElasticpool(),
"azurerm_nat_gateway": dataSourceArmNatGateway(),
"azurerm_netapp_account": dataSourceArmNetAppAccount(),
"azurerm_netapp_pool": dataSourceArmNetAppPool(),
"azurerm_network_ddos_protection_plan": dataSourceNetworkDDoSProtectionPlan(),
Expand Down Expand Up @@ -367,6 +368,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_mysql_firewall_rule": resourceArmMySqlFirewallRule(),
"azurerm_mysql_server": resourceArmMySqlServer(),
"azurerm_mysql_virtual_network_rule": resourceArmMySqlVirtualNetworkRule(),
"azurerm_nat_gateway": resourceArmNatGateway(),
"azurerm_network_connection_monitor": resourceArmNetworkConnectionMonitor(),
"azurerm_network_ddos_protection_plan": resourceArmNetworkDDoSProtectionPlan(),
"azurerm_network_interface": resourceArmNetworkInterface(),
Expand Down Expand Up @@ -473,6 +475,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_stream_analytics_stream_input_iothub": resourceArmStreamAnalyticsStreamInputIoTHub(),
"azurerm_subnet_network_security_group_association": resourceArmSubnetNetworkSecurityGroupAssociation(),
"azurerm_subnet_route_table_association": resourceArmSubnetRouteTableAssociation(),
"azurerm_subnet_nat_gateway_association": resourceArmSubnetNatGatewayAssociation(),
"azurerm_subnet": resourceArmSubnet(),
"azurerm_template_deployment": resourceArmTemplateDeployment(),
"azurerm_traffic_manager_endpoint": resourceArmTrafficManagerEndpoint(),
Expand Down
Loading