Adding config to specify allowed inbound IP addresses and CIDR blocks (#1)

* Adding config to specify allowed inbound IP addresses

* Also allowing CIDR blocks in addition to IP addresses
This commit is contained in:
Sumit Kalra 2019-09-24 09:34:19 -07:00 committed by sumit-kalra​​
parent 7a554e3cd3
commit 132779c343
2 changed files with 125 additions and 0 deletions

View File

@ -12,6 +12,7 @@ import (
"fmt"
"io/ioutil"
"math/big"
"net"
"regexp"
"strings"
"time"
@ -342,6 +343,11 @@ type Config struct {
// are None, ReadOnly, and ReadWrite. The default value is ReadWrite.
DiskCachingType string `mapstructure:"disk_caching_type" required:"false"`
diskCachingType compute.CachingTypes
// Specify the list of IP addresses and CIDR blocks that should be
// allowed access to the VM. If provided, an Azure Network Security
// Group will be created with corresponding rules and be bound to
// the NIC attached to the VM.
AllowedInboundIpAddresses []string `mapstructure:"allowed_inbound_ip_addresses"`
// Runtime Values
UserName string
@ -872,6 +878,12 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("If virtual_network_subnet_name is specified, so must virtual_network_name"))
}
if c.AllowedInboundIpAddresses != nil && len(c.AllowedInboundIpAddresses) >= 1 {
if ok, err := assertAllowedInboundIpAddresses(c.AllowedInboundIpAddresses, "allowed_inbound_ip_addresses"); !ok {
errs = packer.MultiErrorAppend(errs, err)
}
}
/////////////////////////////////////////////
// Plan Info
if c.PlanInfo.PlanName != "" || c.PlanInfo.PlanProduct != "" || c.PlanInfo.PlanPublisher != "" || c.PlanInfo.PlanPromotionCode != "" {
@ -943,6 +955,17 @@ func assertManagedImageDataDiskSnapshotName(name, setting string) (bool, error)
return true, nil
}
func assertAllowedInboundIpAddresses(ipAddresses []string, setting string) (bool, error) {
for _, ipAddress := range ipAddresses {
if net.ParseIP(ipAddress) == nil {
if _, _, err := net.ParseCIDR(ipAddress); err != nil {
return false, fmt.Errorf("The setting %s must only contain valid IP addresses or CIDR blocks", setting)
}
}
}
return true, nil
}
func assertResourceGroupName(rgn, setting string) (bool, error) {
if !isValidAzureName(reResourceGroupName, rgn) {
return false, fmt.Errorf("The setting %s must match the regular expression %q, and not end with a '-' or '.'.", setting, validResourceGroupNameRe)

View File

@ -270,6 +270,108 @@ func TestConfigVirtualNetworkSubnetNameMustBeSetWithVirtualNetworkName(t *testin
}
}
func TestConfigAllowedInboundIpAddressesIsOptional(t *testing.T) {
config := map[string]string{
"capture_name_prefix": "ignore",
"capture_container_name": "ignore",
"location": "ignore",
"image_url": "ignore",
"storage_account": "ignore",
"resource_group_name": "ignore",
"subscription_id": "ignore",
"os_type": constants.Target_Linux,
"communicator": "none",
"virtual_network_name": "MyVirtualNetwork",
}
c, _, err := newConfig(config, getPackerConfiguration())
if err != nil {
t.Fatal(err)
}
if c.AllowedInboundIpAddresses != nil {
t.Errorf("Expected Config to set allowed_inbound_ip_addresses to nil, but got %v", c.AllowedInboundIpAddresses)
}
}
func TestConfigShouldAcceptCorrectInboundIpAddresses(t *testing.T) {
ipValue0 := "127.0.0.1"
ipValue1 := "127.0.0.2"
cidrValue2 := "192.168.100.0/24"
cidrValue3 := "10.10.1.16/32"
config := map[string]interface{}{
"capture_name_prefix": "ignore",
"capture_container_name": "ignore",
"location": "ignore",
"image_url": "ignore",
"storage_account": "ignore",
"resource_group_name": "ignore",
"subscription_id": "ignore",
"os_type": constants.Target_Linux,
"communicator": "none",
"virtual_network_name": "MyVirtualNetwork",
}
config["allowed_inbound_ip_addresses"] = ipValue0
c, _, err := newConfig(config, getPackerConfiguration())
if err != nil {
t.Fatal(err)
}
if c.AllowedInboundIpAddresses == nil || len(c.AllowedInboundIpAddresses) != 1 ||
c.AllowedInboundIpAddresses[0] != ipValue0 {
t.Errorf("Expected 'allowed_inbound_ip_addresses' to have one element (%s), but got '%v'.", ipValue0, c.AllowedInboundIpAddresses)
}
config["allowed_inbound_ip_addresses"] = cidrValue2
c, _, err = newConfig(config, getPackerConfiguration())
if err != nil {
t.Fatal(err)
}
if c.AllowedInboundIpAddresses == nil || len(c.AllowedInboundIpAddresses) != 1 ||
c.AllowedInboundIpAddresses[0] != cidrValue2 {
t.Errorf("Expected 'allowed_inbound_ip_addresses' to have one element (%s), but got '%v'.", cidrValue2, c.AllowedInboundIpAddresses)
}
config["allowed_inbound_ip_addresses"] = []string{ipValue0, cidrValue2, ipValue1, cidrValue3}
c, _, err = newConfig(config, getPackerConfiguration())
if err != nil {
t.Fatal(err)
}
if c.AllowedInboundIpAddresses == nil || len(c.AllowedInboundIpAddresses) != 4 ||
c.AllowedInboundIpAddresses[0] != ipValue0 || c.AllowedInboundIpAddresses[1] != cidrValue2 ||
c.AllowedInboundIpAddresses[2] != ipValue1 || c.AllowedInboundIpAddresses[3] != cidrValue3 {
t.Errorf("Expected 'allowed_inbound_ip_addresses' to have four elements (%s %s %s %s), but got '%v'.", ipValue0, cidrValue2, ipValue1,
cidrValue3, c.AllowedInboundIpAddresses)
}
}
func TestConfigShouldRejectIncorrectInboundIpAddresses(t *testing.T) {
config := map[string]interface{}{
"capture_name_prefix": "ignore",
"capture_container_name": "ignore",
"location": "ignore",
"image_url": "ignore",
"storage_account": "ignore",
"resource_group_name": "ignore",
"subscription_id": "ignore",
"os_type": constants.Target_Linux,
"communicator": "none",
"virtual_network_name": "MyVirtualNetwork",
}
config["allowed_inbound_ip_addresses"] = []string{"127.0.0.1", "127.0.0.two"}
c, _, err := newConfig(config, getPackerConfiguration())
if err == nil {
t.Errorf("Expected configuration creation to fail, but it succeeded with the malformed allowed_inbound_ip_addresses set to %v", c.AllowedInboundIpAddresses)
}
config["allowed_inbound_ip_addresses"] = []string{"192.168.100.1000/24", "10.10.1.16/32"}
c, _, err = newConfig(config, getPackerConfiguration())
if err == nil {
// 192.168.100.1000/24 is invalid
t.Errorf("Expected configuration creation to fail, but it succeeded with the malformed allowed_inbound_ip_addresses set to %v", c.AllowedInboundIpAddresses)
}
}
func TestConfigShouldDefaultToPublicCloud(t *testing.T) {
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())