github.com/mitchellh/packer@v1.3.2/builder/azure/arm/config_test.go (about)

     1  package arm
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute"
     9  	"github.com/hashicorp/packer/builder/azure/common/constants"
    10  )
    11  
    12  // List of configuration parameters that are required by the ARM builder.
    13  var requiredConfigValues = []string{
    14  	"capture_name_prefix",
    15  	"capture_container_name",
    16  	"client_id",
    17  	"client_secret",
    18  	"image_offer",
    19  	"image_publisher",
    20  	"image_sku",
    21  	"location",
    22  	"os_type",
    23  	"storage_account",
    24  	"resource_group_name",
    25  	"subscription_id",
    26  }
    27  
    28  func TestConfigShouldProvideReasonableDefaultValues(t *testing.T) {
    29  	c, _, err := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
    30  
    31  	if err != nil {
    32  		t.Error("Expected configuration creation to succeed, but it failed!\n")
    33  		t.Fatalf(" errors: %s\n", err)
    34  	}
    35  
    36  	if c.UserName == "" {
    37  		t.Error("Expected 'UserName' to be populated, but it was empty!")
    38  	}
    39  
    40  	if c.VMSize == "" {
    41  		t.Error("Expected 'VMSize' to be populated, but it was empty!")
    42  	}
    43  
    44  	if c.ObjectID != "" {
    45  		t.Errorf("Expected 'ObjectID' to be nil, but it was '%s'!", c.ObjectID)
    46  	}
    47  
    48  	if c.managedImageStorageAccountType == "" {
    49  		t.Errorf("Expected 'managedImageStorageAccountType' to be populated, but it was empty!")
    50  	}
    51  }
    52  
    53  func TestConfigShouldBeAbleToOverrideDefaultedValues(t *testing.T) {
    54  	builderValues := getArmBuilderConfiguration()
    55  	builderValues["ssh_password"] = "override_password"
    56  	builderValues["ssh_username"] = "override_username"
    57  	builderValues["vm_size"] = "override_vm_size"
    58  	builderValues["communicator"] = "ssh"
    59  	builderValues["managed_image_storage_account_type"] = "Premium_LRS"
    60  
    61  	c, _, err := newConfig(builderValues, getPackerConfiguration())
    62  
    63  	if err != nil {
    64  		t.Fatalf("newConfig failed: %s", err)
    65  	}
    66  
    67  	if c.Password != "override_password" {
    68  		t.Errorf("Expected 'Password' to be set to 'override_password', but found %q!", c.Password)
    69  	}
    70  
    71  	if c.Comm.SSHPassword != "override_password" {
    72  		t.Errorf("Expected 'c.Comm.SSHPassword' to be set to 'override_password', but found %q!", c.Comm.SSHPassword)
    73  	}
    74  
    75  	if c.UserName != "override_username" {
    76  		t.Errorf("Expected 'UserName' to be set to 'override_username', but found %q!", c.UserName)
    77  	}
    78  
    79  	if c.Comm.SSHUsername != "override_username" {
    80  		t.Errorf("Expected 'c.Comm.SSHUsername' to be set to 'override_username', but found %q!", c.Comm.SSHUsername)
    81  	}
    82  
    83  	if c.VMSize != "override_vm_size" {
    84  		t.Errorf("Expected 'vm_size' to be set to 'override_vm_size', but found %q!", c.VMSize)
    85  	}
    86  
    87  	if c.managedImageStorageAccountType != compute.StorageAccountTypesPremiumLRS {
    88  		t.Errorf("Expected 'managed_image_storage_account_type' to be set to 'Premium_LRS', but found %q!", c.managedImageStorageAccountType)
    89  	}
    90  }
    91  
    92  func TestConfigShouldDefaultVMSizeToStandardA1(t *testing.T) {
    93  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
    94  
    95  	if c.VMSize != "Standard_A1" {
    96  		t.Errorf("Expected 'VMSize' to default to 'Standard_A1', but got '%s'.", c.VMSize)
    97  	}
    98  }
    99  
   100  func TestConfigShouldDefaultImageVersionToLatest(t *testing.T) {
   101  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   102  
   103  	if c.ImageVersion != "latest" {
   104  		t.Errorf("Expected 'ImageVersion' to default to 'latest', but got '%s'.", c.ImageVersion)
   105  	}
   106  }
   107  
   108  func TestConfigShouldNotDefaultImageVersionIfCustomImage(t *testing.T) {
   109  	config := map[string]string{
   110  		"capture_name_prefix":    "ignore",
   111  		"capture_container_name": "ignore",
   112  		"location":               "ignore",
   113  		"image_url":              "ignore",
   114  		"storage_account":        "ignore",
   115  		"resource_group_name":    "ignore",
   116  		"subscription_id":        "ignore",
   117  		"os_type":                constants.Target_Linux,
   118  		"communicator":           "none",
   119  	}
   120  
   121  	c, _, _ := newConfig(config, getPackerConfiguration())
   122  	if c.ImageVersion != "" {
   123  		t.Errorf("Expected 'ImageVersion' to empty, but got '%s'.", c.ImageVersion)
   124  	}
   125  }
   126  
   127  func TestConfigShouldNormalizeOSTypeCase(t *testing.T) {
   128  	config := map[string]string{
   129  		"capture_name_prefix":    "ignore",
   130  		"capture_container_name": "ignore",
   131  		"location":               "ignore",
   132  		"image_url":              "ignore",
   133  		"storage_account":        "ignore",
   134  		"resource_group_name":    "ignore",
   135  		"subscription_id":        "ignore",
   136  		"communicator":           "none",
   137  	}
   138  
   139  	os_types := map[string][]string{
   140  		constants.Target_Linux:   {"linux", "LiNuX"},
   141  		constants.Target_Windows: {"windows", "WiNdOWs"},
   142  	}
   143  
   144  	for k, v := range os_types {
   145  		for _, os_type := range v {
   146  			config["os_type"] = os_type
   147  			c, _, err := newConfig(config, getPackerConfiguration())
   148  			if err != nil {
   149  				t.Fatalf("Expected config to accept the value %q, but it did not", os_type)
   150  			}
   151  
   152  			if c.OSType != k {
   153  				t.Fatalf("Expected config to normalize the value %q to %q, but it did not", os_type, constants.Target_Linux)
   154  			}
   155  		}
   156  	}
   157  
   158  	bad_os_types := []string{"", "does-not-exist"}
   159  	for _, os_type := range bad_os_types {
   160  		config["os_type"] = os_type
   161  		_, _, err := newConfig(config, getPackerConfiguration())
   162  		if err == nil {
   163  			t.Fatalf("Expected config to not accept the value %q, but it did", os_type)
   164  		}
   165  	}
   166  }
   167  
   168  func TestConfigShouldRejectCustomImageAndMarketPlace(t *testing.T) {
   169  	config := map[string]string{
   170  		"capture_name_prefix":    "ignore",
   171  		"capture_container_name": "ignore",
   172  		"location":               "ignore",
   173  		"image_url":              "ignore",
   174  		"resource_group_name":    "ignore",
   175  		"storage_account":        "ignore",
   176  		"subscription_id":        "ignore",
   177  		"os_type":                constants.Target_Linux,
   178  		"communicator":           "none",
   179  	}
   180  	packerConfiguration := getPackerConfiguration()
   181  	marketPlace := []string{"image_publisher", "image_offer", "image_sku"}
   182  
   183  	for _, x := range marketPlace {
   184  		config[x] = "ignore"
   185  		_, _, err := newConfig(config, packerConfiguration)
   186  		if err == nil {
   187  			t.Errorf("Expected Config to reject image_url and %s, but it did not", x)
   188  		}
   189  	}
   190  }
   191  
   192  func TestConfigVirtualNetworkNameIsOptional(t *testing.T) {
   193  	config := map[string]string{
   194  		"capture_name_prefix":    "ignore",
   195  		"capture_container_name": "ignore",
   196  		"location":               "ignore",
   197  		"image_url":              "ignore",
   198  		"storage_account":        "ignore",
   199  		"resource_group_name":    "ignore",
   200  		"subscription_id":        "ignore",
   201  		"os_type":                constants.Target_Linux,
   202  		"communicator":           "none",
   203  		"virtual_network_name":   "MyVirtualNetwork",
   204  	}
   205  
   206  	c, _, _ := newConfig(config, getPackerConfiguration())
   207  	if c.VirtualNetworkName != "MyVirtualNetwork" {
   208  		t.Errorf("Expected Config to set virtual_network_name to MyVirtualNetwork, but got %q", c.VirtualNetworkName)
   209  	}
   210  	if c.VirtualNetworkResourceGroupName != "" {
   211  		t.Errorf("Expected Config to leave virtual_network_resource_group_name to '', but got %q", c.VirtualNetworkResourceGroupName)
   212  	}
   213  	if c.VirtualNetworkSubnetName != "" {
   214  		t.Errorf("Expected Config to leave virtual_network_subnet_name to '', but got %q", c.VirtualNetworkSubnetName)
   215  	}
   216  }
   217  
   218  // The user can pass the value virtual_network_resource_group_name to avoid the lookup of
   219  // a virtual network's resource group, or to help with disambiguation.  The value should
   220  // only be set if virtual_network_name was set.
   221  func TestConfigVirtualNetworkResourceGroupNameMustBeSetWithVirtualNetworkName(t *testing.T) {
   222  	config := map[string]string{
   223  		"capture_name_prefix":                 "ignore",
   224  		"capture_container_name":              "ignore",
   225  		"location":                            "ignore",
   226  		"image_url":                           "ignore",
   227  		"storage_account":                     "ignore",
   228  		"resource_group_name":                 "ignore",
   229  		"subscription_id":                     "ignore",
   230  		"os_type":                             constants.Target_Linux,
   231  		"communicator":                        "none",
   232  		"virtual_network_resource_group_name": "MyVirtualNetworkRG",
   233  	}
   234  
   235  	_, _, err := newConfig(config, getPackerConfiguration())
   236  	if err == nil {
   237  		t.Error("Expected Config to reject virtual_network_resource_group_name, if virtual_network_name is not set.")
   238  	}
   239  }
   240  
   241  // The user can pass the value virtual_network_subnet_name to avoid the lookup of
   242  // a virtual network subnet's name, or to help with disambiguation.  The value should
   243  // only be set if virtual_network_name was set.
   244  func TestConfigVirtualNetworkSubnetNameMustBeSetWithVirtualNetworkName(t *testing.T) {
   245  	config := map[string]string{
   246  		"capture_name_prefix":         "ignore",
   247  		"capture_container_name":      "ignore",
   248  		"location":                    "ignore",
   249  		"image_url":                   "ignore",
   250  		"storage_account":             "ignore",
   251  		"resource_group_name":         "ignore",
   252  		"subscription_id":             "ignore",
   253  		"os_type":                     constants.Target_Linux,
   254  		"communicator":                "none",
   255  		"virtual_network_subnet_name": "MyVirtualNetworkRG",
   256  	}
   257  
   258  	_, _, err := newConfig(config, getPackerConfiguration())
   259  	if err == nil {
   260  		t.Error("Expected Config to reject virtual_network_subnet_name, if virtual_network_name is not set.")
   261  	}
   262  }
   263  
   264  func TestConfigShouldDefaultToPublicCloud(t *testing.T) {
   265  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   266  
   267  	if c.CloudEnvironmentName != "Public" {
   268  		t.Errorf("Expected 'CloudEnvironmentName' to default to 'Public', but got '%s'.", c.CloudEnvironmentName)
   269  	}
   270  
   271  	if c.cloudEnvironment == nil || c.cloudEnvironment.Name != "AzurePublicCloud" {
   272  		t.Errorf("Expected 'cloudEnvironment' to be set to 'AzurePublicCloud', but got '%s'.", c.cloudEnvironment)
   273  	}
   274  }
   275  
   276  func TestConfigInstantiatesCorrectAzureEnvironment(t *testing.T) {
   277  	config := map[string]string{
   278  		"capture_name_prefix":    "ignore",
   279  		"capture_container_name": "ignore",
   280  		"image_offer":            "ignore",
   281  		"image_publisher":        "ignore",
   282  		"image_sku":              "ignore",
   283  		"location":               "ignore",
   284  		"storage_account":        "ignore",
   285  		"resource_group_name":    "ignore",
   286  		"subscription_id":        "ignore",
   287  		"os_type":                constants.Target_Linux,
   288  		"communicator":           "none",
   289  	}
   290  
   291  	// user input is fun :)
   292  	var table = []struct {
   293  		name            string
   294  		environmentName string
   295  	}{
   296  		{"China", "AzureChinaCloud"},
   297  		{"ChinaCloud", "AzureChinaCloud"},
   298  		{"AzureChinaCloud", "AzureChinaCloud"},
   299  		{"aZuReChInAcLoUd", "AzureChinaCloud"},
   300  
   301  		{"USGovernment", "AzureUSGovernmentCloud"},
   302  		{"USGovernmentCloud", "AzureUSGovernmentCloud"},
   303  		{"AzureUSGovernmentCloud", "AzureUSGovernmentCloud"},
   304  		{"aZuReUsGoVeRnMeNtClOuD", "AzureUSGovernmentCloud"},
   305  
   306  		{"Public", "AzurePublicCloud"},
   307  		{"PublicCloud", "AzurePublicCloud"},
   308  		{"AzurePublicCloud", "AzurePublicCloud"},
   309  		{"aZuRePuBlIcClOuD", "AzurePublicCloud"},
   310  	}
   311  
   312  	packerConfiguration := getPackerConfiguration()
   313  
   314  	for _, x := range table {
   315  		config["cloud_environment_name"] = x.name
   316  		c, _, err := newConfig(config, packerConfiguration)
   317  		if err != nil {
   318  			t.Fatal(err)
   319  		}
   320  
   321  		if c.cloudEnvironment == nil || c.cloudEnvironment.Name != x.environmentName {
   322  			t.Errorf("Expected 'cloudEnvironment' to be set to '%s', but got '%s'.", x.environmentName, c.cloudEnvironment)
   323  		}
   324  	}
   325  }
   326  
   327  func TestUserShouldProvideRequiredValues(t *testing.T) {
   328  	builderValues := getArmBuilderConfiguration()
   329  
   330  	// Ensure we can successfully create a config.
   331  	_, _, err := newConfig(builderValues, getPackerConfiguration())
   332  	if err != nil {
   333  		t.Error("Expected configuration creation to succeed, but it failed!\n")
   334  		t.Fatalf(" -> %+v\n", builderValues)
   335  	}
   336  
   337  	// Take away a required element, and ensure construction fails.
   338  	for _, v := range requiredConfigValues {
   339  		originalValue := builderValues[v]
   340  		delete(builderValues, v)
   341  
   342  		_, _, err := newConfig(builderValues, getPackerConfiguration())
   343  		if err == nil {
   344  			t.Error("Expected configuration creation to fail, but it succeeded!\n")
   345  			t.Fatalf(" -> %+v\n", builderValues)
   346  		}
   347  
   348  		builderValues[v] = originalValue
   349  	}
   350  }
   351  
   352  func TestSystemShouldDefineRuntimeValues(t *testing.T) {
   353  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   354  
   355  	if c.Password == "" {
   356  		t.Errorf("Expected Password to not be empty, but it was '%s'!", c.Password)
   357  	}
   358  
   359  	if c.tmpComputeName == "" {
   360  		t.Errorf("Expected tmpComputeName to not be empty, but it was '%s'!", c.tmpComputeName)
   361  	}
   362  
   363  	if c.tmpDeploymentName == "" {
   364  		t.Errorf("Expected tmpDeploymentName to not be empty, but it was '%s'!", c.tmpDeploymentName)
   365  	}
   366  
   367  	if c.tmpResourceGroupName == "" {
   368  		t.Errorf("Expected tmpResourceGroupName to not be empty, but it was '%s'!", c.tmpResourceGroupName)
   369  	}
   370  
   371  	if c.tmpOSDiskName == "" {
   372  		t.Errorf("Expected tmpOSDiskName to not be empty, but it was '%s'!", c.tmpOSDiskName)
   373  	}
   374  }
   375  
   376  func TestConfigShouldTransformToVirtualMachineCaptureParameters(t *testing.T) {
   377  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   378  	parameters := c.toVirtualMachineCaptureParameters()
   379  
   380  	if *parameters.DestinationContainerName != c.CaptureContainerName {
   381  		t.Errorf("Expected DestinationContainerName to be equal to config's CaptureContainerName, but they were '%s' and '%s' respectively.", *parameters.DestinationContainerName, c.CaptureContainerName)
   382  	}
   383  
   384  	if *parameters.VhdPrefix != c.CaptureNamePrefix {
   385  		t.Errorf("Expected DestinationContainerName to be equal to config's CaptureContainerName, but they were '%s' and '%s' respectively.", *parameters.VhdPrefix, c.CaptureNamePrefix)
   386  	}
   387  
   388  	if *parameters.OverwriteVhds != false {
   389  		t.Error("Expected OverwriteVhds to be false, but it was not.")
   390  	}
   391  }
   392  
   393  func TestConfigShouldSupportPackersConfigElements(t *testing.T) {
   394  	c, _, err := newConfig(
   395  		getArmBuilderConfiguration(),
   396  		getPackerConfiguration(),
   397  		getPackerCommunicatorConfiguration())
   398  
   399  	if err != nil {
   400  		t.Fatal(err)
   401  	}
   402  
   403  	if c.Comm.SSHTimeout != 1*time.Hour {
   404  		t.Errorf("Expected Comm.SSHTimeout to be a duration of an hour, but got '%s' instead.", c.Comm.SSHTimeout)
   405  	}
   406  
   407  	if c.Comm.WinRMTimeout != 2*time.Hour {
   408  		t.Errorf("Expected Comm.WinRMTimeout to be a durationof two hours, but got '%s' instead.", c.Comm.WinRMTimeout)
   409  	}
   410  }
   411  
   412  func TestWinRMConfigShouldSetRoundTripDecorator(t *testing.T) {
   413  	config := getArmBuilderConfiguration()
   414  	config["communicator"] = "winrm"
   415  	config["winrm_username"] = "username"
   416  	config["winrm_password"] = "password"
   417  
   418  	c, _, err := newConfig(config, getPackerConfiguration())
   419  	if err != nil {
   420  		t.Fatal(err)
   421  	}
   422  
   423  	if c.Comm.WinRMTransportDecorator == nil {
   424  		t.Error("Expected WinRMTransportDecorator to be set, but it was nil")
   425  	}
   426  }
   427  
   428  func TestUserDeviceLoginIsEnabledForLinux(t *testing.T) {
   429  	config := map[string]string{
   430  		"capture_name_prefix":    "ignore",
   431  		"capture_container_name": "ignore",
   432  		"image_offer":            "ignore",
   433  		"image_publisher":        "ignore",
   434  		"image_sku":              "ignore",
   435  		"location":               "ignore",
   436  		"storage_account":        "ignore",
   437  		"resource_group_name":    "ignore",
   438  		"subscription_id":        "ignore",
   439  		"os_type":                constants.Target_Linux,
   440  		"communicator":           "none",
   441  	}
   442  
   443  	_, _, err := newConfig(config, getPackerConfiguration())
   444  	if err != nil {
   445  		t.Fatalf("failed to use device login for Linux: %s", err)
   446  	}
   447  }
   448  
   449  func TestConfigShouldRejectMalformedCaptureNamePrefix(t *testing.T) {
   450  	config := map[string]string{
   451  		"capture_container_name": "ignore",
   452  		"image_offer":            "ignore",
   453  		"image_publisher":        "ignore",
   454  		"image_sku":              "ignore",
   455  		"location":               "ignore",
   456  		"storage_account":        "ignore",
   457  		"resource_group_name":    "ignore",
   458  		"subscription_id":        "ignore",
   459  		"communicator":           "none",
   460  		// Does not matter for this test case, just pick one.
   461  		"os_type": constants.Target_Linux,
   462  	}
   463  
   464  	wellFormedCaptureNamePrefix := []string{
   465  		"packer",
   466  		"AbcdefghijklmnopqrstuvwX",
   467  		"hyphen-hyphen",
   468  		"0leading-number",
   469  		"v1.core.local",
   470  	}
   471  
   472  	for _, x := range wellFormedCaptureNamePrefix {
   473  		config["capture_name_prefix"] = x
   474  		_, _, err := newConfig(config, getPackerConfiguration())
   475  
   476  		if err != nil {
   477  			t.Errorf("Expected test to pass, but it failed with the well-formed capture_name_prefix set to %q.", x)
   478  		}
   479  	}
   480  
   481  	malformedCaptureNamePrefix := []string{
   482  		"-leading-hyphen",
   483  		"trailing-hyphen-",
   484  		"trailing-period.",
   485  		"_leading-underscore",
   486  		"punc-!@#$%^&*()_+-=-punc",
   487  		"There-are-too-many-characters-in-the-name-and-the-limit-is-twenty-four",
   488  	}
   489  
   490  	for _, x := range malformedCaptureNamePrefix {
   491  		config["capture_name_prefix"] = x
   492  		_, _, err := newConfig(config, getPackerConfiguration())
   493  
   494  		if err == nil {
   495  			t.Errorf("Expected test to fail, but it succeeded with the malformed capture_name_prefix set to %q.", x)
   496  		}
   497  	}
   498  }
   499  
   500  func TestConfigShouldRejectMalformedCaptureContainerName(t *testing.T) {
   501  	config := map[string]string{
   502  		"capture_name_prefix": "ignore",
   503  		"image_offer":         "ignore",
   504  		"image_publisher":     "ignore",
   505  		"image_sku":           "ignore",
   506  		"location":            "ignore",
   507  		"storage_account":     "ignore",
   508  		"resource_group_name": "ignore",
   509  		"subscription_id":     "ignore",
   510  		"communicator":        "none",
   511  		// Does not matter for this test case, just pick one.
   512  		"os_type": constants.Target_Linux,
   513  	}
   514  
   515  	wellFormedCaptureContainerName := []string{
   516  		"0leading",
   517  		"aleading",
   518  		"hype-hyphen",
   519  		"abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz", // 63 characters
   520  	}
   521  
   522  	for _, x := range wellFormedCaptureContainerName {
   523  		config["capture_container_name"] = x
   524  		_, _, err := newConfig(config, getPackerConfiguration())
   525  
   526  		if err != nil {
   527  			t.Errorf("Expected test to pass, but it failed with the well-formed capture_container_name set to %q.", x)
   528  		}
   529  	}
   530  
   531  	malformedCaptureContainerName := []string{
   532  		"No-Capitals",
   533  		"double--hyphens",
   534  		"-leading-hyphen",
   535  		"trailing-hyphen-",
   536  		"punc-!@#$%^&*()_+-=-punc",
   537  		"there-are-over-63-characters-in-this-string-and-that-is-a-bad-container-name",
   538  	}
   539  
   540  	for _, x := range malformedCaptureContainerName {
   541  		config["capture_container_name"] = x
   542  		_, _, err := newConfig(config, getPackerConfiguration())
   543  
   544  		if err == nil {
   545  			t.Errorf("Expected test to fail, but it succeeded with the malformed capture_container_name set to %q.", x)
   546  		}
   547  	}
   548  }
   549  
   550  func TestConfigShouldAcceptTags(t *testing.T) {
   551  	config := map[string]interface{}{
   552  		"capture_name_prefix":    "ignore",
   553  		"capture_container_name": "ignore",
   554  		"image_offer":            "ignore",
   555  		"image_publisher":        "ignore",
   556  		"image_sku":              "ignore",
   557  		"location":               "ignore",
   558  		"storage_account":        "ignore",
   559  		"resource_group_name":    "ignore",
   560  		"subscription_id":        "ignore",
   561  		"communicator":           "none",
   562  		// Does not matter for this test case, just pick one.
   563  		"os_type": constants.Target_Linux,
   564  		"azure_tags": map[string]string{
   565  			"tag01": "value01",
   566  			"tag02": "value02",
   567  		},
   568  	}
   569  
   570  	c, _, err := newConfig(config, getPackerConfiguration())
   571  
   572  	if err != nil {
   573  		t.Fatal(err)
   574  	}
   575  
   576  	if len(c.AzureTags) != 2 {
   577  		t.Fatalf("expected to find 2 tags, but got %d", len(c.AzureTags))
   578  	}
   579  
   580  	if _, ok := c.AzureTags["tag01"]; !ok {
   581  		t.Error("expected to find key=\"tag01\", but did not")
   582  	}
   583  	if _, ok := c.AzureTags["tag02"]; !ok {
   584  		t.Error("expected to find key=\"tag02\", but did not")
   585  	}
   586  
   587  	value := c.AzureTags["tag01"]
   588  	if *value != "value01" {
   589  		t.Errorf("expected AzureTags[\"tag01\"] to have value \"value01\", but got %q", *value)
   590  	}
   591  
   592  	value = c.AzureTags["tag02"]
   593  	if *value != "value02" {
   594  		t.Errorf("expected AzureTags[\"tag02\"] to have value \"value02\", but got %q", *value)
   595  	}
   596  }
   597  
   598  func TestConfigShouldRejectTagsInExcessOf15AcceptTags(t *testing.T) {
   599  	tooManyTags := map[string]string{}
   600  	for i := 0; i < 16; i++ {
   601  		tooManyTags[fmt.Sprintf("tag%.2d", i)] = "ignored"
   602  	}
   603  
   604  	config := map[string]interface{}{
   605  		"capture_name_prefix":    "ignore",
   606  		"capture_container_name": "ignore",
   607  		"image_offer":            "ignore",
   608  		"image_publisher":        "ignore",
   609  		"image_sku":              "ignore",
   610  		"location":               "ignore",
   611  		"storage_account":        "ignore",
   612  		"resource_group_name":    "ignore",
   613  		"subscription_id":        "ignore",
   614  		"communicator":           "none",
   615  		// Does not matter for this test case, just pick one.
   616  		"os_type":    constants.Target_Linux,
   617  		"azure_tags": tooManyTags,
   618  	}
   619  
   620  	_, _, err := newConfig(config, getPackerConfiguration())
   621  
   622  	if err == nil {
   623  		t.Fatal("expected config to reject based on an excessive amount of tags (> 15)")
   624  	}
   625  }
   626  
   627  func TestConfigShouldRejectExcessiveTagNameLength(t *testing.T) {
   628  	nameTooLong := make([]byte, 513)
   629  	for i := range nameTooLong {
   630  		nameTooLong[i] = 'a'
   631  	}
   632  
   633  	tags := map[string]string{}
   634  	tags[string(nameTooLong)] = "ignored"
   635  
   636  	config := map[string]interface{}{
   637  		"capture_name_prefix":    "ignore",
   638  		"capture_container_name": "ignore",
   639  		"image_offer":            "ignore",
   640  		"image_publisher":        "ignore",
   641  		"image_sku":              "ignore",
   642  		"location":               "ignore",
   643  		"storage_account":        "ignore",
   644  		"resource_group_name":    "ignore",
   645  		"subscription_id":        "ignore",
   646  		"communicator":           "none",
   647  		// Does not matter for this test case, just pick one.
   648  		"os_type":    constants.Target_Linux,
   649  		"azure_tags": tags,
   650  	}
   651  
   652  	_, _, err := newConfig(config, getPackerConfiguration())
   653  	if err == nil {
   654  		t.Fatal("expected config to reject tag name based on length (> 512)")
   655  	}
   656  }
   657  
   658  func TestConfigShouldRejectExcessiveTagValueLength(t *testing.T) {
   659  	valueTooLong := make([]byte, 257)
   660  	for i := range valueTooLong {
   661  		valueTooLong[i] = 'a'
   662  	}
   663  
   664  	tags := map[string]string{}
   665  	tags["tag01"] = string(valueTooLong)
   666  
   667  	config := map[string]interface{}{
   668  		"capture_name_prefix":    "ignore",
   669  		"capture_container_name": "ignore",
   670  		"image_offer":            "ignore",
   671  		"image_publisher":        "ignore",
   672  		"image_sku":              "ignore",
   673  		"location":               "ignore",
   674  		"storage_account":        "ignore",
   675  		"resource_group_name":    "ignore",
   676  		"subscription_id":        "ignore",
   677  		"communicator":           "none",
   678  		// Does not matter for this test case, just pick one.
   679  		"os_type":    constants.Target_Linux,
   680  		"azure_tags": tags,
   681  	}
   682  
   683  	_, _, err := newConfig(config, getPackerConfiguration())
   684  	if err == nil {
   685  		t.Fatal("expected config to reject tag value based on length (> 256)")
   686  	}
   687  }
   688  
   689  func TestConfigShouldRejectMissingCustomDataFile(t *testing.T) {
   690  	config := map[string]interface{}{
   691  		"capture_name_prefix":    "ignore",
   692  		"capture_container_name": "ignore",
   693  		"image_offer":            "ignore",
   694  		"image_publisher":        "ignore",
   695  		"image_sku":              "ignore",
   696  		"location":               "ignore",
   697  		"storage_account":        "ignore",
   698  		"resource_group_name":    "ignore",
   699  		"subscription_id":        "ignore",
   700  		"communicator":           "none",
   701  		// Does not matter for this test case, just pick one.
   702  		"os_type":          constants.Target_Linux,
   703  		"custom_data_file": "/this/file/does/not/exist",
   704  	}
   705  
   706  	_, _, err := newConfig(config, getPackerConfiguration())
   707  	if err == nil {
   708  		t.Fatal("expected config to reject missing custom data file")
   709  	}
   710  }
   711  
   712  func TestConfigShouldAcceptPlatformManagedImageBuild(t *testing.T) {
   713  	config := map[string]interface{}{
   714  		"image_offer":                       "ignore",
   715  		"image_publisher":                   "ignore",
   716  		"image_sku":                         "ignore",
   717  		"location":                          "ignore",
   718  		"subscription_id":                   "ignore",
   719  		"communicator":                      "none",
   720  		"managed_image_resource_group_name": "ignore",
   721  		"managed_image_name":                "ignore",
   722  
   723  		// Does not matter for this test case, just pick one.
   724  		"os_type": constants.Target_Linux,
   725  	}
   726  
   727  	_, _, err := newConfig(config, getPackerConfiguration())
   728  	if err != nil {
   729  		t.Fatal("expected config to accept platform managed image build")
   730  	}
   731  }
   732  
   733  // If the user specified a build for a VHD and a Managed Image it should be rejected.
   734  func TestConfigShouldRejectVhdAndManagedImageOutput(t *testing.T) {
   735  	config := map[string]interface{}{
   736  		"image_offer":                       "ignore",
   737  		"image_publisher":                   "ignore",
   738  		"image_sku":                         "ignore",
   739  		"location":                          "ignore",
   740  		"subscription_id":                   "ignore",
   741  		"communicator":                      "none",
   742  		"capture_container_name":            "ignore",
   743  		"capture_name_prefix":               "ignore",
   744  		"managed_image_resource_group_name": "ignore",
   745  		"managed_image_name":                "ignore",
   746  
   747  		// Does not matter for this test case, just pick one.
   748  		"os_type": constants.Target_Linux,
   749  	}
   750  
   751  	_, _, err := newConfig(config, getPackerConfiguration())
   752  	if err == nil {
   753  		t.Fatal("expected config to reject VHD and Managed Image build")
   754  	}
   755  }
   756  
   757  // If the user specified a build of a VHD, but started with a managed image it should be rejected.
   758  func TestConfigShouldRejectManagedImageSourceAndVhdOutput(t *testing.T) {
   759  	config := map[string]interface{}{
   760  		"image_url":                         "ignore",
   761  		"location":                          "ignore",
   762  		"subscription_id":                   "ignore",
   763  		"communicator":                      "none",
   764  		"managed_image_resource_group_name": "ignore",
   765  		"managed_image_name":                "ignore",
   766  
   767  		// Does not matter for this test case, just pick one.
   768  		"os_type": constants.Target_Linux,
   769  	}
   770  
   771  	_, _, err := newConfig(config, getPackerConfiguration())
   772  	if err == nil {
   773  		t.Fatal("expected config to reject VHD and Managed Image build")
   774  	}
   775  }
   776  
   777  func TestConfigShouldRejectCustomAndPlatformManagedImageBuild(t *testing.T) {
   778  	config := map[string]interface{}{
   779  		"custom_managed_image_resource_group_name": "ignore",
   780  		"custom_managed_image_name":                "ignore",
   781  		"image_offer":                              "ignore",
   782  		"image_publisher":                          "ignore",
   783  		"image_sku":                                "ignore",
   784  		"location":                                 "ignore",
   785  		"subscription_id":                          "ignore",
   786  		"communicator":                             "none",
   787  		"managed_image_resource_group_name":        "ignore",
   788  		"managed_image_name":                       "ignore",
   789  
   790  		// Does not matter for this test case, just pick one.
   791  		"os_type": constants.Target_Linux,
   792  	}
   793  
   794  	_, _, err := newConfig(config, getPackerConfiguration())
   795  	if err == nil {
   796  		t.Fatal("expected config to reject custom and platform input for a managed image build")
   797  	}
   798  }
   799  
   800  func TestConfigShouldRejectCustomAndImageUrlForManagedImageBuild(t *testing.T) {
   801  	config := map[string]interface{}{
   802  		"image_url": "ignore",
   803  		"custom_managed_image_resource_group_name": "ignore",
   804  		"custom_managed_image_name":                "ignore",
   805  		"location":                                 "ignore",
   806  		"subscription_id":                          "ignore",
   807  		"communicator":                             "none",
   808  		"managed_image_resource_group_name":        "ignore",
   809  		"managed_image_name":                       "ignore",
   810  
   811  		// Does not matter for this test case, just pick one.
   812  		"os_type": constants.Target_Linux,
   813  	}
   814  
   815  	_, _, err := newConfig(config, getPackerConfiguration())
   816  	if err == nil {
   817  		t.Fatal("expected config to reject custom and platform input for a managed image build")
   818  	}
   819  }
   820  
   821  func TestConfigShouldRejectMalformedManageImageStorageAccountTypes(t *testing.T) {
   822  	config := map[string]interface{}{
   823  		"custom_managed_image_resource_group_name": "ignore",
   824  		"custom_managed_image_name":                "ignore",
   825  		"location":                                 "ignore",
   826  		"subscription_id":                          "ignore",
   827  		"communicator":                             "none",
   828  		"managed_image_resource_group_name":        "ignore",
   829  		"managed_image_name":                       "ignore",
   830  		"managed_image_storage_account_type":       "--invalid--",
   831  
   832  		// Does not matter for this test case, just pick one.
   833  		"os_type": constants.Target_Linux,
   834  	}
   835  
   836  	_, _, err := newConfig(config, getPackerConfiguration())
   837  	if err == nil {
   838  		t.Fatal("expected config to reject custom and platform input for a managed image build")
   839  	}
   840  }
   841  
   842  func TestConfigShouldAcceptManagedImageStorageAccountTypes(t *testing.T) {
   843  	config := map[string]interface{}{
   844  		"custom_managed_image_resource_group_name": "ignore",
   845  		"custom_managed_image_name":                "ignore",
   846  		"location":                                 "ignore",
   847  		"subscription_id":                          "ignore",
   848  		"communicator":                             "none",
   849  		"managed_image_resource_group_name":        "ignore",
   850  		"managed_image_name":                       "ignore",
   851  
   852  		// Does not matter for this test case, just pick one.
   853  		"os_type": constants.Target_Linux,
   854  	}
   855  
   856  	storage_account_types := []string{"Premium_LRS", "Standard_LRS"}
   857  
   858  	for _, x := range storage_account_types {
   859  		config["managed_image_storage_account_type"] = x
   860  		_, _, err := newConfig(config, getPackerConfiguration())
   861  		if err != nil {
   862  			t.Fatalf("expected config to accept a managed_image_storage_account_type of %q", x)
   863  		}
   864  	}
   865  }
   866  
   867  func TestConfigShouldRejectTempAndBuildResourceGroupName(t *testing.T) {
   868  	config := map[string]interface{}{
   869  		"capture_name_prefix":    "ignore",
   870  		"capture_container_name": "ignore",
   871  		"image_offer":            "ignore",
   872  		"image_publisher":        "ignore",
   873  		"image_sku":              "ignore",
   874  		"location":               "ignore",
   875  		"storage_account":        "ignore",
   876  		"resource_group_name":    "ignore",
   877  		"subscription_id":        "ignore",
   878  		"communicator":           "none",
   879  
   880  		// custom may define one or the other, but not both
   881  		"temp_resource_group_name":  "rgn00",
   882  		"build_resource_group_name": "rgn00",
   883  	}
   884  
   885  	_, _, err := newConfig(config, getPackerConfiguration())
   886  	if err == nil {
   887  		t.Fatal("expected config to reject the use of both temp_resource_group_name and build_resource_group_name")
   888  	}
   889  }
   890  
   891  func TestConfigShouldRejectInvalidResourceGroupNames(t *testing.T) {
   892  	config := map[string]interface{}{
   893  		"capture_name_prefix":    "ignore",
   894  		"capture_container_name": "ignore",
   895  		"image_offer":            "ignore",
   896  		"image_publisher":        "ignore",
   897  		"image_sku":              "ignore",
   898  		"location":               "ignore",
   899  		"storage_account":        "ignore",
   900  		"resource_group_name":    "ignore",
   901  		"subscription_id":        "ignore",
   902  		"communicator":           "none",
   903  		"os_type":                "linux",
   904  	}
   905  
   906  	tests := []struct {
   907  		name string
   908  		ok   bool
   909  	}{
   910  		// The Good
   911  		{"packer-Resource-Group-jt2j3fc", true},
   912  		{"My", true},
   913  		{"My-(with-parens)-Resource-Group", true},
   914  
   915  		// The Bad
   916  		{"My Resource Group", false},
   917  		{"My-Resource-Group-", false},
   918  		{"My.Resource.Group.", false},
   919  
   920  		// The Ugly
   921  		{"My!@#!@#%$%yM", false},
   922  		{"   ", false},
   923  		{"My10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false},
   924  	}
   925  
   926  	settings := []string{"temp_resource_group_name", "build_resource_group_name"}
   927  
   928  	for _, x := range settings {
   929  		for _, y := range tests {
   930  			config[x] = y.name
   931  
   932  			_, _, err := newConfig(config, getPackerConfiguration())
   933  			if !y.ok && err == nil {
   934  				t.Errorf("expected config to reject %q for setting %q", y.name, x)
   935  			} else if y.ok && err != nil {
   936  				t.Errorf("expected config to accept %q for setting %q", y.name, x)
   937  			}
   938  		}
   939  
   940  		delete(config, "location") // not valid for build_resource_group_name
   941  		delete(config, x)
   942  	}
   943  }
   944  
   945  func TestConfigShouldRejectManagedDiskNames(t *testing.T) {
   946  	config := map[string]interface{}{
   947  		"image_offer":                       "ignore",
   948  		"image_publisher":                   "ignore",
   949  		"image_sku":                         "ignore",
   950  		"location":                          "ignore",
   951  		"subscription_id":                   "ignore",
   952  		"communicator":                      "none",
   953  		"os_type":                           "linux",
   954  		"managed_image_name":                "ignore",
   955  		"managed_image_resource_group_name": "ignore",
   956  	}
   957  
   958  	testsResourceGroupNames := []struct {
   959  		name string
   960  		ok   bool
   961  	}{
   962  		// The Good
   963  		{"packer-Resource-Group-jt2j3fc", true},
   964  		{"My", true},
   965  		{"My-(with-parens)-Resource-Group", true},
   966  
   967  		// The Bad
   968  		{"My Resource Group", false},
   969  		{"My-Resource-Group-", false},
   970  		{"My.Resource.Group.", false},
   971  
   972  		// The Ugly
   973  		{"My!@#!@#%$%yM", false},
   974  		{"   ", false},
   975  		{"My10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false},
   976  	}
   977  
   978  	settingUnderTest := "managed_image_resource_group_name"
   979  	for _, y := range testsResourceGroupNames {
   980  		config[settingUnderTest] = y.name
   981  
   982  		_, _, err := newConfig(config, getPackerConfiguration())
   983  		if !y.ok && err == nil {
   984  			t.Errorf("expected config to reject %q for setting %q", y.name, settingUnderTest)
   985  		} else if y.ok && err != nil {
   986  			t.Errorf("expected config to accept %q for setting %q", y.name, settingUnderTest)
   987  		}
   988  	}
   989  
   990  	config["managed_image_resource_group_name"] = "ignored"
   991  
   992  	testNames := []struct {
   993  		name string
   994  		ok   bool
   995  	}{
   996  		// The Good
   997  		{"ManagedDiskName", true},
   998  		{"Managed-Disk-Name", true},
   999  		{"My33", true},
  1000  
  1001  		// The Bad
  1002  		{"Managed Disk Name", false},
  1003  		{"Managed-Disk-Name-", false},
  1004  		{"Managed.Disk.Name.", false},
  1005  
  1006  		// The Ugly
  1007  		{"My!@#!@#%$%yM", false},
  1008  		{"   ", false},
  1009  		{"My10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false},
  1010  	}
  1011  
  1012  	settingUnderTest = "managed_image_name"
  1013  	for _, y := range testNames {
  1014  		config[settingUnderTest] = y.name
  1015  
  1016  		_, _, err := newConfig(config, getPackerConfiguration())
  1017  		if !y.ok && err == nil {
  1018  			t.Logf("expected config to reject %q for setting %q", y.name, settingUnderTest)
  1019  		} else if y.ok && err != nil {
  1020  			t.Logf("expected config to accept %q for setting %q", y.name, settingUnderTest)
  1021  		}
  1022  	}
  1023  }
  1024  
  1025  func TestConfigAdditionalDiskDefaultIsNil(t *testing.T) {
  1026  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
  1027  	if c.AdditionalDiskSize != nil {
  1028  		t.Errorf("Expected Config to not have a set of additional disks, but got a non nil value")
  1029  	}
  1030  }
  1031  
  1032  func TestConfigAdditionalDiskOverrideDefault(t *testing.T) {
  1033  	config := map[string]string{
  1034  		"capture_name_prefix":    "ignore",
  1035  		"capture_container_name": "ignore",
  1036  		"location":               "ignore",
  1037  		"image_url":              "ignore",
  1038  		"storage_account":        "ignore",
  1039  		"resource_group_name":    "ignore",
  1040  		"subscription_id":        "ignore",
  1041  		"os_type":                constants.Target_Linux,
  1042  		"communicator":           "none",
  1043  	}
  1044  
  1045  	diskconfig := map[string][]int32{
  1046  		"disk_additional_size": {32, 64},
  1047  	}
  1048  
  1049  	c, _, _ := newConfig(config, diskconfig, getPackerConfiguration())
  1050  	if c.AdditionalDiskSize == nil {
  1051  		t.Errorf("Expected Config to have a set of additional disks, but got nil")
  1052  	}
  1053  	if len(c.AdditionalDiskSize) != 2 {
  1054  		t.Errorf("Expected Config to have a 2 additional disks, but got %d additional disks", len(c.AdditionalDiskSize))
  1055  	}
  1056  	if c.AdditionalDiskSize[0] != 32 {
  1057  		t.Errorf("Expected Config to have the first additional disks of size 32Gb, but got %dGb", c.AdditionalDiskSize[0])
  1058  	}
  1059  	if c.AdditionalDiskSize[1] != 64 {
  1060  		t.Errorf("Expected Config to have the second additional disks of size 64Gb, but got %dGb", c.AdditionalDiskSize[1])
  1061  	}
  1062  }
  1063  
  1064  // Test that configuration handles plan info
  1065  //
  1066  // The use of plan info requires that the following three properties are set.
  1067  //
  1068  //  1. plan_name
  1069  //  2. plan_product
  1070  //  3. plan_publisher
  1071  func TestPlanInfoConfiguration(t *testing.T) {
  1072  	config := map[string]interface{}{
  1073  		"capture_name_prefix":    "ignore",
  1074  		"capture_container_name": "ignore",
  1075  		"image_offer":            "ignore",
  1076  		"image_publisher":        "ignore",
  1077  		"image_sku":              "ignore",
  1078  		"location":               "ignore",
  1079  		"storage_account":        "ignore",
  1080  		"resource_group_name":    "ignore",
  1081  		"subscription_id":        "ignore",
  1082  		"os_type":                "linux",
  1083  		"communicator":           "none",
  1084  	}
  1085  
  1086  	planInfo := map[string]string{
  1087  		"plan_name": "--plan-name--",
  1088  	}
  1089  	config["plan_info"] = planInfo
  1090  
  1091  	_, _, err := newConfig(config, getPackerConfiguration())
  1092  	if err == nil {
  1093  		t.Fatal("expected config to reject the use of plan_name without plan_product and plan_publisher")
  1094  	}
  1095  
  1096  	planInfo["plan_product"] = "--plan-product--"
  1097  	_, _, err = newConfig(config, getPackerConfiguration())
  1098  	if err == nil {
  1099  		t.Fatal("expected config to reject the use of plan_name and plan_product without plan_publisher")
  1100  	}
  1101  
  1102  	planInfo["plan_publisher"] = "--plan-publisher--"
  1103  	c, _, err := newConfig(config, getPackerConfiguration())
  1104  	if err != nil {
  1105  		t.Fatalf("expected config to accept a complete plan configuration: %s", err)
  1106  	}
  1107  
  1108  	if c.PlanInfo.PlanName != "--plan-name--" {
  1109  		t.Fatalf("Expected PlanName to be '--plan-name--', but got %q", c.PlanInfo.PlanName)
  1110  	}
  1111  	if c.PlanInfo.PlanProduct != "--plan-product--" {
  1112  		t.Fatalf("Expected PlanProduct to be '--plan-product--', but got %q", c.PlanInfo.PlanProduct)
  1113  	}
  1114  	if c.PlanInfo.PlanPublisher != "--plan-publisher--" {
  1115  		t.Fatalf("Expected PlanPublisher to be '--plan-publisher--, but got %q", c.PlanInfo.PlanPublisher)
  1116  	}
  1117  }
  1118  
  1119  func TestPlanInfoPromotionCode(t *testing.T) {
  1120  	config := map[string]interface{}{
  1121  		"capture_name_prefix":    "ignore",
  1122  		"capture_container_name": "ignore",
  1123  		"image_offer":            "ignore",
  1124  		"image_publisher":        "ignore",
  1125  		"image_sku":              "ignore",
  1126  		"location":               "ignore",
  1127  		"storage_account":        "ignore",
  1128  		"resource_group_name":    "ignore",
  1129  		"subscription_id":        "ignore",
  1130  		"os_type":                "linux",
  1131  		"communicator":           "none",
  1132  		"plan_info": map[string]string{
  1133  			"plan_name":           "--plan-name--",
  1134  			"plan_product":        "--plan-product--",
  1135  			"plan_publisher":      "--plan-publisher--",
  1136  			"plan_promotion_code": "--plan-promotion-code--",
  1137  		},
  1138  	}
  1139  
  1140  	c, _, err := newConfig(config, getPackerConfiguration())
  1141  	if err != nil {
  1142  		t.Fatalf("expected config to accept plan_info configuration, but got %s", err)
  1143  	}
  1144  
  1145  	if c.PlanInfo.PlanName != "--plan-name--" {
  1146  		t.Fatalf("Expected PlanName to be '--plan-name--', but got %q", c.PlanInfo.PlanName)
  1147  	}
  1148  	if c.PlanInfo.PlanProduct != "--plan-product--" {
  1149  		t.Fatalf("Expected PlanProduct to be '--plan-product--', but got %q", c.PlanInfo.PlanProduct)
  1150  	}
  1151  	if c.PlanInfo.PlanPublisher != "--plan-publisher--" {
  1152  		t.Fatalf("Expected PlanPublisher to be '--plan-publisher--, but got %q", c.PlanInfo.PlanPublisher)
  1153  	}
  1154  	if c.PlanInfo.PlanPromotionCode != "--plan-promotion-code--" {
  1155  		t.Fatalf("Expected PlanPublisher to be '--plan-promotion-code----, but got %q", c.PlanInfo.PlanPromotionCode)
  1156  	}
  1157  }
  1158  
  1159  // plan_info defines 3 or 4 tags based on plan data.
  1160  // The user can define up to 15 tags.  If the combination of these two
  1161  // exceeds the max tag amount, the builder should reject the configuration.
  1162  func TestPlanInfoTooManyTagsErrors(t *testing.T) {
  1163  	exactMaxNumberOfTags := map[string]string{}
  1164  	for i := 0; i < 15; i++ {
  1165  		exactMaxNumberOfTags[fmt.Sprintf("tag%.2d", i)] = "ignored"
  1166  	}
  1167  
  1168  	config := map[string]interface{}{
  1169  		"capture_name_prefix":    "ignore",
  1170  		"capture_container_name": "ignore",
  1171  		"image_offer":            "ignore",
  1172  		"image_publisher":        "ignore",
  1173  		"image_sku":              "ignore",
  1174  		"location":               "ignore",
  1175  		"storage_account":        "ignore",
  1176  		"resource_group_name":    "ignore",
  1177  		"subscription_id":        "ignore",
  1178  		"os_type":                "linux",
  1179  		"communicator":           "none",
  1180  		"azure_tags":             exactMaxNumberOfTags,
  1181  		"plan_info": map[string]string{
  1182  			"plan_name":           "--plan-name--",
  1183  			"plan_product":        "--plan-product--",
  1184  			"plan_publisher":      "--plan-publisher--",
  1185  			"plan_promotion_code": "--plan-promotion-code--",
  1186  		},
  1187  	}
  1188  
  1189  	_, _, err := newConfig(config, getPackerConfiguration())
  1190  	if err == nil {
  1191  		t.Fatal("expected config to reject configuration due to excess tags")
  1192  	}
  1193  }
  1194  
  1195  // The Azure builder creates temporary resources, but the user has some control over
  1196  // these values. This test asserts those values are controllable by the user.
  1197  func TestConfigShouldAllowTempNameOverrides(t *testing.T) {
  1198  	config := map[string]interface{}{
  1199  		"image_offer":                       "ignore",
  1200  		"image_publisher":                   "ignore",
  1201  		"image_sku":                         "ignore",
  1202  		"location":                          "ignore",
  1203  		"subscription_id":                   "ignore",
  1204  		"communicator":                      "none",
  1205  		"os_type":                           "linux",
  1206  		"managed_image_name":                "ignore",
  1207  		"managed_image_resource_group_name": "ignore",
  1208  		"temp_resource_group_name":          "myTempResourceGroupName",
  1209  		"temp_compute_name":                 "myTempComputeName",
  1210  	}
  1211  
  1212  	c, _, err := newConfig(config, getPackerConfiguration())
  1213  	if err != nil {
  1214  		t.Errorf("newConfig failed with %q", err)
  1215  	}
  1216  
  1217  	if c.TempResourceGroupName != "myTempResourceGroupName" {
  1218  		t.Errorf("expected TempResourceGroupName to be %q, but got %q", "myTempResourceGroupName", c.TempResourceGroupName)
  1219  	}
  1220  	if c.tmpResourceGroupName != "myTempResourceGroupName" {
  1221  		t.Errorf("expected tmpResourceGroupName to be %q, but got %q", "myTempResourceGroupName", c.tmpResourceGroupName)
  1222  	}
  1223  
  1224  	if c.TempComputeName != "myTempComputeName" {
  1225  		t.Errorf("expected TempComputeName to be %q, but got %q", "myTempComputeName", c.TempComputeName)
  1226  	}
  1227  	if c.tmpComputeName != "myTempComputeName" {
  1228  		t.Errorf("expected tmpComputeName to be %q, but got %q", "myTempComputeName", c.tmpResourceGroupName)
  1229  	}
  1230  }
  1231  
  1232  func TestConfigShouldAllowAsyncResourceGroupOverride(t *testing.T) {
  1233  	config := map[string]interface{}{
  1234  		"image_offer":                       "ignore",
  1235  		"image_publisher":                   "ignore",
  1236  		"image_sku":                         "ignore",
  1237  		"location":                          "ignore",
  1238  		"subscription_id":                   "ignore",
  1239  		"communicator":                      "none",
  1240  		"os_type":                           "linux",
  1241  		"managed_image_name":                "ignore",
  1242  		"managed_image_resource_group_name": "ignore",
  1243  		"async_resourcegroup_delete":        "true",
  1244  	}
  1245  
  1246  	c, _, err := newConfig(config, getPackerConfiguration())
  1247  	if err != nil {
  1248  		t.Errorf("newConfig failed with %q", err)
  1249  	}
  1250  
  1251  	if c.AsyncResourceGroupDelete != true {
  1252  		t.Errorf("expected async_resourcegroup_delete to be %q, but got %t", "async_resourcegroup_delete", c.AsyncResourceGroupDelete)
  1253  	}
  1254  }
  1255  func TestConfigShouldAllowAsyncResourceGroupOverrideNoValue(t *testing.T) {
  1256  	config := map[string]interface{}{
  1257  		"image_offer":                       "ignore",
  1258  		"image_publisher":                   "ignore",
  1259  		"image_sku":                         "ignore",
  1260  		"location":                          "ignore",
  1261  		"subscription_id":                   "ignore",
  1262  		"communicator":                      "none",
  1263  		"os_type":                           "linux",
  1264  		"managed_image_name":                "ignore",
  1265  		"managed_image_resource_group_name": "ignore",
  1266  	}
  1267  
  1268  	c, _, err := newConfig(config, getPackerConfiguration())
  1269  	if err != nil {
  1270  		t.Errorf("newConfig failed with %q", err)
  1271  	}
  1272  
  1273  	if c.AsyncResourceGroupDelete != false {
  1274  		t.Errorf("expected async_resourcegroup_delete to be %q, but got %t", "async_resourcegroup_delete", c.AsyncResourceGroupDelete)
  1275  	}
  1276  }
  1277  func TestConfigShouldAllowAsyncResourceGroupOverrideBadValue(t *testing.T) {
  1278  	config := map[string]interface{}{
  1279  		"image_offer":                       "ignore",
  1280  		"image_publisher":                   "ignore",
  1281  		"image_sku":                         "ignore",
  1282  		"location":                          "ignore",
  1283  		"subscription_id":                   "ignore",
  1284  		"communicator":                      "none",
  1285  		"os_type":                           "linux",
  1286  		"managed_image_name":                "ignore",
  1287  		"managed_image_resource_group_name": "ignore",
  1288  		"async_resourcegroup_delete":        "asdasda",
  1289  	}
  1290  
  1291  	c, _, err := newConfig(config, getPackerConfiguration())
  1292  	if err != nil && c == nil {
  1293  		t.Log("newConfig failed  which is expected ", err)
  1294  
  1295  	}
  1296  
  1297  }
  1298  func TestConfigShouldAllowSharedImageGalleryOptions(t *testing.T) {
  1299  	config := map[string]interface{}{
  1300  		"location":        "ignore",
  1301  		"subscription_id": "ignore",
  1302  		"os_type":         "linux",
  1303  		"shared_image_gallery": map[string]string{
  1304  			"subscription":   "ignore",
  1305  			"resource_group": "ignore",
  1306  			"gallery_name":   "ignore",
  1307  			"image_name":     "ignore",
  1308  			"image_version":  "ignore",
  1309  		},
  1310  	}
  1311  
  1312  	_, _, err := newConfig(config, getPackerConfiguration())
  1313  	if err == nil {
  1314  		t.Log("expected config to accept Shared Image Gallery options", err)
  1315  	}
  1316  
  1317  }
  1318  
  1319  func TestConfigShouldRejectSharedImageGalleryWithVhdTarget(t *testing.T) {
  1320  	config := map[string]interface{}{
  1321  		"location":        "ignore",
  1322  		"subscription_id": "ignore",
  1323  		"os_type":         "linux",
  1324  		"shared_image_gallery": map[string]string{
  1325  			"subscription":   "ignore",
  1326  			"resource_group": "ignore",
  1327  			"gallery_name":   "ignore",
  1328  			"image_name":     "ignore",
  1329  			"image_version":  "ignore",
  1330  		},
  1331  		"resource_group_name":    "ignore",
  1332  		"storage_account":        "ignore",
  1333  		"capture_container_name": "ignore",
  1334  		"capture_name_prefix":    "ignore",
  1335  	}
  1336  
  1337  	_, _, err := newConfig(config, getPackerConfiguration())
  1338  	if err != nil {
  1339  		t.Log("expected an error if Shared Image Gallery source is used with VHD target", err)
  1340  	}
  1341  
  1342  }
  1343  
  1344  func getArmBuilderConfiguration() map[string]string {
  1345  	m := make(map[string]string)
  1346  	for _, v := range requiredConfigValues {
  1347  		m[v] = "ignored00"
  1348  	}
  1349  
  1350  	m["communicator"] = "none"
  1351  	m["os_type"] = constants.Target_Linux
  1352  	return m
  1353  }
  1354  
  1355  func getArmBuilderConfigurationWithWindows() map[string]string {
  1356  	m := make(map[string]string)
  1357  	for _, v := range requiredConfigValues {
  1358  		m[v] = "ignored00"
  1359  	}
  1360  
  1361  	m["object_id"] = "ignored00"
  1362  	m["tenant_id"] = "ignored00"
  1363  	m["winrm_username"] = "ignored00"
  1364  	m["communicator"] = "winrm"
  1365  	m["os_type"] = constants.Target_Windows
  1366  	return m
  1367  }
  1368  
  1369  func getPackerConfiguration() interface{} {
  1370  	config := map[string]interface{}{
  1371  		"packer_build_name":    "azure-arm-vm",
  1372  		"packer_builder_type":  "azure-arm-vm",
  1373  		"packer_debug":         "false",
  1374  		"packer_force":         "false",
  1375  		"packer_template_path": "/home/jenkins/azure-arm-vm/template.json",
  1376  	}
  1377  
  1378  	return config
  1379  }
  1380  
  1381  func getPackerCommunicatorConfiguration() map[string]string {
  1382  	config := map[string]string{
  1383  		"ssh_timeout":   "1h",
  1384  		"winrm_timeout": "2h",
  1385  	}
  1386  
  1387  	return config
  1388  }