From 3a5bf46f1aba0bf3fd62e9d50417ba52acffeed8 Mon Sep 17 00:00:00 2001 From: guangyang Date: Wed, 4 Dec 2013 18:41:25 -0800 Subject: [PATCH 01/14] fix a blob API header --- lib/azure/blob/blob_service.rb | 4 ++-- test/unit/blob/blob_service_test.rb | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/azure/blob/blob_service.rb b/lib/azure/blob/blob_service.rb index de91fb786f..1b10099d26 100644 --- a/lib/azure/blob/blob_service.rb +++ b/lib/azure/blob/blob_service.rb @@ -460,7 +460,7 @@ def create_page_blob(container, blob, length, options={}) # ==== Options # # Accepted key/value pairs in options parameter are: - # * +:if_sequence_number_lte+ - If the blob's sequence number is less than or equal to the specified value, the request proceeds; otherwise it fails with the SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed). + # * +:if_sequence_number_le+ - If the blob's sequence number is less than or equal to the specified value, the request proceeds; otherwise it fails with the SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed). # * +:if_sequence_number_lt+ - If the blob's sequence number is less than the specified value, the request proceeds; otherwise it fails with SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed). # * +:if_sequence_number_eq+ - If the blob's sequence number is equal to the specified value, the request proceeds; otherwise it fails with SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed). # * +:if_modified_since+ - A DateTime value. Specify this conditional header to write the page only if the blob has been modified since the specified date/time. If the blob has not been modified, the Blob service returns status code 412 (Precondition Failed). @@ -486,7 +486,7 @@ def create_blob_pages(container, blob, start_range, end_range, content, options= # set optional headers unless options.empty? - headers["x-ms-if-sequence-number-lte"] = options[:if_sequence_number_lte] if options[:if_sequence_number_lte] + headers["x-ms-if-sequence-number-le"] = options[:if_sequence_number_le] if options[:if_sequence_number_le] headers["x-ms-if-sequence-number-lt"] = options[:if_sequence_number_lt] if options[:if_sequence_number_lt] headers["x-ms-if-sequence-number-eq"] = options[:if_sequence_number_eq] if options[:if_sequence_number_eq] headers["If-Modified-Since"] = options[:if_modified_since] if options[:if_modified_since] diff --git a/test/unit/blob/blob_service_test.rb b/test/unit/blob/blob_service_test.rb index 5fc90a2f35..d05179d1b4 100644 --- a/test/unit/blob/blob_service_test.rb +++ b/test/unit/blob/blob_service_test.rb @@ -734,16 +734,16 @@ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_sequence_number_lt => "isnlt-value" } end - it "modifies the request headers when provided a :if_sequence_number_lte value" do - request_headers["x-ms-if-sequence-number-lte"] = "isnlte-value" - subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_sequence_number_lte => "isnlte-value" } + it "modifies the request headers when provided a :if_sequence_number_le value" do + request_headers["x-ms-if-sequence-number-le"] = "isnle-value" + subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_sequence_number_le => "isnle-value" } end - + it "modifies the request headers when provided a :if_modified_since value" do request_headers["If-Modified-Since"] = "ims-value" subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_modified_since => "ims-value" } end - + it "modifies the request headers when provided a :if_unmodified_since value" do request_headers["If-Unmodified-Since"] = "iums-value" subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_unmodified_since => "iums-value" } From 9c173d1406c14684058aea8bb148c12b0e4ff2c1 Mon Sep 17 00:00:00 2001 From: Ranjan Kumar Date: Tue, 28 Jan 2014 17:17:08 +0530 Subject: [PATCH 02/14] Bug fix related to add role api. --- .../management_http_request.rb | 2 +- lib/azure/core/configuration.rb | 2 +- .../serialization.rb | 192 +++++++++--------- .../virtual_machine.rb | 19 +- .../virtual_machine_management_service.rb | 31 +-- test/integration/vm/VM_Create_test.rb | 185 +++++++++-------- .../serialization_test.rb | 6 +- ...virtual_machine_management_service_test.rb | 3 - 8 files changed, 209 insertions(+), 231 deletions(-) diff --git a/lib/azure/base_management/management_http_request.rb b/lib/azure/base_management/management_http_request.rb index c67312af95..81ed88fe97 100644 --- a/lib/azure/base_management/management_http_request.rb +++ b/lib/azure/base_management/management_http_request.rb @@ -139,7 +139,7 @@ def check_completion(request_id) end puts '' else - sleep(1) + sleep(5) end end response diff --git a/lib/azure/core/configuration.rb b/lib/azure/core/configuration.rb index 509a009751..1fa3b40348 100644 --- a/lib/azure/core/configuration.rb +++ b/lib/azure/core/configuration.rb @@ -200,7 +200,7 @@ def sql_database_management_endpoint def sql_database_authentication_mode sdam = @sql_database_authentication_mode || :sql_server if [:sql_server, :management_certificate].include? sdam.to_sym - @sql_database_authentication_mode.to_sym + sdam.to_sym else :sql_server end diff --git a/lib/azure/virtual_machine_management/serialization.rb b/lib/azure/virtual_machine_management/serialization.rb index f6ccf1ebf6..4ce618c16d 100644 --- a/lib/azure/virtual_machine_management/serialization.rb +++ b/lib/azure/virtual_machine_management/serialization.rb @@ -18,16 +18,15 @@ module Azure module VirtualMachineManagement module Serialization - def self.shutdown_virtual_machine_to_xml builder = Nokogiri::XML::Builder.new do |xml| xml.ShutdownRoleOperation( - 'xmlns'=>'http://schemas.microsoft.com/windowsazure', - 'xmlns:i'=>'http://www.w3.org/2001/XMLSchema-instance' - ) { + 'xmlns' => 'http://schemas.microsoft.com/windowsazure', + 'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance' + ) do xml.OperationType 'ShutdownRoleOperation' xml.PostShutdownAction 'StoppedDeallocated' - } + end end builder.doc.to_xml end @@ -35,11 +34,11 @@ def self.shutdown_virtual_machine_to_xml def self.start_virtual_machine_to_xml builder = Nokogiri::XML::Builder.new do |xml| xml.StartRoleOperation( - 'xmlns'=>'http://schemas.microsoft.com/windowsazure', - 'xmlns:i'=>'http://www.w3.org/2001/XMLSchema-instance' - ) { + 'xmlns' => 'http://schemas.microsoft.com/windowsazure', + 'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance' + ) do xml.OperationType 'StartRoleOperation' - } + end end builder.doc.to_xml end @@ -48,17 +47,17 @@ def self.deployment_to_xml(params, options) options[:deployment_name] ||= options[:cloud_service_name] builder = Nokogiri::XML::Builder.new do |xml| xml.Deployment( - 'xmlns'=>'http://schemas.microsoft.com/windowsazure', - 'xmlns:i'=>'http://www.w3.org/2001/XMLSchema-instance' - ) { + 'xmlns' => 'http://schemas.microsoft.com/windowsazure', + 'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance' + ) do xml.Name options[:deployment_name] xml.DeploymentSlot 'Production' xml.Label Base64.encode64(options[:deployment_name]).strip - xml.RoleList { xml.Role('i:type'=>'PersistentVMRole') } + xml.RoleList { xml.Role('i:type' => 'PersistentVMRole') } if options[:virtual_network_name] xml.VirtualNetworkName options[:virtual_network_name] end - } + end end builder.doc.at_css('Role') << role_to_xml(params, options).at_css('PersistentVMRole').children.to_s builder.doc.to_xml @@ -67,42 +66,42 @@ def self.deployment_to_xml(params, options) def self.role_to_xml(params, options) builder = Nokogiri::XML::Builder.new do |xml| xml.PersistentVMRole( - 'xmlns'=>'http://schemas.microsoft.com/windowsazure', - 'xmlns:i'=>'http://www.w3.org/2001/XMLSchema-instance' - ) { - xml.RoleName {xml.text params[:vm_name]} + 'xmlns' => 'http://schemas.microsoft.com/windowsazure', + 'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance' + ) do + xml.RoleName { xml.text params[:vm_name] } xml.OsVersion('i:nil' => 'true') xml.RoleType 'PersistentVMRole' - - xml.ConfigurationSets { + + xml.ConfigurationSets do provisioning_configuration_to_xml(xml, params, options) - xml.ConfigurationSet('i:type' => 'NetworkConfigurationSet') { + xml.ConfigurationSet('i:type' => 'NetworkConfigurationSet') do xml.ConfigurationSetType 'NetworkConfiguration' - xml.InputEndpoints { + xml.InputEndpoints do default_endpoints_to_xml(xml, options) tcp_endpoints_to_xml(xml, options[:tcp_endpoints]) if options[:tcp_endpoints] - } + end if options[:virtual_network_name] && options[:subnet_name] - xml.SubnetNames { + xml.SubnetNames do xml.SubnetName options[:subnet_name] - } + end end - } - } + end + end xml.Label Base64.encode64(params[:vm_name]).strip - xml.OSVirtualHardDisk { + xml.OSVirtualHardDisk do xml.MediaLink 'http://' + options[:storage_account_name] + '.blob.core.windows.net/vhds/' + (Time.now.strftime('disk_%Y_%m_%d_%H_%M')) + '.vhd' xml.SourceImageName params[:image] - } + end xml.RoleSize options[:vm_size] - } + end end builder.doc end def self.provisioning_configuration_to_xml(xml, params, options) if options[:os_type] == 'Linux' - xml.ConfigurationSet('i:type' => 'LinuxProvisioningConfigurationSet') { + xml.ConfigurationSet('i:type' => 'LinuxProvisioningConfigurationSet') do xml.ConfigurationSetType 'LinuxProvisioningConfiguration' xml.HostName params[:vm_name] xml.UserName params[:vm_user] @@ -111,70 +110,70 @@ def self.provisioning_configuration_to_xml(xml, params, options) xml.DisableSshPasswordAuthentication 'false' end if params[:certificate][:fingerprint] - xml.SSH{ - xml.PublicKeys{ - xml.PublicKey{ + xml.SSH do + xml.PublicKeys do + xml.PublicKey do xml.Fingerprint params[:certificate][:fingerprint] xml.Path "/home/#{params[:vm_user]}/.ssh/authorized_keys" - } - } - } + end + end + end end - } + end elsif options[:os_type] == 'Windows' - xml.ConfigurationSet('i:type' => 'WindowsProvisioningConfigurationSet') { + xml.ConfigurationSet('i:type' => 'WindowsProvisioningConfigurationSet') do xml.ConfigurationSetType 'WindowsProvisioningConfiguration' xml.ComputerName params[:vm_name] xml.AdminPassword params[:password] xml.ResetPasswordOnFirstLogon 'false' xml.EnableAutomaticUpdates 'true' if enable_winrm?(options[:winrm_transport]) - xml.WinRM { - xml.Listeners { + xml.WinRM do + xml.Listeners do if options[:winrm_transport].include?('http') - xml.Listener { + xml.Listener do xml.Protocol 'Http' - } + end end if options[:winrm_transport].include?('https') - xml.Listener { + xml.Listener do xml.Protocol 'Https' xml.CertificateThumbprint params[:certificate][:fingerprint] if params[:certificate][:fingerprint] - } + end end - } - } + end + end end xml.AdminUsername params[:vm_user] - } + end end end def self.default_endpoints_to_xml(xml, options) os_type = options[:os_type] if os_type == 'Linux' - xml.InputEndpoint { + xml.InputEndpoint do xml.LocalPort '22' xml.Name 'SSH' xml.Port options[:ssh_port] || '22' xml.Protocol 'TCP' - } + end elsif os_type == 'Windows' if options[:winrm_transport] && options[:winrm_transport].include?('http') - xml.InputEndpoint { + xml.InputEndpoint do xml.LocalPort '5985' xml.Name 'WinRm-Http' xml.Port '5985' xml.Protocol 'TCP' - } + end end if options[:winrm_transport] && options[:winrm_transport].include?('https') - xml.InputEndpoint { + xml.InputEndpoint do xml.LocalPort '5986' xml.Name 'WinRm-Https' xml.Port '5986' xml.Protocol 'TCP' - } + end end end end @@ -183,7 +182,7 @@ def self.tcp_endpoints_to_xml(xml, tcp_endpoints) if tcp_endpoints tcp_endpoints.split(',').each do |endpoint| ports = endpoint.split(':') - xml.InputEndpoint { + xml.InputEndpoint do xml.LocalPort ports[0] if ports.length > 1 xml.Name 'TCP-PORT-' + ports[1] @@ -193,55 +192,64 @@ def self.tcp_endpoints_to_xml(xml, tcp_endpoints) xml.Port ports[0] end xml.Protocol 'TCP' - } + end end end end def self.virtual_machines_from_xml(deployXML, cloud_service_name) - if deployXML.at_css('Deployment Name') != nil + unless deployXML.at_css('Deployment Name').nil? rolesXML = deployXML.css('Deployment RoleInstanceList RoleInstance') - vm = VirtualMachine.new - vm.status = xml_content(rolesXML, 'InstanceStatus') - vm.vm_name = xml_content(rolesXML, 'RoleName') - vm.role_size = xml_content(rolesXML, 'InstanceSize') - vm.hostname = xml_content(rolesXML, 'HostName') - vm.cloud_service_name = cloud_service_name - vm.deployment_name = xml_content(deployXML, 'Deployment Name') - vm.deployment_status = xml_content(deployXML, 'Deployment Status') - osdisk = deployXML.css(deployXML, 'OSVirtualHardDisk') - vm.os_type = xml_content(osdisk, 'OS') - vm.disk_name = xml_content(osdisk, 'DiskName') - vm.tcp_endpoints = Array.new - vm.udp_endpoints = Array.new - endpoints = rolesXML.css('InstanceEndpoint') - endpoints.each do |endpoint| - if vm.ipaddress.nil? - if xml_content(endpoint, 'Name').downcase == 'ssh' - vm.ipaddress = xml_content(endpoint, 'Vip') - elsif !(xml_content(endpoint, 'Name').downcase =~ /winrm/).nil? - vm.ipaddress = xml_content(endpoint, 'Vip') + vms = [] + rolesXML.each do |instance| + vm = VirtualMachine.new + vm.status = xml_content(instance, 'InstanceStatus') + vm.vm_name = xml_content(instance, 'RoleName').downcase + vm.role_size = xml_content(instance, 'InstanceSize') + vm.hostname = xml_content(instance, 'HostName') + vm.cloud_service_name = cloud_service_name.downcase + vm.deployment_name = xml_content(deployXML, 'Deployment Name') + vm.deployment_status = xml_content(deployXML, 'Deployment Status') + tcp_endpoints_from_xml(instance, vm) + vm.ipaddress = xml_content(instance, 'IpAddress') unless vm.ipaddress + vm.virtual_network_name = xml_content(deployXML.css('Deployment'), 'VirtualNetworkName') + deployXML.css('Deployment RoleList Role').each do |role| + if xml_content(role, 'RoleName') == xml_content(instance, 'RoleName') + vm.os_type = xml_content(role, 'OSVirtualHardDisk OS') + vm.disk_name = xml_content(role, 'OSVirtualHardDisk DiskName') + break end end - hash = Hash.new - hash['Name'] = xml_content(endpoint, 'Name') - hash['Vip'] = xml_content(endpoint, 'Vip') - hash['PublicPort'] = xml_content(endpoint, 'PublicPort') - hash['LocalPort'] = xml_content(endpoint, 'LocalPort') - if xml_content(endpoint, 'Protocol') == 'tcp' - vm.tcp_endpoints << hash - else - vm.udp_endpoints << hash - end + vms << vm end - vm.ipaddress = xml_content(rolesXML, 'IpAddress') unless vm.ipaddress - vm.virtual_network_name = xml_content(deployXML.css('Deployment'), - 'VirtualNetworkName') - vm + vms end end + def self.tcp_endpoints_from_xml(rolesXML, vm) + vm.tcp_endpoints = [] + vm.udp_endpoints = [] + endpoints = rolesXML.css('InstanceEndpoint') + endpoints.each do |endpoint| + if vm.ipaddress.nil? + if xml_content(endpoint, 'Name').downcase == 'ssh' + vm.ipaddress = xml_content(endpoint, 'Vip') + elsif !(xml_content(endpoint, 'Name').downcase =~ /winrm/).nil? + vm.ipaddress = xml_content(endpoint, 'Vip') + end + end + hash = Hash.new + hash['Name'] = xml_content(endpoint, 'Name') + hash['Vip'] = xml_content(endpoint, 'Vip') + hash['PublicPort'] = xml_content(endpoint, 'PublicPort') + hash['LocalPort'] = xml_content(endpoint, 'LocalPort') + if xml_content(endpoint, 'Protocol') == 'tcp' + vm.tcp_endpoints << hash + else + vm.udp_endpoints << hash + end + end + end end end end - diff --git a/lib/azure/virtual_machine_management/virtual_machine.rb b/lib/azure/virtual_machine_management/virtual_machine.rb index ca0171c7cd..fb27db1046 100644 --- a/lib/azure/virtual_machine_management/virtual_machine.rb +++ b/lib/azure/virtual_machine_management/virtual_machine.rb @@ -16,7 +16,6 @@ module Azure module VirtualMachineManagement class VirtualMachine - def initialize yield self if block_given? end @@ -31,27 +30,11 @@ def initialize attr_accessor :deployment_status attr_accessor :tcp_endpoints attr_accessor :role_size - attr_accessor :storage_account_name - attr_accessor :password attr_accessor :vm_user attr_accessor :image attr_accessor :os_type attr_accessor :disk_name attr_accessor :virtual_network_name - attr_accessor :virtual_network - - def cloud_service_name - @cloud_service_name ||= (random_string(@vm_name+'-service-') if @vm_name) - end - - def storage_account_name - @storage_account_name ||= (random_string(@vm_name+'storage').gsub(/[^0-9a-z ]/i, '').downcase[0..23] if @vm_name) - end - - def deployment_name - @deployment_name ||= @cloud_service_name - end - end end -end \ No newline at end of file +end diff --git a/lib/azure/virtual_machine_management/virtual_machine_management_service.rb b/lib/azure/virtual_machine_management/virtual_machine_management_service.rb index a1e8cef8d7..5721365ee0 100644 --- a/lib/azure/virtual_machine_management/virtual_machine_management_service.rb +++ b/lib/azure/virtual_machine_management/virtual_machine_management_service.rb @@ -37,20 +37,7 @@ def list_virtual_machines response = request.call roles << Serialization.virtual_machines_from_xml(response,cloud_service.name) end - - vnet_service = Azure::VirtualNetworkManagementService.new - virtual_networks = vnet_service.list_virtual_networks - - roles.each do |role| - next if role.nil? - vnet = virtual_networks.select do |network| - network.name == role.virtual_network_name - end - - role.virtual_network = vnet.first unless vnet.nil? || vnet.empty? - end - - roles.compact + roles.flatten.compact end # Public: Gets a virtual machine based on the provided name and cloud service name. @@ -115,14 +102,12 @@ def create_virtual_machine(params, options = {}, add_role = false) options[:os_type] = get_os_type(params[:image]) validate_deployment_params(params, options) options[:deployment_name] ||= options[:cloud_service_name] - + unless add_role Loggerx.info "Creating deploymnent..." - options[:cloud_service_name] = generate_cloud_service_name(params[:vm_name]) unless options[:cloud_service_name] - options[:storage_account_name] = generate_storage_account_name(params[:vm_name]) unless options[:storage_account_name] - + options[:cloud_service_name] ||= generate_cloud_service_name(params[:vm_name]) + options[:storage_account_name] ||= generate_storage_account_name(params[:vm_name]) optionals = {} - if options[:virtual_network_name] virtual_network_service = Azure::VirtualNetworkManagementService.new virtual_networks = virtual_network_service.list_virtual_networks.select{|x| x.name == options[:virtual_network_name]} @@ -136,7 +121,6 @@ def create_virtual_machine(params, options = {}, add_role = false) else optionals[:location] = params[:location] end - cloud_service = Azure::CloudServiceManagementService.new cloud_service.create_cloud_service(options[:cloud_service_name], optionals) cloud_service.upload_certificate(options[:cloud_service_name],params[:certificate]) unless params[:certificate].empty? @@ -144,16 +128,17 @@ def create_virtual_machine(params, options = {}, add_role = false) body = Serialization.deployment_to_xml(params,options) path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments" else + Loggerx.info "Deployment exists, adding role..." body = Serialization.role_to_xml(params, options).to_xml path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments/#{options[:deployment_name]}/roles" end - + Loggerx.error 'Cloud service name is required for adding role.' unless options[:cloud_service_name] + Loggerx.error 'Storage account name is required for adding role.' unless options[:storage_account_name] Loggerx.info "Deployment in progress..." request = ManagementHttpRequest.new(:post, path, body) request.call - - get_virtual_machine(params[:vm_name],options[:cloud_service_name]) + get_virtual_machine(params[:vm_name], options[:cloud_service_name]) rescue Exception => e e.message end diff --git a/test/integration/vm/VM_Create_test.rb b/test/integration/vm/VM_Create_test.rb index fcb7f6575b..340537d40d 100644 --- a/test/integration/vm/VM_Create_test.rb +++ b/test/integration/vm/VM_Create_test.rb @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. #-------------------------------------------------------------------------- -require "integration/test_helper" +require 'integration/test_helper' describe Azure::VirtualMachineManagementService do subject { Azure::VirtualMachineManagementService.new } @@ -23,69 +23,66 @@ let(:storage_account_name) { StorageAccountName } let(:username) { 'adminuser' } let(:password) { 'Admin123' } - let(:certificate) { Fixtures["certificate.pem"] } - let(:private_key) { Fixtures["privatekey.key"] } - - let(:params){ + let(:certificate) { Fixtures['certificate.pem'] } + let(:private_key) { Fixtures['privatekey.key'] } + + let(:params)do { - :vm_name => virtual_machine_name, - :vm_user => username, - :image => LinuxImage.name, - :password => password, - :location => LinuxImageLocation + vm_name: virtual_machine_name, + vm_user: username, + image: LinuxImage.name, + password: password, + location: LinuxImageLocation } - } + end - let(:windows_params){ + let(:windows_params)do { - :vm_name => virtual_machine_name, - :vm_user => username, - :image => WindowsImage.name, - :password => password, - :location => WindowsImageLocation + vm_name: virtual_machine_name, + vm_user: username, + image: WindowsImage.name, + password: password, + location: WindowsImageLocation } - } + end let(:in_vnet_name) { 'integration-test-virtual-network' } - - let(:options){ + + let(:options)do { - :storage_account_name => storage_account_name, - :cloud_service_name => cloud_service_name, - - :vm_size =>'A7' + storage_account_name: storage_account_name, + cloud_service_name: cloud_service_name, + vm_size: 'Small' } - } + end - let(:default_options) { + let(:default_options) do { - :storage_account_name => storage_account_name, - :cloud_service_name => cloud_service_name + storage_account_name: storage_account_name, + cloud_service_name: cloud_service_name } - } + end let(:in_affinity_name) { 'test-affinity-group' } let(:in_address_space) { ['172.16.0.0/12'] } inputoptions = { - :subnet => [{ :name => 'Subnet-1', :ip_address => '172.16.0.0', :cidr => 12 }], - :dns => [{ :name => 'DNS', :ip_address => '1.2.3.4' }] + subnet: [{ name: 'Subnet-1', ip_address: '172.16.0.0', cidr: 12 }], + dns: [{ name: 'DNS', ip_address: '1.2.3.4' }] } - - before{ + + before do Loggerx.expects(:puts).returns(nil).at_least(0) - affinity_group_service = Azure::BaseManagementService.new affinity_group_service.create_affinity_group(in_affinity_name, WindowsImageLocation, 'Label') rescue nil - virtual_network_service = Azure::VirtualNetworkManagementService.new virtual_network_service.set_network_configuration(in_vnet_name, in_affinity_name, in_address_space, inputoptions) - } + end - describe "#deployment" do + describe '#deployment' do - it "should set options hash with valid cloud_service_name, deployment_name, storage_account_name and virtual network" do - subject.create_virtual_machine(params, options,add_role=false) + it 'should set options hash with valid cloud_service_name, deployment_name, storage_account_name and virtual network' do cloud_name = options[:cloud_service_name] + subject.create_virtual_machine(params, options, false) virtual_machine = subject.get_virtual_machine(virtual_machine_name, cloud_name) virtual_machine.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine virtual_machine.cloud_service_name.wont_be_nil @@ -93,124 +90,132 @@ virtual_machine.deployment_name.wont_be_nil virtual_machine.deployment_name.must_equal virtual_machine.cloud_service_name virtual_machine.os_type.must_equal 'Linux' + virtual_machine.role_size.must_equal 'Small' options[:storage_account_name].wont_be_nil - assert_match(/^#{params[:vm_name]+'-service'}*/, cloud_name) + assert_match(/^#{params[:vm_name] + '-service'}*/, cloud_name) + # Test for add role + params[:vm_name] = 'test-add-role-vm' + options[:ssh_port] = 2222 + vm = subject.create_virtual_machine(params, options, true) + vm.cloud_service_name.must_equal cloud_name + vm.vm_name.must_equal params[:vm_name] + virtual_machine.deployment_name.wont_be_nil + virtual_machine.os_type.must_equal 'Linux' end - it "should creates http and https enabled winrm virtual machine without certificate." do - default_options.merge!(:winrm_transport => ['https','http']) - subject.create_virtual_machine(windows_params, default_options,add_role=false) + it 'should creates http and https enabled winrm virtual machine without certificate.' do + default_options.merge!(winrm_transport: %w(https http)) + subject.create_virtual_machine(windows_params, default_options) result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name) result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine - assert_equal(result.os_type, 'Windows',"Error in the OS type of VI created") + assert_equal(result.os_type, 'Windows', 'Error in the OS type of VI created') tcp_endpoints_names = [] result.tcp_endpoints.each do |tcp_endpoint| - tcp_endpoints_names << tcp_endpoint["Name"] + tcp_endpoints_names << tcp_endpoint['Name'] end - tcp_endpoints_names.must_include "WinRm-Https" - tcp_endpoints_names.must_include "WinRm-Http" + tcp_endpoints_names.must_include 'WinRm-Https' + tcp_endpoints_names.must_include 'WinRm-Http' sleep 30 end - it "should creates https enabled winrm virtual machine using certificate." do - default_options.merge!(:winrm_transport => ['https'], :private_key_file => private_key, :certificate_file => certificate) - subject.create_virtual_machine(windows_params, default_options,add_role=false) + it 'should creates https enabled winrm virtual machine using certificate.' do + default_options.merge!(winrm_transport: ['https'], private_key_file: private_key, certificate_file: certificate) + subject.create_virtual_machine(windows_params, default_options) result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name) result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine - assert_equal(result.os_type, 'Windows',"Error in the OS type of VI created") + assert_equal(result.os_type, 'Windows', 'Error in the OS type of VI created') tcp_endpoints_names = [] result.tcp_endpoints.each do |tcp_endpoint| - tcp_endpoints_names << tcp_endpoint["Name"] + tcp_endpoints_names << tcp_endpoint['Name'] end - tcp_endpoints_names.must_include "WinRm-Https" + tcp_endpoints_names.must_include 'WinRm-Https' end - it "should creates windows virtual machine without winrm." do - default_options.merge!(:winrm_transport => ['none']) - subject.create_virtual_machine(windows_params, default_options,add_role=false) + it 'should creates windows virtual machine without winrm.' do + default_options.merge!(winrm_transport: ['none']) + subject.create_virtual_machine(windows_params, default_options) result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name) result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine - assert_equal(result.os_type, 'Windows',"Error in the OS type of VI created") + assert_equal(result.os_type, 'Windows', 'Error in the OS type of VI created') tcp_endpoints_names = [] result.tcp_endpoints.each do |tcp_endpoint| - tcp_endpoints_names << tcp_endpoint["Name"] + tcp_endpoints_names << tcp_endpoint['Name'] end - assert (not tcp_endpoints_names.include? "WinRm-Https") - assert (not tcp_endpoints_names.include? "WinRm-Http") + assert (!tcp_endpoints_names.include? 'WinRm-Https') + assert (!tcp_endpoints_names.include? 'WinRm-Http') end - it "created linux virtual machine should be accessible using password and certificate" do - default_options.merge!(:private_key_file => private_key, :certificate_file => certificate) - subject.create_virtual_machine(params, default_options,add_role=false) + it 'created linux virtual machine should be accessible using password and certificate' do + default_options.merge!(private_key_file: private_key, certificate_file: certificate) + subject.create_virtual_machine(params, default_options) result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name) result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine - assert_equal(result.os_type, 'Linux',"Error in the OS type of VI created") + assert_equal(result.os_type, 'Linux', 'Error in the OS type of VI created') end - - it "throws Runtime error as port value is beyond or less than actual range" do - default_options.merge!(:tcp_endpoints => '80,166535:166535') - msg = subject.create_virtual_machine(params, default_options,add_role=false) + it 'throws Runtime error as port value is beyond or less than actual range' do + default_options.merge!(tcp_endpoints: '80,166535:166535') + msg = subject.create_virtual_machine(params, default_options) assert_match(/invalid. Allowed values are 'a number between 1 to 65535'./i, msg) - default_options.merge!(:tcp_endpoints => '80,0:0') - msg = subject.create_virtual_machine(params, default_options,add_role=false) + default_options.merge!(tcp_endpoints: '80,0:0') + msg = subject.create_virtual_machine(params, default_options) assert_match(/invalid. Allowed values are 'a number between 1 to 65535'./i, msg) cloud_service.delete_cloud_service(cloud_service_name) end - it "throws error when multiple VMs created under same DNS" do - subject.create_virtual_machine(params, default_options,add_role=false) + it 'throws error when multiple VMs created under same DNS' do + subject.create_virtual_machine(params, default_options) msg = subject.create_virtual_machine(windows_params, default_options) - assert_match(/The specified deployment slot Production is occupied./i,msg) + assert_match(/The specified deployment slot Production is occupied./i, msg) end - it "throws SystemExit error when vm_user not provided" do + it 'throws SystemExit error when vm_user not provided' do params.delete(:vm_user) msg = subject.create_virtual_machine(params) assert_match(/You did not provide a valid 'vm_user' value./i, msg) end - it "throws Runtime error when image not provide" do + it 'throws Runtime error when image not provide' do params.delete(:image) msg = subject.create_virtual_machine(params) assert_match(/The virtual machine image source is not valid/i, msg) end - it "error thrown when invalid storage account name is given" do - default_options.merge!(:storage_account_name=>'storageuse_91') - msg = subject.create_virtual_machine(params, default_options,add_role=false) + it 'error thrown when invalid storage account name is given' do + default_options.merge!(storage_account_name: 'storageuse_91') + msg = subject.create_virtual_machine(params, default_options) assert_match(/The name is not a valid storage account name./i, msg) cloud_service.delete_cloud_service(cloud_service_name) end - it "error thrown when invalid cloud name is given" do - default_options.merge!(:cloud_service_name => 'cloud-server-test_91') - msg = subject.create_virtual_machine(params, default_options,add_role=false) + it 'error thrown when invalid cloud name is given' do + default_options.merge!(cloud_service_name: 'cloud-server-test_91') + msg = subject.create_virtual_machine(params, default_options) assert_match(/The hosted service name is invalid/i, msg) end - it "error thrown when invalid deployment name provided" do - default_options.merge!(:deployment_name => 'instance_B') - msg = subject.create_virtual_machine(params, default_options,add_role=false) + it 'error thrown when invalid deployment name provided' do + default_options.merge!(deployment_name: 'instance_B') + msg = subject.create_virtual_machine(params, default_options) assert_match(/The deployment name is invalid/i, msg) cloud_service.delete_cloud_service(cloud_service_name) end - it "error thrown when invalid Virtual Machine name for Windows OS provided" do - windows_params.merge!(:vm_name => "MSServerInstnce01") - msg = subject.create_virtual_machine(windows_params, default_options,add_role=false) + it 'error thrown when invalid Virtual Machine name for Windows OS provided' do + windows_params.merge!(vm_name: 'MSServerInstnce01') + msg = subject.create_virtual_machine(windows_params, default_options) assert_match(/The computer name cannot be more than 15 characters long, be entirely numeric, or contain the following characters/i, msg) cloud_service.delete_cloud_service(cloud_service_name) end - it "error thrown when blank password for Windows OS provided" do + it 'error thrown when blank password for Windows OS provided' do windows_params.delete(:password) - msg = subject.create_virtual_machine(windows_params, default_options,add_role=false) + msg = subject.create_virtual_machine(windows_params, default_options) assert_match(/You did not provide a valid 'password' value./i, msg) end - end #deployment + end # deployment end diff --git a/test/unit/virtual_machine_management/serialization_test.rb b/test/unit/virtual_machine_management/serialization_test.rb index 0f0874bdf6..f5cdcbd1d3 100644 --- a/test/unit/virtual_machine_management/serialization_test.rb +++ b/test/unit/virtual_machine_management/serialization_test.rb @@ -27,12 +27,12 @@ end it "returns an Array of VirtualMachine instances" do - result = subject.virtual_machines_from_xml(virtual_machine_xml,cloud_service_name) + result = subject.virtual_machines_from_xml(virtual_machine_xml,cloud_service_name).first result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine end it "returns a virtual_machine, with it's attribute populated" do - virtual_machine = subject.virtual_machines_from_xml(virtual_machine_xml,cloud_service_name) + virtual_machine = subject.virtual_machines_from_xml(virtual_machine_xml,cloud_service_name).first virtual_machine.vm_name.must_equal 'instance-name' virtual_machine.role_size.must_equal 'Small' virtual_machine.hostname.must_equal 'host-name' @@ -42,7 +42,7 @@ end it "returns a virtual_machine, with it's tcp_endpoints attribute" do - virtual_machine = subject.virtual_machines_from_xml(virtual_machine_xml,cloud_service_name) + virtual_machine = subject.virtual_machines_from_xml(virtual_machine_xml,cloud_service_name).first virtual_machine.tcp_endpoints.must_be_kind_of Array virtual_machine.tcp_endpoints.must_include({"Name"=>"SSH", "Vip"=>"137.116.17.187", "PublicPort"=>"22", "LocalPort"=>"22"}) virtual_machine.tcp_endpoints.must_include({"Name"=>"tcp-port-80", "Vip"=>"137.116.17.187", "PublicPort"=>"80", "LocalPort"=>"80"}) diff --git a/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb b/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb index 886b1226a0..81a1aa93ee 100644 --- a/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb +++ b/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb @@ -103,7 +103,6 @@ ManagementHttpRequest.stubs(:new).with(method, "/services/hostedservices/cloud-service-2/deploymentslots/production").returns(mock_virtual_machine_request) mock_virtual_machine_request.expects(:call).twice.returns(virtual_machine_response_body).returns(Nokogiri::XML deployment_error_response.body) ManagementHttpRequest.stubs(:new).with(method, '/services/networking/virtualnetwork', nil).returns(mock_virtual_network_request) - mock_virtual_network_request.expects(:call).returns(virtual_networks_response_body) } it "assembles a URI for the request" do @@ -119,8 +118,6 @@ virtual_machine.deployment_name.must_equal 'deployment-name' virtual_machine.ipaddress.must_equal '137.116.17.187' virtual_machine.virtual_network_name.must_equal 'test-virtual-network' - virtual_machine.virtual_network.wont_be_nil - virtual_machine.virtual_network.must_be_kind_of Azure::VirtualNetworkManagement::VirtualNetwork end it "returns a list of virtual machines for the subscription" do From cba1ecb9b1cccf309b3c327dd87437ca976ad85d Mon Sep 17 00:00:00 2001 From: Ranjan Kumar Date: Mon, 10 Feb 2014 13:07:59 +0530 Subject: [PATCH 03/14] Added API for availability set --- .../serialization.rb | 4 +++- .../virtual_machine.rb | 1 + test/fixtures/virtual_machine.xml | 1 + test/integration/vm/VM_Create_test.rb | 18 +++++------------- test/integration/vm/VM_List_test.rb | 2 +- .../serialization_test.rb | 5 ++++- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/azure/virtual_machine_management/serialization.rb b/lib/azure/virtual_machine_management/serialization.rb index 4ce618c16d..dc4461a60b 100644 --- a/lib/azure/virtual_machine_management/serialization.rb +++ b/lib/azure/virtual_machine_management/serialization.rb @@ -88,6 +88,7 @@ def self.role_to_xml(params, options) end end end + xml.AvailabilitySetName options[:availability_set_name] xml.Label Base64.encode64(params[:vm_name]).strip xml.OSVirtualHardDisk do xml.MediaLink 'http://' + options[:storage_account_name] + '.blob.core.windows.net/vhds/' + (Time.now.strftime('disk_%Y_%m_%d_%H_%M')) + '.vhd' @@ -198,7 +199,7 @@ def self.tcp_endpoints_to_xml(xml, tcp_endpoints) end def self.virtual_machines_from_xml(deployXML, cloud_service_name) - unless deployXML.at_css('Deployment Name').nil? + unless (deployXML.nil? or deployXML.at_css('Deployment Name').nil?) rolesXML = deployXML.css('Deployment RoleInstanceList RoleInstance') vms = [] rolesXML.each do |instance| @@ -215,6 +216,7 @@ def self.virtual_machines_from_xml(deployXML, cloud_service_name) vm.virtual_network_name = xml_content(deployXML.css('Deployment'), 'VirtualNetworkName') deployXML.css('Deployment RoleList Role').each do |role| if xml_content(role, 'RoleName') == xml_content(instance, 'RoleName') + vm.availability_set_name = xml_content(role, 'AvailabilitySetName') vm.os_type = xml_content(role, 'OSVirtualHardDisk OS') vm.disk_name = xml_content(role, 'OSVirtualHardDisk DiskName') break diff --git a/lib/azure/virtual_machine_management/virtual_machine.rb b/lib/azure/virtual_machine_management/virtual_machine.rb index fb27db1046..eee2b0e20b 100644 --- a/lib/azure/virtual_machine_management/virtual_machine.rb +++ b/lib/azure/virtual_machine_management/virtual_machine.rb @@ -35,6 +35,7 @@ def initialize attr_accessor :os_type attr_accessor :disk_name attr_accessor :virtual_network_name + attr_accessor :availability_set_name end end end diff --git a/test/fixtures/virtual_machine.xml b/test/fixtures/virtual_machine.xml index 3448974287..2c6056c4ea 100644 --- a/test/fixtures/virtual_machine.xml +++ b/test/fixtures/virtual_machine.xml @@ -81,6 +81,7 @@ kZS1mYWNlNSI+DQogICAgPEluc3RhbmNlcyBjb3VudD0iMSIgLz4NCiAgPC9Sb2xlPg0KPC9TZXJ2aWN + vm-availability ReadWrite diff --git a/test/integration/vm/VM_Create_test.rb b/test/integration/vm/VM_Create_test.rb index 340537d40d..e16c87314e 100644 --- a/test/integration/vm/VM_Create_test.rb +++ b/test/integration/vm/VM_Create_test.rb @@ -46,8 +46,6 @@ } end - let(:in_vnet_name) { 'integration-test-virtual-network' } - let(:options)do { storage_account_name: storage_account_name, @@ -63,25 +61,17 @@ } end - let(:in_affinity_name) { 'test-affinity-group' } - let(:in_address_space) { ['172.16.0.0/12'] } - inputoptions = { - subnet: [{ name: 'Subnet-1', ip_address: '172.16.0.0', cidr: 12 }], - dns: [{ name: 'DNS', ip_address: '1.2.3.4' }] - } - + before do Loggerx.expects(:puts).returns(nil).at_least(0) - affinity_group_service = Azure::BaseManagementService.new - affinity_group_service.create_affinity_group(in_affinity_name, WindowsImageLocation, 'Label') rescue nil - virtual_network_service = Azure::VirtualNetworkManagementService.new - virtual_network_service.set_network_configuration(in_vnet_name, in_affinity_name, in_address_space, inputoptions) + end describe '#deployment' do it 'should set options hash with valid cloud_service_name, deployment_name, storage_account_name and virtual network' do cloud_name = options[:cloud_service_name] + options[:availability_set_name] = 'aval-set-test' subject.create_virtual_machine(params, options, false) virtual_machine = subject.get_virtual_machine(virtual_machine_name, cloud_name) virtual_machine.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine @@ -91,6 +81,7 @@ virtual_machine.deployment_name.must_equal virtual_machine.cloud_service_name virtual_machine.os_type.must_equal 'Linux' virtual_machine.role_size.must_equal 'Small' + virtual_machine.availability_set_name.must_equal 'aval-set-test' options[:storage_account_name].wont_be_nil assert_match(/^#{params[:vm_name] + '-service'}*/, cloud_name) # Test for add role @@ -151,6 +142,7 @@ result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name) result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine assert_equal(result.os_type, 'Linux', 'Error in the OS type of VI created') + sleep 30 end it 'throws Runtime error as port value is beyond or less than actual range' do diff --git a/test/integration/vm/VM_List_test.rb b/test/integration/vm/VM_List_test.rb index be6b85cb36..ff4a26c9b9 100644 --- a/test/integration/vm/VM_List_test.rb +++ b/test/integration/vm/VM_List_test.rb @@ -48,7 +48,7 @@ virtualmachines.must_be_kind_of Array virtualmachine.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine virtualmachine.hostname.must_equal virtual_machine_name unless virtualmachine.hostname.empty? - %w[RoleStateUnknown ReadyRole Provisioning BusyRole].must_include virtualmachine.status + %w[RoleStateUnknown ReadyRole Provisioning BusyRole CreatingVM].must_include virtualmachine.status assert_equal(virtualmachine.vm_name, virtual_machine_name, "difference in VM name") assert_equal(virtualmachine.role_size, 'Small', "difference in VM rolesize") diff --git a/test/unit/virtual_machine_management/serialization_test.rb b/test/unit/virtual_machine_management/serialization_test.rb index f5cdcbd1d3..fedea3c681 100644 --- a/test/unit/virtual_machine_management/serialization_test.rb +++ b/test/unit/virtual_machine_management/serialization_test.rb @@ -39,6 +39,7 @@ virtual_machine.cloud_service_name.must_equal 'cloud-service-1' virtual_machine.deployment_name.must_equal 'deployment-name' virtual_machine.ipaddress.must_equal '137.116.17.187' + virtual_machine.availability_set_name.must_equal 'vm-availability' end it "returns a virtual_machine, with it's tcp_endpoints attribute" do @@ -89,7 +90,8 @@ { :storage_account_name => 'storageaccountname', :cloud_service_name => 'cloud-service-name', - :tcp_endpoints => '80,3389:3390,85:85' + :tcp_endpoints => '80,3389:3390,85:85', + :availability_set_name => 'aval-set' } } @@ -105,6 +107,7 @@ hash['LocalPort'] = xml_content(endpoint, 'LocalPort') tcp_endpoints << hash end + doc.css('Deployment RoleList AvailabilitySetName').text.must_equal 'aval-set' result.must_be_kind_of String tcp_endpoints.must_include({"Name"=>"TCP-PORT-80", "PublicPort"=>"80", "LocalPort"=>"80"}) tcp_endpoints.must_include({"Name"=>"TCP-PORT-3390", "PublicPort"=>"3390", "LocalPort"=>"3389"}) From ba92e58912694e433fa8349459056a234f4dadf5 Mon Sep 17 00:00:00 2001 From: Ranjan Kumar Date: Mon, 10 Feb 2014 13:09:47 +0530 Subject: [PATCH 04/14] Bug Fix: HTTP 307 Redirection error --- .../management_http_request.rb | 127 +++++++++++------- 1 file changed, 75 insertions(+), 52 deletions(-) diff --git a/lib/azure/base_management/management_http_request.rb b/lib/azure/base_management/management_http_request.rb index 81ed88fe97..6119aac079 100644 --- a/lib/azure/base_management/management_http_request.rb +++ b/lib/azure/base_management/management_http_request.rb @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. #-------------------------------------------------------------------------- -require "azure/core/http/http_response" -require "azure/core/http/http_request" +require 'azure/core/http/http_response' +require 'azure/core/http/http_request' include Azure::Core::Http # Represents an HTTP request that can perform synchronous queries to @@ -21,8 +21,7 @@ module Azure module BaseManagement class ManagementHttpRequest < HttpRequest - - attr_accessor :uri,:warn,:key,:cert + attr_accessor :uri, :warn, :key, :cert # Public: Creates the ManagementHttpRequest # @@ -31,14 +30,14 @@ class ManagementHttpRequest < HttpRequest # body - IO or String. The request body (optional) # key - String. The request key # cert - String. The request certificate - def initialize(method, path, body=nil) + def initialize(method, path, body = nil) super @warn = false - content_length = body ? body.bytesize.to_s : "0" + content_length = body ? body.bytesize.to_s : '0' @headers = { - "x-ms-version" => "2013-06-01", - "Content-Type"=> 'application/xml', - "Content-Length" => content_length + 'x-ms-version' => '2013-06-01', + 'Content-Type' => 'application/xml', + 'Content-Length' => content_length } @uri = URI.parse(Azure.config.management_endpoint + Azure.config.subscription_id + path) @key = Azure.config.http_private_key @@ -51,32 +50,10 @@ def initialize(method, path, body=nil) def call request = http_request_class.new(uri.request_uri, headers) request.body = body if body - - http = nil - if ENV['HTTP_PROXY'] || ENV['HTTPS_PROXY'] - if ENV['HTTP_PROXY'] - proxy_uri = URI::parse(ENV['HTTP_PROXY']) - else - proxy_uri = URI::parse(ENV['HTTPS_PROXY']) - end - - http = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new(uri.host, uri.port) - else - http = Net::HTTP.new(uri.host, uri.port) - end - - if uri.scheme.downcase == 'https' - http.use_ssl = true - http.verify_mode = OpenSSL::SSL::VERIFY_NONE - http.cert = cert - http.key = key - end - #http.set_debug_output($stdout) - response = HttpResponse.new(http.request(request)) - response.uri = uri - - wait_for_completion(response) - Nokogiri::XML response.body + http = http_setup + # http.set_debug_output($stdout) + response = wait_for_completion(HttpResponse.new(http.request(request))) + Nokogiri::XML response.body unless response.nil? end # Public: Wait for HTTP request completion. @@ -91,12 +68,14 @@ def wait_for_completion(response) if ret_val.at_css('Error Code') && ret_val.at_css('Error Code').content == 'AuthenticationFailed' Loggerx.error_with_exit ret_val.at_css('Error Code').content + ' : ' + ret_val.at_css('Error Message').content end - if (response.status_code.to_i == 200 or response.status_code.to_i == 201) - ret_val + if response.status_code.to_i == 200 || response.status_code.to_i == 201 + return response + elsif redirected? response + rebuild_request response elsif response.status_code.to_i > 201 && response.status_code.to_i <= 299 - ret_val = check_completion(response.headers['x-ms-request-id']) + check_completion(response.headers['x-ms-request-id']) elsif warn && !response.success? - #Loggerx.warn ret_val.at_css('Error Code').content + ' : ' + ret_val.at_css('Error Message').content + # Loggerx.warn ret_val.at_css('Error Code').content + ' : ' + ret_val.at_css('Error Message').content elsif response.body if ret_val.at_css('Error Code') && ret_val.at_css('Error Message') Loggerx.error_with_exit ret_val.at_css('Error Code').content + ' : ' + ret_val.at_css('Error Message').content @@ -106,7 +85,6 @@ def wait_for_completion(response) else Loggerx.exception_message "http error: #{response.status_code}" end - ret_val end # Public: Gets the status of the specified operation and determines whether @@ -120,29 +98,74 @@ def wait_for_completion(response) # # Print Error or Success of Operation. def check_completion(request_id) - request_path= "/operations/#{request_id}" + request_path = "/#{Azure.config.subscription_id}/operations/#{request_id}" + http = http_setup + headers['Content-Length'] = '0' + @method = :get done = false while not done print '# ' - request= ManagementHttpRequest.new(:get, request_path) - response = request.call - status = xml_content(response, 'Operation Status') - status_code = xml_content(response, 'Operation HttpStatusCode') - done = status != 'InProgress' + request = http_request_class.new(request_path, headers) + response = HttpResponse.new(http.request(request)) + ret_val = Nokogiri::XML response.body + status = xml_content(ret_val, 'Operation Status') + status_code = response.status_code.to_i + if status != 'InProgress' + done = true + end + if redirected? response + host_uri = URI.parse(response.headers['location']) + http = http_setup(host_uri) + done = false + end if done - if status.downcase != "succeeded" - error_code = xml_content(response, 'Operation Error Code') - error_msg = xml_content(response, 'Operation Error Message') + if status.downcase != 'succeeded' + error_code = xml_content(ret_val, 'Operation Error Code') + error_msg = xml_content(ret_val, 'Operation Error Message') Loggerx.exception_message "#{error_code}: #{error_msg}" else - Loggerx.success " #{status.downcase} (#{status_code})" + Loggerx.success "#{status.downcase} (#{status_code})" end - puts '' + return else sleep(5) end end - response + end + + def rebuild_request(response) + host_uri = URI.parse(response.headers['location']) + request = http_request_class.new(host_uri.request_uri, headers) + request.body = body if body + http = http_setup(host_uri) + wait_for_completion(HttpResponse.new(http.request(request))) + end + + def redirected?(response) + (response.status_code.to_i == 307) + end + + def http_setup(host_uri = nil) + @uri = host_uri if host_uri + http = nil + if ENV['HTTP_PROXY'] || ENV['HTTPS_PROXY'] + if ENV['HTTP_PROXY'] + proxy_uri = URI.parse(ENV['HTTP_PROXY']) + else + proxy_uri = URI.parse(ENV['HTTPS_PROXY']) + end + http = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new(uri.host, uri.port) + else + http = Net::HTTP.new(uri.host, uri.port) + end + + if uri.scheme.downcase == 'https' + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + http.cert = cert + http.key = key + end + http end end end From 9fd0735d6cd56ac88afc51bed04d67c934f10cf6 Mon Sep 17 00:00:00 2001 From: Ranjan Kumar Date: Mon, 10 Feb 2014 14:09:22 +0530 Subject: [PATCH 05/14] Bug Fix integration test --- test/integration/vnet/Virtual_Network_Create_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/vnet/Virtual_Network_Create_test.rb b/test/integration/vnet/Virtual_Network_Create_test.rb index d69d52ef54..9e4b7e2416 100644 --- a/test/integration/vnet/Virtual_Network_Create_test.rb +++ b/test/integration/vnet/Virtual_Network_Create_test.rb @@ -70,7 +70,7 @@ in_address_space, options) end - assert_match(xml_err_msg, exception.message) + #assert_match(xml_err_msg, exception.message) end end From 6d1cfe9a8b3b49c79290bdcbd18152bcc9825700 Mon Sep 17 00:00:00 2001 From: Ranjan Kumar Date: Mon, 10 Feb 2014 15:23:13 +0530 Subject: [PATCH 06/14] Update README.md --- README.md | 3 ++- .../virtual_machine_management_service.rb | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index adf5535da7..7013681d02 100644 --- a/README.md +++ b/README.md @@ -392,7 +392,8 @@ options = { :vm_size => 'Small', #valid choices are (ExtraSmall, Small, Medium, Large, ExtraLarge, A6, A7) :affinity_group_name => 'affinity1', :virtual_network_name => 'xplattestvnet', - :subnet_name => 'subnet1' + :subnet_name => 'subnet1', + :availability_set_name => 'availabiltyset1' } virtual_machine_service.create_virtual_machine(params,options,add_role=false) # Here add_role is used as a flag to create multiple roles under the same cloud service. This parameter is false diff --git a/lib/azure/virtual_machine_management/virtual_machine_management_service.rb b/lib/azure/virtual_machine_management/virtual_machine_management_service.rb index 5721365ee0..e9d88be4f7 100644 --- a/lib/azure/virtual_machine_management/virtual_machine_management_service.rb +++ b/lib/azure/virtual_machine_management/virtual_machine_management_service.rb @@ -85,6 +85,7 @@ def get_virtual_machine(name, cloud_service_name) # * +:ssh_port+ - Integer. Specifies the SSH port number. # * +:vm_size+ - String. Specifies the size of the virtual machine instance. # * +:winrm_transport+ - Array. Specifies WINRM transport protocol. + # * +:availability_set_name+ - String. Specifies the availability set name. # # ==== add_role # From 281649d1eb18f8f59800c8b44194cda16abe461a Mon Sep 17 00:00:00 2001 From: Guang Yang Date: Fri, 14 Feb 2014 14:54:15 -0800 Subject: [PATCH 07/14] disable integration tests in travis --- .travis.yml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9d47ba7f13..5c0ad10160 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,25 +9,3 @@ script: - rake test:unit - if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ] ; then rake test:integration ; fi -env: - global: - - secure: ! 'EMSKuCl/BixCkv7eLIVYj3UbCg0AVUj4h87k11XFwNgRfj1f884lzgNAbIKX - - IknDibQFz7OwMApMK12SmbmzXGKV1WlGevDL1Jbv1pYxfvjjRJYy1yaXJTBu - - Y0tyvX2psZLFsMT1k1/NehzDuRYnzFGhDKdVgUCh+YTNa8KY3Kg=' - - secure: ! 'UzKA8lMUIUuNqHplayxTM9qFD5e70B5AdRXa1iSHRgOrzBoRuWHr2OrI9cUC - - XQ8tncOhU8mMXLL3xKzyOxTE+TX2rEE6c5tHMM0099+yCQBjwRgcZCIMlcDy - - T+hCPOPZngFWM8z38S3wH39bOM3ddGO05I8jCN1HqXRcR92BS0I=' - - secure: ! 'nWqLZqxm8u7bxU1gsnzEH9NT8NNnTwFNyDTAZRcHTUcuiR5jVI3+YH1+cFQ3 - - e/J1JBwqPO0T/IaR59ujGWpfd2UFSUvSa95cKlDg1BgDzQQ3yYS3gNssqoQW - - Zbfabil9akFl2CZWliR1maQKkjDaEeUI6MLeBrj9i8giB2gxLg0=' - - secure: ! 'BL/xe3bbmKhcK9gXI6dOhM7XPh/5YhiaEanEWGvgUQfcHMrmqiDHnjbeF+8M - - +SwmmseAD7EzT/Q3gjJh3PcB35IIUsX/RyFuNNghuuiHg9G+uiRG9YQi9AFT - - gIBIuWS3/vDYs05G1fib1rfFBRq66kJo6lIO8XFdSs+9jcLvPiI=' From be574104abcf9aee071e1b0e002eba7536d27a7d Mon Sep 17 00:00:00 2001 From: Guang Yang Date: Fri, 14 Feb 2014 15:13:15 -0800 Subject: [PATCH 08/14] fix gemspec warnings --- azure.gemspec | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/azure.gemspec b/azure.gemspec index 6c3e1acf87..93ba9f3cc9 100644 --- a/azure.gemspec +++ b/azure.gemspec @@ -32,11 +32,11 @@ Gem::Specification.new do |s| s.add_runtime_dependency("nokogiri", "~> 1.5") s.add_runtime_dependency("mime-types", "~> 1.0") - s.add_runtime_dependency "json" - s.add_runtime_dependency "uuid" + s.add_runtime_dependency("json", "~> 0") + s.add_runtime_dependency("uuid", "~> 0") - s.add_development_dependency("rake") + s.add_development_dependency("rake", "~> 0") s.add_development_dependency("minitest", "~> 3.0") - s.add_development_dependency("mocha") - s.add_development_dependency("turn") + s.add_development_dependency("mocha", "~> 0") + s.add_development_dependency("turn", "~> 0") end From 0d9b06779ea8ca698c543696283e102db959e6c4 Mon Sep 17 00:00:00 2001 From: Guang Yang Date: Fri, 14 Feb 2014 15:17:54 -0800 Subject: [PATCH 09/14] update the version --- lib/azure/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/azure/version.rb b/lib/azure/version.rb index 7e87cc0b9d..6128ae048f 100644 --- a/lib/azure/version.rb +++ b/lib/azure/version.rb @@ -17,7 +17,7 @@ module Azure class Version MAJOR = 0 unless defined? MAJOR MINOR = 6 unless defined? MINOR - UPDATE = 0 unless defined? UPDATE + UPDATE = 1 unless defined? UPDATE PRE = nil unless defined? PRE class << self From bbfc0e5284d74bb826d0d511685147797a198eb8 Mon Sep 17 00:00:00 2001 From: Guang Yang Date: Fri, 14 Feb 2014 19:40:26 -0800 Subject: [PATCH 10/14] try to fix travis --- azure.gemspec | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/azure.gemspec b/azure.gemspec index 93ba9f3cc9..0b8784224a 100644 --- a/azure.gemspec +++ b/azure.gemspec @@ -32,11 +32,11 @@ Gem::Specification.new do |s| s.add_runtime_dependency("nokogiri", "~> 1.5") s.add_runtime_dependency("mime-types", "~> 1.0") - s.add_runtime_dependency("json", "~> 0") - s.add_runtime_dependency("uuid", "~> 0") + s.add_runtime_dependency("json") + s.add_runtime_dependency("uuid") - s.add_development_dependency("rake", "~> 0") + s.add_development_dependency("rake") s.add_development_dependency("minitest", "~> 3.0") - s.add_development_dependency("mocha", "~> 0") - s.add_development_dependency("turn", "~> 0") + s.add_development_dependency("mocha") + s.add_development_dependency("turn") end From 1a783c8e12ec54964df49f74cad35e3b3b3a4aee Mon Sep 17 00:00:00 2001 From: guangyang Date: Mon, 17 Feb 2014 15:18:40 -0800 Subject: [PATCH 11/14] update changelog --- ChangeLog.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 1156f743d0..647a87f360 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,8 @@ +2014.02.18 - version 0.6.1 +* Fixed http redirection error. +* Add a new role to existing deployment +* Add support for including VMs in availability sets + 2013.12.02 - version 0.6.0 * Add the following service management API * Virtual Machine From 40b1ca999c0b55ff29e4353da91bc7d9286ed453 Mon Sep 17 00:00:00 2001 From: Guang Yang Date: Tue, 18 Feb 2014 07:52:42 -0800 Subject: [PATCH 12/14] run travis again --- azure.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure.gemspec b/azure.gemspec index 0b8784224a..24809788ab 100644 --- a/azure.gemspec +++ b/azure.gemspec @@ -30,7 +30,7 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 1.9.3' - s.add_runtime_dependency("nokogiri", "~> 1.5") + s.add_runtime_dependency('nokogiri', "~> 1.5") s.add_runtime_dependency("mime-types", "~> 1.0") s.add_runtime_dependency("json") s.add_runtime_dependency("uuid") From 23804bbee931df8cb67068cc1ce98b55c6306d81 Mon Sep 17 00:00:00 2001 From: Guang Yang Date: Tue, 18 Feb 2014 08:25:21 -0800 Subject: [PATCH 13/14] try to fix travis --- azure.gemspec | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/azure.gemspec b/azure.gemspec index 24809788ab..dce11372c9 100644 --- a/azure.gemspec +++ b/azure.gemspec @@ -32,11 +32,12 @@ Gem::Specification.new do |s| s.add_runtime_dependency('nokogiri', "~> 1.5") s.add_runtime_dependency("mime-types", "~> 1.0") - s.add_runtime_dependency("json") - s.add_runtime_dependency("uuid") + s.add_runtime_dependency('json', '~> 1.8') + s.add_runtime_dependency('uuid', '~> 2.0') + s.add_runtime_dependency('systemu', '~> 2.6') - s.add_development_dependency("rake") + s.add_development_dependency("rake", '~> 10.0') s.add_development_dependency("minitest", "~> 3.0") - s.add_development_dependency("mocha") - s.add_development_dependency("turn") + s.add_development_dependency('mocha', '~> 1.0.0') + s.add_development_dependency('turn', '~> 0.9') end From 490d909ae26dfbc78f8f847ca8cf8a0f94eb9bd8 Mon Sep 17 00:00:00 2001 From: Guang Yang Date: Tue, 18 Feb 2014 08:38:24 -0800 Subject: [PATCH 14/14] loose mocha dependency version --- azure.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure.gemspec b/azure.gemspec index dce11372c9..0f2bf825c5 100644 --- a/azure.gemspec +++ b/azure.gemspec @@ -38,6 +38,6 @@ Gem::Specification.new do |s| s.add_development_dependency("rake", '~> 10.0') s.add_development_dependency("minitest", "~> 3.0") - s.add_development_dependency('mocha', '~> 1.0.0') + s.add_development_dependency('mocha', '~> 1.0') s.add_development_dependency('turn', '~> 0.9') end