juliusl-azure-sdk-for-ruby 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. checksums.yaml +7 -0
  2. data/.env_sample +11 -0
  3. data/.gitignore +15 -0
  4. data/.travis.yml +13 -0
  5. data/ChangeLog.txt +56 -0
  6. data/Gemfile +16 -0
  7. data/LICENSE.txt +202 -0
  8. data/README.md +630 -0
  9. data/Rakefile +121 -0
  10. data/azure.gemspec +47 -0
  11. data/bin/pfxer +35 -0
  12. data/lib/azure.rb +60 -0
  13. data/lib/azure/base_management/affinity_group.rb +32 -0
  14. data/lib/azure/base_management/base_management_service.rb +245 -0
  15. data/lib/azure/base_management/location.rb +27 -0
  16. data/lib/azure/base_management/management_http_request.rb +175 -0
  17. data/lib/azure/base_management/serialization.rb +135 -0
  18. data/lib/azure/base_management/sql_management_http_request.rb +45 -0
  19. data/lib/azure/blob/auth/shared_access_signature.rb +141 -0
  20. data/lib/azure/blob/blob.rb +32 -0
  21. data/lib/azure/blob/blob_service.rb +1427 -0
  22. data/lib/azure/blob/block.rb +31 -0
  23. data/lib/azure/blob/container.rb +32 -0
  24. data/lib/azure/blob/serialization.rb +285 -0
  25. data/lib/azure/cloud_service_management/cloud_service.rb +38 -0
  26. data/lib/azure/cloud_service_management/cloud_service_management_service.rb +137 -0
  27. data/lib/azure/cloud_service_management/serialization.rb +118 -0
  28. data/lib/azure/core.rb +41 -0
  29. data/lib/azure/core/auth/authorizer.rb +36 -0
  30. data/lib/azure/core/auth/shared_key.rb +110 -0
  31. data/lib/azure/core/auth/shared_key_lite.rb +48 -0
  32. data/lib/azure/core/auth/signer.rb +52 -0
  33. data/lib/azure/core/configuration.rb +218 -0
  34. data/lib/azure/core/error.rb +22 -0
  35. data/lib/azure/core/filtered_service.rb +44 -0
  36. data/lib/azure/core/http/debug_filter.rb +36 -0
  37. data/lib/azure/core/http/http_error.rb +88 -0
  38. data/lib/azure/core/http/http_filter.rb +53 -0
  39. data/lib/azure/core/http/http_request.rb +160 -0
  40. data/lib/azure/core/http/http_response.rb +140 -0
  41. data/lib/azure/core/http/retry_policy.rb +74 -0
  42. data/lib/azure/core/http/signer_filter.rb +34 -0
  43. data/lib/azure/core/service.rb +63 -0
  44. data/lib/azure/core/signed_service.rb +43 -0
  45. data/lib/azure/core/utility.rb +242 -0
  46. data/lib/azure/queue/message.rb +30 -0
  47. data/lib/azure/queue/queue.rb +29 -0
  48. data/lib/azure/queue/queue_service.rb +568 -0
  49. data/lib/azure/queue/serialization.rb +106 -0
  50. data/lib/azure/service/access_policy.rb +26 -0
  51. data/lib/azure/service/cors.rb +11 -0
  52. data/lib/azure/service/cors_rule.rb +15 -0
  53. data/lib/azure/service/enumeration_results.rb +21 -0
  54. data/lib/azure/service/logging.rb +32 -0
  55. data/lib/azure/service/metrics.rb +31 -0
  56. data/lib/azure/service/retention_policy.rb +25 -0
  57. data/lib/azure/service/serialization.rb +299 -0
  58. data/lib/azure/service/signed_identifier.rb +30 -0
  59. data/lib/azure/service/storage_service.rb +83 -0
  60. data/lib/azure/service/storage_service_properties.rb +37 -0
  61. data/lib/azure/service_bus/action.rb +21 -0
  62. data/lib/azure/service_bus/auth/wrap_service.rb +89 -0
  63. data/lib/azure/service_bus/auth/wrap_signer.rb +69 -0
  64. data/lib/azure/service_bus/brokered_message.rb +124 -0
  65. data/lib/azure/service_bus/brokered_message_serializer.rb +159 -0
  66. data/lib/azure/service_bus/correlation_filter.rb +45 -0
  67. data/lib/azure/service_bus/empty_rule_action.rb +30 -0
  68. data/lib/azure/service_bus/false_filter.rb +38 -0
  69. data/lib/azure/service_bus/filter.rb +21 -0
  70. data/lib/azure/service_bus/interval.rb +104 -0
  71. data/lib/azure/service_bus/queue.rb +230 -0
  72. data/lib/azure/service_bus/relay.rb +88 -0
  73. data/lib/azure/service_bus/resource.rb +109 -0
  74. data/lib/azure/service_bus/rule.rb +98 -0
  75. data/lib/azure/service_bus/rule_aspect.rb +34 -0
  76. data/lib/azure/service_bus/serialization.rb +161 -0
  77. data/lib/azure/service_bus/service_bus_service.rb +895 -0
  78. data/lib/azure/service_bus/sql_filter.rb +50 -0
  79. data/lib/azure/service_bus/sql_rule_action.rb +50 -0
  80. data/lib/azure/service_bus/subscription.rb +184 -0
  81. data/lib/azure/service_bus/topic.rb +187 -0
  82. data/lib/azure/service_bus/true_filter.rb +38 -0
  83. data/lib/azure/sql_database_management/serialization.rb +112 -0
  84. data/lib/azure/sql_database_management/sql_database.rb +31 -0
  85. data/lib/azure/sql_database_management/sql_database_management_service.rb +200 -0
  86. data/lib/azure/storage_management/serialization.rb +204 -0
  87. data/lib/azure/storage_management/storage_account.rb +48 -0
  88. data/lib/azure/storage_management/storage_management_service.rb +208 -0
  89. data/lib/azure/table/auth/shared_key.rb +92 -0
  90. data/lib/azure/table/auth/shared_key_lite.rb +44 -0
  91. data/lib/azure/table/batch.rb +330 -0
  92. data/lib/azure/table/batch_response.rb +118 -0
  93. data/lib/azure/table/edmtype.rb +127 -0
  94. data/lib/azure/table/entity.rb +31 -0
  95. data/lib/azure/table/guid.rb +24 -0
  96. data/lib/azure/table/query.rb +112 -0
  97. data/lib/azure/table/serialization.rb +108 -0
  98. data/lib/azure/table/table_service.rb +560 -0
  99. data/lib/azure/version.rb +31 -0
  100. data/lib/azure/virtual_machine_image_management/serialization.rb +70 -0
  101. data/lib/azure/virtual_machine_image_management/virtual_machine_disk.rb +25 -0
  102. data/lib/azure/virtual_machine_image_management/virtual_machine_image.rb +25 -0
  103. data/lib/azure/virtual_machine_image_management/virtual_machine_image_management_service.rb +89 -0
  104. data/lib/azure/virtual_machine_management/serialization.rb +459 -0
  105. data/lib/azure/virtual_machine_management/virtual_machine.rb +44 -0
  106. data/lib/azure/virtual_machine_management/virtual_machine_management_service.rb +554 -0
  107. data/lib/azure/virtual_network_management/serialization.rb +193 -0
  108. data/lib/azure/virtual_network_management/virtual_network.rb +37 -0
  109. data/lib/azure/virtual_network_management/virtual_network_management_service.rb +109 -0
  110. data/test/fixtures/32px-fulls-black.jpg +0 -0
  111. data/test/fixtures/affinity_group.xml +33 -0
  112. data/test/fixtures/all_containers.xml +20 -0
  113. data/test/fixtures/all_tables.xml +22 -0
  114. data/test/fixtures/container_acl.xml +11 -0
  115. data/test/fixtures/create_sql_database_server.xml +2 -0
  116. data/test/fixtures/create_storage_desc_error.xml +5 -0
  117. data/test/fixtures/create_storage_extendedprop_error.xml +8 -0
  118. data/test/fixtures/create_storage_extendedpropname_error.xml +6 -0
  119. data/test/fixtures/create_storage_full_error.xml +6 -0
  120. data/test/fixtures/create_storage_label_error.xml +5 -0
  121. data/test/fixtures/create_storage_location_error.xml +5 -0
  122. data/test/fixtures/create_storage_name_error.xml +6 -0
  123. data/test/fixtures/create_table_response_entry.xml +15 -0
  124. data/test/fixtures/delete_storage_container_error.xml +5 -0
  125. data/test/fixtures/delete_storage_error.xml +5 -0
  126. data/test/fixtures/deployment_error.xml +5 -0
  127. data/test/fixtures/empty_xml_file +0 -0
  128. data/test/fixtures/get_storage_account_error.xml +5 -0
  129. data/test/fixtures/get_storage_account_properties.xml +34 -0
  130. data/test/fixtures/get_storage_account_properties_new.xml +32 -0
  131. data/test/fixtures/http_error.xml +5 -0
  132. data/test/fixtures/insert_entity_response_entry.xml +25 -0
  133. data/test/fixtures/list_affinity_groups.xml +22 -0
  134. data/test/fixtures/list_blobs.xml +121 -0
  135. data/test/fixtures/list_block_all_with_none_committed.xml +22 -0
  136. data/test/fixtures/list_blocks_all.xml +23 -0
  137. data/test/fixtures/list_blocks_committed.xml +13 -0
  138. data/test/fixtures/list_cloud_services.xml +39 -0
  139. data/test/fixtures/list_containers.xml +38 -0
  140. data/test/fixtures/list_firewall_management_endpoint.xml +27 -0
  141. data/test/fixtures/list_locations.xml +212 -0
  142. data/test/fixtures/list_os_images.xml +110 -0
  143. data/test/fixtures/list_page_ranges.xml +11 -0
  144. data/test/fixtures/list_sql_database.xml +36 -0
  145. data/test/fixtures/list_sql_server_firewall.xml +23 -0
  146. data/test/fixtures/list_storage_account_single.xml +25 -0
  147. data/test/fixtures/list_storage_accounts.xml +48 -0
  148. data/test/fixtures/list_virtual_networks.xml +92 -0
  149. data/test/fixtures/list_vm_images.xml +21 -0
  150. data/test/fixtures/logging.xml +11 -0
  151. data/test/fixtures/messages.xml +12 -0
  152. data/test/fixtures/metrics.xml +10 -0
  153. data/test/fixtures/privatekey.key +28 -0
  154. data/test/fixtures/query_entities_empty_response.xml +7 -0
  155. data/test/fixtures/query_entities_response.xml +45 -0
  156. data/test/fixtures/queue_service_properties.xml +22 -0
  157. data/test/fixtures/queue_service_properties_original.xml +19 -0
  158. data/test/fixtures/queues.xml +16 -0
  159. data/test/fixtures/retention_policy.xml +5 -0
  160. data/test/fixtures/sb_default_create_queue_response.xml +23 -0
  161. data/test/fixtures/sb_default_create_relay_response.xml +15 -0
  162. data/test/fixtures/sb_default_create_topic_response.xml +18 -0
  163. data/test/fixtures/sb_get_access_token_response.txt +1 -0
  164. data/test/fixtures/sb_queues_runtime_peek_message_response_headers.txt +9 -0
  165. data/test/fixtures/storage_service_keys.xml +8 -0
  166. data/test/fixtures/storage_service_properties.xml +55 -0
  167. data/test/fixtures/update_storage_account.xml +16 -0
  168. data/test/fixtures/update_storage_error.xml +5 -0
  169. data/test/fixtures/updated_storage_accounts.xml +55 -0
  170. data/test/fixtures/virtual_machine.xml +116 -0
  171. data/test/fixtures/windows_virtual_machine.xml +106 -0
  172. data/test/integration/affinity_group/Affinity_test.rb +55 -0
  173. data/test/integration/affinity_group/Create_Affinity_test.rb +64 -0
  174. data/test/integration/affinity_group/Delete_Affinity_test.rb +56 -0
  175. data/test/integration/affinity_group/List_Affinity_test.rb +41 -0
  176. data/test/integration/affinity_group/Update_Affinity_test.rb +83 -0
  177. data/test/integration/blob/blob_gb18030_test.rb +199 -0
  178. data/test/integration/blob/blob_metadata_test.rb +75 -0
  179. data/test/integration/blob/blob_pages_test.rb +119 -0
  180. data/test/integration/blob/blob_properties_test.rb +77 -0
  181. data/test/integration/blob/block_blob_test.rb +254 -0
  182. data/test/integration/blob/container/container_acl_test.rb +69 -0
  183. data/test/integration/blob/container/container_metadata_test.rb +50 -0
  184. data/test/integration/blob/container/create_container_test.rb +60 -0
  185. data/test/integration/blob/container/delete_container_test.rb +39 -0
  186. data/test/integration/blob/container/get_container_properties_test.rb +48 -0
  187. data/test/integration/blob/container/list_containers_test.rb +79 -0
  188. data/test/integration/blob/container/root_container_test.rb +54 -0
  189. data/test/integration/blob/copy_blob_test.rb +113 -0
  190. data/test/integration/blob/create_blob_snapshot_test.rb +80 -0
  191. data/test/integration/blob/create_page_blob_test.rb +83 -0
  192. data/test/integration/blob/delete_blob_test.rb +159 -0
  193. data/test/integration/blob/get_blob_test.rb +65 -0
  194. data/test/integration/blob/informative_errors_test.rb +39 -0
  195. data/test/integration/blob/lease/acquire_lease_test.rb +36 -0
  196. data/test/integration/blob/lease/break_lease_test.rb +40 -0
  197. data/test/integration/blob/lease/release_lease_test.rb +40 -0
  198. data/test/integration/blob/lease/renew_lease_test.rb +42 -0
  199. data/test/integration/blob/list_blobs_test.rb +113 -0
  200. data/test/integration/cloud_service/Cloud_Create_test.rb +45 -0
  201. data/test/integration/cloud_service/Cloud_Delete_test.rb +45 -0
  202. data/test/integration/database/create_sql_server_firewall_test.rb +86 -0
  203. data/test/integration/database/create_sql_server_test.rb +53 -0
  204. data/test/integration/database/delete_sql_server_firewall_test.rb +70 -0
  205. data/test/integration/database/delete_sql_server_test.rb +58 -0
  206. data/test/integration/database/list_sql_server_firewall_test.rb +45 -0
  207. data/test/integration/database/list_sql_servers_test.rb +44 -0
  208. data/test/integration/database/reset_password_sql_server_test.rb +55 -0
  209. data/test/integration/location/Location_List_test.rb +39 -0
  210. data/test/integration/location/RoleSize_List_test.rb +35 -0
  211. data/test/integration/queue/clear_messages_test.rb +42 -0
  212. data/test/integration/queue/create_message_test.rb +75 -0
  213. data/test/integration/queue/create_queue_test.rb +50 -0
  214. data/test/integration/queue/delete_message_test.rb +67 -0
  215. data/test/integration/queue/delete_queue_test.rb +45 -0
  216. data/test/integration/queue/informative_errors_test.rb +42 -0
  217. data/test/integration/queue/list_messages_encoded_test.rb +79 -0
  218. data/test/integration/queue/list_messages_test.rb +79 -0
  219. data/test/integration/queue/list_queues_test.rb +44 -0
  220. data/test/integration/queue/peek_messages_test.rb +59 -0
  221. data/test/integration/queue/queue_gb18030_test.rb +131 -0
  222. data/test/integration/queue/queue_metadata_test.rb +40 -0
  223. data/test/integration/queue/update_message_test.rb +74 -0
  224. data/test/integration/service_bus/informative_errors_test.rb +37 -0
  225. data/test/integration/service_bus/queues_scenario_test.rb +200 -0
  226. data/test/integration/service_bus/queues_test.rb +266 -0
  227. data/test/integration/service_bus/relay_test.rb +132 -0
  228. data/test/integration/service_bus/rules_test.rb +145 -0
  229. data/test/integration/service_bus/sb_queue_gb18030_test.rb +182 -0
  230. data/test/integration/service_bus/scenario_test.rb +101 -0
  231. data/test/integration/service_bus/subscriptions_test.rb +211 -0
  232. data/test/integration/service_bus/topics_scenario_test.rb +406 -0
  233. data/test/integration/service_bus/topics_test.rb +129 -0
  234. data/test/integration/storage_management/storage_management_test.rb +185 -0
  235. data/test/integration/table/create_table_test.rb +36 -0
  236. data/test/integration/table/delete_entity_batch_test.rb +107 -0
  237. data/test/integration/table/delete_entity_test.rb +94 -0
  238. data/test/integration/table/delete_table_test.rb +40 -0
  239. data/test/integration/table/get_table_test.rb +37 -0
  240. data/test/integration/table/informative_errors_test.rb +39 -0
  241. data/test/integration/table/insert_entity_batch_test.rb +100 -0
  242. data/test/integration/table/insert_entity_test.rb +88 -0
  243. data/test/integration/table/insert_or_merge_entity_batch_test.rb +159 -0
  244. data/test/integration/table/insert_or_merge_entity_test.rb +143 -0
  245. data/test/integration/table/insert_or_replace_entity_batch_test.rb +152 -0
  246. data/test/integration/table/insert_or_replace_entity_test.rb +137 -0
  247. data/test/integration/table/merge_entity_batch_test.rb +128 -0
  248. data/test/integration/table/merge_entity_test.rb +113 -0
  249. data/test/integration/table/query_entities_test.rb +195 -0
  250. data/test/integration/table/query_tables_test.rb +43 -0
  251. data/test/integration/table/query_test.rb +251 -0
  252. data/test/integration/table/table_acl_test.rb +52 -0
  253. data/test/integration/table/table_gb18030_test.rb +355 -0
  254. data/test/integration/table/update_entity_batch_test.rb +149 -0
  255. data/test/integration/table/update_entity_test.rb +131 -0
  256. data/test/integration/test_helper.rb +38 -0
  257. data/test/integration/vm/VM_Create_test.rb +262 -0
  258. data/test/integration/vm/VM_Delete_test.rb +53 -0
  259. data/test/integration/vm/VM_Operations_test.rb +172 -0
  260. data/test/integration/vm_image/virtual_machine_disk_test.rb +37 -0
  261. data/test/integration/vm_image/virtual_machine_image_test.rb +37 -0
  262. data/test/integration/vnet/Virtual_Network_Create_test.rb +116 -0
  263. data/test/integration/vnet/Virtual_Network_list_test.rb +48 -0
  264. data/test/support/env.rb +19 -0
  265. data/test/support/fixtures.rb +36 -0
  266. data/test/support/name_generator.rb +168 -0
  267. data/test/support/stubs.rb +42 -0
  268. data/test/support/virtual_machine_name_generator.rb +102 -0
  269. data/test/support/virtual_network_helper.rb +73 -0
  270. data/test/test_helper.rb +44 -0
  271. data/test/unit/affinity_group/affinity_group_test.rb +189 -0
  272. data/test/unit/affinity_group/serialization_test.rb +87 -0
  273. data/test/unit/base_management/location_test.rb +56 -0
  274. data/test/unit/base_management/role_size_test.rb +50 -0
  275. data/test/unit/blob/auth/shared_access_signature_test.rb +71 -0
  276. data/test/unit/blob/blob_service_test.rb +1969 -0
  277. data/test/unit/cloud_service_management/cloud_service_management_service_test.rb +94 -0
  278. data/test/unit/cloud_service_management/serialization_test.rb +169 -0
  279. data/test/unit/core/auth/shared_key_lite_test.rb +51 -0
  280. data/test/unit/core/auth/shared_key_test.rb +58 -0
  281. data/test/unit/core/auth/signer_test.rb +30 -0
  282. data/test/unit/core/http/http_error_test.rb +62 -0
  283. data/test/unit/core/http/http_request_test.rb +113 -0
  284. data/test/unit/core/http/http_response_test.rb +45 -0
  285. data/test/unit/core/http/retry_policy_test.rb +23 -0
  286. data/test/unit/core/utility_test.rb +122 -0
  287. data/test/unit/database/serialization_test.rb +97 -0
  288. data/test/unit/database/sql_database_server_service_test.rb +284 -0
  289. data/test/unit/service/serialization_test.rb +533 -0
  290. data/test/unit/service/storage_service_test.rb +293 -0
  291. data/test/unit/storage_management/serialization_test.rb +244 -0
  292. data/test/unit/storage_management/storage_management_service_test.rb +247 -0
  293. data/test/unit/table/edmtype_test.rb +108 -0
  294. data/test/unit/virtual_machine_image_management/serialization_test.rb +50 -0
  295. data/test/unit/virtual_machine_image_management/virtual_machine_image_management_service_test.rb +114 -0
  296. data/test/unit/virtual_machine_management/serialization_test.rb +316 -0
  297. data/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb +478 -0
  298. data/test/unit/vnet/serialization_test.rb +187 -0
  299. data/test/unit/vnet/virtual_network_management_service_test.rb +131 -0
  300. metadata +512 -0
