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 vpn client protocol support for virtual network gateway #946

Merged
merged 12 commits into from Jun 15, 2018
Merged

Add vpn client protocol support for virtual network gateway #946

merged 12 commits into from Jun 15, 2018

Conversation

dcaro
Copy link
Contributor

@dcaro dcaro commented Mar 7, 2018

Added support for vpn client protocol and radius server with the following fields:
vpn_client_protocol
radius_server_address
radius_server_secret

@dcaro dcaro changed the title Add vpn client protocol Add vpn client protocol support for virtual network gateway Mar 7, 2018
@tombuildsstuff tombuildsstuff added this to the 1.3.1 milestone Mar 14, 2018
@tombuildsstuff tombuildsstuff modified the milestones: 1.3.1, 1.3.2 Mar 28, 2018
@tombuildsstuff tombuildsstuff modified the milestones: 1.3.2, 1.3.3 Apr 4, 2018
@tombuildsstuff tombuildsstuff modified the milestones: 1.3.3, 1.4.0 Apr 17, 2018
@tombuildsstuff tombuildsstuff modified the milestones: 1.4.0, 1.5.0 Apr 25, 2018
@tombuildsstuff tombuildsstuff modified the milestones: 1.5.0, 1.6.0 May 8, 2018
Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dcaro,

Thank you for adding this! I've taken a look over it and left some comments inline. Outside of that running the tests produces a none empty plan for me:

DIFF:
		
		UPDATE: azurerm_virtual_network_gateway.test
		  vpn_client_configuration.0.radius_server_address: "" => "1.2.3.4"
		  vpn_client_configuration.0.radius_server_secret:  "" => "verysecretsecret"
		
		STATE:

Look forward to getting this merged once these concerns are worked out 🙂

Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to get some validation of this property?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I have added a value validation.

@@ -137,9 +137,20 @@ func resourceArmVirtualNetworkGateway() *schema.Resource {
Type: schema.TypeString,
},
},
"vpn_client_protocol": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we name this vpn_client_protocols to match the SDK?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, done.

@@ -137,9 +137,20 @@ func resourceArmVirtualNetworkGateway() *schema.Resource {
Type: schema.TypeString,
},
},
"vpn_client_protocol": {
Type: schema.TypeList,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be a set unless order matters/duplicates are allowed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, order does not matters, changed.

"root_certificate": {
Type: schema.TypeSet,
Required: true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if neither root_certificate or radius_server_address are set? if that is an error condition we should use a CustomizeDiff to check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the root_certificate and radius_server_address are set, this is accepted by azure with no root cert and the vpnclient cannot be downloaded. I've added a CustomizeDiff so that if a radius_server_address is set is had to be a valid IPv4 address and the secret shall not be empty.

Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMVirtualNetworkGatewayExists("azurerm_virtual_network_gateway.test"),
),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we check here to see if the state is correct:

resource.TestCheckResourceAttr(resourceName, "key", "value"),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, I have added couple of other attribute checks on basic and lowerCaseSubnetName tests as well.

@tombuildsstuff tombuildsstuff modified the milestones: 1.6.0, 1.7.0 May 21, 2018
Copy link
Contributor Author

@dcaro dcaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have included the changes and added a regex validation for the IPv4 address using regex. Let me know if you have a preferred method.

@@ -137,9 +137,20 @@ func resourceArmVirtualNetworkGateway() *schema.Resource {
Type: schema.TypeString,
},
},
"vpn_client_protocol": {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, done.

@@ -137,9 +137,20 @@ func resourceArmVirtualNetworkGateway() *schema.Resource {
Type: schema.TypeString,
},
},
"vpn_client_protocol": {
Type: schema.TypeList,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, order does not matters, changed.

Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I have added a value validation.

"root_certificate": {
Type: schema.TypeSet,
Required: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the root_certificate and radius_server_address are set, this is accepted by azure with no root cert and the vpnclient cannot be downloaded. I've added a CustomizeDiff so that if a radius_server_address is set is had to be a valid IPv4 address and the secret shall not be empty.

Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMVirtualNetworkGatewayExists("azurerm_virtual_network_gateway.test"),
),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, I have added couple of other attribute checks on basic and lowerCaseSubnetName tests as well.

Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dcaro,

Thank you for the updates. I've given this another look and left some comments inline.

@@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
"regexp"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we sort this and put regex above with the other built in packages?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, updated.

}
flat["vpn_client_protocols"] = vpnClientProtocols

