azure 0.6.4 → 0.7.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.env_sample +11 -0
  3. data/.gitignore +4 -1
  4. data/.travis.yml +3 -1
  5. data/ChangeLog.txt +17 -1
  6. data/LICENSE.txt +202 -0
  7. data/README.md +58 -20
  8. data/Rakefile +27 -35
  9. data/azure.gemspec +17 -13
  10. data/bin/pfxer +35 -0
  11. data/lib/azure.rb +8 -0
  12. data/lib/azure/base_management/base_management_service.rb +24 -26
  13. data/lib/azure/base_management/management_http_request.rb +17 -14
  14. data/lib/azure/base_management/serialization.rb +1 -0
  15. data/lib/azure/blob/auth/shared_access_signature.rb +141 -0
  16. data/lib/azure/blob/blob_service.rb +221 -217
  17. data/lib/azure/cloud_service_management/cloud_service_management_service.rb +27 -30
  18. data/lib/azure/cloud_service_management/serialization.rb +1 -0
  19. data/lib/azure/core.rb +17 -15
  20. data/lib/azure/core/configuration.rb +7 -0
  21. data/lib/azure/core/http/http_error.rb +1 -1
  22. data/lib/azure/core/http/http_request.rb +4 -1
  23. data/lib/azure/core/utility.rb +16 -1
  24. data/lib/azure/queue/queue_service.rb +13 -13
  25. data/lib/azure/service/cors.rb +11 -0
  26. data/lib/azure/service/cors_rule.rb +15 -0
  27. data/lib/azure/service/serialization.rb +69 -10
  28. data/lib/azure/service/storage_service.rb +10 -6
  29. data/lib/azure/service/storage_service_properties.rb +8 -3
  30. data/lib/azure/service_bus/brokered_message.rb +1 -1
  31. data/lib/azure/service_bus/relay.rb +88 -0
  32. data/lib/azure/service_bus/serialization.rb +1 -0
  33. data/lib/azure/service_bus/service_bus_service.rb +70 -4
  34. data/lib/azure/sql_database_management/serialization.rb +1 -0
  35. data/lib/azure/sql_database_management/sql_database_management_service.rb +22 -22
  36. data/lib/azure/storage_management/serialization.rb +34 -14
  37. data/lib/azure/storage_management/storage_account.rb +9 -1
  38. data/lib/azure/storage_management/storage_management_service.rb +74 -32
  39. data/lib/azure/table/batch.rb +6 -6
  40. data/lib/azure/table/table_service.rb +13 -13
  41. data/lib/azure/version.rb +3 -3
  42. data/lib/azure/virtual_machine_image_management/serialization.rb +19 -0
  43. data/lib/azure/virtual_machine_image_management/virtual_machine_image.rb +1 -1
  44. data/lib/azure/virtual_machine_image_management/virtual_machine_image_management_service.rb +30 -7
  45. data/lib/azure/virtual_machine_management/serialization.rb +32 -12
  46. data/lib/azure/virtual_machine_management/virtual_machine.rb +1 -0
  47. data/lib/azure/virtual_machine_management/virtual_machine_management_service.rb +92 -81
  48. data/lib/azure/virtual_network_management/serialization.rb +12 -5
  49. data/lib/azure/virtual_network_management/virtual_network.rb +1 -0
  50. data/lib/azure/virtual_network_management/virtual_network_management_service.rb +11 -11
  51. data/test/fixtures/get_storage_account_properties.xml +6 -4
  52. data/test/fixtures/{list_images.xml → list_os_images.xml} +1 -1
  53. data/test/fixtures/list_storage_accounts.xml +2 -0
  54. data/test/fixtures/list_vm_images.xml +21 -0
  55. data/test/fixtures/metrics.xml +2 -2
  56. data/test/fixtures/sb_default_create_relay_response.xml +15 -0
  57. data/test/fixtures/storage_service_keys.xml +8 -0
  58. data/test/fixtures/storage_service_properties.xml +35 -3
  59. data/test/fixtures/updated_storage_accounts.xml +2 -0
  60. data/test/fixtures/virtual_machine.xml +3 -1
  61. data/test/integration/affinity_group/Affinity_test.rb +1 -1
  62. data/test/integration/affinity_group/Create_Affinity_test.rb +8 -7
  63. data/test/integration/affinity_group/Delete_Affinity_test.rb +3 -3
  64. data/test/integration/affinity_group/List_Affinity_test.rb +1 -1
  65. data/test/integration/affinity_group/Update_Affinity_test.rb +9 -8
  66. data/test/integration/cloud_service/Cloud_Create_test.rb +3 -2
  67. data/test/integration/cloud_service/Cloud_Delete_test.rb +5 -4
  68. data/test/integration/database/create_sql_server_firewall_test.rb +1 -1
  69. data/test/integration/database/create_sql_server_test.rb +1 -1
  70. data/test/integration/database/delete_sql_server_firewall_test.rb +1 -1
  71. data/test/integration/database/delete_sql_server_test.rb +1 -1
  72. data/test/integration/database/list_sql_server_firewall_test.rb +1 -1
  73. data/test/integration/database/list_sql_servers_test.rb +1 -1
  74. data/test/integration/database/reset_password_sql_server_test.rb +1 -1
  75. data/test/integration/service_bus/queues_test.rb +22 -22
  76. data/test/integration/service_bus/relay_test.rb +132 -0
  77. data/test/integration/storage_management/storage_management_test.rb +58 -33
  78. data/test/integration/test_helper.rb +11 -15
  79. data/test/integration/vm/VM_Create_test.rb +17 -18
  80. data/test/integration/vm/VM_Delete_test.rb +2 -4
  81. data/test/integration/vm/VM_Operations_test.rb +1 -2
  82. data/test/integration/vnet/Virtual_Network_Create_test.rb +9 -15
  83. data/test/integration/vnet/Virtual_Network_list_test.rb +4 -9
  84. data/test/support/name_generator.rb +8 -0
  85. data/test/support/virtual_network_helper.rb +2 -2
  86. data/test/test_helper.rb +13 -24
  87. data/test/unit/affinity_group/affinity_group_test.rb +10 -13
  88. data/test/unit/affinity_group/serialization_test.rb +7 -8
  89. data/test/unit/base_management/location_test.rb +1 -2
  90. data/test/unit/blob/auth/shared_access_signature_test.rb +71 -0
  91. data/test/unit/blob/blob_service_test.rb +393 -371
  92. data/test/unit/cloud_service_management/cloud_service_management_service_test.rb +16 -16
  93. data/test/unit/core/auth/shared_key_lite_test.rb +4 -4
  94. data/test/unit/core/auth/shared_key_test.rb +2 -2
  95. data/test/unit/core/http/http_error_test.rb +10 -5
  96. data/test/unit/core/http/http_request_test.rb +72 -25
  97. data/test/unit/database/serialization_test.rb +7 -7
  98. data/test/unit/database/sql_database_server_service_test.rb +43 -47
  99. data/test/unit/service/serialization_test.rb +40 -9
  100. data/test/unit/service/storage_service_test.rb +13 -11
  101. data/test/unit/storage_management/serialization_test.rb +26 -14
  102. data/test/unit/storage_management/storage_management_service_test.rb +48 -62
  103. data/test/unit/virtual_machine_image_management/serialization_test.rb +20 -5
  104. data/test/unit/virtual_machine_image_management/virtual_machine_image_management_service_test.rb +78 -29
  105. data/test/unit/virtual_machine_management/serialization_test.rb +112 -43
  106. data/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb +123 -100
  107. data/test/unit/vnet/serialization_test.rb +7 -7
  108. data/test/unit/vnet/virtual_network_management_service_test.rb +1 -1
  109. metadata +70 -16
  110. data/test/fixtures/certificate.pem +0 -21