@@ -0,0 +1,44 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright 2013 Microsoft Open Technologies, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+
16
+ module Azure
17
+ module VirtualMachineManagement
18
+ class VirtualMachine
19
+ def initialize
20
+ yield self if block_given?
21
+ end
22
+
23
+ attr_accessor :cloud_service_name
24
+ attr_accessor :status
25
+ attr_accessor :ipaddress
26
+ attr_accessor :vm_name
27
+ attr_accessor :udp_endpoints
28
+ attr_accessor :hostname
29
+ attr_accessor :deployment_name
30
+ attr_accessor :deployment_status
31
+ attr_accessor :tcp_endpoints
32
+ attr_accessor :role_size
33
+ attr_accessor :image
34
+ attr_accessor :os_type
35
+ attr_accessor :disk_name
36
+ attr_accessor :virtual_network_name
37
+ attr_accessor :availability_set_name
38
+ attr_accessor :media_link
39
+ attr_accessor :data_disks
40
+ attr_accessor :subnet
41
+ attr_accessor :static_virtual_network_ipaddress
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,554 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright 2013 Microsoft Open Technologies, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'azure/virtual_machine_management/serialization'
16
+ include Azure::VirtualMachineImageManagement
17
+
18
+ module Azure
19
+ module VirtualMachineManagement
20
+ class VirtualMachineManagementService < BaseManagement::BaseManagementService
21
+ include Azure::Core::Utility
22
+
23
+ def initialize
24
+ super()
25
+ end
26
+
27
+ # Public: Get a lists of virtual machines available under the current subscription.
28
+ #
29
+ # Returns an list of Azure::VirtualMachineManagement::VirtualMachine instances.
30
+ def list_virtual_machines(*cloud_service_names)
31
+ roles = []
32
+ cloud_service_names.flatten!
33
+ if cloud_service_names.empty?
34
+ cloud_service = Azure::CloudServiceManagementService.new
35
+ cloud_service_names = cloud_service.list_cloud_services.map(&:name)
36
+ end
37
+ cloud_service_names.each do |cloud_service_name|
38
+ request_path = "/services/hostedservices/#{cloud_service_name}/deploymentslots/production"
39
+ request = BaseManagement::ManagementHttpRequest.new(:get, request_path)
40
+ request.warn = true
41
+ response = request.call
42
+ roles << Serialization.virtual_machines_from_xml(response, cloud_service_name)
43
+ end
44
+ roles.flatten.compact
45
+ end
46
+
47
+ # Public: Gets a virtual machine based on the provided name and cloud service name.
48
+ #
49
+ # ==== Attributes
50
+ #
51
+ # * +name+ - String. Virtual machine name.
52
+ # * +cloud_service_name+ - String. Cloud service name.
53
+ #
54
+ # Returns an Azure::VirtualMachineManagement::VirtualMachine instance.
55
+ def get_virtual_machine(name, cloud_service_name)
56
+ server = list_virtual_machines(cloud_service_name).select { |x| x.vm_name.casecmp(name) == 0 }
57
+ server.first
58
+ end
59
+
60
+ # Public: Provisions a virtual machine based on the supplied configuration.
61
+ #
62
+ # ==== Attributes
63
+ #
64
+ # * +params+ - Hash. parameters.
65
+ # * +options+ - Hash. Optional parameters.
66
+ #
67
+ # ==== Params
68
+ #
69
+ # Accepted key/value pairs are:
70
+ # * +:vm_name+ - String. Name of virtual machine.
71
+ # * +:vm_user+ - String. User name for the virtual machine instance.
72
+ # * +:password+ - String. A description for the hosted service.
73
+ # * +:image+ - String. Name of the disk image to use to create the virtual machine.
74
+ # * +:location+ - String. The location where the virtual machine will be created.
75
+ # * +:affinity_group_name - String. The affinity group name to be used
76
+ # for the cloud service and the storage account if these do not exist.
77
+ #
78
+ # ==== Options
79
+ #
80
+ # Accepted key/value pairs are:
81
+ # * +:storage_account_name+ - String. Name of storage account.
82
+ # * +:cloud_service_name+ - String. Name of cloud service.
83
+ # * +:deployment_name+ - String. A name for the deployment.
84
+ # * +:tcp_endpoints+ - String. Specifies the internal port and external/public port separated by a colon.
85
+ # You can map multiple internal and external ports by separating them with a comma.
86
+ # * +:ssh_private_key_file+ - String. Path of private key file.
87
+ # * +:ssh_port+ - Integer. Specifies the SSH port number.
88
+ # * +:winrm_http_port - Integer. Specifies the WinRM HTTP port number.
89
+ # * +:winrm_https_port - Integer. Specifies the WinRM HTTPS port number.
90
+ # * +:vm_size+ - String. Specifies the size of the virtual machine instance.
91
+ # * +:winrm_transport+ - Array. Specifies WINRM transport protocol.
92
+ # * +:availability_set_name+ - String. Specifies the availability set name.
93
+ # * +:reserved_ip_name+ - String. Specifies the reserved IP name.
94
+ #
95
+ # Returns Azure::VirtualMachineManagement::VirtualMachine objects of newly created instance.
96
+ #
97
+ # See:
98
+ # http://msdn.microsoft.com/en-us/library/azure/jj157194.aspx
99
+ def create_virtual_machine(params, options = {})
100
+ image = get_image(params[:image])
101
+ options[:os_type] = image.os_type
102
+ validate_deployment_params(params, options)
103
+ options[:deployment_name] ||= options[:cloud_service_name]
104
+ Azure::Loggerx.info 'Creating deployment...'
105
+
106
+ options[:cloud_service_name] ||= generate_cloud_service_name(params[:vm_name])
107
+ options[:storage_account_name] ||= generate_storage_account_name(params[:vm_name])
108
+ optionals = {}
109
+ if options[:virtual_network_name]
110
+ virtual_network_service = Azure::VirtualNetworkManagementService.new
111
+ virtual_networks = virtual_network_service.list_virtual_networks.select { |x| x.name == options[:virtual_network_name] }
112
+ if virtual_networks.empty?
113
+ Azure::Loggerx.error_with_exit "Virtual network #{options[:virtual_network_name]} doesn't exists"
114
+ else
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
+ end
122
+ elsif options[:affinity_group_name]
123
+ optionals[:affinity_group_name] = options[:affinity_group_name]
124
+ else
125
+ optionals[:location] = params[:location]
126
+ end
127
+ cloud_service = Azure::CloudServiceManagementService.new
128
+ cloud_service.create_cloud_service(options[:cloud_service_name], optionals)
129
+ cloud_service.upload_certificate(options[:cloud_service_name], params[:certificate]) unless params[:certificate].empty?
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)
135
+ path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments"
136
+ Azure::Loggerx.info 'Deployment in progress...'
137
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
138
+ request.call
139
+ get_virtual_machine(params[:vm_name], options[:cloud_service_name])
140
+ rescue Exception => e
141
+ Azure::Loggerx.error_with_exit "Failed to create virtual machine : "+e.message
142
+ end
143
+
144
+ # Public: Add a new role to a cloud service. Atleast one deployment should exist before you can add a role.
145
+ #
146
+ # ==== Attributes
147
+ #
148
+ # * +params+ - Hash. parameters.
149
+ # * +options+ - Hash. Optional parameters.
150
+ #
151
+ # ==== Params
152
+ #
153
+ # Accepted key/value pairs are:
154
+ # * +:vm_name+ - String. Name of virtual machine.
155
+ # * +:vm_user+ - String. User name for the virtual machine instance.
156
+ # * +:password+ - String. A description for the hosted service.
157
+ # * +:image+ - String. Name of the disk image to use to create the virtual machine.
158
+ # * +:cloud_service_name+ - String. Name of cloud service.
159
+ #
160
+ # ==== Options
161
+ #
162
+ # Accepted key/value pairs are:
163
+ # * +:storage_account_name+ - String. Name of storage account.
164
+ # * +:tcp_endpoints+ - String. Specifies the internal port and external/public port separated by a colon.
165
+ # You can map multiple internal and external ports by separating them with a comma.
166
+ # * +:ssh_private_key_file+ - String. Path of private key file.
167
+ # * +:ssh_port+ - Integer. Specifies the SSH port number.
168
+ # * +:winrm_http_port - Integer. Specifies the WinRM HTTP port number.
169
+ # * +:winrm_https_port - Integer. Specifies the WinRM HTTPS port number.
170
+ # * +:vm_size+ - String. Specifies the size of the virtual machine instance.
171
+ # * +:winrm_transport+ - Array. Specifies WINRM transport protocol.
172
+ #
173
+ # Returns Azure::VirtualMachineManagement::VirtualMachine objects of newly created instance.
174
+ #
175
+ # See:
176
+ # http://msdn.microsoft.com/en-us/library/azure/jj157186.aspx
177
+ def add_role(params, options = {})
178
+ image = get_image(params[:image])
179
+ options[:os_type] = image.os_type
180
+ validate_deployment_params(params, options, true)
181
+ cloud_service = Azure::CloudServiceManagementService.new
182
+ cloud_service = cloud_service.get_cloud_service_properties(params[:cloud_service_name])
183
+ deployment_name = cloud_service.deployment_name
184
+ Azure::Loggerx.error_with_exit "Deployment doesn't exists." if cloud_service && deployment_name.empty?
185
+ others = {}
186
+ if cloud_service.location
187
+ others[:location] = cloud_service.location
188
+ elsif cloud_service.affinity_group
189
+ others[:affinity_group_name] = cloud_service.affinity_group
190
+ end
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...'
196
+ existing_ports = []
197
+ cloud_service.virtual_machines[deployment_name.to_sym].each do |vm|
198
+ vm.tcp_endpoints.each do |endpoint|
199
+ existing_ports << endpoint[:public_port]
200
+ end
201
+ end
202
+ options[:existing_ports] = existing_ports
203
+ body = Serialization.role_to_xml(params, image, options).to_xml
204
+ path = "/services/hostedservices/#{cloud_service.name}/deployments/#{deployment_name}/roles"
205
+ Azure::Loggerx.info 'Deployment in progress...'
206
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
207
+ request.call
208
+ get_virtual_machine(params[:vm_name], cloud_service.name)
209
+ end
210
+
211
+ # Public: Deletes the deployment, cloud service and disk.
212
+ #
213
+ # ==== Attributes
214
+ #
215
+ # * +vm_name+ - String. Virtual machine name.
216
+ # * +cloud_service_name+ - String. Cloud service name.
217
+ #
218
+ # See http://msdn.microsoft.com/en-us/library/azure/gg441305.aspx
219
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157179.aspx
220
+ #
221
+ # Returns NONE
222
+ def delete_virtual_machine(vm_name, cloud_service_name)
223
+ virtual_machines = list_virtual_machines(cloud_service_name)
224
+ vm = virtual_machines.select { |x| x.vm_name == vm_name }.first
225
+ if vm
226
+ if virtual_machines.size == 1
227
+ cloud_service = Azure::CloudServiceManagementService.new
228
+ cloud_service.delete_cloud_service_deployment(cloud_service_name)
229
+ cloud_service.delete_cloud_service(cloud_service_name)
230
+ else
231
+ path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm.vm_name}"
232
+ Azure::Loggerx.info "Deleting virtual machine #{vm_name}. \n"
233
+ request = BaseManagement::ManagementHttpRequest.new(:delete, path)
234
+ request.call
235
+ end
236
+ Azure::Loggerx.info "Waiting for disk to be released.\n"
237
+ disk_name = vm.disk_name
238
+ disk_management_service = VirtualMachineDiskManagementService.new
239
+ # Wait for 180s for disk to be released.
240
+ disk = nil
241
+ 18.times do
242
+ print '# '
243
+ disk = disk_management_service.get_virtual_machine_disk(disk_name)
244
+ unless disk.attached
245
+ print "Disk released.\n"
246
+ break
247
+ end
248
+ sleep 10
249
+ end
250
+ if disk.attached
251
+ Azure::Loggerx.error "\nCannot delete disk #{disk_name}."
252
+ else
253
+ disk_management_service.delete_virtual_machine_disk(disk_name)
254
+ end
255
+ else
256
+ Azure::Loggerx.error "Cannot find virtual machine #{vm_name} under cloud service #{cloud_service_name}"
257
+ end
258
+ rescue
259
+ end
260
+
261
+ # Public: Shuts down the specified virtual machine.
262
+ #
263
+ # ==== Attributes
264
+ #
265
+ # * +name+ - String. Virtual machine name.
266
+ # * +cloud_service_name+ - String. Cloud service name.
267
+ #
268
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157195.aspx
269
+ #
270
+ # Returns NONE
271
+ def shutdown_virtual_machine(vm_name, cloud_service_name)
272
+ vm = get_virtual_machine(vm_name, cloud_service_name)
273
+ if vm
274
+ if %w(StoppedVM StoppedDeallocated).include?(vm.status)
275
+ Azure::Loggerx.error 'Cannot perform the shutdown operation on a stopped virtual machine.'
276
+ elsif vm.deployment_status == 'Running'
277
+ path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
278
+ body = Serialization.shutdown_virtual_machine_to_xml
279
+ Azure::Loggerx.info "Shutting down virtual machine \"#{vm.vm_name}\" ..."
280
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
281
+ request.call
282
+ else
283
+ Azure::Loggerx.error 'Cannot perform the shutdown operation on a stopped deployment.'
284
+ end
285
+ else
286
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\". "
287
+ end
288
+ end
289
+
290
+ # Public: Starts the specified virtual machine.
291
+ #
292
+ # ==== Attributes
293
+ #
294
+ # * +name+ - String. Virtual machine name.
295
+ # * +cloud_service_name+ - String. Cloud service name.
296
+ #
297
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157189.aspx
298
+ #
299
+ # Returns NONE
300
+ def start_virtual_machine(vm_name, cloud_service_name)
301
+ vm = get_virtual_machine(vm_name, cloud_service_name)
302
+ if vm
303
+ if vm.status == 'ReadyRole'
304
+ Azure::Loggerx.error 'Cannot perform the start operation on started virtual machine.'
305
+ else
306
+ path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
307
+ body = Serialization.start_virtual_machine_to_xml
308
+ Azure::Loggerx.info "Starting virtual machine \"#{vm.vm_name}\" ..."
309
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
310
+ request.call
311
+ end
312
+ else
313
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
314
+ end
315
+ end
316
+
317
+ # Public: Restarts the specified virtual machine.
318
+ #
319
+ # ==== Attributes
320
+ #
321
+ # * +name+ - String. Virtual machine name.
322
+ # * +cloud_service_name+ - String. Cloud service name.
323
+ #
324
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157197.aspx
325
+ #
326
+ # Returns NONE
327
+ def restart_virtual_machine(vm_name, cloud_service_name)
328
+ vm = get_virtual_machine(vm_name, cloud_service_name)
329
+ if vm
330
+ path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
331
+ body = Serialization.restart_virtual_machine_to_xml
332
+ Azure::Loggerx.info "Restarting virtual machine \"#{vm.vm_name}\" ..."
333
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
334
+ request.call
335
+ else
336
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
337
+ end
338
+ end
339
+
340
+ # Public: Add/Update endpoints of virtual machine.
341
+ #
342
+ # ==== Attributes
343
+ #
344
+ # * +name+ - String. Virtual machine name.
345
+ # * +cloud_service_name+ - String. Cloud service name.
346
+ # * +input_endpoints+ - Hash. A hash of the name/value pairs for the endpoint.
347
+ #
348
+ # ==== Endpoint
349
+ #
350
+ # Accepted key/value pairs are:
351
+ # * +:local_port+ - String. Specifies the internal port on which the
352
+ # Virtual Machine is listening.
353
+ # * +:public_port+ - String. Specifies the external port to use for
354
+ # the endpoint.
355
+ # * +:name+ - String. Specifies the name of the external endpoint.
356
+ # * +load_balancer_name+ - String. Specifies a name for a set of
357
+ # load-balanced endpoints.
358
+ # * +:protocol+ - String. Specifies the transport protocol
359
+ # for the endpoint. Possible values are: TCP, UDP
360
+ # * +:direct_server_return+ - String. Specifies whether the endpoint
361
+ # uses Direct Server Return. Possible values are: true, false (optional)
362
+ # * +:load_balancer - Hash. Contains properties that define the
363
+ # endpoint settings that the load balancer uses to monitor the
364
+ # availability of the Virtual Machine (optional)
365
+ #
366
+ # === Load balancer
367
+ #
368
+ # Accepted key/value pairs are:
369
+ # * +:port+ - String. Specifies the internal port on which the
370
+ # Virtual Machine is listening.
371
+ # * +:protocol+ - String. Specifies the protocol to use to inspect the
372
+ # availability status of the virtual machine.
373
+ # * +:interval+ - String. Specifies the interval for the load balancer
374
+ # probe in seconds. (optional)
375
+ # * +:timeout+ - String. Specifies the timeout for the load balancer
376
+ # probe in seconds. (optional)
377
+ # * +:path+ - String. Specifies the relative path to inspect to
378
+ # determine the availability status of the Virtual Machine. (optional)
379
+ #
380
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157187.aspx
381
+ #
382
+ # Returns NONE
383
+ def update_endpoints(vm_name, cloud_service_name, *input_endpoints)
384
+ input_endpoints.flatten!
385
+ vm = get_virtual_machine(vm_name, cloud_service_name)
386
+ if vm
387
+ path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm_name}"
388
+ endpoints = vm.tcp_endpoints + vm.udp_endpoints
389
+ input_endpoints.each do |iep|
390
+ endpoints.delete_if { |ep| iep[:name].downcase == ep[:name].downcase }
391
+ end
392
+ endpoints += input_endpoints
393
+ body = Serialization.update_role_to_xml(endpoints, vm)
394
+ request = BaseManagement::ManagementHttpRequest.new(:put, path, body)
395
+ Azure::Loggerx.info "Updating endpoints of virtual machine #{vm.vm_name} ..."
396
+ request.call
397
+ else
398
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
399
+ end
400
+ end
401
+
402
+ # Public: Delete endpoint of virtual machine.
403
+ #
404
+ # ==== Attributes
405
+ #
406
+ # * +name+ - String. Virtual machine name.
407
+ # * +cloud_service_name+ - String. Cloud service name.
408
+ # * +endpoint_name+ - String. Name of endpoint.
409
+ #
410
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157187.aspx
411
+ #
412
+ # Returns NONE
413
+ def delete_endpoint(vm_name, cloud_service_name, endpoint_name)
414
+ vm = get_virtual_machine(vm_name, cloud_service_name)
415
+ if vm
416
+ path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm_name}"
417
+ endpoints = vm.tcp_endpoints + vm.udp_endpoints
418
+ endpoints.delete_if { |ep| endpoint_name.downcase == ep[:name].downcase }
419
+ body = Serialization.update_role_to_xml(endpoints, vm)
420
+ request = BaseManagement::ManagementHttpRequest.new(:put, path, body)
421
+ Azure::Loggerx.info "Deleting virtual machine endpoint #{endpoint_name} ..."
422
+ request.call
423
+ else
424
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
425
+ end
426
+ end
427
+
428
+ # Public: adds a data disk to a virtual machine.
429
+ #
430
+ # ==== Attributes
431
+ #
432
+ # * +cloud_service_name+ - String. Cloud service name.
433
+ # * +vm_name+ - String. Virtual machine name.
434
+ # * +options+ - Hash. Optional parameters.
435
+ #
436
+ # ==== Options
437
+ #
438
+ # Accepted key/value pairs in options parameter are:
439
+ # * +:import+ - Boolean. if true, then allows to use an existing
440
+ # disk by disk name. if false, then create and attach new data disk.
441
+ # * +:disk_name+ - String. Specifies the name of the disk.
442
+ # Reqruied if using existing disk.
443
+ # * +:host_caching+ - String. Specifies the caching behavior of data disk
444
+ # The default is ReadOnly. Possible values are: None, ReadOnly, ReadWrite
445
+ # * +:disk_label+ - String. Specifies the description of the data disk.
446
+ # * +:disk_size+ - String. Specifies the size of disk in GB
447
+ #
448
+ # See http://msdn.microsoft.com/en-us/library/azure/jj157199.aspx
449
+ #
450
+ # Returns None
451
+ def add_data_disk(vm_name, cloud_service_name, options = {})
452
+ options[:import] ||= false
453
+ vm = get_virtual_machine(vm_name, cloud_service_name)
454
+ if vm
455
+ path = "/services/hostedservices/#{cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm_name}/DataDisks"
456
+ body = Serialization.add_data_disk_to_xml(vm, options)
457
+ Azure::Loggerx.info "Adding data disk to virtual machine #{vm_name} ..."
458
+ request = BaseManagement::ManagementHttpRequest.new(:post, path, body)
459
+ request.call
460
+ else
461
+ Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
462
+ end
463
+ end
464
+
465
+ private
466
+
467
+ # Private: Gets the operating system type of an image.
468
+ #
469
+ # Returns Linux or Windows
470
+ def get_image(image_name)
471
+ image_service = Azure::VirtualMachineImageManagementService.new
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
475
+ end
476
+
477
+ def generate_cloud_service_name(vm_name)
478
+ random_string(vm_name + '-service-')
479
+ end
480
+
481
+ def generate_storage_account_name(vm_name)
482
+ random_string(vm_name + 'storage').gsub(/[^0-9a-z ]/i, '').downcase[0..23]
483
+ end
484
+
485
+ def validate_deployment_params(params, options, add_role = false)
486
+ errors = []
487
+ params_keys = %w(vm_name image vm_user)
488
+ params_keys += ['password'] if options[:os_type] == 'Windows'
489
+ options_keys = []
490
+ options_keys = %w(private_key_file) if certificate_required?(params, options)
491
+ if add_role
492
+ params_keys += ['cloud_service_name']
493
+ else
494
+ params_keys += ['location']
495
+ end
496
+ params_keys.each do |key|
497
+ errors << key if params[key.to_sym].nil?
498
+ end
499
+
500
+ options_keys.each do |key|
501
+ errors << key if options[key.to_sym].nil?
502
+ end
503
+
504
+ if errors.empty?
505
+ validate_location(params[:location]) unless add_role
506
+ validate_role_size(options[:vm_size])
507
+ params[:certificate] = {}
508
+ if certificate_required?(params, options)
509
+ begin
510
+ params[:certificate][:key] = OpenSSL::PKey.read File.read(options[:private_key_file])
511
+ params[:certificate][:cert] = get_certificate(options[:private_key_file])
512
+ params[:certificate][:fingerprint] = export_fingerprint(params[:certificate][:cert])
513
+ rescue Exception => e
514
+ Azure::Loggerx.error_with_exit e.message
515
+ end
516
+ end
517
+ else
518
+ Azure::Loggerx.error_with_exit "You did not provide a valid '#{errors.uniq.join(", ")}' value."
519
+ end
520
+ end
521
+
522
+ def certificate_required?(params, options)
523
+ if options[:os_type] == 'Linux'
524
+ params[:password].nil?
525
+ else
526
+ winrm_with_https(options)
527
+ end
528
+ end
529
+
530
+ def winrm_with_https(options)
531
+ if options[:os_type] == 'Windows'
532
+ options[:winrm_transport] && options[:winrm_transport].include?('https') && options[:private_key_file]
533
+ end
534
+ end
535
+
536
+ def validate_role_size(vm_size)
537
+ suggested_role_sizes = Azure::BaseManagementService.new.list_role_sizes
538
+ if vm_size && !suggested_role_sizes.include?(vm_size)
539
+ 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(',')}'"
540
+ end
541
+ end
542
+
543
+ def validate_location(location_name)
544
+ locations = Azure::BaseManagementService.new.list_locations
545
+ location = locations.select { |loc| loc.name.downcase == location_name.downcase }.first
546
+ if location.nil?
547
+ Azure::Loggerx.error_with_exit "Value '#{location_name}' specified for parameter 'location' is invalid. Allowed values are #{locations.map(&:name).join(',')}"
548
+ elsif !location.available_services.include?('PersistentVMRole')
549
+ Azure::Loggerx.error_with_exit "Persistentvmrole not enabled for \"#{location.name}\". Try different location"
550
+ end
551
+ end
552
+ end
553
+ end
554
+ end