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