=== modified file 'helpers_apiobjects_test.go'
--- helpers_apiobjects_test.go 2014-12-02 00:36:45 +0000
+++ helpers_apiobjects_test.go 2015-07-28 13:15:20 +0000
@@ -48,6 +48,25 @@
return NewLinuxProvisioningConfigurationSet(hostname, username, password, customdata, disableSSH)
}
+func makeWindowsProvisioningConfiguration() *ConfigurationSet {
+ ComputerName := MakeRandomString(10)
+ Password := MakeRandomString(10)
+ AdminUsername := MakeRandomString(10)
+ TimeZone := MakeRandomString(10)
+ AdditionalUnattendContent := MakeRandomString(10)
+ CustomData := MakeRandomString(10)
+ EnableAutomaticUpdates := BoolToString(MakeRandomBool())
+
+ StoreLocation := MakeRandomString(10)
+ StoreName := MakeRandomString(10)
+ Thumbprint := MakeRandomString(10)
+ CertSettings := []CertificateSetting{CertificateSetting{StoreLocation, StoreName, Thumbprint}}
+
+ WinRMListener := &WinRMListener{WinRMProtocolHTTP, Thumbprint}
+
+ return NewWindowsProvisioningConfigurationSet(ComputerName, Password, EnableAutomaticUpdates, TimeZone, CertSettings, WinRMListener, AdminUsername, AdditionalUnattendContent, CustomData)
+}
+
func makeOSVirtualHardDisk() *OSVirtualHardDisk {
HostCaching := BoolToString(MakeRandomBool())
DiskLabel := MakeRandomString(10)
@@ -63,7 +82,7 @@
SourceImageName: SourceImageName}
}
-func makeRole() *Role {
+func makeLinuxRole() *Role {
RoleSize := "ExtraSmall"
RoleName := MakeRandomString(10)
RoleType := "PersistentVMRole"
@@ -77,6 +96,51 @@
ConfigurationSets: configset}
}
+func makeWindowsRole() *Role {
+ RoleSize := "ExtraSmall"
+ RoleName := MakeRandomString(10)
+ RoleType := "PersistentVMRole"
+ config := makeWindowsProvisioningConfiguration()
+ configset := []ConfigurationSet{*config}
+ provisionGuestAgent := BoolToString(MakeRandomBool())
+ resourceReference := makeWindowsResourceExtensionReference()
+
+ return &Role{
+ RoleSize: RoleSize,
+ RoleName: RoleName,
+ RoleType: RoleType,
+ ConfigurationSets: configset,
+ ProvisionGuestAgent: provisionGuestAgent,
+ ResourceExtensionReferences: &[]ResourceExtensionReference{*resourceReference},
+ }
+}
+
+func makeWindowsResourceExtensionReference() *ResourceExtensionReference {
+ refName := MakeRandomString(10)
+ publisher := MakeRandomString(10)
+ name := MakeRandomString(10)
+ version := MakeRandomString(10)
+ state := MakeRandomString(10)
+
+ param1 := makeWindowsResourceExtensionParameter(true)
+ param2 := makeWindowsResourceExtensionParameter(false)
+
+ return NewResourceExtensionReference(refName, publisher, name, version, state,
+ []ResourceExtensionParameter{*param1, *param2})
+}
+
+func makeWindowsResourceExtensionParameter(private bool) *ResourceExtensionParameter {
+ key := MakeRandomString(10)
+ value := MakeRandomString(10)
+ var paramType ResourceExtensionParameterType
+ if private {
+ paramType = ResourceExtensionParameterTypePrivate
+ } else {
+ paramType = ResourceExtensionParameterTypePublic
+ }
+ return NewResourceExtensionParameter(key, value, paramType)
+}
+
func makeDnsServer() *DnsServer {
name := MakeRandomString(10)
address := MakeRandomString(10)
@@ -91,7 +155,7 @@
DeploymentSlot := "Staging"
Label := MakeRandomString(10)
VirtualNetworkName := MakeRandomString(10)
- role := makeRole()
+ role := makeLinuxRole()
RoleList := []Role{*role}
Dns := []DnsServer{*makeDnsServer()}
=== modified file 'management_base_test.go'
--- management_base_test.go 2015-07-28 13:15:20 +0000
+++ management_base_test.go 2015-07-28 13:15:20 +0000
@@ -706,7 +706,7 @@
serviceName := "serviceName"
configurationSet := NewLinuxProvisioningConfigurationSet("testHostname12345", "test", "test123#@!", "user-data", "false")
vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "http://mediaLink", "sourceImageName", "os")
- role := NewRole("ExtraSmall", "test-role-123", vhd, []ConfigurationSet{*configurationSet})
+ role := NewLinuxRole("ExtraSmall", "test-role-123", vhd, []ConfigurationSet{*configurationSet})
deployment := NewDeploymentForCreateVMDeployment("test-machine-name", "Staging", "testLabel", []Role{*role}, "testNetwork")
err := api.AddDeployment(deployment, serviceName)
=== modified file 'xmlobjects.go'
--- xmlobjects.go 2015-07-28 13:15:20 +0000
+++ xmlobjects.go 2015-07-28 13:15:20 +0000
@@ -35,13 +35,37 @@
return string(out), nil
}
+// CertificateSetting specifies the parameters for the certificate which to
+// provision to the new Virtual Machine.
+type CertificateSetting struct {
+ StoreLocation string
+ StoreName string
+ Thumbprint string
+}
+
+// WinRMListener specifies the protocol and certificate information for a WinRM
+// listener.
+type WinRMListener struct {
+ Protocol WinRMProtocol
+ CertificateThumbprint string `xml:",omitempty"`
+}
+
+type WinRMProtocol string
+
+// Enum values for WinRMProtocol
+const (
+ WinRMProtocolHTTP WinRMProtocol = "Http"
+ WinRMProtocolHTTPS WinRMProtocol = "Https"
+)
+
//
// ConfigurationSet bits
//
const (
- CONFIG_SET_LINUX_PROVISIONING = "LinuxProvisioningConfiguration"
- CONFIG_SET_NETWORK = "NetworkConfiguration"
+ CONFIG_SET_LINUX_PROVISIONING = "LinuxProvisioningConfiguration"
+ CONFIG_SET_WINDOWS_PROVISIONING = "WindowsProvisioningConfiguration"
+ CONFIG_SET_NETWORK = "NetworkConfiguration"
)
// A ConfigurationSet object can be different things depending on its 'type'.
@@ -55,9 +79,19 @@
Hostname string `xml:"HostName,omitempty"`
Username string `xml:"UserName,omitempty"`
Password string `xml:"UserPassword,omitempty"`
- CustomData string `xml:"CustomData,omitempty"`
DisableSSHPasswordAuthentication string `xml:"DisableSshPasswordAuthentication,omitempty"`
+ // WindowsProvisioningConfiguration fields.
+ ComputerName string `xml:"ComputerName,omitempty"`
+ AdminPassword string `xml:"AdminPassword,omitempty"`
+ EnableAutomaticUpdates string `xml:"EnableAutomaticUpdates,omitempty"`
+ TimeZone string `xml:"TimeZone,omitempty"`
+ StoredCertificateSettings []CertificateSetting `xml:"StoredCertificateSettings,omitempty"`
+ WinRMListeners *WinRMListener `xml:"WinRM>Listeners>Listener,omitempty"`
+ AdminUsername string `xml:"AdminUsername,omitempty"`
+ AdditionalUnattendContent string `xml:"AdditionalUnattendContent,omitempty"`
+
+ CustomData string `xml:"CustomData,omitempty"`
// NetworkConfiguration fields.
// We use slice pointers to work around a Go bug:
// https://code.google.com/p/go/issues/detail?id=4168
@@ -98,6 +132,24 @@
}
}
+func NewWindowsProvisioningConfigurationSet(
+ ComputerName, AdminPassword, EnableAutomaticUpdates string, TimeZone string,
+ StoredCertificateSettings []CertificateSetting, WinRMListeners *WinRMListener,
+ AdminUsername, AdditionalUnattendContent, CustomData string) *ConfigurationSet {
+ return &ConfigurationSet{
+ ConfigurationSetType: CONFIG_SET_WINDOWS_PROVISIONING,
+ ComputerName: ComputerName,
+ AdminPassword: AdminPassword,
+ EnableAutomaticUpdates: EnableAutomaticUpdates,
+ TimeZone: TimeZone,
+ StoredCertificateSettings: StoredCertificateSettings,
+ WinRMListeners: WinRMListeners,
+ AdminUsername: AdminUsername,
+ CustomData: CustomData,
+ AdditionalUnattendContent: AdditionalUnattendContent,
+ }
+}
+
// NewNetworkConfiguration creates a ConfigurationSet of type "NetworkConfiguration".
func NewNetworkConfigurationSet(
inputEndpoints []InputEndpoint, subnetNames []string) *ConfigurationSet {
@@ -333,6 +385,69 @@
return fmt.Sprintf("http://%s.blob.core.windows.net/%s", StorageName, StoragePath)
}
+// ResourceExtensionReference contains a collection of resource extensions that
+// are to be installed on the Virtual Machine. The VM Agent must be installed on
+// the Virtual Machine to install resource extensions. For more information, see
+// Manage Extensions:
+//
+// https://msdn.microsoft.com/en-us/library/dn606311.aspx.
+type ResourceExtensionReference struct {
+ ReferenceName string `xml:"ReferenceName"`
+ Publisher string `xml:"Publisher"`
+ Name string `xml:"Name"`
+ Version string `xml:"Version"`
+ ParameterValues []ResourceExtensionParameter `xml:"ResourceExtensionParameterValues>ResourceExtensionParameterValue,omitempty"`
+ State string `xml:"State,omitempty"`
+}
+
+func (r *ResourceExtensionReference) Serialize() (string, error) {
+ return toxml(r)
+}
+
+func NewResourceExtensionReference(
+ ReferenceName, Publisher, Name, Version, State string,
+ ParameterValues []ResourceExtensionParameter,
+) *ResourceExtensionReference {
+ return &ResourceExtensionReference{
+ ReferenceName: ReferenceName,
+ Publisher: Publisher,
+ Name: Name,
+ Version: Version,
+ ParameterValues: ParameterValues,
+ State: State,
+ }
+}
+
+// ResourceExtensionParameter specifies the key, value, and type of a parameter that is passed to the
+// resource extension when it is installed.
+type ResourceExtensionParameter struct {
+ Key string
+ Value string
+ Type ResourceExtensionParameterType // If this value is set to Private, the parameter will not be returned by Get Deployment ().
+}
+
+type ResourceExtensionParameterType string
+
+// Enum values for ResourceExtensionParameterType
+const (
+ ResourceExtensionParameterTypePublic ResourceExtensionParameterType = "Public"
+ ResourceExtensionParameterTypePrivate ResourceExtensionParameterType = "Private"
+)
+
+func (r *ResourceExtensionParameter) Serialize() (string, error) {
+ return toxml(r)
+}
+
+func NewResourceExtensionParameter(
+ Key, Value string, Type ResourceExtensionParameterType,
+) *ResourceExtensionParameter {
+ return &ResourceExtensionParameter{
+ Key: Key,
+ Value: Value,
+ Type: Type,
+ }
+}
+
type Role struct {
XMLNS string `xml:"xmlns,attr,omitempty"`
RoleName string `xml:"RoleName"`
@@ -341,12 +456,13 @@
MediaLocation string `xml:"MediaLocation,omitempty"`
ConfigurationSets []ConfigurationSet `xml:"ConfigurationSets>ConfigurationSet"`
// TODO(axw) ResourceExtensionReferences
- AvailabilitySetName string `xml:"AvailabilitySetName,omitempty"`
- DataVirtualHardDisks *[]DataVirtualHardDisk `xml:"DataVirtualHardDisks>DataVirtualHardDisk,omitempty"`
- OSVirtualHardDisk *OSVirtualHardDisk `xml:"OSVirtualHardDisk,omitempty"`
- RoleSize string `xml:"RoleSize"`
- ProvisionGuestAgent bool `xml:"ProvisionGuestAgent,omitempty"`
- DefaultWinRmCertificateThumbprint string `xml:"DefaultWinRmCertificateThumbprint,omitempty"`
+ ResourceExtensionReferences *[]ResourceExtensionReference `xml:"ResourceExtensionReferences>ResourceExtensionReference,omitempty"`
+ AvailabilitySetName string `xml:"AvailabilitySetName,omitempty"`
+ DataVirtualHardDisks *[]DataVirtualHardDisk `xml:"DataVirtualHardDisks>DataVirtualHardDisk,omitempty"`
+ OSVirtualHardDisk *OSVirtualHardDisk `xml:"OSVirtualHardDisk,omitempty"`
+ RoleSize string `xml:"RoleSize"`
+ ProvisionGuestAgent string `xml:"ProvisionGuestAgent,omitempty"`
+ DefaultWinRmCertificateThumbprint string `xml:"DefaultWinRmCertificateThumbprint,omitempty"`
// TODO(axw) VMImageInput
}
@@ -358,7 +474,7 @@
return toxml(c)
}
-func NewRole(RoleSize, RoleName string, vhd *OSVirtualHardDisk, ConfigurationSets []ConfigurationSet) *Role {
+func newRole(RoleSize, RoleName string, vhd *OSVirtualHardDisk, ConfigurationSets []ConfigurationSet) *Role {
return &Role{
RoleSize: RoleSize,
RoleName: RoleName,
@@ -368,6 +484,20 @@
}
}
+func NewLinuxRole(RoleSize, RoleName string, vhd *OSVirtualHardDisk, ConfigurationSets []ConfigurationSet) *Role {
+ return newRole(RoleSize, RoleName, vhd, ConfigurationSets)
+}
+
+func NewWindowsRole(
+ RoleSize, RoleName string, vhd *OSVirtualHardDisk, ConfigurationSets []ConfigurationSet,
+ ResourceExtensionReferences *[]ResourceExtensionReference, ProvisionGuestAgent string,
+) *Role {
+ role := newRole(RoleSize, RoleName, vhd, ConfigurationSets)
+ role.ResourceExtensionReferences = ResourceExtensionReferences
+ role.ProvisionGuestAgent = ProvisionGuestAgent
+ return role
+}
+
//
// DnsServer bits
//
=== modified file 'xmlobjects_test.go'
--- xmlobjects_test.go 2015-07-28 13:15:20 +0000
+++ xmlobjects_test.go 2015-07-28 13:15:20 +0000
@@ -22,7 +22,7 @@
// Tests for Marshallers
//
-func (suite *xmlSuite) TestConfigurationSet(c *C) {
+func (suite *xmlSuite) TestLinuxConfigurationSet(c *C) {
config := makeLinuxProvisioningConfiguration()
xml, err := config.Serialize()
@@ -33,12 +33,52 @@
%s
%s
%s
- %s
%v
+ %s
`)
expected := fmt.Sprintf(template, config.Hostname, config.Username,
- config.Password, config.CustomData,
- config.DisableSSHPasswordAuthentication)
+ config.Password, config.DisableSSHPasswordAuthentication,
+ config.CustomData)
+ c.Check(strings.TrimSpace(xml), Equals, strings.TrimSpace(expected))
+}
+
+func (suite *xmlSuite) TestWindowsConfigurationSet(c *C) {
+ config := makeWindowsProvisioningConfiguration()
+
+ xml, err := config.Serialize()
+ c.Assert(err, IsNil)
+ template := dedent.Dedent(`
+
+ WindowsProvisioningConfiguration
+ %s
+ %s
+ %s
+ %v
+
+ %s
+ %s
+ %s
+
+
+
+
+ %s
+ %s
+
+
+
+ %s
+ %s
+ %s
+ `)
+ expected := fmt.Sprintf(template, config.ComputerName, config.AdminPassword,
+ config.EnableAutomaticUpdates, config.TimeZone,
+ config.StoredCertificateSettings[0].StoreLocation,
+ config.StoredCertificateSettings[0].StoreName,
+ config.StoredCertificateSettings[0].Thumbprint,
+ config.WinRMListeners.Protocol, config.WinRMListeners.CertificateThumbprint,
+ config.AdminUsername, config.AdditionalUnattendContent,
+ config.CustomData)
c.Check(strings.TrimSpace(xml), Equals, strings.TrimSpace(expected))
}
@@ -146,8 +186,8 @@
c.Check(strings.TrimSpace(xml), Equals, strings.TrimSpace(expected))
}
-func (suite *xmlSuite) TestRole(c *C) {
- role := makeRole()
+func (suite *xmlSuite) TestLinuxRole(c *C) {
+ role := makeLinuxRole()
config := role.ConfigurationSets[0]
xml, err := role.Serialize()
@@ -162,16 +202,101 @@
%s
%s
%s
- %s
%v
+ %s
%s
`)
expected := fmt.Sprintf(template, role.RoleName,
config.ConfigurationSetType, config.Hostname, config.Username,
- config.Password, config.CustomData,
- config.DisableSSHPasswordAuthentication, role.RoleSize)
+ config.Password, config.DisableSSHPasswordAuthentication,
+ config.CustomData, role.RoleSize)
+ c.Check(strings.TrimSpace(xml), Equals, strings.TrimSpace(expected))
+}
+
+func (suite *xmlSuite) TestWindowsRole(c *C) {
+ role := makeWindowsRole()
+ config := role.ConfigurationSets[0]
+ resources := role.ResourceExtensionReferences
+ resource := (*resources)[0]
+
+ xml, err := role.Serialize()
+ c.Assert(err, IsNil)
+ template := dedent.Dedent(`
+
+ %s
+ PersistentVMRole
+
+
+ WindowsProvisioningConfiguration
+ %s
+ %s
+ %s
+ %v
+
+ %s
+ %s
+ %s
+
+
+
+
+ %s
+ %s
+
+
+
+ %s
+ %s
+ %s
+
+
+
+
+ %s
+ %s
+ %s
+ %s
+
+
+ %s
+ %s
+ %s
+
+
+ %s
+ %s
+ %s
+
+
+ %s
+
+
+ %s
+ %s
+ `)
+ expected := fmt.Sprintf(template, role.RoleName,
+ config.ComputerName, config.AdminPassword,
+ config.EnableAutomaticUpdates, config.TimeZone,
+ config.StoredCertificateSettings[0].StoreLocation,
+ config.StoredCertificateSettings[0].StoreName,
+ config.StoredCertificateSettings[0].Thumbprint,
+ config.WinRMListeners.Protocol, config.WinRMListeners.CertificateThumbprint,
+ config.AdminUsername, config.AdditionalUnattendContent,
+ config.CustomData,
+ resource.ReferenceName, resource.Publisher, resource.Name,
+ resource.Version,
+ resource.ParameterValues[0].Key,
+ resource.ParameterValues[0].Value,
+ resource.ParameterValues[0].Type,
+ resource.ParameterValues[1].Key,
+ resource.ParameterValues[1].Value,
+ resource.ParameterValues[1].Type,
+ resource.State,
+ role.RoleSize,
+ role.ProvisionGuestAgent,
+ )
c.Check(strings.TrimSpace(xml), Equals, strings.TrimSpace(expected))
}
@@ -712,8 +837,8 @@
%s
%s
%s
+ %v
%s
- %v
%s
@@ -733,8 +858,8 @@
expected := fmt.Sprintf(template, deployment.Name,
deployment.DeploymentSlot, deployment.Label,
role.RoleName, config.ConfigurationSetType, config.Hostname,
- config.Username, config.Password, config.CustomData,
- config.DisableSSHPasswordAuthentication, role.RoleSize,
+ config.Username, config.Password, config.DisableSSHPasswordAuthentication,
+ config.CustomData, role.RoleSize,
deployment.VirtualNetworkName, dns.Name, dns.Address)
c.Check(strings.TrimSpace(xml), Equals, strings.TrimSpace(expected))
}
@@ -1034,7 +1159,7 @@
deploymentSlot := "staging"
label := "deploymentLabel"
vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os")
- roles := []Role{*NewRole("size", "name", vhd, []ConfigurationSet{})}
+ roles := []Role{*NewLinuxRole("size", "name", vhd, []ConfigurationSet{})}
virtualNetworkName := "network"
deployment := NewDeploymentForCreateVMDeployment(name, deploymentSlot, label, roles, virtualNetworkName)
@@ -1305,7 +1430,7 @@
configset := []ConfigurationSet{*config}
vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os")
- role := NewRole(rolesize, rolename, vhd, configset)
+ role := NewLinuxRole(rolesize, rolename, vhd, configset)
c.Check(role.RoleSize, Equals, rolesize)
c.Check(role.RoleName, Equals, rolename)
c.Check(role.ConfigurationSets, DeepEquals, configset)