flat["radius_server_address"] = *cfg.RadiusServerAddress
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we check these for nil?

if v := cfg.RadiusServerAddress; if v != nil {
  flat["radius_server_address"] = *v
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

"vpn_client_configuration.0.root_certificate",
"vpn_client_configuration.0.revoked_certificate",
},
Elem: &schema.Schema{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't apply to a TypeString

"vpn_client_configuration.0.root_certificate",
"vpn_client_configuration.0.revoked_certificate",
},
Elem: &schema.Schema{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't apply to a TypeString

if vpnClientConfig, ok := vpnClient.([]interface{})[0].(map[string]interface{}); ok {
if vpnClientConfig["radius_server_address"] != "" {
if !validIP4(vpnClientConfig["radius_server_address"].(string)) {
return fmt.Errorf("radius_server_address is not an IPv4 address")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This validation can be done in the schema, for example:

				ValidateFunc: validation.StringMatch(
					regexp.MustCompile("^[-a-z0-9]{3,50}$"),
					"Cosmos DB Account name must be 3 - 50 characters long, contain only letters, numbers and hyphens.",
				),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema is indeed a better place to do this check.

if !validIP4(vpnClientConfig["radius_server_address"].(string)) {
return fmt.Errorf("radius_server_address is not an IPv4 address")
}
if vpnClientConfig["radius_server_secret"] == "" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, could be validated by schema & regex


if vpnClient, ok := diff.GetOk("vpn_client_configuration"); ok {
if vpnClientConfig, ok := vpnClient.([]interface{})[0].(map[string]interface{}); ok {
if vpnClientConfig["radius_server_address"] != "" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what you want to do here is check to make sure one or the other is set as mentioned above?

as in:

_, hasRadius := vpnClientConfig["radius_server_address"]
_, hasRootCert := vpnClientConfig["root_certificate"]

if !hasRadius && !hasRootCert {
    #error
}

if hasRadius {
    if _, hasRadiusSecret := vpnClientConfig["radius_server_secret"]; !hasRadiusSecret {
        #error
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this hasRadius and hasRootCert are set to true. I have changed a bit the logic to check if both radius server address and value are set. If this neither of them are set, we can assume that we are using the certificate method and nil is accepted.

return nil
}

func validIP4(ipAddress string) bool {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we rename this to validateIP4?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed since this is done in the schema.

@@ -269,11 +276,20 @@ resource "azurerm_virtual_network_gateway" "test" {
private_ip_address_allocation = "Dynamic"
subnet_id = "${azurerm_subnet.test.id}"
}

vpn_client_configuration {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add an entirely new test for these properties instead of adding them to an existing test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, done.

@katbyte katbyte modified the milestones: 1.7.0, Soon Jun 12, 2018
@dcaro
Copy link
Contributor Author

dcaro commented Jun 14, 2018

I have just pushed an update with the changes that you have suggested. Let me know if there are any other points. Thanks for the review.

Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes @dcaro! This LGTM now 👍

@katbyte
Copy link
Collaborator

katbyte commented Jun 15, 2018

Tests pass aside from the usual flakiness:

screen shot 2018-06-14 at 23 48 23

screen shot 2018-06-14 at 23 48 43

@katbyte katbyte merged commit 66d9de4 into hashicorp:master Jun 15, 2018
@katbyte katbyte modified the milestones: Soon, 1.7.0 Jun 15, 2018
katbyte added a commit that referenced this pull request Jun 15, 2018
@Phydeauxman
Copy link

I am trying to use the new vpn_client_protocol argument and it is not working. I am running Terraform v0.11.7 and provider.azurerm v1.8.0. The output I am getting from plan is:

Error: azurerm_virtual_network_gateway.sdvnet: vpn_client_configuration.0: invalid or unknown key: vpn_client_protocol

@ghost
Copy link

ghost commented Mar 30, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 hashibot-feedback@hashicorp.com. Thanks!

@hashicorp hashicorp locked and limited conversation to collaborators Mar 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants