Utilizando PowerShell para entender as chamadas REST das APIs de gerenciamento do Windows Azure

Olá pessoal,

Para quem não sabe, o Windows Azure possui uma camada de APIs REST que permitem realizar o gerenciamento do seu ambiente, chamada de Windows Azure Service Management REST API. O interessante é que tudo que interage com o ambiente do Azure utiliza essas APIs, ou seja, tanto o portal de administração, o Visual Studio, System Center e ferramentas de linhas de comando.

Isso é excelente, afinal praticamente tudo que pode ser administrado no ambiente é feito por essas APIs. Entretanto, esse processo não é fácil. Como a API é muito poderosa, sua documentação é bastante extensa e seu uso pode ficar um pouco confuso.

Quando esse tipo de situação ocorre, eu recorro ao PowerShell. Os cmdlets do Windows Azure possuem mecanismos de depuração que retornam a chamada REST realizada na API, e o PowerShell gerencia essas informações de depuração com variáveis de preferências que são capazes de modificar o comportamento do script. Dessas variáveis, uma muito importante é a $DebugPreference que indica como o PowerShell deve tratar as informações de depuração e pode ter os seguintes valores:

  • Stop: exibe a mensagem de depuração e finaliza a execução do script
  • Inquire: exibe a mensagem de depuração e pergunta se deve continuar a execução do script
  • Continue: exibe a mensagem de depuração e continua a execução do script
  • SilentlyContinue: é o valor padrão. Não exibe a mensagem de depuração e executa o script sem interrupção

Logo, se mudarmos o valor da variável $DebugPreference para algum valor diferente do padrão temos informações úteis das chamadas aos serviços REST. Vou utilizar o script de criação de VMs de um post que fiz anteriormente, apenas alterando as informações de depuração.

clear

$DebugPreference
=
"Continue"

 

$imageName
=
"a699494373c04fc0bc8f2bb1389d6106__Win2K8R2SP1-Datacenter-201306.01-en.us-127GB.vhd"

$user
=
"<SeuUsuario>"

$password
=
"<SuaSenha>"

 

New-AzureVMConfig
-Name
"<NomeDaSuaMaquina>"
-InstanceSize
"Small"
-ImageName
$imageName
|

Add-AzureProvisioningConfig
-Windows
-AdminUsername
$user
-Password
$password
|

New-AzureVM
-ServiceName
"<NomeDoSeuServico>"
-Location
"East US"

 

Com isso, é possível perceber que o PowerShell realizar uma série chamadas REST ao Windows Azure:

Primeiro ele verifica se o serviço ainda não existe:

DEBUG: 11:59:50 - NewAzureVMCommand begin processing with ParameterSet 'CreateService'.

DEBUG: ============================ HTTP REQUEST ============================

 

HTTP Method:

GET

 

Absolute Uri:

https://management.core.windows.net/\<SubscriptionId>/services/hostedservices/<NomeDoSeuServico>/deploymentslots/Production

 

Headers:

x-ms-version : 2013-06-01

x-ms-client-id : <GuidDaChamada>

User-Agent : WindowsAzurePowershell/v0.6.16.1

 

Body:

 

Depois envia um comando para criar o serviço e recebe o id da operação como resposta:

DEBUG: ============================ HTTP REQUEST ============================

 

HTTP Method:

POST

 

Absolute Uri:

https://management.core.windows.net/\<SubscriptionId>/services/hostedservices

 

Headers:

x-ms-version : 2013-06-01

x-ms-client-id : <GuidDaChamada>

User-Agent : WindowsAzurePowershell/v0.6.16.1

 

Body:

<?xml version="1.0" encoding="utf-16"?>

<CreateHostedService xmlns="https://schemas.microsoft.com/windowsazure" xmlns:i="https://www.w3.org/2001/XMLSchema-instance">

 

    <ServiceName><NomeDoSeuServico></ServiceName>

    <Label>cmdvZGluaG9kYmc=</Label>

    <Description>Implicitly created hosted service2013-07-22 14:59</Description>

    <Location>East US</Location>

</CreateHostedService>

 

 

DEBUG: ============================ HTTP RESPONSE ============================

 

Status Code:

Created

 

Headers:

x-ms-servedbyregion : ussouth

x-ms-request-id : <IdDaOperacao>

Content-Length : 0

Cache-Control : no-cache

Date : Mon, 22 Jul 2013 14:59:58 GMT

Location : https://management.core.windows.net/subscriptions/\<SubscriptionId>/compute/<NomeDoSeuServico>

Server : 33.0.6198.68 (rd_rdfe_stable.130710-0833) Microsoft-HTTPAPI/2.0

 

Body:

 

Depois ele fica em um loop verificando o status da operação até ela ser finalizada com sucesso:

DEBUG: ============================ HTTP REQUEST ============================

 

HTTP Method:

GET

 

Absolute Uri:

https://management.core.windows.net/\<SubscriptionId>/operations/<IdDaOperacao>

 

