Remove extra calls from CreateAzureVM
Also rename GetDeployment & DeleteDeployment and give async control to the caller
This commit is contained in:
Родитель
de1dcac65f
Коммит
588a3bb281
|
@ -18,22 +18,17 @@ import (
|
|||
"unicode"
|
||||
|
||||
"github.com/MSOpenTech/azure-sdk-for-go/management"
|
||||
hostedserviceclient "github.com/MSOpenTech/azure-sdk-for-go/management/hostedservice"
|
||||
locationclient "github.com/MSOpenTech/azure-sdk-for-go/management/location"
|
||||
storageserviceclient "github.com/MSOpenTech/azure-sdk-for-go/management/storageservice"
|
||||
)
|
||||
|
||||
const (
|
||||
azureDeploymentListURL = "services/hostedservices/%s/deployments"
|
||||
azureHostedServiceListURL = "services/hostedservices"
|
||||
deleteAzureHostedServiceURL = "services/hostedservices/%s?comp=media"
|
||||
azureHostedServiceAvailabilityURL = "services/hostedservices/operations/isavailable/%s"
|
||||
azureDeploymentURL = "services/hostedservices/%s/deployments/%s"
|
||||
deleteAzureDeploymentURL = "services/hostedservices/%s/deployments/%s?comp=media"
|
||||
azureRoleURL = "services/hostedservices/%s/deployments/%s/roles/%s"
|
||||
azureOperationsURL = "services/hostedservices/%s/deployments/%s/roleinstances/%s/Operations"
|
||||
azureCertificatListURL = "services/hostedservices/%s/certificates"
|
||||
azureRoleSizeListURL = "rolesizes"
|
||||
azureDeploymentListURL = "services/hostedservices/%s/deployments"
|
||||
azureDeploymentURL = "services/hostedservices/%s/deployments/%s"
|
||||
deleteAzureDeploymentURL = "services/hostedservices/%s/deployments/%s?comp=media"
|
||||
azureRoleURL = "services/hostedservices/%s/deployments/%s/roles/%s"
|
||||
azureOperationsURL = "services/hostedservices/%s/deployments/%s/roleinstances/%s/Operations"
|
||||
azureRoleSizeListURL = "rolesizes"
|
||||
|
||||
osLinux = "Linux"
|
||||
osWindows = "Windows"
|
||||
|
@ -47,7 +42,6 @@ const (
|
|||
errInvalidPassword = "Password must have at least one upper case, lower case and numeric character."
|
||||
errInvalidRoleSize = "Invalid role size: %s. Available role sizes: %s"
|
||||
errInvalidRoleSizeInLocation = "Role size: %s not available in location: %s."
|
||||
errInvalidDnsLength = "The DNS name must be between 3 and 25 characters."
|
||||
)
|
||||
|
||||
//NewClient is used to instantiate a new VmClient from an Azure client
|
||||
|
@ -55,51 +49,19 @@ func NewClient(client management.Client) VirtualMachineClient {
|
|||
return VirtualMachineClient{client: client}
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) CreateAzureVM(azureVMConfiguration *Role, dnsName, location string) error {
|
||||
if azureVMConfiguration == nil {
|
||||
return fmt.Errorf(errParamNotSpecified, "azureVMConfiguration")
|
||||
}
|
||||
if dnsName == "" {
|
||||
return fmt.Errorf(errParamNotSpecified, "dnsName")
|
||||
}
|
||||
if location == "" {
|
||||
return fmt.Errorf(errParamNotSpecified, "location")
|
||||
func (self VirtualMachineClient) CreateDeployment(role *Role, cloudserviceName string) (requestId string, err error) {
|
||||
if role == nil {
|
||||
return "", fmt.Errorf(errParamNotSpecified, "role")
|
||||
}
|
||||
|
||||
hostedServiceClient := hostedserviceclient.NewClient(self.client)
|
||||
requestId, err := hostedServiceClient.CreateHostedService(dnsName, location, "", dnsName, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vMDeploymentBytes, err := xml.Marshal(DeploymentRequest{
|
||||
Name: role.RoleName,
|
||||
DeploymentSlot: "Production",
|
||||
Label: role.RoleName,
|
||||
RoleList: []*Role{role}})
|
||||
|
||||
err = self.client.WaitAsyncOperation(requestId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if azureVMConfiguration.UseCertAuth {
|
||||
err = self.uploadServiceCert(dnsName, azureVMConfiguration.CertPath)
|
||||
if err != nil {
|
||||
hostedServiceClient.DeleteHostedService(dnsName)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
vMDeployment := self.createVMDeploymentConfig(azureVMConfiguration)
|
||||
vMDeploymentBytes, err := xml.Marshal(vMDeployment)
|
||||
if err != nil {
|
||||
hostedServiceClient.DeleteHostedService(dnsName)
|
||||
return err
|
||||
}
|
||||
|
||||
requestURL := fmt.Sprintf(azureDeploymentListURL, azureVMConfiguration.RoleName)
|
||||
requestId, err = self.client.SendAzurePostRequest(requestURL, vMDeploymentBytes)
|
||||
if err != nil {
|
||||
hostedServiceClient.DeleteHostedService(dnsName)
|
||||
return err
|
||||
}
|
||||
|
||||
return self.client.WaitAsyncOperation(requestId)
|
||||
requestURL := fmt.Sprintf(azureDeploymentListURL, cloudserviceName)
|
||||
return self.client.SendAzurePostRequest(requestURL, vMDeploymentBytes)
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) CreateAzureVMConfiguration(dnsName, instanceSize, imageName, location string) (*Role, error) {
|
||||
|
@ -242,7 +204,7 @@ func (self VirtualMachineClient) SetAzureDockerVMExtension(azureVMConfiguration
|
|||
return azureVMConfiguration, nil
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) GetVMDeployment(cloudserviceName, deploymentName string) (*DeploymentResponse, error) {
|
||||
func (self VirtualMachineClient) GetDeployment(cloudserviceName, deploymentName string) (*DeploymentResponse, error) {
|
||||
if cloudserviceName == "" {
|
||||
return nil, fmt.Errorf(errParamNotSpecified, "cloudserviceName")
|
||||
}
|
||||
|
@ -266,26 +228,16 @@ func (self VirtualMachineClient) GetVMDeployment(cloudserviceName, deploymentNam
|
|||
return deployment, nil
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) DeleteVMDeployment(cloudserviceName, deploymentName string) error {
|
||||
func (self VirtualMachineClient) DeleteDeployment(cloudserviceName, deploymentName string) (requestId string, err error) {
|
||||
if cloudserviceName == "" {
|
||||
return fmt.Errorf(errParamNotSpecified, "cloudserviceName")
|
||||
return "", fmt.Errorf(errParamNotSpecified, "cloudserviceName")
|
||||
}
|
||||
if deploymentName == "" {
|
||||
return fmt.Errorf(errParamNotSpecified, "deploymentName")
|
||||
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
|
||||
}
|
||||
|
||||
requestURL := fmt.Sprintf(deleteAzureDeploymentURL, cloudserviceName, deploymentName)
|
||||
requestId, err := self.client.SendAzureDeleteRequest(requestURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = self.client.WaitAsyncOperation(requestId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return self.client.SendAzureDeleteRequest(requestURL)
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) GetRole(cloudserviceName, deploymentName, roleName string) (*Role, error) {
|
||||
|
@ -326,9 +278,9 @@ func (self VirtualMachineClient) StartRole(cloudserviceName, deploymentName, rol
|
|||
return fmt.Errorf(errParamNotSpecified, "roleName")
|
||||
}
|
||||
|
||||
startRoleOperation := self.createStartRoleOperation()
|
||||
|
||||
startRoleOperationBytes, err := xml.Marshal(startRoleOperation)
|
||||
startRoleOperationBytes, err := xml.Marshal(StartRoleOperation{
|
||||
OperationType: "StartRoleOperation",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -353,9 +305,9 @@ func (self VirtualMachineClient) ShutdownRole(cloudserviceName, deploymentName,
|
|||
return fmt.Errorf(errParamNotSpecified, "roleName")
|
||||
}
|
||||
|
||||
shutdownRoleOperation := self.createShutdowRoleOperation()
|
||||
|
||||
shutdownRoleOperationBytes, err := xml.Marshal(shutdownRoleOperation)
|
||||
shutdownRoleOperationBytes, err := xml.Marshal(ShutdownRoleOperation{
|
||||
OperationType: "ShutdownRoleOperation",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -380,9 +332,9 @@ func (self VirtualMachineClient) RestartRole(cloudserviceName, deploymentName, r
|
|||
return fmt.Errorf(errParamNotSpecified, "roleName")
|
||||
}
|
||||
|
||||
restartRoleOperation := self.createRestartRoleOperation()
|
||||
|
||||
restartRoleOperationBytes, err := xml.Marshal(restartRoleOperation)
|
||||
restartRoleOperationBytes, err := xml.Marshal(RestartRoleOperation{
|
||||
OperationType: "RestartRoleOperation",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -458,24 +410,6 @@ func (self VirtualMachineClient) ResolveRoleSize(roleSizeName string) error {
|
|||
return errors.New(fmt.Sprintf(errInvalidRoleSize, roleSizeName, strings.Trim(availableSizes.String(), ", ")))
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) createStartRoleOperation() StartRoleOperation {
|
||||
return StartRoleOperation{
|
||||
OperationType: "StartRoleOperation",
|
||||
}
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) createShutdowRoleOperation() ShutdownRoleOperation {
|
||||
return ShutdownRoleOperation{
|
||||
OperationType: "ShutdownRoleOperation",
|
||||
}
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) createRestartRoleOperation() RestartRoleOperation {
|
||||
return RestartRoleOperation{
|
||||
OperationType: "RestartRoleOperation",
|
||||
}
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) createDockerPublicConfig(dockerPort int) (string, error) {
|
||||
config := dockerPublicConfig{DockerPort: dockerPort, Version: dockerPublicConfigVersion}
|
||||
configJson, err := json.Marshal(config)
|
||||
|
@ -502,16 +436,6 @@ func (self VirtualMachineClient) addDockerPort(configurationSets []Configuration
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) createVMDeploymentConfig(role *Role) DeploymentRequest {
|
||||
return DeploymentRequest{
|
||||
Name: role.RoleName,
|
||||
DeploymentSlot: "Production",
|
||||
Label: role.RoleName,
|
||||
RoleList: []*Role{role},
|
||||
}
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) createAzureVMRole(name, instanceSize, imageName, location string) (*Role, error) {
|
||||
vhd, err := self.createOSVirtualHardDisk(name, imageName, location)
|
||||
if err != nil {
|
||||
|
@ -608,41 +532,6 @@ func (self VirtualMachineClient) createLinuxProvisioningConfig(dnsName, userName
|
|||
return provisioningConfig, nil
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) uploadServiceCert(dnsName, certPath string) error {
|
||||
certificateConfig, err := self.createServiceCertDeploymentConf(certPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
certificateConfigBytes, err := xml.Marshal(certificateConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
requestURL := fmt.Sprintf(azureCertificatListURL, dnsName)
|
||||
requestId, azureErr := self.client.SendAzurePostRequest(requestURL, certificateConfigBytes)
|
||||
if azureErr != nil {
|
||||
return azureErr
|
||||
}
|
||||
|
||||
return self.client.WaitAsyncOperation(requestId)
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) createServiceCertDeploymentConf(certPath string) (ServiceCertificate, error) {
|
||||
certConfig := ServiceCertificate{}
|
||||
|
||||
data, err := ioutil.ReadFile(certPath)
|
||||
if err != nil {
|
||||
return certConfig, err
|
||||
}
|
||||
|
||||
certData := base64.StdEncoding.EncodeToString(data)
|
||||
certConfig.Data = certData
|
||||
certConfig.CertificateFormat = "pfx"
|
||||
|
||||
return certConfig, nil
|
||||
}
|
||||
|
||||
func (self VirtualMachineClient) createSshConfig(certPath, userName string) (SSH, error) {
|
||||
sshConfig := SSH{}
|
||||
publicKey := PublicKey{}
|
||||
|
|
|
@ -1,284 +1,284 @@
|
|||
package virtualmachine
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDocumentedDeploymentRequest(t *testing.T) {
|
||||
// xml based on https://msdn.microsoft.com/en-us/library/azure/jj157194.aspx
|
||||
// fixed typos, replaced strongly typed fields with values of correct type
|
||||
xmlString := `<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Name>name-of-deployment</Name>
|
||||
<DeploymentSlot>deployment-environment</DeploymentSlot>
|
||||
<Label>identifier-of-deployment</Label>
|
||||
<RoleList>
|
||||
<Role>
|
||||
<RoleName>name-of-the-virtual-machine</RoleName>
|
||||
<RoleType>PersistentVMRole</RoleType>
|
||||
<ConfigurationSets>
|
||||
<ConfigurationSet i:type="WindowsProvisioningConfigurationSet">
|
||||
<ConfigurationSetType>WindowsProvisioningConfiguration</ConfigurationSetType>
|
||||
<ComputerName>name-of-computer</ComputerName>
|
||||
<AdminPassword>administrator-password</AdminPassword>
|
||||
<EnableAutomaticUpdates>true</EnableAutomaticUpdates>
|
||||
<TimeZone>time-zone</TimeZone>
|
||||
<DomainJoin>
|
||||
<Credentials>
|
||||
<Domain>domain-to-join</Domain>
|
||||
<Username>user-name-in-the-domain</Username>
|
||||
<Password>password-for-the-user-name</Password>
|
||||
</Credentials>
|
||||
<JoinDomain>domain-to-join</JoinDomain>
|
||||
<MachineObjectOU>distinguished-name-of-the-ou</MachineObjectOU>
|
||||
</DomainJoin>
|
||||
<StoredCertificateSettings>
|
||||
<CertificateSetting>
|
||||
<StoreLocation>LocalMachine</StoreLocation>
|
||||
<StoreName>name-of-store-on-the-machine</StoreName>
|
||||
<Thumbprint>certificate-thumbprint</Thumbprint>
|
||||
</CertificateSetting>
|
||||
</StoredCertificateSettings>
|
||||
<WinRM>
|
||||
<Listeners>
|
||||
<Listener>
|
||||
<Protocol>listener-protocol</Protocol>
|
||||
</Listener>
|
||||
<Listener>
|
||||
<CertificateThumbprint>certificate-thumbprint</CertificateThumbprint>
|
||||
<Protocol>listener-protocol</Protocol>
|
||||
</Listener>
|
||||
</Listeners>
|
||||
</WinRM>
|
||||
<AdminUsername>name-of-administrator-account</AdminUsername>
|
||||
<CustomData>base-64-encoded-data</CustomData>
|
||||
<AdditionalUnattendContent>
|
||||
<Passes>
|
||||
<UnattendPass>
|
||||
<PassName>name-of-pass</PassName>
|
||||
<Components>
|
||||
<UnattendComponent>
|
||||
<ComponentName>name-of-component</ComponentName>
|
||||
<ComponentSettings>
|
||||
<ComponentSetting>
|
||||
<SettingName>name-of-setting</SettingName>
|
||||
<Content>base-64-encoded-XML-content</Content>
|
||||
</ComponentSetting>
|
||||
</ComponentSettings>
|
||||
</UnattendComponent>
|
||||
</Components>
|
||||
</UnattendPass>
|
||||
</Passes>
|
||||
</AdditionalUnattendContent>
|
||||
</ConfigurationSet>
|
||||
<ConfigurationSet i:type="LinuxProvisioningConfigurationSet">
|
||||
<ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType>
|
||||
<HostName>host-name-for-the-virtual-machine</HostName>
|
||||
<UserName>new-user-name</UserName>
|
||||
<UserPassword>password-for-the-new-user</UserPassword>
|
||||
<DisableSshPasswordAuthentication>true</DisableSshPasswordAuthentication>
|
||||
<SSH>
|
||||
<PublicKeys>
|
||||
<PublicKey>
|
||||
<FingerPrint>certificate-fingerprint</FingerPrint>
|
||||
<Path>SSH-public-key-storage-location</Path>
|
||||
</PublicKey>
|
||||
</PublicKeys>
|
||||
<KeyPairs>
|
||||
<KeyPair>
|
||||
<FingerPrint>certificate-fingerprint</FingerPrint>
|
||||
<Path>SSH-public-key-storage-location</Path>
|
||||
</KeyPair>
|
||||
</KeyPairs>
|
||||
</SSH>
|
||||
<CustomData>base-64-encoded-data</CustomData>
|
||||
</ConfigurationSet>
|
||||
<ConfigurationSet>
|
||||
<ConfigurationSetType>NetworkConfiguration</ConfigurationSetType>
|
||||
<InputEndpoints>
|
||||
<InputEndpoint>
|
||||
<LoadBalancedEndpointSetName>name-of-load-balanced-set</LoadBalancedEndpointSetName>
|
||||
<LocalPort>22</LocalPort>
|
||||
<Name>ZZH</Name>
|
||||
<Port>33</Port>
|
||||
<LoadBalancerProbe>
|
||||
<Path>/probe/me</Path>
|
||||
<Port>80</Port>
|
||||
<Protocol>http</Protocol>
|
||||
<IntervalInSeconds>30</IntervalInSeconds>
|
||||
<TimeoutInSeconds>5</TimeoutInSeconds>
|
||||
</LoadBalancerProbe>
|
||||
<Protocol>endpoint-protocol</Protocol>
|
||||
<EnableDirectServerReturn>enable-direct-server-return</EnableDirectServerReturn>
|
||||
<EndpointACL>
|
||||
<Rules>
|
||||
<Rule>
|
||||
<Order>priority-of-the-rule</Order>
|
||||
<Action>permit-rule</Action>
|
||||
<RemoteSubnet>subnet-of-the-rule</RemoteSubnet>
|
||||
<Description>description-of-the-rule</Description>
|
||||
</Rule>
|
||||
</Rules>
|
||||
</EndpointACL>
|
||||
<LoadBalancerName>name-of-internal-loadbalancer</LoadBalancerName>
|
||||
<IdleTimeoutInMinutes>9</IdleTimeoutInMinutes>
|
||||
</InputEndpoint>
|
||||
</InputEndpoints>
|
||||
<SubnetNames>
|
||||
<SubnetName>name-of-subnet</SubnetName>
|
||||
</SubnetNames>
|
||||
<StaticVirtualNetworkIPAddress>ip-address</StaticVirtualNetworkIPAddress>
|
||||
<PublicIPs>
|
||||
<PublicIP>
|
||||
<Name>name-of-public-ip</Name>
|
||||
<IdleTimeoutInMinutes>11</IdleTimeoutInMinutes>
|
||||
</PublicIP>
|
||||
</PublicIPs>
|
||||
</ConfigurationSet>
|
||||
</ConfigurationSets>
|
||||
<ResourceExtensionReferences>
|
||||
<ResourceExtensionReference>
|
||||
<ReferenceName>name-of-reference</ReferenceName>
|
||||
<Publisher>name-of-publisher</Publisher>
|
||||
<Name>name-of-extension</Name>
|
||||
<Version>version-of-extension</Version>
|
||||
<ResourceExtensionParameterValues>
|
||||
<ResourceExtensionParameterValue>
|
||||
<Key>name-of-parameter-key</Key>
|
||||
<Value>parameter-value</Value>
|
||||
<Type>type-of-parameter</Type>
|
||||
</ResourceExtensionParameterValue>
|
||||
</ResourceExtensionParameterValues>
|
||||
<State>state-of-resource</State>
|
||||
<Certificates>
|
||||
<Certificate>
|
||||
<Thumbprint>certificate-thumbprint</Thumbprint>
|
||||
<ThumbprintAlgorithm>certificate-algorithm</ThumbprintAlgorithm>
|
||||
</Certificate>
|
||||
</Certificates>
|
||||
</ResourceExtensionReference>
|
||||
</ResourceExtensionReferences>
|
||||
<VMImageName>name-of-vm-image</VMImageName>
|
||||
<MediaLocation>path-to-vhd</MediaLocation>
|
||||
<AvailabilitySetName>name-of-availability-set</AvailabilitySetName>
|
||||
<DataVirtualHardDisks>
|
||||
<DataVirtualHardDisk>
|
||||
<HostCaching>caching-mode</HostCaching>
|
||||
<DiskLabel>label-of-data-disk</DiskLabel>
|
||||
<DiskName>name-of-disk</DiskName>
|
||||
<Lun>0</Lun>
|
||||
<LogicalDiskSizeInGB>50</LogicalDiskSizeInGB>
|
||||
<MediaLink>path-to-vhd</MediaLink>
|
||||
</DataVirtualHardDisk>
|
||||
</DataVirtualHardDisks>
|
||||
<OSVirtualHardDisk>
|
||||
<HostCaching>caching-mode</HostCaching>
|
||||
<DiskLabel>label-of-operating-system-disk</DiskLabel>
|
||||
<DiskName>name-of-disk</DiskName>
|
||||
<MediaLink>path-to-vhd</MediaLink>
|
||||
<SourceImageName>name-of-source-image</SourceImageName>
|
||||
<OS>operating-system-of-image</OS>
|
||||
<RemoteSourceImageLink>path-to-source-image</RemoteSourceImageLink>
|
||||
<ResizedSizeInGB>125</ResizedSizeInGB>
|
||||
</OSVirtualHardDisk>
|
||||
<RoleSize>size-of-virtual-machine</RoleSize>
|
||||
<ProvisionGuestAgent>true</ProvisionGuestAgent>
|
||||
<VMImageInput>
|
||||
<OSDiskConfiguration>
|
||||
<ResizedSizeInGB>126</ResizedSizeInGB>
|
||||
</OSDiskConfiguration>
|
||||
<DataDiskConfigurations>
|
||||
<DataDiskConfiguration>
|
||||
<Name>disk-name</Name>
|
||||
<ResizedSizeInGB>127</ResizedSizeInGB>
|
||||
</DataDiskConfiguration>
|
||||
</DataDiskConfigurations>
|
||||
</VMImageInput>
|
||||
</Role>
|
||||
</RoleList>
|
||||
<VirtualNetworkName>name-of-virtual-network</VirtualNetworkName>
|
||||
<Dns>
|
||||
<DnsServers>
|
||||
<DnsServer>
|
||||
<Name>dns-name</Name>
|
||||
<Address>dns-ip-address</Address>
|
||||
</DnsServer>
|
||||
</DnsServers>
|
||||
</Dns>
|
||||
<ReservedIPName>name-of-reserved-ip</ReservedIPName>
|
||||
<LoadBalancers>
|
||||
<LoadBalancer>
|
||||
<Name>name-of-internal-load-balancer</Name>
|
||||
<FrontendIpConfiguration>
|
||||
<Type>Private</Type>
|
||||
<SubnetName>name-of-subnet</SubnetName>
|
||||
<StaticVirtualNetworkIPAddress>static-ip-address</StaticVirtualNetworkIPAddress>
|
||||
</FrontendIpConfiguration>
|
||||
</LoadBalancer>
|
||||
</LoadBalancers>
|
||||
</Deployment>`
|
||||
|
||||
deployment := DeploymentRequest{}
|
||||
if err := xml.Unmarshal([]byte(xmlString), &deployment); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if deployment.Name != "name-of-deployment" {
|
||||
t.Fatalf("Expected deployment.Name=\"name-of-deployment\", but got \"%s\"",
|
||||
deployment.Name)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
t.Logf("deployment.RoleList[0]: %+v", deployment.RoleList[0])
|
||||
if expected := "name-of-the-virtual-machine"; deployment.RoleList[0].RoleName != expected {
|
||||
t.Fatalf("Expected deployment.RoleList[0].RoleName=%v, but got %v", expected, deployment.RoleList[0].RoleName)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
t.Logf("deployment.DnsServers[0]: %+v", (*deployment.DnsServers)[0])
|
||||
if (*deployment.DnsServers)[0].Name != "dns-name" {
|
||||
t.Fatalf("Expected deployment.DnsServers[0].Name=\"dns-name\", but got \"%s\"",
|
||||
(*deployment.DnsServers)[0].Name)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
t.Logf("deployment.LoadBalancers[0]: %+v", (*deployment.LoadBalancers)[0])
|
||||
if (*deployment.LoadBalancers)[0].Name != "name-of-internal-load-balancer" {
|
||||
t.Fatalf("Expected deployment.LoadBalancers[0].Name=\"name-of-internal-load-balancer\", but got \"%s\"",
|
||||
(*deployment.LoadBalancers)[0].Name)
|
||||
}
|
||||
|
||||
if (*deployment.LoadBalancers)[0].Type != IPAddressTypePrivate {
|
||||
t.Fatalf("Expected deployment.LoadBalancers[0].Type=IPAddressTypePrivate, but got \"%s\"",
|
||||
(*deployment.LoadBalancers)[0].Type)
|
||||
}
|
||||
|
||||
if (*deployment.LoadBalancers)[0].StaticVirtualNetworkIPAddress != "static-ip-address" {
|
||||
t.Fatalf("Expected deployment.LoadBalancers[0].StaticVirtualNetworkIPAddress=\"static-ip-address\", but got \"%s\"",
|
||||
(*deployment.LoadBalancers)[0].StaticVirtualNetworkIPAddress)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
t.Logf("(*deployment.RoleList[0].ResourceExtensionReferences)[0]: %+v", (*deployment.RoleList[0].ResourceExtensionReferences)[0])
|
||||
if (*deployment.RoleList[0].ResourceExtensionReferences)[0].Name != "name-of-extension" {
|
||||
t.Fatalf("Expected (*deployment.RoleList[0].ResourceExtensionReferences)[0].Name=\"name-of-extension\", but got \"%s\"",
|
||||
(*deployment.RoleList[0].ResourceExtensionReferences)[0].Name)
|
||||
}
|
||||
|
||||
if (*deployment.RoleList[0].ResourceExtensionReferences)[0].ParameterValues[0].Key != "name-of-parameter-key" {
|
||||
t.Fatalf("Expected (*deployment.RoleList[0].ResourceExtensionReferences)[0].ParameterValues[0].Key=\"name-of-parameter-key\", but got %v",
|
||||
(*deployment.RoleList[0].ResourceExtensionReferences)[0].ParameterValues[0].Key)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
if deployment.RoleList[0].VMImageInput.DataDiskConfigurations[0].ResizedSizeInGB != 127 {
|
||||
t.Fatalf("Expected deployment.RoleList[0].VMImageInput.DataDiskConfigurations[0].ResizedSizeInGB=127, but got %v",
|
||||
deployment.RoleList[0].VMImageInput.DataDiskConfigurations[0].ResizedSizeInGB)
|
||||
}
|
||||
|
||||
}
|
||||
package virtualmachine
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDocumentedDeploymentRequest(t *testing.T) {
|
||||
// xml based on https://msdn.microsoft.com/en-us/library/azure/jj157194.aspx
|
||||
// fixed typos, replaced strongly typed fields with values of correct type
|
||||
xmlString := `<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Name>name-of-deployment</Name>
|
||||
<DeploymentSlot>deployment-environment</DeploymentSlot>
|
||||
<Label>identifier-of-deployment</Label>
|
||||
<RoleList>
|
||||
<Role>
|
||||
<RoleName>name-of-the-virtual-machine</RoleName>
|
||||
<RoleType>PersistentVMRole</RoleType>
|
||||
<ConfigurationSets>
|
||||
<ConfigurationSet i:type="WindowsProvisioningConfigurationSet">
|
||||
<ConfigurationSetType>WindowsProvisioningConfiguration</ConfigurationSetType>
|
||||
<ComputerName>name-of-computer</ComputerName>
|
||||
<AdminPassword>administrator-password</AdminPassword>
|
||||
<EnableAutomaticUpdates>true</EnableAutomaticUpdates>
|
||||
<TimeZone>time-zone</TimeZone>
|
||||
<DomainJoin>
|
||||
<Credentials>
|
||||
<Domain>domain-to-join</Domain>
|
||||
<Username>user-name-in-the-domain</Username>
|
||||
<Password>password-for-the-user-name</Password>
|
||||
</Credentials>
|
||||
<JoinDomain>domain-to-join</JoinDomain>
|
||||
<MachineObjectOU>distinguished-name-of-the-ou</MachineObjectOU>
|
||||
</DomainJoin>
|
||||
<StoredCertificateSettings>
|
||||
<CertificateSetting>
|
||||
<StoreLocation>LocalMachine</StoreLocation>
|
||||
<StoreName>name-of-store-on-the-machine</StoreName>
|
||||
<Thumbprint>certificate-thumbprint</Thumbprint>
|
||||
</CertificateSetting>
|
||||
</StoredCertificateSettings>
|
||||
<WinRM>
|
||||
<Listeners>
|
||||
<Listener>
|
||||
<Protocol>listener-protocol</Protocol>
|
||||
</Listener>
|
||||
<Listener>
|
||||
<CertificateThumbprint>certificate-thumbprint</CertificateThumbprint>
|
||||
<Protocol>listener-protocol</Protocol>
|
||||
</Listener>
|
||||
</Listeners>
|
||||
</WinRM>
|
||||
<AdminUsername>name-of-administrator-account</AdminUsername>
|
||||
<CustomData>base-64-encoded-data</CustomData>
|
||||
<AdditionalUnattendContent>
|
||||
<Passes>
|
||||
<UnattendPass>
|
||||
<PassName>name-of-pass</PassName>
|
||||
<Components>
|
||||
<UnattendComponent>
|
||||
<ComponentName>name-of-component</ComponentName>
|
||||
<ComponentSettings>
|
||||
<ComponentSetting>
|
||||
<SettingName>name-of-setting</SettingName>
|
||||
<Content>base-64-encoded-XML-content</Content>
|
||||
</ComponentSetting>
|
||||
</ComponentSettings>
|
||||
</UnattendComponent>
|
||||
</Components>
|
||||
</UnattendPass>
|
||||
</Passes>
|
||||
</AdditionalUnattendContent>
|
||||
</ConfigurationSet>
|
||||
<ConfigurationSet i:type="LinuxProvisioningConfigurationSet">
|
||||
<ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType>
|
||||
<HostName>host-name-for-the-virtual-machine</HostName>
|
||||
<UserName>new-user-name</UserName>
|
||||
<UserPassword>password-for-the-new-user</UserPassword>
|
||||
<DisableSshPasswordAuthentication>true</DisableSshPasswordAuthentication>
|
||||
<SSH>
|
||||
<PublicKeys>
|
||||
<PublicKey>
|
||||
<FingerPrint>certificate-fingerprint</FingerPrint>
|
||||
<Path>SSH-public-key-storage-location</Path>
|
||||
</PublicKey>
|
||||
</PublicKeys>
|
||||
<KeyPairs>
|
||||
<KeyPair>
|
||||
<FingerPrint>certificate-fingerprint</FingerPrint>
|
||||
<Path>SSH-public-key-storage-location</Path>
|
||||
</KeyPair>
|
||||
</KeyPairs>
|
||||
</SSH>
|
||||
<CustomData>base-64-encoded-data</CustomData>
|
||||
</ConfigurationSet>
|
||||
<ConfigurationSet>
|
||||
<ConfigurationSetType>NetworkConfiguration</ConfigurationSetType>
|
||||
<InputEndpoints>
|
||||
<InputEndpoint>
|
||||
<LoadBalancedEndpointSetName>name-of-load-balanced-set</LoadBalancedEndpointSetName>
|
||||
<LocalPort>22</LocalPort>
|
||||
<Name>ZZH</Name>
|
||||
<Port>33</Port>
|
||||
<LoadBalancerProbe>
|
||||
<Path>/probe/me</Path>
|
||||
<Port>80</Port>
|
||||
<Protocol>http</Protocol>
|
||||
<IntervalInSeconds>30</IntervalInSeconds>
|
||||
<TimeoutInSeconds>5</TimeoutInSeconds>
|
||||
</LoadBalancerProbe>
|
||||
<Protocol>endpoint-protocol</Protocol>
|
||||
<EnableDirectServerReturn>enable-direct-server-return</EnableDirectServerReturn>
|
||||
<EndpointACL>
|
||||
<Rules>
|
||||
<Rule>
|
||||
<Order>priority-of-the-rule</Order>
|
||||
<Action>permit-rule</Action>
|
||||
<RemoteSubnet>subnet-of-the-rule</RemoteSubnet>
|
||||
<Description>description-of-the-rule</Description>
|
||||
</Rule>
|
||||
</Rules>
|
||||
</EndpointACL>
|
||||
<LoadBalancerName>name-of-internal-loadbalancer</LoadBalancerName>
|
||||
<IdleTimeoutInMinutes>9</IdleTimeoutInMinutes>
|
||||
</InputEndpoint>
|
||||
</InputEndpoints>
|
||||
<SubnetNames>
|
||||
<SubnetName>name-of-subnet</SubnetName>
|
||||
</SubnetNames>
|
||||
<StaticVirtualNetworkIPAddress>ip-address</StaticVirtualNetworkIPAddress>
|
||||
<PublicIPs>
|
||||
<PublicIP>
|
||||
<Name>name-of-public-ip</Name>
|
||||
<IdleTimeoutInMinutes>11</IdleTimeoutInMinutes>
|
||||
</PublicIP>
|
||||
</PublicIPs>
|
||||
</ConfigurationSet>
|
||||
</ConfigurationSets>
|
||||
<ResourceExtensionReferences>
|
||||
<ResourceExtensionReference>
|
||||
<ReferenceName>name-of-reference</ReferenceName>
|
||||
<Publisher>name-of-publisher</Publisher>
|
||||
<Name>name-of-extension</Name>
|
||||
<Version>version-of-extension</Version>
|
||||
<ResourceExtensionParameterValues>
|
||||
<ResourceExtensionParameterValue>
|
||||
<Key>name-of-parameter-key</Key>
|
||||
<Value>parameter-value</Value>
|
||||
<Type>type-of-parameter</Type>
|
||||
</ResourceExtensionParameterValue>
|
||||
</ResourceExtensionParameterValues>
|
||||
<State>state-of-resource</State>
|
||||
<Certificates>
|
||||
<Certificate>
|
||||
<Thumbprint>certificate-thumbprint</Thumbprint>
|
||||
<ThumbprintAlgorithm>certificate-algorithm</ThumbprintAlgorithm>
|
||||
</Certificate>
|
||||
</Certificates>
|
||||
</ResourceExtensionReference>
|
||||
</ResourceExtensionReferences>
|
||||
<VMImageName>name-of-vm-image</VMImageName>
|
||||
<MediaLocation>path-to-vhd</MediaLocation>
|
||||
<AvailabilitySetName>name-of-availability-set</AvailabilitySetName>
|
||||
<DataVirtualHardDisks>
|
||||
<DataVirtualHardDisk>
|
||||
<HostCaching>caching-mode</HostCaching>
|
||||
<DiskLabel>label-of-data-disk</DiskLabel>
|
||||
<DiskName>name-of-disk</DiskName>
|
||||
<Lun>0</Lun>
|
||||
<LogicalDiskSizeInGB>50</LogicalDiskSizeInGB>
|
||||
<MediaLink>path-to-vhd</MediaLink>
|
||||
</DataVirtualHardDisk>
|
||||
</DataVirtualHardDisks>
|
||||
<OSVirtualHardDisk>
|
||||
<HostCaching>caching-mode</HostCaching>
|
||||
<DiskLabel>label-of-operating-system-disk</DiskLabel>
|
||||
<DiskName>name-of-disk</DiskName>
|
||||
<MediaLink>path-to-vhd</MediaLink>
|
||||
<SourceImageName>name-of-source-image</SourceImageName>
|
||||
<OS>operating-system-of-image</OS>
|
||||
<RemoteSourceImageLink>path-to-source-image</RemoteSourceImageLink>
|
||||
<ResizedSizeInGB>125</ResizedSizeInGB>
|
||||
</OSVirtualHardDisk>
|
||||
<RoleSize>size-of-virtual-machine</RoleSize>
|
||||
<ProvisionGuestAgent>true</ProvisionGuestAgent>
|
||||
<VMImageInput>
|
||||
<OSDiskConfiguration>
|
||||
<ResizedSizeInGB>126</ResizedSizeInGB>
|
||||
</OSDiskConfiguration>
|
||||
<DataDiskConfigurations>
|
||||
<DataDiskConfiguration>
|
||||
<Name>disk-name</Name>
|
||||
<ResizedSizeInGB>127</ResizedSizeInGB>
|
||||
</DataDiskConfiguration>
|
||||
</DataDiskConfigurations>
|
||||
</VMImageInput>
|
||||
</Role>
|
||||
</RoleList>
|
||||
<VirtualNetworkName>name-of-virtual-network</VirtualNetworkName>
|
||||
<Dns>
|
||||
<DnsServers>
|
||||
<DnsServer>
|
||||
<Name>dns-name</Name>
|
||||
<Address>dns-ip-address</Address>
|
||||
</DnsServer>
|
||||
</DnsServers>
|
||||
</Dns>
|
||||
<ReservedIPName>name-of-reserved-ip</ReservedIPName>
|
||||
<LoadBalancers>
|
||||
<LoadBalancer>
|
||||
<Name>name-of-internal-load-balancer</Name>
|
||||
<FrontendIpConfiguration>
|
||||
<Type>Private</Type>
|
||||
<SubnetName>name-of-subnet</SubnetName>
|
||||
<StaticVirtualNetworkIPAddress>static-ip-address</StaticVirtualNetworkIPAddress>
|
||||
</FrontendIpConfiguration>
|
||||
</LoadBalancer>
|
||||
</LoadBalancers>
|
||||
</Deployment>`
|
||||
|
||||
deployment := DeploymentRequest{}
|
||||
if err := xml.Unmarshal([]byte(xmlString), &deployment); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if deployment.Name != "name-of-deployment" {
|
||||
t.Fatalf("Expected deployment.Name=\"name-of-deployment\", but got \"%s\"",
|
||||
deployment.Name)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
t.Logf("deployment.RoleList[0]: %+v", deployment.RoleList[0])
|
||||
if expected := "name-of-the-virtual-machine"; deployment.RoleList[0].RoleName != expected {
|
||||
t.Fatalf("Expected deployment.RoleList[0].RoleName=%v, but got %v", expected, deployment.RoleList[0].RoleName)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
t.Logf("deployment.DnsServers[0]: %+v", (*deployment.DnsServers)[0])
|
||||
if (*deployment.DnsServers)[0].Name != "dns-name" {
|
||||
t.Fatalf("Expected deployment.DnsServers[0].Name=\"dns-name\", but got \"%s\"",
|
||||
(*deployment.DnsServers)[0].Name)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
t.Logf("deployment.LoadBalancers[0]: %+v", (*deployment.LoadBalancers)[0])
|
||||
if (*deployment.LoadBalancers)[0].Name != "name-of-internal-load-balancer" {
|
||||
t.Fatalf("Expected deployment.LoadBalancers[0].Name=\"name-of-internal-load-balancer\", but got \"%s\"",
|
||||
(*deployment.LoadBalancers)[0].Name)
|
||||
}
|
||||
|
||||
if (*deployment.LoadBalancers)[0].Type != IPAddressTypePrivate {
|
||||
t.Fatalf("Expected deployment.LoadBalancers[0].Type=IPAddressTypePrivate, but got \"%s\"",
|
||||
(*deployment.LoadBalancers)[0].Type)
|
||||
}
|
||||
|
||||
if (*deployment.LoadBalancers)[0].StaticVirtualNetworkIPAddress != "static-ip-address" {
|
||||
t.Fatalf("Expected deployment.LoadBalancers[0].StaticVirtualNetworkIPAddress=\"static-ip-address\", but got \"%s\"",
|
||||
(*deployment.LoadBalancers)[0].StaticVirtualNetworkIPAddress)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
t.Logf("(*deployment.RoleList[0].ResourceExtensionReferences)[0]: %+v", (*deployment.RoleList[0].ResourceExtensionReferences)[0])
|
||||
if (*deployment.RoleList[0].ResourceExtensionReferences)[0].Name != "name-of-extension" {
|
||||
t.Fatalf("Expected (*deployment.RoleList[0].ResourceExtensionReferences)[0].Name=\"name-of-extension\", but got \"%s\"",
|
||||
(*deployment.RoleList[0].ResourceExtensionReferences)[0].Name)
|
||||
}
|
||||
|
||||
if (*deployment.RoleList[0].ResourceExtensionReferences)[0].ParameterValues[0].Key != "name-of-parameter-key" {
|
||||
t.Fatalf("Expected (*deployment.RoleList[0].ResourceExtensionReferences)[0].ParameterValues[0].Key=\"name-of-parameter-key\", but got %v",
|
||||
(*deployment.RoleList[0].ResourceExtensionReferences)[0].ParameterValues[0].Key)
|
||||
}
|
||||
|
||||
// ======
|
||||
|
||||
if deployment.RoleList[0].VMImageInput.DataDiskConfigurations[0].ResizedSizeInGB != 127 {
|
||||
t.Fatalf("Expected deployment.RoleList[0].VMImageInput.DataDiskConfigurations[0].ResizedSizeInGB=127, but got %v",
|
||||
deployment.RoleList[0].VMImageInput.DataDiskConfigurations[0].ResizedSizeInGB)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче