rclone/vendor/github.com/Azure/azure-sdk-for-go/management/virtualmachine/client.go
2017-09-30 15:27:27 +01:00

345 lines
12 KiB
Go

// +build go1.7
// Package virtualmachine provides a client for Virtual Machines.
package virtualmachine
// Copyright 2017 Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import (
"encoding/xml"
"fmt"
"github.com/Azure/azure-sdk-for-go/management"
)
const (
azureDeploymentListURL = "services/hostedservices/%s/deployments"
azureDeploymentURL = "services/hostedservices/%s/deployments/%s"
azureListDeploymentsInSlotURL = "services/hostedservices/%s/deploymentslots/Production"
deleteAzureDeploymentURL = "services/hostedservices/%s/deployments/%s?comp=media"
azureAddRoleURL = "services/hostedservices/%s/deployments/%s/roles"
azureRoleURL = "services/hostedservices/%s/deployments/%s/roles/%s"
azureOperationsURL = "services/hostedservices/%s/deployments/%s/roleinstances/%s/Operations"
azureRoleSizeListURL = "rolesizes"
errParamNotSpecified = "Parameter %s is not specified."
)
//NewClient is used to instantiate a new VirtualMachineClient from an Azure client
func NewClient(client management.Client) VirtualMachineClient {
return VirtualMachineClient{client: client}
}
// CreateDeploymentOptions can be used to create a customized deployement request
type CreateDeploymentOptions struct {
DNSServers []DNSServer
LoadBalancers []LoadBalancer
ReservedIPName string
VirtualNetworkName string
}
// CreateDeployment creates a deployment and then creates a virtual machine
// in the deployment based on the specified configuration.
//
// https://msdn.microsoft.com/en-us/library/azure/jj157194.aspx
func (vm VirtualMachineClient) CreateDeployment(
role Role,
cloudServiceName string,
options CreateDeploymentOptions) (management.OperationID, error) {
req := DeploymentRequest{
Name: role.RoleName,
DeploymentSlot: "Production",
Label: role.RoleName,
RoleList: []Role{role},
DNSServers: options.DNSServers,
LoadBalancers: options.LoadBalancers,
ReservedIPName: options.ReservedIPName,
VirtualNetworkName: options.VirtualNetworkName,
}
data, err := xml.Marshal(req)
if err != nil {
return "", err
}
requestURL := fmt.Sprintf(azureDeploymentListURL, cloudServiceName)
return vm.client.SendAzurePostRequest(requestURL, data)
}
// GetDeploymentName queries an existing Azure cloud service for the name of the Deployment,
// if any, in its 'Production' slot (the only slot possible). If none exists, it returns empty
// string but no error
//
//https://msdn.microsoft.com/en-us/library/azure/ee460804.aspx
func (vm VirtualMachineClient) GetDeploymentName(cloudServiceName string) (string, error) {
var deployment DeploymentResponse
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
requestURL := fmt.Sprintf(azureListDeploymentsInSlotURL, cloudServiceName)
response, err := vm.client.SendAzureGetRequest(requestURL)
if err != nil {
if management.IsResourceNotFoundError(err) {
return "", nil
}
return "", err
}
err = xml.Unmarshal(response, &deployment)
if err != nil {
return "", err
}
return deployment.Name, nil
}
func (vm VirtualMachineClient) GetDeployment(cloudServiceName, deploymentName string) (DeploymentResponse, error) {
var deployment DeploymentResponse
if cloudServiceName == "" {
return deployment, fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return deployment, fmt.Errorf(errParamNotSpecified, "deploymentName")
}
requestURL := fmt.Sprintf(azureDeploymentURL, cloudServiceName, deploymentName)
response, azureErr := vm.client.SendAzureGetRequest(requestURL)
if azureErr != nil {
return deployment, azureErr
}
err := xml.Unmarshal(response, &deployment)
return deployment, err
}
func (vm VirtualMachineClient) DeleteDeployment(cloudServiceName, deploymentName string) (management.OperationID, error) {
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
}
requestURL := fmt.Sprintf(deleteAzureDeploymentURL, cloudServiceName, deploymentName)
return vm.client.SendAzureDeleteRequest(requestURL)
}
func (vm VirtualMachineClient) GetRole(cloudServiceName, deploymentName, roleName string) (*Role, error) {
if cloudServiceName == "" {
return nil, fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return nil, fmt.Errorf(errParamNotSpecified, "deploymentName")
}
if roleName == "" {
return nil, fmt.Errorf(errParamNotSpecified, "roleName")
}
role := new(Role)
requestURL := fmt.Sprintf(azureRoleURL, cloudServiceName, deploymentName, roleName)
response, azureErr := vm.client.SendAzureGetRequest(requestURL)
if azureErr != nil {
return nil, azureErr
}
err := xml.Unmarshal(response, role)
if err != nil {
return nil, err
}
return role, nil
}
// AddRole adds a Virtual Machine to a deployment of Virtual Machines, where role name = VM name
// See https://msdn.microsoft.com/en-us/library/azure/jj157186.aspx
func (vm VirtualMachineClient) AddRole(cloudServiceName string, deploymentName string, role Role) (management.OperationID, error) {
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
}
data, err := xml.Marshal(PersistentVMRole{Role: role})
if err != nil {
return "", err
}
requestURL := fmt.Sprintf(azureAddRoleURL, cloudServiceName, deploymentName)
return vm.client.SendAzurePostRequest(requestURL, data)
}
// UpdateRole updates the configuration of the specified virtual machine
// See https://msdn.microsoft.com/en-us/library/azure/jj157187.aspx
func (vm VirtualMachineClient) UpdateRole(cloudServiceName, deploymentName, roleName string, role Role) (management.OperationID, error) {
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
}
if roleName == "" {
return "", fmt.Errorf(errParamNotSpecified, "roleName")
}
data, err := xml.Marshal(PersistentVMRole{Role: role})
if err != nil {
return "", err
}
requestURL := fmt.Sprintf(azureRoleURL, cloudServiceName, deploymentName, roleName)
return vm.client.SendAzurePutRequest(requestURL, "text/xml", data)
}
func (vm VirtualMachineClient) StartRole(cloudServiceName, deploymentName, roleName string) (management.OperationID, error) {
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
}
if roleName == "" {
return "", fmt.Errorf(errParamNotSpecified, "roleName")
}
startRoleOperationBytes, err := xml.Marshal(StartRoleOperation{
OperationType: "StartRoleOperation",
})
if err != nil {
return "", err
}
requestURL := fmt.Sprintf(azureOperationsURL, cloudServiceName, deploymentName, roleName)
return vm.client.SendAzurePostRequest(requestURL, startRoleOperationBytes)
}
func (vm VirtualMachineClient) ShutdownRole(cloudServiceName, deploymentName, roleName string, postaction PostShutdownAction) (management.OperationID, error) {
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
}
if roleName == "" {
return "", fmt.Errorf(errParamNotSpecified, "roleName")
}
shutdownRoleOperationBytes, err := xml.Marshal(ShutdownRoleOperation{
OperationType: "ShutdownRoleOperation",
PostShutdownAction: postaction,
})
if err != nil {
return "", err
}
requestURL := fmt.Sprintf(azureOperationsURL, cloudServiceName, deploymentName, roleName)
return vm.client.SendAzurePostRequest(requestURL, shutdownRoleOperationBytes)
}
func (vm VirtualMachineClient) RestartRole(cloudServiceName, deploymentName, roleName string) (management.OperationID, error) {
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
}
if roleName == "" {
return "", fmt.Errorf(errParamNotSpecified, "roleName")
}
restartRoleOperationBytes, err := xml.Marshal(RestartRoleOperation{
OperationType: "RestartRoleOperation",
})
if err != nil {
return "", err
}
requestURL := fmt.Sprintf(azureOperationsURL, cloudServiceName, deploymentName, roleName)
return vm.client.SendAzurePostRequest(requestURL, restartRoleOperationBytes)
}
func (vm VirtualMachineClient) DeleteRole(cloudServiceName, deploymentName, roleName string, deleteVHD bool) (management.OperationID, error) {
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
}
if roleName == "" {
return "", fmt.Errorf(errParamNotSpecified, "roleName")
}
requestURL := fmt.Sprintf(azureRoleURL, cloudServiceName, deploymentName, roleName)
if deleteVHD {
requestURL += "?comp=media"
}
return vm.client.SendAzureDeleteRequest(requestURL)
}
func (vm VirtualMachineClient) GetRoleSizeList() (RoleSizeList, error) {
roleSizeList := RoleSizeList{}
response, err := vm.client.SendAzureGetRequest(azureRoleSizeListURL)
if err != nil {
return roleSizeList, err
}
err = xml.Unmarshal(response, &roleSizeList)
return roleSizeList, err
}
// CaptureRole captures a VM role. If reprovisioningConfigurationSet is non-nil,
// the VM role is redeployed after capturing the image, otherwise, the original
// VM role is deleted.
//
// NOTE: an image resulting from this operation shows up in
// osimage.GetImageList() as images with Category "User".
func (vm VirtualMachineClient) CaptureRole(cloudServiceName, deploymentName, roleName, imageName, imageLabel string,
reprovisioningConfigurationSet *ConfigurationSet) (management.OperationID, error) {
if cloudServiceName == "" {
return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName")
}
if deploymentName == "" {
return "", fmt.Errorf(errParamNotSpecified, "deploymentName")
}
if roleName == "" {
return "", fmt.Errorf(errParamNotSpecified, "roleName")
}
if reprovisioningConfigurationSet != nil &&
!(reprovisioningConfigurationSet.ConfigurationSetType == ConfigurationSetTypeLinuxProvisioning ||
reprovisioningConfigurationSet.ConfigurationSetType == ConfigurationSetTypeWindowsProvisioning) {
return "", fmt.Errorf("ConfigurationSet type can only be WindowsProvisioningConfiguration or LinuxProvisioningConfiguration")
}
operation := CaptureRoleOperation{
OperationType: "CaptureRoleOperation",
PostCaptureAction: PostCaptureActionReprovision,
ProvisioningConfiguration: reprovisioningConfigurationSet,
TargetImageLabel: imageLabel,
TargetImageName: imageName,
}
if reprovisioningConfigurationSet == nil {
operation.PostCaptureAction = PostCaptureActionDelete
}
data, err := xml.Marshal(operation)
if err != nil {
return "", err
}
return vm.client.SendAzurePostRequest(fmt.Sprintf(azureOperationsURL, cloudServiceName, deploymentName, roleName), data)
}