@@ -16,9 +16,9 @@
16
16
  module Azure
17
17
  class Version
18
18
  MAJOR = 0 unless defined? MAJOR
19
- MINOR = 6 unless defined? MINOR
20
- UPDATE = 4 unless defined? UPDATE
21
- PRE = nil unless defined? PRE
19
+ MINOR = 7 unless defined? MINOR
20
+ UPDATE = 0 unless defined? UPDATE
21
+ PRE = 'pre' unless defined? PRE
22
22
 
23
23
  class << self
24
24
 
@@ -18,6 +18,7 @@ require 'azure/virtual_machine_image_management/virtual_machine_disk'
18
18
  module Azure
19
19
  module VirtualMachineImageManagement
20
20
  module Serialization
21
+ extend Azure::Core::Utility
21
22
  def self.virtual_machine_images_from_xml(imageXML)
22
23
  os_images = []
23
24
  virtual_machine_images = imageXML.css('Images OSImage')
@@ -26,7 +27,25 @@ module Azure
26
27
  image.os_type = xml_content(image_node, 'OS')
27
28
  image.name = xml_content(image_node, 'Name')
28
29
  image.category = xml_content(image_node, 'Category')
30
+ image.media_link = xml_content(image_node, 'MediaLink')
29
31
  image.locations = xml_content(image_node, 'Location')
32
+ image.image_type = 'OS'
33
+ os_images << image
34
+ end
35
+ os_images
36
+ end
37
+
38
+ def self.virtual_machine_vm_images_from_xml(imageXML)
39
+ os_images = []
40
+ virtual_machine_images = imageXML.css('VMImages VMImage')
41
+ virtual_machine_images.each do |image_node|
42
+ image = VirtualMachineImage.new
43
+ image.name = xml_content(image_node, 'Name')
44
+ image.category = xml_content(image_node, 'Category')
45
+ image.locations = xml_content(image_node, 'Location')
46
+ image.os_type = xml_content(image_node, 'OSDiskConfiguration OS')
47
+ image.media_link = xml_content(image_node, 'OSDiskConfiguration MediaLink')
48
+ image.image_type = 'VM'
30
49
  os_images << image
31
50
  end
32
51
  os_images
@@ -19,7 +19,7 @@ module Azure
19
19
  yield self if block_given?
20
20
  end
21
21
 
22
- attr_accessor :os_type, :name, :category, :locations
22
+ attr_accessor :os_type, :name, :category, :locations, :media_link, :image_type
23
23
  end
24
24
  end
25
25
  end
@@ -16,23 +16,46 @@ require 'azure/virtual_machine_image_management/serialization'
16
16
 
17
17
  module Azure
18
18
  module VirtualMachineImageManagement
19
- class VirtualMachineImageManagementService < BaseManagementService
19
+ class VirtualMachineImageManagementService < BaseManagement::BaseManagementService
20
+
20
21
  def initialize
21
22
  super()
22
23
  end
23
24
 
24
25
  # Public: Gets a list of virtual machine images from the server
25
26
  #
26
- # Returns an array of Azure::VirtualMachineImageManagementService objects
27
+ # Returns an array of Azure::VirtualMachineImageManagement::VirtualMachineImage objects
27
28
  def list_virtual_machine_images
29
+ list_os_images + list_vm_images
30
+ end
31
+
32
+ # Private: Gets a list of the operating system images that is associated with the specified subscription
33
+ #
34
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157191.aspx
35
+ #
36
+ # Returns an array of Azure::VirtualMachineImageManagement::VirtualMachineImage objects
37
+ def list_os_images
28
38
  request_path = '/services/images'
29
- request = ManagementHttpRequest.new(:get, request_path, nil)
39
+ request = BaseManagement::ManagementHttpRequest.new(:get, request_path, nil)
30
40
  response = request.call
