github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/azure/arm/config_test.go (about)

     1  package arm
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/Azure/azure-sdk-for-go/arm/compute"
    10  	"github.com/hashicorp/packer/builder/azure/common/constants"
    11  	"github.com/hashicorp/packer/packer"
    12  )
    13  
    14  // List of configuration parameters that are required by the ARM builder.
    15  var requiredConfigValues = []string{
    16  	"capture_name_prefix",
    17  	"capture_container_name",
    18  	"client_id",
    19  	"client_secret",
    20  	"image_offer",
    21  	"image_publisher",
    22  	"image_sku",
    23  	"location",
    24  	"os_type",
    25  	"storage_account",
    26  	"resource_group_name",
    27  	"subscription_id",
    28  }
    29  
    30  func TestConfigShouldProvideReasonableDefaultValues(t *testing.T) {
    31  	c, _, err := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
    32  
    33  	if err != nil {
    34  		t.Error("Expected configuration creation to succeed, but it failed!\n")
    35  		t.Fatalf(" errors: %s\n", err)
    36  	}
    37  
    38  	if c.UserName == "" {
    39  		t.Error("Expected 'UserName' to be populated, but it was empty!")
    40  	}
    41  
    42  	if c.VMSize == "" {
    43  		t.Error("Expected 'VMSize' to be populated, but it was empty!")
    44  	}
    45  
    46  	if c.ObjectID != "" {
    47  		t.Errorf("Expected 'ObjectID' to be nil, but it was '%s'!", c.ObjectID)
    48  	}
    49  
    50  	if c.managedImageStorageAccountType == "" {
    51  		t.Errorf("Expected 'managedImageStorageAccountType' to be populated, but it was empty!")
    52  	}
    53  }
    54  
    55  func TestConfigShouldBeAbleToOverrideDefaultedValues(t *testing.T) {
    56  	builderValues := getArmBuilderConfiguration()
    57  	builderValues["ssh_password"] = "override_password"
    58  	builderValues["ssh_username"] = "override_username"
    59  	builderValues["vm_size"] = "override_vm_size"
    60  	builderValues["communicator"] = "ssh"
    61  	builderValues["managed_image_storage_account_type"] = "Premium_LRS"
    62  
    63  	c, _, err := newConfig(builderValues, getPackerConfiguration())
    64  
    65  	if err != nil {
    66  		t.Fatalf("newConfig failed: %s", err)
    67  	}
    68  
    69  	if c.Password != "override_password" {
    70  		t.Errorf("Expected 'Password' to be set to 'override_password', but found %q!", c.Password)
    71  	}
    72  
    73  	if c.Comm.SSHPassword != "override_password" {
    74  		t.Errorf("Expected 'c.Comm.SSHPassword' to be set to 'override_password', but found %q!", c.Comm.SSHPassword)
    75  	}
    76  
    77  	if c.UserName != "override_username" {
    78  		t.Errorf("Expected 'UserName' to be set to 'override_username', but found %q!", c.UserName)
    79  	}
    80  
    81  	if c.Comm.SSHUsername != "override_username" {
    82  		t.Errorf("Expected 'c.Comm.SSHUsername' to be set to 'override_username', but found %q!", c.Comm.SSHUsername)
    83  	}
    84  
    85  	if c.VMSize != "override_vm_size" {
    86  		t.Errorf("Expected 'vm_size' to be set to 'override_vm_size', but found %q!", c.VMSize)
    87  	}
    88  
    89  	if c.managedImageStorageAccountType != compute.PremiumLRS {
    90  		t.Errorf("Expected 'managed_image_storage_account_type' to be set to 'Premium_LRS', but found %q!", c.managedImageStorageAccountType)
    91  	}
    92  }
    93  
    94  func TestConfigShouldDefaultVMSizeToStandardA1(t *testing.T) {
    95  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
    96  
    97  	if c.VMSize != "Standard_A1" {
    98  		t.Errorf("Expected 'VMSize' to default to 'Standard_A1', but got '%s'.", c.VMSize)
    99  	}
   100  }
   101  
   102  func TestConfigShouldDefaultImageVersionToLatest(t *testing.T) {
   103  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   104  
   105  	if c.ImageVersion != "latest" {
   106  		t.Errorf("Expected 'ImageVersion' to default to 'latest', but got '%s'.", c.ImageVersion)
   107  	}
   108  }
   109  
   110  func TestConfigShouldNotDefaultImageVersionIfCustomImage(t *testing.T) {
   111  	config := map[string]string{
   112  		"capture_name_prefix":    "ignore",
   113  		"capture_container_name": "ignore",
   114  		"location":               "ignore",
   115  		"image_url":              "ignore",
   116  		"storage_account":        "ignore",
   117  		"resource_group_name":    "ignore",
   118  		"subscription_id":        "ignore",
   119  		"os_type":                constants.Target_Linux,
   120  		"communicator":           "none",
   121  	}
   122  
   123  	c, _, _ := newConfig(config, getPackerConfiguration())
   124  	if c.ImageVersion != "" {
   125  		t.Errorf("Expected 'ImageVersion' to empty, but got '%s'.", c.ImageVersion)
   126  	}
   127  }
   128  
   129  func TestConfigShouldNormalizeOSTypeCase(t *testing.T) {
   130  	config := map[string]string{
   131  		"capture_name_prefix":    "ignore",
   132  		"capture_container_name": "ignore",
   133  		"location":               "ignore",
   134  		"image_url":              "ignore",
   135  		"storage_account":        "ignore",
   136  		"resource_group_name":    "ignore",
   137  		"subscription_id":        "ignore",
   138  		"communicator":           "none",
   139  	}
   140  
   141  	os_types := map[string][]string{
   142  		constants.Target_Linux:   {"linux", "LiNuX"},
   143  		constants.Target_Windows: {"windows", "WiNdOWs"},
   144  	}
   145  
   146  	for k, v := range os_types {
   147  		for _, os_type := range v {
   148  			config["os_type"] = os_type
   149  			c, _, err := newConfig(config, getPackerConfiguration())
   150  			if err != nil {
   151  				t.Fatalf("Expected config to accept the value %q, but it did not", os_type)
   152  			}
   153  
   154  			if c.OSType != k {
   155  				t.Fatalf("Expected config to normalize the value %q to %q, but it did not", os_type, constants.Target_Linux)
   156  			}
   157  		}
   158  	}
   159  
   160  	bad_os_types := []string{"", "does-not-exist"}
   161  	for _, os_type := range bad_os_types {
   162  		config["os_type"] = os_type
   163  		_, _, err := newConfig(config, getPackerConfiguration())
   164  		if err == nil {
   165  			t.Fatalf("Expected config to not accept the value %q, but it did", os_type)
   166  		}
   167  	}
   168  }
   169  
   170  func TestConfigShouldRejectCustomImageAndMarketPlace(t *testing.T) {
   171  	config := map[string]string{
   172  		"capture_name_prefix":    "ignore",
   173  		"capture_container_name": "ignore",
   174  		"location":               "ignore",
   175  		"image_url":              "ignore",
   176  		"resource_group_name":    "ignore",
   177  		"storage_account":        "ignore",
   178  		"subscription_id":        "ignore",
   179  		"os_type":                constants.Target_Linux,
   180  		"communicator":           "none",
   181  	}
   182  	packerConfiguration := getPackerConfiguration()
   183  	marketPlace := []string{"image_publisher", "image_offer", "image_sku"}
   184  
   185  	for _, x := range marketPlace {
   186  		config[x] = "ignore"
   187  		_, _, err := newConfig(config, packerConfiguration)
   188  		if err == nil {
   189  			t.Errorf("Expected Config to reject image_url and %s, but it did not", x)
   190  		}
   191  	}
   192  }
   193  
   194  func TestConfigVirtualNetworkNameIsOptional(t *testing.T) {
   195  	config := map[string]string{
   196  		"capture_name_prefix":    "ignore",
   197  		"capture_container_name": "ignore",
   198  		"location":               "ignore",
   199  		"image_url":              "ignore",
   200  		"storage_account":        "ignore",
   201  		"resource_group_name":    "ignore",
   202  		"subscription_id":        "ignore",
   203  		"os_type":                constants.Target_Linux,
   204  		"communicator":           "none",
   205  		"virtual_network_name":   "MyVirtualNetwork",
   206  	}
   207  
   208  	c, _, _ := newConfig(config, getPackerConfiguration())
   209  	if c.VirtualNetworkName != "MyVirtualNetwork" {
   210  		t.Errorf("Expected Config to set virtual_network_name to MyVirtualNetwork, but got %q", c.VirtualNetworkName)
   211  	}
   212  	if c.VirtualNetworkResourceGroupName != "" {
   213  		t.Errorf("Expected Config to leave virtual_network_resource_group_name to '', but got %q", c.VirtualNetworkResourceGroupName)
   214  	}
   215  	if c.VirtualNetworkSubnetName != "" {
   216  		t.Errorf("Expected Config to leave virtual_network_subnet_name to '', but got %q", c.VirtualNetworkSubnetName)
   217  	}
   218  }
   219  
   220  // The user can pass the value virtual_network_resource_group_name to avoid the lookup of
   221  // a virtual network's resource group, or to help with disambiguation.  The value should
   222  // only be set if virtual_network_name was set.
   223  func TestConfigVirtualNetworkResourceGroupNameMustBeSetWithVirtualNetworkName(t *testing.T) {
   224  	config := map[string]string{
   225  		"capture_name_prefix":                 "ignore",
   226  		"capture_container_name":              "ignore",
   227  		"location":                            "ignore",
   228  		"image_url":                           "ignore",
   229  		"storage_account":                     "ignore",
   230  		"resource_group_name":                 "ignore",
   231  		"subscription_id":                     "ignore",
   232  		"os_type":                             constants.Target_Linux,
   233  		"communicator":                        "none",
   234  		"virtual_network_resource_group_name": "MyVirtualNetworkRG",
   235  	}
   236  
   237  	_, _, err := newConfig(config, getPackerConfiguration())
   238  	if err == nil {
   239  		t.Error("Expected Config to reject virtual_network_resource_group_name, if virtual_network_name is not set.")
   240  	}
   241  }
   242  
   243  // The user can pass the value virtual_network_subnet_name to avoid the lookup of
   244  // a virtual network subnet's name, or to help with disambiguation.  The value should
   245  // only be set if virtual_network_name was set.
   246  func TestConfigVirtualNetworkSubnetNameMustBeSetWithVirtualNetworkName(t *testing.T) {
   247  	config := map[string]string{
   248  		"capture_name_prefix":         "ignore",
   249  		"capture_container_name":      "ignore",
   250  		"location":                    "ignore",
   251  		"image_url":                   "ignore",
   252  		"storage_account":             "ignore",
   253  		"resource_group_name":         "ignore",
   254  		"subscription_id":             "ignore",
   255  		"os_type":                     constants.Target_Linux,
   256  		"communicator":                "none",
   257  		"virtual_network_subnet_name": "MyVirtualNetworkRG",
   258  	}
   259  
   260  	_, _, err := newConfig(config, getPackerConfiguration())
   261  	if err == nil {
   262  		t.Error("Expected Config to reject virtual_network_subnet_name, if virtual_network_name is not set.")
   263  	}
   264  }
   265  
   266  func TestConfigShouldDefaultToPublicCloud(t *testing.T) {
   267  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   268  
   269  	if c.CloudEnvironmentName != "Public" {
   270  		t.Errorf("Expected 'CloudEnvironmentName' to default to 'Public', but got '%s'.", c.CloudEnvironmentName)
   271  	}
   272  
   273  	if c.cloudEnvironment == nil || c.cloudEnvironment.Name != "AzurePublicCloud" {
   274  		t.Errorf("Expected 'cloudEnvironment' to be set to 'AzurePublicCloud', but got '%s'.", c.cloudEnvironment)
   275  	}
   276  }
   277  
   278  func TestConfigInstantiatesCorrectAzureEnvironment(t *testing.T) {
   279  	config := map[string]string{
   280  		"capture_name_prefix":    "ignore",
   281  		"capture_container_name": "ignore",
   282  		"image_offer":            "ignore",
   283  		"image_publisher":        "ignore",
   284  		"image_sku":              "ignore",
   285  		"location":               "ignore",
   286  		"storage_account":        "ignore",
   287  		"resource_group_name":    "ignore",
   288  		"subscription_id":        "ignore",
   289  		"os_type":                constants.Target_Linux,
   290  		"communicator":           "none",
   291  	}
   292  
   293  	// user input is fun :)
   294  	var table = []struct {
   295  		name            string
   296  		environmentName string
   297  	}{
   298  		{"China", "AzureChinaCloud"},
   299  		{"ChinaCloud", "AzureChinaCloud"},
   300  		{"AzureChinaCloud", "AzureChinaCloud"},
   301  		{"aZuReChInAcLoUd", "AzureChinaCloud"},
   302  
   303  		{"USGovernment", "AzureUSGovernmentCloud"},
   304  		{"USGovernmentCloud", "AzureUSGovernmentCloud"},
   305  		{"AzureUSGovernmentCloud", "AzureUSGovernmentCloud"},
   306  		{"aZuReUsGoVeRnMeNtClOuD", "AzureUSGovernmentCloud"},
   307  
   308  		{"Public", "AzurePublicCloud"},
   309  		{"PublicCloud", "AzurePublicCloud"},
   310  		{"AzurePublicCloud", "AzurePublicCloud"},
   311  		{"aZuRePuBlIcClOuD", "AzurePublicCloud"},
   312  	}
   313  
   314  	packerConfiguration := getPackerConfiguration()
   315  
   316  	for _, x := range table {
   317  		config["cloud_environment_name"] = x.name
   318  		c, _, err := newConfig(config, packerConfiguration)
   319  		if err != nil {
   320  			t.Fatal(err)
   321  		}
   322  
   323  		if c.cloudEnvironment == nil || c.cloudEnvironment.Name != x.environmentName {
   324  			t.Errorf("Expected 'cloudEnvironment' to be set to '%s', but got '%s'.", x.environmentName, c.cloudEnvironment)
   325  		}
   326  	}
   327  }
   328  
   329  func TestUserShouldProvideRequiredValues(t *testing.T) {
   330  	builderValues := getArmBuilderConfiguration()
   331  
   332  	// Ensure we can successfully create a config.
   333  	_, _, err := newConfig(builderValues, getPackerConfiguration())
   334  	if err != nil {
   335  		t.Error("Expected configuration creation to succeed, but it failed!\n")
   336  		t.Fatalf(" -> %+v\n", builderValues)
   337  	}
   338  
   339  	// Take away a required element, and ensure construction fails.
   340  	for _, v := range requiredConfigValues {
   341  		originalValue := builderValues[v]
   342  		delete(builderValues, v)
   343  
   344  		_, _, err := newConfig(builderValues, getPackerConfiguration())
   345  		if err == nil {
   346  			t.Error("Expected configuration creation to fail, but it succeeded!\n")
   347  			t.Fatalf(" -> %+v\n", builderValues)
   348  		}
   349  
   350  		builderValues[v] = originalValue
   351  	}
   352  }
   353  
   354  func TestSystemShouldDefineRuntimeValues(t *testing.T) {
   355  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   356  
   357  	if c.Password == "" {
   358  		t.Errorf("Expected Password to not be empty, but it was '%s'!", c.Password)
   359  	}
   360  
   361  	if c.tmpComputeName == "" {
   362  		t.Errorf("Expected tmpComputeName to not be empty, but it was '%s'!", c.tmpComputeName)
   363  	}
   364  
   365  	if c.tmpDeploymentName == "" {
   366  		t.Errorf("Expected tmpDeploymentName to not be empty, but it was '%s'!", c.tmpDeploymentName)
   367  	}
   368  
   369  	if c.tmpResourceGroupName == "" {
   370  		t.Errorf("Expected tmpResourceGroupName to not be empty, but it was '%s'!", c.tmpResourceGroupName)
   371  	}
   372  
   373  	if c.tmpOSDiskName == "" {
   374  		t.Errorf("Expected tmpOSDiskName to not be empty, but it was '%s'!", c.tmpOSDiskName)
   375  	}
   376  }
   377  
   378  func TestConfigShouldTransformToVirtualMachineCaptureParameters(t *testing.T) {
   379  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   380  	parameters := c.toVirtualMachineCaptureParameters()
   381  
   382  	if *parameters.DestinationContainerName != c.CaptureContainerName {
   383  		t.Errorf("Expected DestinationContainerName to be equal to config's CaptureContainerName, but they were '%s' and '%s' respectively.", *parameters.DestinationContainerName, c.CaptureContainerName)
   384  	}
   385  
   386  	if *parameters.VhdPrefix != c.CaptureNamePrefix {
   387  		t.Errorf("Expected DestinationContainerName to be equal to config's CaptureContainerName, but they were '%s' and '%s' respectively.", *parameters.VhdPrefix, c.CaptureNamePrefix)
   388  	}
   389  
   390  	if *parameters.OverwriteVhds != false {
   391  		t.Error("Expected OverwriteVhds to be false, but it was not.")
   392  	}
   393  }
   394  
   395  func TestConfigShouldSupportPackersConfigElements(t *testing.T) {
   396  	c, _, err := newConfig(
   397  		getArmBuilderConfiguration(),
   398  		getPackerConfiguration(),
   399  		getPackerCommunicatorConfiguration())
   400  
   401  	if err != nil {
   402  		t.Fatal(err)
   403  	}
   404  
   405  	if c.Comm.SSHTimeout != 1*time.Hour {
   406  		t.Errorf("Expected Comm.SSHTimeout to be a duration of an hour, but got '%s' instead.", c.Comm.SSHTimeout)
   407  	}
   408  
   409  	if c.Comm.WinRMTimeout != 2*time.Hour {
   410  		t.Errorf("Expected Comm.WinRMTimeout to be a durationof two hours, but got '%s' instead.", c.Comm.WinRMTimeout)
   411  	}
   412  }
   413  
   414  func TestWinRMConfigShouldSetRoundTripDecorator(t *testing.T) {
   415  	config := getArmBuilderConfiguration()
   416  	config["communicator"] = "winrm"
   417  	config["winrm_username"] = "username"
   418  	config["winrm_password"] = "password"
   419  
   420  	c, _, err := newConfig(config, getPackerConfiguration())
   421  	if err != nil {
   422  		t.Fatal(err)
   423  	}
   424  
   425  	if c.Comm.WinRMTransportDecorator == nil {
   426  		t.Error("Expected WinRMTransportDecorator to be set, but it was nil")
   427  	}
   428  }
   429  
   430  func TestUserDeviceLoginIsEnabledForLinux(t *testing.T) {
   431  	config := map[string]string{
   432  		"capture_name_prefix":    "ignore",
   433  		"capture_container_name": "ignore",
   434  		"image_offer":            "ignore",
   435  		"image_publisher":        "ignore",
   436  		"image_sku":              "ignore",
   437  		"location":               "ignore",
   438  		"storage_account":        "ignore",
   439  		"resource_group_name":    "ignore",
   440  		"subscription_id":        "ignore",
   441  		"os_type":                constants.Target_Linux,
   442  		"communicator":           "none",
   443  	}
   444  
   445  	_, _, err := newConfig(config, getPackerConfiguration())
   446  	if err != nil {
   447  		t.Fatalf("failed to use device login for Linux: %s", err)
   448  	}
   449  }
   450  
   451  func TestUseDeviceLoginIsDisabledForWindows(t *testing.T) {
   452  	config := map[string]string{
   453  		"capture_name_prefix":    "ignore",
   454  		"capture_container_name": "ignore",
   455  		"image_offer":            "ignore",
   456  		"image_publisher":        "ignore",
   457  		"image_sku":              "ignore",
   458  		"location":               "ignore",
   459  		"storage_account":        "ignore",
   460  		"resource_group_name":    "ignore",
   461  		"subscription_id":        "ignore",
   462  		"os_type":                constants.Target_Windows,
   463  		"communicator":           "none",
   464  	}
   465  
   466  	_, _, err := newConfig(config, getPackerConfiguration())
   467  	if err == nil {
   468  		t.Fatal("Expected test to fail, but it succeeded")
   469  	}
   470  
   471  	multiError, _ := err.(*packer.MultiError)
   472  	if len(multiError.Errors) != 2 {
   473  		t.Errorf("Expected to find 2 errors, but found %d errors", len(multiError.Errors))
   474  	}
   475  
   476  	if !strings.Contains(err.Error(), "client_id must be specified") {
   477  		t.Error("Expected to find error for 'client_id must be specified")
   478  	}
   479  	if !strings.Contains(err.Error(), "client_secret must be specified") {
   480  		t.Error("Expected to find error for 'client_secret must be specified")
   481  	}
   482  }
   483  
   484  func TestConfigShouldRejectMalformedCaptureNamePrefix(t *testing.T) {
   485  	config := map[string]string{
   486  		"capture_container_name": "ignore",
   487  		"image_offer":            "ignore",
   488  		"image_publisher":        "ignore",
   489  		"image_sku":              "ignore",
   490  		"location":               "ignore",
   491  		"storage_account":        "ignore",
   492  		"resource_group_name":    "ignore",
   493  		"subscription_id":        "ignore",
   494  		"communicator":           "none",
   495  		// Does not matter for this test case, just pick one.
   496  		"os_type": constants.Target_Linux,
   497  	}
   498  
   499  	wellFormedCaptureNamePrefix := []string{
   500  		"packer",
   501  		"AbcdefghijklmnopqrstuvwX",
   502  		"hypen-hypen",
   503  		"0leading-number",
   504  		"v1.core.local",
   505  	}
   506  
   507  	for _, x := range wellFormedCaptureNamePrefix {
   508  		config["capture_name_prefix"] = x
   509  		_, _, err := newConfig(config, getPackerConfiguration())
   510  
   511  		if err != nil {
   512  			t.Errorf("Expected test to pass, but it failed with the well-formed capture_name_prefix set to %q.", x)
   513  		}
   514  	}
   515  
   516  	malformedCaptureNamePrefix := []string{
   517  		"-leading-hypen",
   518  		"trailing-hypen-",
   519  		"trailing-period.",
   520  		"_leading-underscore",
   521  		"punc-!@#$%^&*()_+-=-punc",
   522  		"There-are-too-many-characters-in-the-name-and-the-limit-is-twenty-four",
   523  	}
   524  
   525  	for _, x := range malformedCaptureNamePrefix {
   526  		config["capture_name_prefix"] = x
   527  		_, _, err := newConfig(config, getPackerConfiguration())
   528  
   529  		if err == nil {
   530  			t.Errorf("Expected test to fail, but it succeeded with the malformed capture_name_prefix set to %q.", x)
   531  		}
   532  	}
   533  }
   534  
   535  func TestConfigShouldRejectMalformedCaptureContainerName(t *testing.T) {
   536  	config := map[string]string{
   537  		"capture_name_prefix": "ignore",
   538  		"image_offer":         "ignore",
   539  		"image_publisher":     "ignore",
   540  		"image_sku":           "ignore",
   541  		"location":            "ignore",
   542  		"storage_account":     "ignore",
   543  		"resource_group_name": "ignore",
   544  		"subscription_id":     "ignore",
   545  		"communicator":        "none",
   546  		// Does not matter for this test case, just pick one.
   547  		"os_type": constants.Target_Linux,
   548  	}
   549  
   550  	wellFormedCaptureContainerName := []string{
   551  		"0leading",
   552  		"aleading",
   553  		"hype-hypen",
   554  		"abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz", // 63 characters
   555  	}
   556  
   557  	for _, x := range wellFormedCaptureContainerName {
   558  		config["capture_container_name"] = x
   559  		_, _, err := newConfig(config, getPackerConfiguration())
   560  
   561  		if err != nil {
   562  			t.Errorf("Expected test to pass, but it failed with the well-formed capture_container_name set to %q.", x)
   563  		}
   564  	}
   565  
   566  	malformedCaptureContainerName := []string{
   567  		"No-Capitals",
   568  		"double--hypens",
   569  		"-leading-hypen",
   570  		"trailing-hypen-",
   571  		"punc-!@#$%^&*()_+-=-punc",
   572  		"there-are-over-63-characters-in-this-string-and-that-is-a-bad-container-name",
   573  	}
   574  
   575  	for _, x := range malformedCaptureContainerName {
   576  		config["capture_container_name"] = x
   577  		_, _, err := newConfig(config, getPackerConfiguration())
   578  
   579  		if err == nil {
   580  			t.Errorf("Expected test to fail, but it succeeded with the malformed capture_container_name set to %q.", x)
   581  		}
   582  	}
   583  }
   584  
   585  func TestConfigShouldAcceptTags(t *testing.T) {
   586  	config := map[string]interface{}{
   587  		"capture_name_prefix":    "ignore",
   588  		"capture_container_name": "ignore",
   589  		"image_offer":            "ignore",
   590  		"image_publisher":        "ignore",
   591  		"image_sku":              "ignore",
   592  		"location":               "ignore",
   593  		"storage_account":        "ignore",
   594  		"resource_group_name":    "ignore",
   595  		"subscription_id":        "ignore",
   596  		"communicator":           "none",
   597  		// Does not matter for this test case, just pick one.
   598  		"os_type": constants.Target_Linux,
   599  		"azure_tags": map[string]string{
   600  			"tag01": "value01",
   601  			"tag02": "value02",
   602  		},
   603  	}
   604  
   605  	c, _, err := newConfig(config, getPackerConfiguration())
   606  
   607  	if err != nil {
   608  		t.Fatal(err)
   609  	}
   610  
   611  	if len(c.AzureTags) != 2 {
   612  		t.Fatalf("expected to find 2 tags, but got %d", len(c.AzureTags))
   613  	}
   614  
   615  	if _, ok := c.AzureTags["tag01"]; !ok {
   616  		t.Error("expected to find key=\"tag01\", but did not")
   617  	}
   618  	if _, ok := c.AzureTags["tag02"]; !ok {
   619  		t.Error("expected to find key=\"tag02\", but did not")
   620  	}
   621  
   622  	value := c.AzureTags["tag01"]
   623  	if *value != "value01" {
   624  		t.Errorf("expected AzureTags[\"tag01\"] to have value \"value01\", but got %q", value)
   625  	}
   626  
   627  	value = c.AzureTags["tag02"]
   628  	if *value != "value02" {
   629  		t.Errorf("expected AzureTags[\"tag02\"] to have value \"value02\", but got %q", value)
   630  	}
   631  }
   632  
   633  func TestConfigShouldRejectTagsInExcessOf15AcceptTags(t *testing.T) {
   634  	tooManyTags := map[string]string{}
   635  	for i := 0; i < 16; i++ {
   636  		tooManyTags[fmt.Sprintf("tag%.2d", i)] = "ignored"
   637  	}
   638  
   639  	config := map[string]interface{}{
   640  		"capture_name_prefix":    "ignore",
   641  		"capture_container_name": "ignore",
   642  		"image_offer":            "ignore",
   643  		"image_publisher":        "ignore",
   644  		"image_sku":              "ignore",
   645  		"location":               "ignore",
   646  		"storage_account":        "ignore",
   647  		"resource_group_name":    "ignore",
   648  		"subscription_id":        "ignore",
   649  		"communicator":           "none",
   650  		// Does not matter for this test case, just pick one.
   651  		"os_type":    constants.Target_Linux,
   652  		"azure_tags": tooManyTags,
   653  	}
   654  
   655  	_, _, err := newConfig(config, getPackerConfiguration())
   656  
   657  	if err == nil {
   658  		t.Fatal("expected config to reject based on an excessive amount of tags (> 15)")
   659  	}
   660  }
   661  
   662  func TestConfigShouldRejectExcessiveTagNameLength(t *testing.T) {
   663  	nameTooLong := make([]byte, 513)
   664  	for i := range nameTooLong {
   665  		nameTooLong[i] = 'a'
   666  	}
   667  
   668  	tags := map[string]string{}
   669  	tags[string(nameTooLong)] = "ignored"
   670  
   671  	config := map[string]interface{}{
   672  		"capture_name_prefix":    "ignore",
   673  		"capture_container_name": "ignore",
   674  		"image_offer":            "ignore",
   675  		"image_publisher":        "ignore",
   676  		"image_sku":              "ignore",
   677  		"location":               "ignore",
   678  		"storage_account":        "ignore",
   679  		"resource_group_name":    "ignore",
   680  		"subscription_id":        "ignore",
   681  		"communicator":           "none",
   682  		// Does not matter for this test case, just pick one.
   683  		"os_type":    constants.Target_Linux,
   684  		"azure_tags": tags,
   685  	}
   686  
   687  	_, _, err := newConfig(config, getPackerConfiguration())
   688  	if err == nil {
   689  		t.Fatal("expected config to reject tag name based on length (> 512)")
   690  	}
   691  }
   692  
   693  func TestConfigShouldRejectExcessiveTagValueLength(t *testing.T) {
   694  	valueTooLong := make([]byte, 257)
   695  	for i := range valueTooLong {
   696  		valueTooLong[i] = 'a'
   697  	}
   698  
   699  	tags := map[string]string{}
   700  	tags["tag01"] = string(valueTooLong)
   701  
   702  	config := map[string]interface{}{
   703  		"capture_name_prefix":    "ignore",
   704  		"capture_container_name": "ignore",
   705  		"image_offer":            "ignore",
   706  		"image_publisher":        "ignore",
   707  		"image_sku":              "ignore",
   708  		"location":               "ignore",
   709  		"storage_account":        "ignore",
   710  		"resource_group_name":    "ignore",
   711  		"subscription_id":        "ignore",
   712  		"communicator":           "none",
   713  		// Does not matter for this test case, just pick one.
   714  		"os_type":    constants.Target_Linux,
   715  		"azure_tags": tags,
   716  	}
   717  
   718  	_, _, err := newConfig(config, getPackerConfiguration())
   719  	if err == nil {
   720  		t.Fatal("expected config to reject tag value based on length (> 256)")
   721  	}
   722  }
   723  
   724  func TestConfigShouldRejectMissingCustomDataFile(t *testing.T) {
   725  	config := map[string]interface{}{
   726  		"capture_name_prefix":    "ignore",
   727  		"capture_container_name": "ignore",
   728  		"image_offer":            "ignore",
   729  		"image_publisher":        "ignore",
   730  		"image_sku":              "ignore",
   731  		"location":               "ignore",
   732  		"storage_account":        "ignore",
   733  		"resource_group_name":    "ignore",
   734  		"subscription_id":        "ignore",
   735  		"communicator":           "none",
   736  		// Does not matter for this test case, just pick one.
   737  		"os_type":          constants.Target_Linux,
   738  		"custom_data_file": "/this/file/does/not/exist",
   739  	}
   740  
   741  	_, _, err := newConfig(config, getPackerConfiguration())
   742  	if err == nil {
   743  		t.Fatal("expected config to reject missing custom data file")
   744  	}
   745  }
   746  
   747  func TestConfigShouldAcceptPlatformManagedImageBuild(t *testing.T) {
   748  	config := map[string]interface{}{
   749  		"image_offer":                       "ignore",
   750  		"image_publisher":                   "ignore",
   751  		"image_sku":                         "ignore",
   752  		"location":                          "ignore",
   753  		"subscription_id":                   "ignore",
   754  		"communicator":                      "none",
   755  		"managed_image_resource_group_name": "ignore",
   756  		"managed_image_name":                "ignore",
   757  
   758  		// Does not matter for this test case, just pick one.
   759  		"os_type": constants.Target_Linux,
   760  	}
   761  
   762  	_, _, err := newConfig(config, getPackerConfiguration())
   763  	if err != nil {
   764  		t.Fatal("expected config to accept platform managed image build")
   765  	}
   766  }
   767  
   768  // If the user specified a build for a VHD and a Managed Image it should be rejected.
   769  func TestConfigShouldRejectVhdAndManagedImageOutput(t *testing.T) {
   770  	config := map[string]interface{}{
   771  		"image_offer":                       "ignore",
   772  		"image_publisher":                   "ignore",
   773  		"image_sku":                         "ignore",
   774  		"location":                          "ignore",
   775  		"subscription_id":                   "ignore",
   776  		"communicator":                      "none",
   777  		"capture_container_name":            "ignore",
   778  		"capture_name_prefix":               "ignore",
   779  		"managed_image_resource_group_name": "ignore",
   780  		"managed_image_name":                "ignore",
   781  
   782  		// Does not matter for this test case, just pick one.
   783  		"os_type": constants.Target_Linux,
   784  	}
   785  
   786  	_, _, err := newConfig(config, getPackerConfiguration())
   787  	if err == nil {
   788  		t.Fatal("expected config to reject VHD and Managed Image build")
   789  	}
   790  }
   791  
   792  // If the user specified a build of a VHD, but started with a managed image it should be rejected.
   793  func TestConfigShouldRejectManagedImageSourceAndVhdOutput(t *testing.T) {
   794  	config := map[string]interface{}{
   795  		"image_url":                         "ignore",
   796  		"location":                          "ignore",
   797  		"subscription_id":                   "ignore",
   798  		"communicator":                      "none",
   799  		"managed_image_resource_group_name": "ignore",
   800  		"managed_image_name":                "ignore",
   801  
   802  		// Does not matter for this test case, just pick one.
   803  		"os_type": constants.Target_Linux,
   804  	}
   805  
   806  	_, _, err := newConfig(config, getPackerConfiguration())
   807  	if err == nil {
   808  		t.Fatal("expected config to reject VHD and Managed Image build")
   809  	}
   810  }
   811  
   812  func TestConfigShouldRejectCustomAndPlatformManagedImageBuild(t *testing.T) {
   813  	config := map[string]interface{}{
   814  		"custom_managed_image_resource_group_name": "ignore",
   815  		"custom_managed_image_name":                "ignore",
   816  		"image_offer":                              "ignore",
   817  		"image_publisher":                          "ignore",
   818  		"image_sku":                                "ignore",
   819  		"location":                                 "ignore",
   820  		"subscription_id":                          "ignore",
   821  		"communicator":                             "none",
   822  		"managed_image_resource_group_name":        "ignore",
   823  		"managed_image_name":                       "ignore",
   824  
   825  		// Does not matter for this test case, just pick one.
   826  		"os_type": constants.Target_Linux,
   827  	}
   828  
   829  	_, _, err := newConfig(config, getPackerConfiguration())
   830  	if err == nil {
   831  		t.Fatal("expected config to reject custom and platform input for a managed image build")
   832  	}
   833  }
   834  
   835  func TestConfigShouldRejectCustomAndImageUrlForManagedImageBuild(t *testing.T) {
   836  	config := map[string]interface{}{
   837  		"image_url":                                "ignore",
   838  		"custom_managed_image_resource_group_name": "ignore",
   839  		"custom_managed_image_name":                "ignore",
   840  		"location":                                 "ignore",
   841  		"subscription_id":                          "ignore",
   842  		"communicator":                             "none",
   843  		"managed_image_resource_group_name":        "ignore",
   844  		"managed_image_name":                       "ignore",
   845  
   846  		// Does not matter for this test case, just pick one.
   847  		"os_type": constants.Target_Linux,
   848  	}
   849  
   850  	_, _, err := newConfig(config, getPackerConfiguration())
   851  	if err == nil {
   852  		t.Fatal("expected config to reject custom and platform input for a managed image build")
   853  	}
   854  }
   855  
   856  func TestConfigShouldRejectMalformedManageImageStorageAccountTypes(t *testing.T) {
   857  	config := map[string]interface{}{
   858  		"custom_managed_image_resource_group_name": "ignore",
   859  		"custom_managed_image_name":                "ignore",
   860  		"location":                                 "ignore",
   861  		"subscription_id":                          "ignore",
   862  		"communicator":                             "none",
   863  		"managed_image_resource_group_name":        "ignore",
   864  		"managed_image_name":                       "ignore",
   865  		"managed_image_storage_account_type":       "--invalid--",
   866  
   867  		// Does not matter for this test case, just pick one.
   868  		"os_type": constants.Target_Linux,
   869  	}
   870  
   871  	_, _, err := newConfig(config, getPackerConfiguration())
   872  	if err == nil {
   873  		t.Fatal("expected config to reject custom and platform input for a managed image build")
   874  	}
   875  }
   876  
   877  func TestConfigShouldAcceptManagedImageStorageAccountTypes(t *testing.T) {
   878  	config := map[string]interface{}{
   879  		"custom_managed_image_resource_group_name": "ignore",
   880  		"custom_managed_image_name":                "ignore",
   881  		"location":                                 "ignore",
   882  		"subscription_id":                          "ignore",
   883  		"communicator":                             "none",
   884  		"managed_image_resource_group_name":        "ignore",
   885  		"managed_image_name":                       "ignore",
   886  
   887  		// Does not matter for this test case, just pick one.
   888  		"os_type": constants.Target_Linux,
   889  	}
   890  
   891  	storage_account_types := []string{"Premium_LRS", "Standard_LRS"}
   892  
   893  	for _, x := range storage_account_types {
   894  		config["managed_image_storage_account_type"] = x
   895  		_, _, err := newConfig(config, getPackerConfiguration())
   896  		if err != nil {
   897  			t.Fatalf("expected config to accept a managed_image_storage_account_type of %q", x)
   898  		}
   899  	}
   900  }
   901  
   902  func getArmBuilderConfiguration() map[string]string {
   903  	m := make(map[string]string)
   904  	for _, v := range requiredConfigValues {
   905  		m[v] = "ignored00"
   906  	}
   907  
   908  	m["communicator"] = "none"
   909  	m["os_type"] = constants.Target_Linux
   910  	return m
   911  }
   912  
   913  func getArmBuilderConfigurationWithWindows() map[string]string {
   914  	m := make(map[string]string)
   915  	for _, v := range requiredConfigValues {
   916  		m[v] = "ignored00"
   917  	}
   918  
   919  	m["object_id"] = "ignored00"
   920  	m["tenant_id"] = "ignored00"
   921  	m["winrm_username"] = "ignored00"
   922  	m["communicator"] = "winrm"
   923  	m["os_type"] = constants.Target_Windows
   924  	return m
   925  }
   926  
   927  func getPackerConfiguration() interface{} {
   928  	config := map[string]interface{}{
   929  		"packer_build_name":    "azure-arm-vm",
   930  		"packer_builder_type":  "azure-arm-vm",
   931  		"packer_debug":         "false",
   932  		"packer_force":         "false",
   933  		"packer_template_path": "/home/jenkins/azure-arm-vm/template.json",
   934  	}
   935  
   936  	return config
   937  }
   938  
   939  func getPackerCommunicatorConfiguration() map[string]string {
   940  	config := map[string]string{
   941  		"ssh_timeout":   "1h",
   942  		"winrm_timeout": "2h",
   943  	}
   944  
   945  	return config
   946  }