Headers:

x-ms-version : 2013-06-01

x-ms-client-id : <GuidDaChamada>

User-Agent : WindowsAzurePowershell/v0.6.16.1

 

Body:

 

 

 

DEBUG: ============================ HTTP RESPONSE ============================

 

Status Code:

OK

 

Headers:

x-ms-servedbyregion : ussouth

x-ms-request-id : <NovoIdDaOperacao>

Content-Length : 232

Cache-Control : no-cache

Content-Type : application/xml; charset=utf-8

Date : Mon, 22 Jul 2013 14:59:58 GMT

Server : 33.0.6198.68 (rd_rdfe_stable.130710-0833) Microsoft-HTTPAPI/2.0

 

Body:

<?xml version="1.0" encoding="utf-16"?>

<Operation xmlns="https://schemas.microsoft.com/windowsazure" xmlns:i="https://www.w3.org/2001/XMLSchema-instance">

    <ID><IdDaOperacao></ID>

    <Status>Succeeded</Status>

    <HttpStatusCode>200</HttpStatusCode>

</Operation>

 

Agora sim ele manda criar a VM:

DEBUG: ============================ HTTP REQUEST ============================

 

HTTP Method:

POST

 

Absolute Uri:

https://management.core.windows.net/\<SubscriptionId>/services/hostedservices/<NomeDoSeuServico>/deployments

 

Headers:

x-ms-version : 2013-06-01

x-ms-client-id : <GuidDaChamada>

User-Agent : WindowsAzurePowershell/v0.6.16.1

 

Body:

<?xml version="1.0" encoding="utf-16"?>

<Deployment xmlns="https://schemas.microsoft.com/windowsazure" xmlns:i="https://www.w3.org/2001/XMLSchema-instance">

    <Name><NomeDoSeuServico></Name>

    <DeploymentSlot>Production</DeploymentSlot>

    <Label><NomeDoSeuServico></Label>

    <RoleList>

        <Role i:type="PersistentVMRole">

            <RoleName><NomeDoSeuServico>1</RoleName>

            <OsVersion i:nil="true"></OsVersion>

            <RoleType>PersistentVMRole</RoleType>

            <ConfigurationSets>

                <ConfigurationSet i:type="WindowsProvisioningConfigurationSet">

                    <ConfigurationSetType>WindowsProvisioningConfiguration</ConfigurationSetType>

                    <ComputerName><NomeDaSuaMaquina></ComputerName>

                    <AdminPassword><SuaSenha></AdminPassword>

                    <EnableAutomaticUpdates>true</EnableAutomaticUpdates>

                    <ResetPasswordOnFirstLogon>false</ResetPasswordOnFirstLogon>

                    <WinRM>

                        <Listeners>

                            <Listener>

                                <Protocol>Https</Protocol>

                            </Listener>

                        </Listeners>

                    </WinRM>

                    <AdminUsername><SeuUsuario></AdminUsername>

                </ConfigurationSet>

                <ConfigurationSet i:type="NetworkConfigurationSet">

                    <ConfigurationSetType>NetworkConfiguration</ConfigurationSetType>

                    <InputEndpoints>

                        <InputEndpoint>

                            <LocalPort>3389</LocalPort>

                            <Name>RDP</Name>

                            <Protocol>tcp</Protocol>

                        </InputEndpoint>

                        <InputEndpoint>

                            <LocalPort>5986</LocalPort>

                            <Name>WinRmHTTPs</Name>

                            <Protocol>tcp</Protocol>

                        </InputEndpoint>

                    </InputEndpoints>

                </ConfigurationSet>

            </ConfigurationSets>

            <DataVirtualHardDisks></DataVirtualHardDisks>

            <Label><NomeDaSuaMaquina></Label>

            <OSVirtualHardDisk>

                <MediaLink>https://<SuaContaDeStorage>.blob.core.windows.net/vhds/<NomeDoSeuServico>-<NomeDaSuaMaquina>-2013-7-22-11-59-58-332-0.vhd</MediaLink>

                <SourceImageName>a699494373c04fc0bc8f2bb1389d6106__Win2K8R2SP1-Datacenter-201306.01-en.us-127GB.vhd</SourceImageName>

            </OSVirtualHardDisk>

            <RoleSize>Small</RoleSize>

        </Role>

    </RoleList>

</Deployment>

 

 

DEBUG: ============================ HTTP RESPONSE ============================

 

Status Code:

Accepted

 

Headers:

x-ms-servedbyregion : ussouth

x-ms-request-id : <IdDaOperacao>

Content-Length : 0

Cache-Control : no-cache

Date : Mon, 22 Jul 2013 15:00:02 GMT

Server : 33.0.6198.68 (rd_rdfe_stable.130710-0833) Microsoft-HTTPAPI/2.0

 

Body:

 

Novamente ele fica em um loop verificando o status da requisição, vou omitir aqui pq a chamada é muito parecida com a anterior, e finalmente finaliza a execução do script.

RG