31
41
  Serialization.virtual_machine_images_from_xml(response)
32
42
  end
43
+
44
+ # Private: Gets a list of the VM Images that is associated with the specified subscription
45
+ #
46
+ # See http://msdn.microsoft.com/en-us/library/azure/dn499770.aspx
47
+ #
48
+ # Returns an array of Azure::VirtualMachineImageManagement::VirtualMachineImage objects
49
+ def list_vm_images
50
+ request_path = '/services/vmimages'
51
+ request = Azure::BaseManagement::ManagementHttpRequest.new(:get, request_path, nil)
52
+ response = request.call
53
+ Serialization.virtual_machine_vm_images_from_xml(response)
54
+ end
33
55
  end
34
56
 
35
- class VirtualMachineDiskManagementService < BaseManagementService
57
+ class VirtualMachineDiskManagementService < BaseManagement::BaseManagementService
58
+
36
59
  def initialize
37
60
  super()
38
61
  end
@@ -42,7 +65,7 @@ module Azure
42
65
  # Returns an array of Azure::VirtualMachineDiskManagementService objects
43
66
  def list_virtual_machine_disks
44
67
  request_path = '/services/disks'
45
- request = ManagementHttpRequest.new(:get, request_path, nil)
68
+ request = Azure::BaseManagement::ManagementHttpRequest.new(:get, request_path, nil)
46
69
  response = request.call
47
70
  Serialization.disks_from_xml(response)
48
71
  end
@@ -56,9 +79,9 @@ module Azure
56
79
  #
57
80
  # Returns None
58
81
  def delete_virtual_machine_disk(disk_name)
59
- Loggerx.info "Deleting Disk \"#{disk_name}\". "
82
+ Azure::Loggerx.info "Deleting Disk \"#{disk_name}\". "
60
83
  path = "/services/disks/#{disk_name}"
61
- request = ManagementHttpRequest.new(:delete, path)
84
+ request = BaseManagement::ManagementHttpRequest.new(:delete, path)
62
85
  request.call
63
86
  end
64
87
  end
@@ -18,6 +18,7 @@ require 'base64'
18
18
  module Azure
19
19
  module VirtualMachineManagement
20
20
  module Serialization
21
+ extend Azure::Core::Utility
21
22
  def self.shutdown_virtual_machine_to_xml
22
23
  builder = Nokogiri::XML::Builder.new do |xml|
