...

Source file src/github.com/Azure/azure-sdk-for-go/services/classic/management/vmutils/vmutils.go

Documentation: github.com/Azure/azure-sdk-for-go/services/classic/management/vmutils

     1  // +build go1.7
     2  
     3  // Package vmutils provides convenience methods for creating Virtual
     4  // Machine Role configurations.
     5  package vmutils
     6  
     7  // Copyright (c) Microsoft Corporation. All rights reserved.
     8  // Licensed under the MIT License. See License.txt in the project root for license information.
     9  
    10  import (
    11  	"fmt"
    12  
    13  	vm "github.com/Azure/azure-sdk-for-go/services/classic/management/virtualmachine"
    14  )
    15  
    16  const (
    17  	errParamNotSpecified = "Parameter %s is not specified."
    18  )
    19  
    20  // NewVMConfiguration creates configuration for a new virtual machine Role.
    21  func NewVMConfiguration(name string, roleSize string) vm.Role {
    22  	return vm.Role{
    23  		RoleName:            name,
    24  		RoleType:            "PersistentVMRole",
    25  		RoleSize:            roleSize,
    26  		ProvisionGuestAgent: true,
    27  	}
    28  }
    29  
    30  // ConfigureForLinux adds configuration when deploying a generalized Linux
    31  // image. If "password" is left empty, SSH password security will be disabled by
    32  // default. Certificates with SSH public keys should already be uploaded to the
    33  // cloud service where the VM will be deployed and referenced here only by their
    34  // thumbprint.
    35  func ConfigureForLinux(role *vm.Role, hostname, user, password string, sshPubkeyCertificateThumbprint ...string) error {
    36  	if role == nil {
    37  		return fmt.Errorf(errParamNotSpecified, "role")
    38  	}
    39  
    40  	role.ConfigurationSets = updateOrAddConfig(role.ConfigurationSets, vm.ConfigurationSetTypeLinuxProvisioning,
    41  		func(config *vm.ConfigurationSet) {
    42  			config.HostName = hostname
    43  			config.UserName = user
    44  			config.UserPassword = password
    45  			if password != "" {
    46  				config.DisableSSHPasswordAuthentication = "false"
    47  			}
    48  			if len(sshPubkeyCertificateThumbprint) != 0 {
    49  				config.SSH = &vm.SSH{}
    50  				for _, k := range sshPubkeyCertificateThumbprint {
    51  					config.SSH.PublicKeys = append(config.SSH.PublicKeys,
    52  						vm.PublicKey{
    53  							Fingerprint: k,
    54  							Path:        "/home/" + user + "/.ssh/authorized_keys",
    55  						},
    56  					)
    57  				}
    58  			}
    59  		},
    60  	)
    61  
    62  	return nil
    63  }
    64  
    65  // ConfigureForWindows adds configuration when deploying a generalized
    66  // Windows image. timeZone can be left empty. For a complete list of supported
    67  // time zone entries, you can either refer to the values listed in the registry
    68  // entry "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time
    69  // Zones" or you can use the tzutil command-line tool to list the valid time.
    70  func ConfigureForWindows(role *vm.Role, hostname, user, password string, enableAutomaticUpdates bool, timeZone string) error {
    71  	if role == nil {
    72  		return fmt.Errorf(errParamNotSpecified, "role")
    73  	}
    74  
    75  	role.ConfigurationSets = updateOrAddConfig(role.ConfigurationSets, vm.ConfigurationSetTypeWindowsProvisioning,
    76  		func(config *vm.ConfigurationSet) {
    77  			config.ComputerName = hostname
    78  			config.AdminUsername = user
    79  			config.AdminPassword = password
    80  			config.EnableAutomaticUpdates = enableAutomaticUpdates
    81  			config.TimeZone = timeZone
    82  		},
    83  	)
    84  
    85  	return nil
    86  }
    87  
    88  // ConfigureWithCustomDataForLinux configures custom data for Linux-based images.
    89  // The customData contains either cloud-init or shell script to be executed upon start.
    90  //
    91  // The function expects the customData to be base64-encoded.
    92  func ConfigureWithCustomDataForLinux(role *vm.Role, customData string) error {
    93  	return configureWithCustomData(role, customData, vm.ConfigurationSetTypeLinuxProvisioning)
    94  }
    95  
    96  // ConfigureWithCustomDataForWindows configures custom data for Windows-based images.
    97  // The customData contains either cloud-init or shell script to be executed upon start.
    98  //
    99  // The function expects the customData to be base64-encoded.
   100  func ConfigureWithCustomDataForWindows(role *vm.Role, customData string) error {
   101  	return configureWithCustomData(role, customData, vm.ConfigurationSetTypeWindowsProvisioning)
   102  }
   103  
   104  func configureWithCustomData(role *vm.Role, customData string, typ vm.ConfigurationSetType) error {
   105  	if role == nil {
   106  		return fmt.Errorf(errParamNotSpecified, "role")
   107  	}
   108  
   109  	role.ConfigurationSets = updateOrAddConfig(role.ConfigurationSets, typ,
   110  		func(config *vm.ConfigurationSet) {
   111  			config.CustomData = customData
   112  		})
   113  
   114  	return nil
   115  }
   116  
   117  // ConfigureWindowsToJoinDomain adds configuration to join a new Windows vm to a
   118  // domain. "username" must be in UPN form (user@domain.com), "machineOU" can be
   119  // left empty
   120  func ConfigureWindowsToJoinDomain(role *vm.Role, username, password, domainToJoin, machineOU string) error {
   121  	if role == nil {
   122  		return fmt.Errorf(errParamNotSpecified, "role")
   123  	}
   124  
   125  	winconfig := findConfig(role.ConfigurationSets, vm.ConfigurationSetTypeWindowsProvisioning)
   126  	if winconfig != nil {
   127  		winconfig.DomainJoin = &vm.DomainJoin{
   128  			Credentials:     vm.Credentials{Username: username, Password: password},
   129  			JoinDomain:      domainToJoin,
   130  			MachineObjectOU: machineOU,
   131  		}
   132  	}
   133  
   134  	return nil
   135  }
   136  
   137  func ConfigureWinRMListener(role *vm.Role, protocol vm.WinRMProtocol, certificateThumbprint string) error {
   138  
   139  	if role == nil {
   140  		return fmt.Errorf(errParamNotSpecified, "role")
   141  	}
   142  
   143  	winconfig := findConfig(role.ConfigurationSets, vm.ConfigurationSetTypeWindowsProvisioning)
   144  
   145  	if winconfig != nil {
   146  
   147  		listener := vm.WinRMListener{
   148  			Protocol:              protocol,
   149  			CertificateThumbprint: certificateThumbprint,
   150  		}
   151  
   152  		if winconfig.WinRMListeners == nil {
   153  			winconfig.WinRMListeners = &[]vm.WinRMListener{}
   154  		}
   155  
   156  		currentListeners := *winconfig.WinRMListeners
   157  
   158  		// replace existing listener if it's already configured
   159  		for i, existingListener := range currentListeners {
   160  			if existingListener.Protocol == protocol {
   161  				currentListeners[i] = listener
   162  				return nil
   163  			}
   164  		}
   165  
   166  		// otherwise append to list of listeners
   167  		newListeners := append(currentListeners, listener)
   168  		winconfig.WinRMListeners = &newListeners
   169  
   170  		return nil
   171  	}
   172  
   173  	return fmt.Errorf("WindowsProvisioningConfigurationSet not found in 'role'")
   174  }
   175  
   176  func ConfigureWinRMOverHTTP(role *vm.Role) error {
   177  	return ConfigureWinRMListener(role, vm.WinRMProtocolHTTP, "")
   178  }
   179  
   180  func ConfigureWinRMOverHTTPS(role *vm.Role, certificateThumbprint string) error {
   181  	return ConfigureWinRMListener(role, vm.WinRMProtocolHTTPS, certificateThumbprint)
   182  }
   183  

View as plain text