23
24
  xml.ShutdownRoleOperation(
@@ -55,7 +56,7 @@ module Azure
55
56
  builder.doc.to_xml
56
57
  end
57
58
 
58
- def self.deployment_to_xml(params, options)
59
+ def self.deployment_to_xml(params, image, options)
59
60
  options[:deployment_name] ||= options[:cloud_service_name]
60
61
  builder = Nokogiri::XML::Builder.new do |xml|
61
62
  xml.Deployment(
@@ -69,13 +70,16 @@ module Azure
69
70
  if options[:virtual_network_name]
70
71
  xml.VirtualNetworkName options[:virtual_network_name]
71
72
  end
73
+ if options[:reserved_ip_name]
74
+ xml.ReservedIPName options[:reserved_ip_name]
75
+ end
72
76
  end
73
77
  end
74
- builder.doc.at_css('Role') << role_to_xml(params, options).at_css('PersistentVMRole').children.to_s
78
+ builder.doc.at_css('Role') << role_to_xml(params, image, options).at_css('PersistentVMRole').children.to_s
75
79
  builder.doc.to_xml
76
80
  end
77
81
 
78
- def self.role_to_xml(params, options)
82
+ def self.role_to_xml(params, image, options)
79
83
  builder = Nokogiri::XML::Builder.new do |xml|
80
84
  xml.PersistentVMRole(
81
85
  'xmlns' => 'http://schemas.microsoft.com/windowsazure',
@@ -84,9 +88,8 @@ module Azure
84
88
  xml.RoleName { xml.text params[:vm_name] }
85
89
  xml.OsVersion('i:nil' => 'true')
86
90
  xml.RoleType 'PersistentVMRole'
87
-
88
91
  xml.ConfigurationSets do
89
- provisioning_configuration_to_xml(xml, params, options)
92
+ provisioning_configuration_to_xml(xml, params, options) if image.image_type == 'OS'
90
93
  xml.ConfigurationSet('i:type' => 'NetworkConfigurationSet') do
91
94
  xml.ConfigurationSetType 'NetworkConfiguration'
92
95
  xml.InputEndpoints do
@@ -101,14 +104,23 @@ module Azure
101
104
  xml.SubnetNames do
102
105
  xml.SubnetName options[:subnet_name]
103
106
  end
107
+ xml.StaticVirtualNetworkIPAddress options[:static_virtual_network_ipaddress] if options[:static_virtual_network_ipaddress]
104
108
  end
105
109
  end
106
110
  end
111
+ xml.VMImageName image.name if image.image_type == 'VM'
107
112
  xml.AvailabilitySetName options[:availability_set_name]
108
113
  xml.Label Base64.encode64(params[:vm_name]).strip
109
- xml.OSVirtualHardDisk do
110
- xml.MediaLink 'http://' + options[:storage_account_name] + '.blob.core.windows.net/vhds/' + (Time.now.strftime('disk_%Y_%m_%d_%H_%M')) + '.vhd'
111
- xml.SourceImageName params[:image]
114
+ if image.category == 'User'
115
+ storage_host = URI.parse( image.media_link ).host
116
+ else
117
+ storage_host = options[:storage_account_name] + '.blob.core.windows.net'
118
+ end
119
+ if image.image_type == 'OS'
120
+ xml.OSVirtualHardDisk do
121
+ xml.MediaLink 'http://' + storage_host + '/vhds/' + (Time.now.strftime('disk_%Y_%m_%d_%H_%M_%S_%L')) + '.vhd'
122
+ xml.SourceImageName params[:image]
123
+ end
112
124
  end
113
125
  xml.RoleSize options[:vm_size]
114
126
  end
@@ -143,6 +155,7 @@ module Azure
143
155
  end
144
156
  end
145
157
  end
158
+ xml.CustomData params[:custom_data] if params[:custom_data]
146
159
  end
147
160
  elsif options[:os_type] == 'Windows'
148
161
  xml.ConfigurationSet('i:type' => 'WindowsProvisioningConfigurationSet') do
@@ -248,11 +261,11 @@ module Azure
248
261
  vm = VirtualMachine.new
249
262
  role_name = xml_content(instance, 'RoleName')
250
263
  vm.status = xml_content(instance, 'InstanceStatus')
251
- vm.vm_name = role_name.downcase
264
+ vm.vm_name = role_name
252
265
  vm.ipaddress = xml_content(ip, 'Address')
253
266
  vm.role_size = xml_content(instance, 'InstanceSize')
254
267
  vm.hostname = xml_content(instance, 'HostName')
255
- vm.cloud_service_name = cloud_service_name.downcase
268
+ vm.cloud_service_name = cloud_service_name
256
269
  vm.deployment_name = xml_content(deployXML, 'Deployment Name')
257
270
  vm.deployment_status = xml_content(deployXML, 'Deployment Status')
258
271
  vm.virtual_network_name = xml_content(
@@ -264,6 +277,10 @@ module Azure
264
277
  vm.availability_set_name = xml_content(role, 'AvailabilitySetName')
265
278
  endpoints_from_xml(role, vm)
266
279
  vm.data_disks = data_disks_from_xml(role)
280
+ subnet = xml_content(role,
281
+ 'ConfigurationSets ConfigurationSet SubnetNames SubnetName'
282
+ )
283
+ vm.subnet = subnet unless subnet.empty?
267
284
  vm.os_type = xml_content(role, 'OSVirtualHardDisk OS')
268
285
  vm.disk_name = xml_content(role, 'OSVirtualHardDisk DiskName')
269
286
  vm.media_link = xml_content(role, 'OSVirtualHardDisk MediaLink')
@@ -347,6 +364,9 @@ module Azure
347
364
  xml.InputEndpoints do
348
365
  endpoints_to_xml(xml, endpoints)
349
366
  end
367
+ xml.SubnetNames do
368
+ xml.SubnetName vm.subnet if vm.subnet
369
+ end
350
370
  end
351
371
  end
352
372
  xml.OSVirtualHardDisk do
@@ -387,7 +407,7 @@ module Azure
387
407
 
388
408
  def self.add_data_disk_to_xml(vm, options)
389
409
  if options[:import] && options[:disk_name].nil?
390
- Loggerx.error_with_exit "The data disk name is not valid."
410
+ Azure::Loggerx.error_with_exit "The data disk name is not valid."
391
411
  end
392
412
  media_link = vm.media_link
393
413
  builder = Nokogiri::XML::Builder.new do |xml|
@@ -401,7 +421,7 @@ module Azure
401
421
  xml.LogicalDiskSizeInGB options[:disk_size] || 100
402
422
  unless options[:import]
403
423
  disk_name = media_link[/([^\/]+)$/]
404
- media_link = media_link.gsub(/#{disk_name}/, (Time.now.strftime('disk_%Y_%m_%d_%H_%M')) + '.vhd')
424
+ media_link = media_link.gsub(/#{disk_name}/, (Time.now.strftime('disk_%Y_%m_%d_%H_%M_%S')) + '.vhd')
405
425
  xml.MediaLink media_link
406
426
  end
407
427
  end
@@ -37,6 +37,7 @@ module Azure
37
37
  attr_accessor :availability_set_name
38
38
  attr_accessor :media_link
39
39
  attr_accessor :data_disks
40
+ attr_accessor :subnet
40
41
  end
41
42
  end
42
43
  end
@@ -17,7 +17,9 @@ include Azure::VirtualMachineImageManagement
17
17
 
18
18
  module Azure
19
19
  module VirtualMachineManagement
20
- class VirtualMachineManagementService < BaseManagementService
20
+ class VirtualMachineManagementService < BaseManagement::BaseManagementService
21
+ include Azure::Core::Utility
22
+
21
23
  def initialize
22
24
  super()
23
25
  end
@@ -34,7 +36,7 @@ module Azure
34
36
  end
35
37
  cloud_service_names.each do |cloud_service_name|
36
38
  request_path = "/services/hostedservices/#{cloud_service_name}/deploymentslots/production"
37
- request = ManagementHttpRequest.new(:get, request_path)
39
+ request = BaseManagement::ManagementHttpRequest.new(:get, request_path)
38
40
  request.warn = true
39
41
  response = request.call
40
42
  roles << Serialization.virtual_machines_from_xml(response, cloud_service_name)
@@ -51,7 +53,7 @@ module Azure
51
53
  #
52
54
  # Returns an Azure::VirtualMachineManagement::VirtualMachine instance.
53
55
  def get_virtual_machine(name, cloud_service_name)
54
- server = list_virtual_machines(cloud_service_name).select { |x| x.vm_name == name.downcase }
56
+ server = list_virtual_machines(cloud_service_name).select { |x| x.vm_name.casecmp(name) == 0 }
55
57
  server.first
56
58
  end
57
59
 
@@ -61,7 +63,6 @@ module Azure
61
63
  #
62
64
  # * +params+ - Hash. parameters.
63
65
  # * +options+ - Hash. Optional parameters.
64
- # * +add_role+ - true/false. Optional Parameter. Default is false
65
66
  #
66
67
  # ==== Params
67
68
  #
@@ -83,31 +84,25 @@ module Azure
83
84
  # * +:tcp_endpoints+ - String. Specifies the internal port and external/public port separated by a colon.
84
85
  # You can map multiple internal and external ports by separating them with a comma.
85
86
  # * +:ssh_private_key_file+ - String. Path of private key file.
86
- # * +:ssh_certificate_file+ - String. Path of certificate file.
87
87
  # * +:ssh_port+ - Integer. Specifies the SSH port number.
88
88
  # * +:winrm_http_port - Integer. Specifies the WinRM HTTP port number.
89
89
  # * +:winrm_https_port - Integer. Specifies the WinRM HTTPS port number.
90
90
  # * +:vm_size+ - String. Specifies the size of the virtual machine instance.
91
91
  # * +:winrm_transport+ - Array. Specifies WINRM transport protocol.
92
92
  # * +:availability_set_name+ - String. Specifies the availability set name.
93
- #
94
- # ==== add_role
95
- #
96
- # Accepted values are:
97
- # * +false+ - Will add a new deployment in a cloud service.
98
- # * +true+ - Will add a new role to a cloud service. Atleast one
99
- # deployment should exist before you can add a role.
93
+ # * +:reserved_ip_name+ - String. Specifies the reserved IP name.
100
94
  #
101
95
  # Returns Azure::VirtualMachineManagement::VirtualMachine objects of newly created instance.
102
96
  #
103
97
  # See:
104
- # http://msdn.microsoft.com/en-us/library/windowsazure/jj157194.aspx
105
- # http://msdn.microsoft.com/en-us/library/windowsazure/jj157186.aspx
98
+ # http://msdn.microsoft.com/en-us/library/azure/jj157194.aspx
106
99
  def create_virtual_machine(params, options = {})
107
- options[:os_type] = get_os_type(params[:image])
100
+ image = get_image(params[:image])
101
+ options[:os_type] = image.os_type
108
102
  validate_deployment_params(params, options)
109
103
  options[:deployment_name] ||= options[:cloud_service_name]
110
- Loggerx.info 'Creating deploymnent...'
104
+ Azure::Loggerx.info 'Creating deployment...'
105
+
111
106
  options[:cloud_service_name] ||= generate_cloud_service_name(params[:vm_name])
112
107
  options[:storage_account_name] ||= generate_storage_account_name(params[:vm_name])
113
108
  optionals = {}
@@ -115,9 +110,14 @@ module Azure
115
110
  virtual_network_service = Azure::VirtualNetworkManagementService.new
116
111
  virtual_networks = virtual_network_service.list_virtual_networks.select { |x| x.name == options[:virtual_network_name] }
117
112
  if virtual_networks.empty?
118
- Loggerx.error_with_exit "Virtual network #{options[:virtual_network_name]} doesn't exists"
113
+ Azure::Loggerx.error_with_exit "Virtual network #{options[:virtual_network_name]} doesn't exists"
119
114
  else
120
- optionals[:affinity_group_name] = virtual_networks.first.affinity_group
115
+ vnet = virtual_networks.first
116
+ if !vnet.affinity_group.empty?
117
+ options[:affinity_group_name] = vnet.affinity_group
118
+ else
119
+ optionals[:location] = vnet.location
120
+ end
121
121
  end
122
122
  elsif options[:affinity_group_name]
123
123
  optionals[:affinity_group_name] = options[:affinity_group_name]
@@ -127,11 +127,14 @@ module Azure
127
127
  cloud_service = Azure::CloudServiceManagementService.new
128
128
  cloud_service.create_cloud_service(options[:cloud_service_name], optionals)
129
129
  cloud_service.upload_certificate(options[:cloud_service_name], params[:certificate]) unless params[:certificate].empty?
130
- Azure::StorageManagementService.new.create_storage_account(options[:storage_account_name], optionals)
131
- body = Serialization.deployment_to_xml(params, options)
130
+ unless image.category == 'User'
131
+ options[:storage_account_name] ||= generate_storage_account_name(params[:vm_name])
132
+ Azure::StorageManagementService.new.create_storage_account(options[:storage_account_name], optionals)
133
+ end
134
+ body = Serialization.deployment_to_xml(params, image, options)
132
135
  path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments"
133
- Loggerx.info 'Deployment in progress...'
134
- request = ManagementHttpRequest.new(:post, path, body)
136
+ Azure::Loggerx.info 'Deployment in progress...'
137
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
135
138
  request.call
136
139
  get_virtual_machine(params[:vm_name], options[:cloud_service_name])
137
140
  rescue Exception => e
@@ -161,7 +164,6 @@ module Azure
161
164
  # * +:tcp_endpoints+ - String. Specifies the internal port and external/public port separated by a colon.
162
165
  # You can map multiple internal and external ports by separating them with a comma.
163
166
  # * +:ssh_private_key_file+ - String. Path of private key file.
164
- # * +:ssh_certificate_file+ - String. Path of certificate file.
165
167
  # * +:ssh_port+ - Integer. Specifies the SSH port number.
166
168
  # * +:winrm_http_port - Integer. Specifies the WinRM HTTP port number.
167
169
  # * +:winrm_https_port - Integer. Specifies the WinRM HTTPS port number.
@@ -171,23 +173,26 @@ module Azure
171
173
  # Returns Azure::VirtualMachineManagement::VirtualMachine objects of newly created instance.
172
174
  #
173
175
  # See:
174
- # http://msdn.microsoft.com/en-us/library/windowsazure/jj157186.aspx
176
+ # http://msdn.microsoft.com/en-us/library/azure/jj157186.aspx
175
177
  def add_role(params, options = {})
176
- options[:os_type] = get_os_type(params[:image])
178
+ image = get_image(params[:image])
179
+ options[:os_type] = image.os_type
177
180
  validate_deployment_params(params, options, true)
178
181
  cloud_service = Azure::CloudServiceManagementService.new
179
182
  cloud_service = cloud_service.get_cloud_service_properties(params[:cloud_service_name])
180
183
  deployment_name = cloud_service.deployment_name
181
- Loggerx.error_with_exit "Deployment doesn't exists." if cloud_service && deployment_name.empty?
184
+ Azure::Loggerx.error_with_exit "Deployment doesn't exists." if cloud_service && deployment_name.empty?
182
185
  others = {}
183
186
  if cloud_service.location
184
187
  others[:location] = cloud_service.location
185
188
  elsif cloud_service.affinity_group
186
189
  others[:affinity_group_name] = cloud_service.affinity_group
187
190
  end
188
- options[:storage_account_name] ||= generate_storage_account_name(params[:vm_name])
189
- Azure::StorageManagementService.new.create_storage_account(options[:storage_account_name], others)
190
- Loggerx.info 'Deployment exists, adding role...'
191
+ unless image.category == 'User'
192
+ options[:storage_account_name] ||= generate_storage_account_name(params[:vm_name])
193
+ Azure::StorageManagementService.new.create_storage_account(options[:storage_account_name], others)
194
+ end
195
+ Azure::Loggerx.info 'Deployment exists, adding role...'
191
196
  existing_ports = []
192
197
  cloud_service.virtual_machines[deployment_name.to_sym].each do |vm|
193
198
  vm.tcp_endpoints.each do |endpoint|
@@ -195,10 +200,10 @@ module Azure
195
200
  end
196
201
  end
197
202
  options[:existing_ports] = existing_ports
198
- body = Serialization.role_to_xml(params, options).to_xml
203
+ body = Serialization.role_to_xml(params, image, options).to_xml
199
204
  path = "/services/hostedservices/#{cloud_service.name}/deployments/#{deployment_name}/roles"
200
- Loggerx.info 'Deployment in progress...'
201
- request = ManagementHttpRequest.new(:post, path, body)
205
+ Azure::Loggerx.info 'Deployment in progress...'
206
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
202
207
  request.call
203
208
  get_virtual_machine(params[:vm_name], cloud_service.name)
204
209
  end
@@ -210,8 +215,8 @@ module Azure
210
215
  # * +vm_name+ - String. Virtual machine name.
211
216
  # * +cloud_service_name+ - String. Cloud service name.
212
217
  #
213
- # See http://msdn.microsoft.com/en-us/library/windowsazure/gg441305.aspx
214
- # See http://msdn.microsoft.com/en-us/library/windowsazure/jj157179.aspx
218
+ # See http://msdn.microsoft.com/en-us/library/azure/gg441305.aspx
219
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157179.aspx
215
220
  #
216
221
  # Returns NONE
217
222
  def delete_virtual_machine(vm_name, cloud_service_name)
@@ -224,11 +229,11 @@ module Azure
224
229
  cloud_service.delete_cloud_service(cloud_service_name)
225
230
  else
226
231
  path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm.vm_name}"
227
- Loggerx.info "Deleting virtual machine #{vm_name}. \n"
228
- request = ManagementHttpRequest.new(:delete, path)
232
+ Azure::Loggerx.info "Deleting virtual machine #{vm_name}. \n"
233
+ request = BaseManagement::ManagementHttpRequest.new(:delete, path)
229
234
  request.call
230
235
  end
231
- Loggerx.info "Waiting for disk to be released.\n"
236
+ Azure::Loggerx.info "Waiting for disk to be released.\n"
232
237
  disk_name = vm.disk_name
233
238
  disk_management_service = VirtualMachineDiskManagementService.new
234
239
  # Wait for 180s for disk to be released.
@@ -243,12 +248,12 @@ module Azure
243
248
  sleep 10
244
249
  end
245
250
  if disk.attached
246
- Loggerx.error "\nCannot delete disk #{disk_name}."
251
+ Azure::Loggerx.error "\nCannot delete disk #{disk_name}."
247
252
  else
248
253
  disk_management_service.delete_virtual_machine_disk(disk_name)
249
254
  end
250
255
  else
251
- Loggerx.error "Cannot find virtual machine #{vm_name} under cloud service #{cloud_service_name}"
256
+ Azure::Loggerx.error "Cannot find virtual machine #{vm_name} under cloud service #{cloud_service_name}"
252
257
  end
253
258
  rescue
254
259
  end
@@ -260,25 +265,25 @@ module Azure
260
265
  # * +name+ - String. Virtual machine name.
261
266
  # * +cloud_service_name+ - String. Cloud service name.
262
267
  #
263
- # See http://msdn.microsoft.com/en-us/library/windowsazure/jj157195.aspx
268
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157195.aspx
264
269
  #
265
270
  # Returns NONE
266
271
  def shutdown_virtual_machine(vm_name, cloud_service_name)
267
272
  vm = get_virtual_machine(vm_name, cloud_service_name)
268
273
  if vm
269
274
  if %w(StoppedVM StoppedDeallocated).include?(vm.status)
270
- Loggerx.error 'Cannot perform the shutdown operation on a stopped virtual machine.'
275
+ Azure::Loggerx.error 'Cannot perform the shutdown operation on a stopped virtual machine.'
271
276
  elsif vm.deployment_status == 'Running'
272
277
  path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
273
278
  body = Serialization.shutdown_virtual_machine_to_xml
274
- Loggerx.info "Shutting down virtual machine \"#{vm.vm_name}\" ..."
275
- request = ManagementHttpRequest.new(:post, path, body)
279
+ Azure::Loggerx.info "Shutting down virtual machine \"#{vm.vm_name}\" ..."
280
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
276
281
  request.call
277
282
  else
278
- Loggerx.error 'Cannot perform the shutdown operation on a stopped deployment.'
283
+ Azure::Loggerx.error 'Cannot perform the shutdown operation on a stopped deployment.'
279
284
  end
280
285
  else
281
- Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\". "
286
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\". "
282
287
  end
283
288
  end
284
289
 
@@ -289,23 +294,23 @@ module Azure
289
294
  # * +name+ - String. Virtual machine name.
290
295
  # * +cloud_service_name+ - String. Cloud service name.
291
296
  #
292
- # See http://msdn.microsoft.com/en-us/library/windowsazure/jj157189.aspx
297
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157189.aspx
293
298
  #
294
299
  # Returns NONE
295
300
  def start_virtual_machine(vm_name, cloud_service_name)
296
301
  vm = get_virtual_machine(vm_name, cloud_service_name)
297
302
  if vm
298
303
  if vm.status == 'ReadyRole'
299
- Loggerx.error 'Cannot perform the start operation on started virtual machine.'
304
+ Azure::Loggerx.error 'Cannot perform the start operation on started virtual machine.'
300
305
  else
301
306
  path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
302
307
  body = Serialization.start_virtual_machine_to_xml
303
- Loggerx.info "Starting virtual machine \"#{vm.vm_name}\" ..."
304
- request = ManagementHttpRequest.new(:post, path, body)
308
+ Azure::Loggerx.info "Starting virtual machine \"#{vm.vm_name}\" ..."
309
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
305
310
  request.call
306
311
  end
307
312
  else
308
- Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
313
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
309
314
  end
310
315
  end
311
316
 
@@ -316,7 +321,7 @@ module Azure
316
321
  # * +name+ - String. Virtual machine name.
317
322
  # * +cloud_service_name+ - String. Cloud service name.
318
323
  #
319
- # See http://msdn.microsoft.com/en-us/library/windowsazure/jj157197.aspx
324
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157197.aspx
320
325
  #
321
326
  # Returns NONE
322
327
  def restart_virtual_machine(vm_name, cloud_service_name)
@@ -324,11 +329,11 @@ module Azure
324
329
  if vm
325
330
  path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
326
331
  body = Serialization.restart_virtual_machine_to_xml
327
- Loggerx.info "Restarting virtual machine \"#{vm.vm_name}\" ..."
328
- request = ManagementHttpRequest.new(:post, path, body)
332
+ Azure::Loggerx.info "Restarting virtual machine \"#{vm.vm_name}\" ..."
333
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
329
334
  request.call
330
335
  else
331
- Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
336
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
332
337
  end
333
338
  end
334
339
 
@@ -372,7 +377,7 @@ module Azure
372
377
  # * +:path+ - String. Specifies the relative path to inspect to
373
378
  # determine the availability status of the Virtual Machine. (optional)
374
379
  #
375
- # See http://msdn.microsoft.com/en-us/library/windowsazure/jj157187.aspx
380
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157187.aspx
376
381
  #
377
382
  # Returns NONE
378
383
  def update_endpoints(vm_name, cloud_service_name, *input_endpoints)
@@ -386,11 +391,11 @@ module Azure
386
391
  end
387
392
  endpoints += input_endpoints
388
393
  body = Serialization.update_role_to_xml(endpoints, vm)
389
- request = ManagementHttpRequest.new(:put, path, body)
390
- Loggerx.info "Updating endpoints of virtual machine #{vm.vm_name} ..."
394
+ request = BaseManagement::ManagementHttpRequest.new(:put, path, body)
395
+ Azure::Loggerx.info "Updating endpoints of virtual machine #{vm.vm_name} ..."
391
396
  request.call
392
397
  else
393
- Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
398
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
394
399
  end
395
400
  end
396
401
 
@@ -402,7 +407,7 @@ module Azure
402
407
  # * +cloud_service_name+ - String. Cloud service name.
403
408
  # * +endpoint_name+ - String. Name of endpoint.
404
409
  #
405
- # See http://msdn.microsoft.com/en-us/library/windowsazure/jj157187.aspx
410
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157187.aspx
406
411
  #
407
412
  # Returns NONE
408
413
  def delete_endpoint(vm_name, cloud_service_name, endpoint_name)
@@ -412,11 +417,11 @@ module Azure
412
417
  endpoints = vm.tcp_endpoints + vm.udp_endpoints
413
418
  endpoints.delete_if { |ep| endpoint_name.downcase == ep[:name].downcase }
414
419
  body = Serialization.update_role_to_xml(endpoints, vm)
415
- request = ManagementHttpRequest.new(:put, path, body)
416
- Loggerx.info "Deleting virtual machine endpoint #{endpoint_name} ..."
420
+ request = BaseManagement::ManagementHttpRequest.new(:put, path, body)
421
+ Azure::Loggerx.info "Deleting virtual machine endpoint #{endpoint_name} ..."
417
422
  request.call
418
423
  else
419
- Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
424
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
420
425
  end
421
426
  end
422
427
 
@@ -440,7 +445,7 @@ module Azure
440
445
  # * +:disk_label+ - String. Specifies the description of the data disk.
441
446
  # * +:disk_size+ - String. Specifies the size of disk in GB
442
447
  #
443
- # See http://msdn.microsoft.com/en-us/library/windowsazure/jj157199.aspx
448
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157199.aspx
444
449
  #
445
450
  # Returns None
446
451
  def add_data_disk(vm_name, cloud_service_name, options = {})
@@ -449,11 +454,11 @@ module Azure
449
454
  if vm
450
455
  path = "/services/hostedservices/#{cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm_name}/DataDisks"
451
456
  body = Serialization.add_data_disk_to_xml(vm, options)
452
- Loggerx.info "Adding data disk to virtual machine #{vm_name} ..."
453
- request = ManagementHttpRequest.new(:post, path, body)
457
+ Azure::Loggerx.info "Adding data disk to virtual machine #{vm_name} ..."
458
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
454
459
  request.call
455
460
  else
456
- Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
461
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
457
462
  end
458
463
  end
459
464
 
@@ -462,11 +467,11 @@ module Azure
462
467
  # Private: Gets the operating system type of an image.
463
468
  #
464
469
  # Returns Linux or Windows
465
- def get_os_type(image_name)
470
+ def get_image(image_name)
466
471
  image_service = Azure::VirtualMachineImageManagementService.new
467
- image = image_service.list_virtual_machine_images.select { |x| x.name == image_name }.first
468
- Loggerx.error_with_exit 'The virtual machine image source is not valid.' unless image
469
- image.os_type
472
+ image = image_service.list_virtual_machine_images.select { |x| x.name.casecmp(image_name.to_s) == 0 }.first
473
+ Azure::Loggerx.error_with_exit 'The virtual machine image source is not valid.' unless image
474
+ image
470
475
  end
471
476
 
472
477
  def generate_cloud_service_name(vm_name)
@@ -482,7 +487,7 @@ module Azure
482
487
  params_keys = %w(vm_name image vm_user)
483
488
  params_keys += ['password'] if options[:os_type] == 'Windows'
484
489
  options_keys = []
485
- options_keys = %w(private_key_file certificate_file) if certificate_required?(params, options)
490
+ options_keys = %w(private_key_file) if certificate_required?(params, options)
486
491
  if add_role
487
492
  params_keys += ['cloud_service_name']
488
493
  else
@@ -503,20 +508,20 @@ module Azure
503
508
  if certificate_required?(params, options)
504
509
  begin
505
510
  params[:certificate][:key] = OpenSSL::PKey.read File.read(options[:private_key_file])
506
- params[:certificate][:cert] = OpenSSL::X509::Certificate.new File.read(options[:certificate_file])
511
+ params[:certificate][:cert] = get_certificate(options[:private_key_file])
507
512
  params[:certificate][:fingerprint] = export_fingerprint(params[:certificate][:cert])
508
513
  rescue Exception => e
509
- Loggerx.error_with_exit e.message
514
+ Azure::Loggerx.error_with_exit e.message
510
515
  end
511
516
  end
512
517
  else
513
- Loggerx.error_with_exit "You did not provide a valid '#{errors.uniq.join(", ")}' value."
518
+ Azure::Loggerx.error_with_exit "You did not provide a valid '#{errors.uniq.join(", ")}' value."
514
519
  end
515
520
  end
516
521
 
517
522
  def certificate_required?(params, options)
518
523
  if options[:os_type] == 'Linux'
519
- (params[:password].nil? or (!options[:certificate_file].nil? && !options[:private_key_file].nil?))
524
+ params[:password].nil?
520
525
  else
521
526
  winrm_with_https(options)
522
527
  end
@@ -524,14 +529,20 @@ module Azure
524
529
 
525
530
  def winrm_with_https(options)
526
531
  if options[:os_type] == 'Windows'
527
- options[:winrm_transport] && options[:winrm_transport].include?('https') && options[:certificate_file] && options[:private_key_file]
532
+ options[:winrm_transport] && options[:winrm_transport].include?('https') && options[:private_key_file]
528
533
  end
529
534
  end
530
535
 
531
536
  def validate_role_size(vm_size)
532
- valid_role_sizes = %w(ExtraSmall Small Medium Large ExtraLarge A5 A6 A7 Basic_A0 Basic_A1 Basic_A2 Basic_A3 Basic_A4)
533
- if vm_size && !valid_role_sizes.include?(vm_size)
534
- Loggerx.error_with_exit "Value '#{vm_size}' specified for parameter 'vm_size' is invalid. Allowed values are 'ExtraSmall,Small,Medium,Large,ExtraLarge,A6,A7'"
537
+ suggested_role_sizes = %w(
538
+ Basic_A0 Basic_A1 Basic_A2 Basic_A3 Basic_A4
539
+ ExtraSmall Small Medium Large ExtraLarge A5 A6 A7 A8 A9 A10 A11
540
+ Standard_D1 Standard_D2 Standard_D3 Standard_D4 Standard_D11 Standard_D12 Standard_D13 Standard_D14
541
+ Standard_DS1 Standard_DS2 Standard_DS3 Standard_DS4 Standard_DS11 Standard_DS12 Standard_DS13 Standard_DS14
542
+ Standard_G1 Standard_G2 Standard_G3 Standard_G4 Standard_G5
543
+ )
544
+ if vm_size && !suggested_role_sizes.include?(vm_size)
545
+ Azure::Loggerx.warn "Value '#{vm_size}' specified for parameter 'vm_size' is not in the list of valid VM role sizes. Suggested values are '#{suggested_role_sizes.join(',')}'"
535
546
  end
536
547
  end
537
548
 
@@ -539,9 +550,9 @@ module Azure
539
550
  locations = Azure::BaseManagementService.new.list_locations
540
551
  location = locations.select { |loc| loc.name.downcase == location_name.downcase }.first
541
552
  if location.nil?
542
- Loggerx.error_with_exit "Value '#{location_name}' specified for parameter 'location' is invalid. Allowed values are #{locations.map(&:name).join(',')}"
553
+ Azure::Loggerx.error_with_exit "Value '#{location_name}' specified for parameter 'location' is invalid. Allowed values are #{locations.map(&:name).join(',')}"
543
554
  elsif !location.available_services.include?('PersistentVMRole')
544
- Loggerx.error_with_exit "Persistentvmrole not enabled for \"#{location.name}\". Try different location"
555
+ Azure::Loggerx.error_with_exit "Persistentvmrole not enabled for \"#{location.name}\". Try different location"
545
556
  end
546
557
  end
547
558
  end