azure-armrest 0.0.3 → 0.0.4
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/CHANGES +19 -0
- data/azure-armrest.gemspec +10 -7
- data/lib/azure/armrest.rb +2 -1
- data/lib/azure/armrest/armrest_service.rb +84 -25
- data/lib/azure/armrest/availability_set_service.rb +6 -82
- data/lib/azure/armrest/exception.rb +45 -0
- data/lib/azure/armrest/model/base_model.rb +54 -31
- data/lib/azure/armrest/model/storage_account.rb +140 -0
- data/lib/azure/armrest/network/ip_address_service.rb +5 -82
- data/lib/azure/armrest/network/network_interface_service.rb +3 -110
- data/lib/azure/armrest/network/network_security_group_service.rb +3 -82
- data/lib/azure/armrest/network/subnet_service.rb +14 -29
- data/lib/azure/armrest/network/virtual_network_service.rb +3 -100
- data/lib/azure/armrest/resource_group_based_service.rb +94 -0
- data/lib/azure/armrest/resource_group_service.rb +3 -3
- data/lib/azure/armrest/resource_provider_service.rb +4 -4
- data/lib/azure/armrest/resource_service.rb +1 -1
- data/lib/azure/armrest/storage_account_service.rb +35 -139
- data/lib/azure/armrest/template_deployment_service.rb +34 -87
- data/lib/azure/armrest/version.rb +1 -1
- data/lib/azure/armrest/virtual_machine_extension_service.rb +109 -35
- data/lib/azure/armrest/virtual_machine_service.rb +30 -187
- metadata +51 -6
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'azure-signature'
|
2
|
+
|
1
3
|
module Azure
|
2
4
|
module Armrest
|
3
5
|
# Class for managing storage accounts.
|
4
|
-
class StorageAccountService <
|
6
|
+
class StorageAccountService < ResourceGroupBasedService
|
5
7
|
|
6
8
|
# Valid account types for the create or update method.
|
7
9
|
VALID_ACCOUNT_TYPES = %w[
|
@@ -18,86 +20,24 @@ module Azure
|
|
18
20
|
@provider = options[:provider] || 'Microsoft.Storage'
|
19
21
|
#set_service_api_version(options, 'storageAccounts')
|
20
22
|
@api_version = '2015-05-01-preview' # Must hard code for now
|
23
|
+
@service_name = 'storageAccounts'
|
21
24
|
end
|
22
25
|
|
23
|
-
# Return information for the given storage account name for the
|
24
|
-
# provided +group+. If no group is specified, it will use the
|
25
|
-
# group set in the constructor.
|
26
|
-
#
|
27
|
-
# If the +include_keys+ option is set to true, then the keys for that
|
28
|
-
# storage account will be included in the output as well.
|
29
|
-
#
|
30
|
-
# Example:
|
31
|
-
#
|
32
|
-
# sas.get('portalvhds1234', 'Default-Storage-CentralUS')
|
33
|
-
#
|
34
|
-
def get(account_name, group = armrest_configuration.resource_group, include_keys = false)
|
35
|
-
raise ArgumentError, "must specify resource group" unless group
|
36
|
-
|
37
|
-
url = build_url(group, account_name)
|
38
|
-
results = JSON.parse(rest_get(url))
|
39
|
-
results['properties'].merge!(list_account_keys(account_name, group)) if include_keys
|
40
|
-
|
41
|
-
results
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns a list of available storage accounts for the given subscription
|
45
|
-
# for the provided +group+, or all resource groups if none is provided.
|
46
|
-
#
|
47
|
-
def list(group = nil)
|
48
|
-
if group
|
49
|
-
url = build_url(group)
|
50
|
-
JSON.parse(rest_get(url))['value']
|
51
|
-
else
|
52
|
-
array = []
|
53
|
-
threads = []
|
54
|
-
mutex = Mutex.new
|
55
|
-
|
56
|
-
resource_groups.each do |rg|
|
57
|
-
threads << Thread.new(rg['name']) do |group|
|
58
|
-
url = build_url(group)
|
59
|
-
response = rest_get(url)
|
60
|
-
results = JSON.parse(response)['value']
|
61
|
-
if results && !results.empty?
|
62
|
-
mutex.synchronize{
|
63
|
-
results.each{ |hash| hash['resourceGroup'] = group }
|
64
|
-
array << results
|
65
|
-
}
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
threads.each(&:join)
|
71
|
-
|
72
|
-
array.flatten
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# List all storage accounts for the current subscription. This does not
|
77
|
-
# include storage account key information.
|
78
|
-
#
|
79
|
-
def list_all_for_subscription
|
80
|
-
sub_id = armrest_configuration.subscription_id
|
81
|
-
url = File.join(Azure::Armrest::COMMON_URI, sub_id, 'providers', @provider, 'storageAccounts')
|
82
|
-
url << "?api-version=#{@api_version}"
|
83
|
-
JSON.parse(rest_get(url))
|
84
|
-
end
|
85
|
-
|
86
|
-
alias list_all list_all_for_subscription
|
87
|
-
|
88
26
|
# Creates a new storage account, or updates an existing account with the
|
89
|
-
# specified parameters.
|
27
|
+
# specified parameters.
|
90
28
|
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
29
|
+
# Note that the name of the storage account within the specified
|
30
|
+
# must be 3-24 alphanumeric lowercase characters.
|
31
|
+
#
|
32
|
+
# The options available are as follows:
|
94
33
|
#
|
95
34
|
# - :validating
|
96
35
|
# Optional. Set to 'nameAvailability' to indicate that the account
|
97
36
|
# name must be checked for global availability.
|
98
37
|
#
|
99
|
-
# - :
|
100
|
-
#
|
38
|
+
# - :properties
|
39
|
+
# - :accountType
|
40
|
+
# The type of storage account, e.g. "Standard_GRS".
|
101
41
|
#
|
102
42
|
# - :location
|
103
43
|
# Required: One of the Azure geo regions, e.g. 'West US'.
|
@@ -111,60 +51,28 @@ module Azure
|
|
111
51
|
#
|
112
52
|
# sas = Azure::Armrest::StorageAccountService(config)
|
113
53
|
#
|
114
|
-
# sas.create(
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
54
|
+
# sas.create("yourstorageaccount1",
|
55
|
+
# {
|
56
|
+
# :location => "West US",
|
57
|
+
# :properties => {:accountType => "Standard_ZRS"},
|
58
|
+
# :tags => {:YourCompany => true}
|
59
|
+
# },
|
60
|
+
# "yourresourcegroup"
|
119
61
|
# )
|
120
62
|
#
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
raise ArgumentError, "No resource group specified" if rgroup.nil?
|
126
|
-
|
127
|
-
# Mandatory options
|
128
|
-
name = options.fetch(:name)
|
129
|
-
location = options.fetch(:location)
|
130
|
-
|
131
|
-
# Optional
|
132
|
-
tags = options[:tags]
|
133
|
-
type = options[:type] || "Standard_GRS"
|
134
|
-
|
135
|
-
properties = {:accountType => type}
|
136
|
-
|
137
|
-
validate_account_type(type)
|
138
|
-
validate_account_name(name)
|
63
|
+
def create(account_name, rgroup = armrest_configuration.resource_group, options)
|
64
|
+
validating = options.delete(:validating)
|
65
|
+
validate_account_type(options[:properties][:accountType])
|
66
|
+
validate_account_name(account_name)
|
139
67
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
body = {
|
144
|
-
:name => name,
|
145
|
-
:location => location,
|
146
|
-
:tags => tags,
|
147
|
-
:properties => properties
|
148
|
-
}.to_json
|
149
|
-
|
150
|
-
response = rest_put(url, body)
|
151
|
-
response.return!
|
68
|
+
super(account_name, rgroup, options) do |url|
|
69
|
+
url << "&validating=" << validating if validating
|
70
|
+
end
|
152
71
|
end
|
153
72
|
|
154
|
-
alias update create
|
155
|
-
|
156
|
-
# Delete the given storage account name.
|
157
|
-
#
|
158
|
-
def delete(account_name, group = armrest_configuration.resource_group)
|
159
|
-
raise ArgumentError, "must specify resource group" unless group
|
160
|
-
|
161
|
-
url = build_url(group, account_name)
|
162
|
-
response = rest_delete(url)
|
163
|
-
response.return!
|
164
|
-
end
|
165
73
|
|
166
74
|
# Returns the primary and secondary access keys for the given
|
167
|
-
# storage account.
|
75
|
+
# storage account as a hash.
|
168
76
|
#
|
169
77
|
def list_account_keys(account_name, group = armrest_configuration.resource_group)
|
170
78
|
raise ArgumentError, "must specify resource group" unless group
|
@@ -177,12 +85,17 @@ module Azure
|
|
177
85
|
# Regenerates the primary and secondary access keys for the given
|
178
86
|
# storage account.
|
179
87
|
#
|
180
|
-
|
88
|
+
# options have only one key with two possible values:
|
89
|
+
# {
|
90
|
+
# "keyName": "key1|key2"
|
91
|
+
# }
|
92
|
+
#
|
93
|
+
def regenerate_storage_account_keys(account_name, group = armrest_configuration.resource_group, options)
|
181
94
|
raise ArgumentError, "must specify resource group" unless group
|
182
95
|
|
183
96
|
url = build_url(group, account_name, 'regenerateKey')
|
184
|
-
response = rest_post(url)
|
185
|
-
response
|
97
|
+
response = rest_post(url, options.to_json)
|
98
|
+
JSON.parse(response)
|
186
99
|
end
|
187
100
|
|
188
101
|
private
|
@@ -198,23 +111,6 @@ module Azure
|
|
198
111
|
raise ArgumentError, "name must be 3-24 alpha-numeric characters only"
|
199
112
|
end
|
200
113
|
end
|
201
|
-
|
202
|
-
# Builds a URL based on subscription_id an resource_group and any other
|
203
|
-
# arguments provided, and appends it with the api-version.
|
204
|
-
def build_url(resource_group, *args)
|
205
|
-
url = File.join(
|
206
|
-
Azure::Armrest::COMMON_URI,
|
207
|
-
armrest_configuration.subscription_id,
|
208
|
-
'resourceGroups',
|
209
|
-
resource_group,
|
210
|
-
'providers',
|
211
|
-
@provider,
|
212
|
-
'storageAccounts',
|
213
|
-
)
|
214
|
-
|
215
|
-
url = File.join(url, *args) unless args.empty?
|
216
|
-
url << "?api-version=#{@api_version}"
|
217
|
-
end
|
218
114
|
end
|
219
115
|
end
|
220
116
|
end
|
@@ -1,97 +1,44 @@
|
|
1
1
|
module Azure::Armrest
|
2
|
-
# Base class for managing templates and deployments
|
3
|
-
class TemplateDeploymentService <
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# Get names of all deployments in a resource group
|
13
|
-
def list_names(resource_group = armrest_configuration.resource_group)
|
14
|
-
list(resource_group).map {|e| e['name']}
|
15
|
-
end
|
16
|
-
|
17
|
-
# Get all deployments in a resource group
|
18
|
-
# If the resource group is nil, then return deployments in all groups
|
19
|
-
def list(resource_group = armrest_configuration.resource_group)
|
20
|
-
if resource_group
|
21
|
-
url = build_deployment_url(resource_group)
|
22
|
-
JSON.parse(rest_get(url))['value']
|
23
|
-
else
|
24
|
-
threads = []
|
25
|
-
array = []
|
26
|
-
mutex = Mutex.new
|
27
|
-
|
28
|
-
resource_groups.each do |rg|
|
29
|
-
threads << Thread.new(rg['name']) do |group|
|
30
|
-
url = build_deployment_url(group)
|
31
|
-
results = JSON.parse(rest_get(url))['value']
|
32
|
-
if results && !results.empty?
|
33
|
-
mutex.synchronize {
|
34
|
-
results.each { |hash| hash['resourceGroup'] = group }
|
35
|
-
array << results
|
36
|
-
}
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
threads.each(&:join)
|
42
|
-
array.flatten
|
2
|
+
# Base class for managing templates and deployments
|
3
|
+
class TemplateDeploymentService < ResourceGroupBasedService
|
4
|
+
|
5
|
+
def initialize(_armrest_configuration, options = {})
|
6
|
+
super
|
7
|
+
@provider = options[:provider] || 'Microsoft.Resources'
|
8
|
+
# Has to be hard coded for now
|
9
|
+
set_service_api_version({'api_version' => '2014-04-01-preview'}, '')
|
10
|
+
@service_name = 'deployments'
|
43
11
|
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Get the deployment in a resource group
|
47
|
-
def get(deploy_name, resource_group = armrest_configuration.resource_group)
|
48
|
-
url = build_deployment_url(resource_group, deploy_name)
|
49
|
-
JSON.parse(rest_get(url))
|
50
|
-
end
|
51
12
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
# Get the operation of a deployment in a resource group
|
59
|
-
def get_deployment_operation(deploy_name, op_id, resource_group = armrest_configuration.resource_group)
|
60
|
-
url = build_deployment_url(resource_group, deploy_name, 'operations', op_id)
|
61
|
-
JSON.parse(rest_get(url))
|
62
|
-
end
|
63
|
-
|
64
|
-
# Create a template deployment
|
65
|
-
# The template and parameters should be provided through the options hash
|
66
|
-
def create(deploy_name, options, resource_group = armrest_configuration.resource_group)
|
67
|
-
url = build_deployment_url(resource_group, deploy_name)
|
68
|
-
body = options.has_key?('properties') ? options.to_json : {'properties' => options}.to_json
|
69
|
-
JSON.parse(rest_put(url, body))
|
70
|
-
end
|
13
|
+
# Get names of all deployments in a resource group
|
14
|
+
def list_names(resource_group = armrest_configuration.resource_group)
|
15
|
+
list(resource_group).map(&:name)
|
16
|
+
end
|
71
17
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
18
|
+
# Get all deployments for the current subscription
|
19
|
+
def list_all
|
20
|
+
list_in_all_groups
|
21
|
+
end
|
77
22
|
|
78
|
-
|
23
|
+
# Get all operations of a deployment in a resource group
|
24
|
+
def list_deployment_operations(deploy_name, resource_group = armrest_configuration.resource_group)
|
25
|
+
raise ArgumentError, "must specify resource group" unless resource_group
|
26
|
+
raise ArgumentError, "must specify name of the resource" unless deploy_name
|
79
27
|
|
28
|
+
url = build_url(resource_group, deploy_name, 'operations')
|
29
|
+
response = rest_get(url)
|
30
|
+
JSON.parse(response)['value'].map{ |hash| TemplateDeploymentOperation.new(hash) }
|
31
|
+
end
|
80
32
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
Azure::Armrest::COMMON_URI,
|
87
|
-
armrest_configuration.subscription_id,
|
88
|
-
'resourceGroups',
|
89
|
-
resource_group,
|
90
|
-
'deployments',
|
91
|
-
)
|
33
|
+
# Get the operation of a deployment in a resource group
|
34
|
+
def get_deployment_operation(op_id, deploy_name, resource_group = armrest_configuration.resource_group)
|
35
|
+
raise ArgumentError, "must specify resource group" unless resource_group
|
36
|
+
raise ArgumentError, "must specify name of the resource" unless deploy_name
|
37
|
+
raise ArgumentError, "must specify operation id" unless op_id
|
92
38
|
|
93
|
-
|
94
|
-
|
39
|
+
url = build_url(resource_group, deploy_name, 'operations', op_id)
|
40
|
+
response = rest_get(url)
|
41
|
+
TemplateDeploymentOperation.new(response)
|
42
|
+
end
|
95
43
|
end
|
96
44
|
end
|
97
|
-
end
|
@@ -5,58 +5,132 @@ module Azure
|
|
5
5
|
# Base class for managing virtual machine extensions
|
6
6
|
class VirtualMachineExtensionService < VirtualMachineService
|
7
7
|
|
8
|
-
|
8
|
+
# Creates and returns a new VirtualMachineExtensionService object.
|
9
|
+
#
|
10
|
+
def initialize(_armrest_configuration, options = {})
|
9
11
|
super
|
12
|
+
@provider = options[:provider] || 'Microsoft.Compute'
|
13
|
+
set_service_api_version(options, 'virtualMachines/extensions')
|
10
14
|
end
|
11
15
|
|
12
|
-
# Creates a new
|
13
|
-
#
|
16
|
+
# Creates a new extension for the provided VM with the given +options+.
|
17
|
+
# The possible options are:
|
18
|
+
#
|
19
|
+
# - :location - The location for the extension. Mandatory.
|
20
|
+
# - :type - The type of compute resource. The default is "Microsoft.Compute/virtualMachines/extensions".
|
21
|
+
# - :tags - A list of key value pairs. Max 10 pairs. Optional.
|
22
|
+
# - :properties
|
23
|
+
# - :type - The type of extension. Required.
|
24
|
+
# - :publisher - Name of extension publisher. Default is the provider.
|
25
|
+
# - :typeHandlerVersion - Optional. Specifies the extension version. Default is "1.*".
|
26
|
+
# - :settings - Public configuration that does not require encryption. Optional.
|
27
|
+
# - :fileUris - The script file path.
|
28
|
+
# - :commandToExecute - The command used to execute the script.
|
14
29
|
#
|
15
|
-
#
|
16
|
-
# :publisher - Required. Name of extension publisher.
|
17
|
-
# :type - Required. The type of extension.
|
18
|
-
# :type_handler_version - Required. Specifies the extension version.
|
19
|
-
# :settings - Optional. Public configuration that does not require encryption.
|
20
|
-
# :protected_settings - Optional. Private configuration that is encrypted.
|
30
|
+
# For convenience, you may also specify a :resource_group as an option.
|
21
31
|
#
|
22
|
-
def create(
|
23
|
-
|
24
|
-
|
25
|
-
|
32
|
+
def create(vm_name, ext_name, options = {}, rgroup = nil)
|
33
|
+
rgroup ||= options.delete(:resource_group) || armrest_configuration.resource_group
|
34
|
+
|
35
|
+
raise ArgumentError, "no resource group provided" unless rgroup
|
26
36
|
|
27
|
-
|
28
|
-
|
37
|
+
# Optional params with defaults
|
38
|
+
options[:type] ||= "Microsoft.Compute/virtualMachines/extensions"
|
39
|
+
options[:name] ||= ext_name
|
40
|
+
options[:properties][:publisher] ||= @provider
|
41
|
+
options[:properties][:typeHandlerVersion] ||= "1.*"
|
42
|
+
|
43
|
+
url = build_url(rgroup, vm_name, ext_name)
|
44
|
+
body = options.to_json
|
45
|
+
|
46
|
+
response = rest_put(url, body)
|
47
|
+
response.return!
|
29
48
|
end
|
30
49
|
|
31
50
|
alias update create
|
32
51
|
|
33
|
-
# Delete the given
|
34
|
-
#--
|
35
|
-
# DELETE
|
52
|
+
# Delete the given extension for the provided VM and resource group.
|
36
53
|
#
|
37
|
-
def delete(
|
38
|
-
|
39
|
-
url
|
54
|
+
def delete(vm_name, ext_name, rgroup = armrest_configuration.resource_group)
|
55
|
+
raise ArgumentError, "no resource group provided" unless rgroup
|
56
|
+
url = build_url(rgroup, vm_name, ext_name)
|
57
|
+
response = rest_delete(url)
|
58
|
+
response.return!
|
59
|
+
end
|
60
|
+
|
61
|
+
# Retrieves the settings of an extension for the provided VM.
|
62
|
+
# If the +instance_view+ option is true, it will retrieve instance
|
63
|
+
# view information instead.
|
64
|
+
#
|
65
|
+
def get(vm_name, ext_name, rgroup = armrest_configuration.resource_group, instance_view = false)
|
66
|
+
raise ArgumentError, "no resource group provided" unless rgroup
|
67
|
+
url = build_url(rgroup, vm_name, ext_name)
|
68
|
+
url << "&expand=instanceView" if instance_view
|
69
|
+
response = rest_get(url)
|
70
|
+
Azure::Armrest::VirtualMachineExtension.new(response)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Shortcut to get an extension in model view.
|
74
|
+
def get_model_view(vm_name, ext_name, rgroup = armrest_configuration.resource_group)
|
75
|
+
raise ArgumentError, "no resource group provided" unless rgroup
|
76
|
+
get(vm_name, ext_name, rgroup, false)
|
40
77
|
end
|
41
78
|
|
42
|
-
#
|
43
|
-
|
79
|
+
# Shortcut to get an extension in instance view.
|
80
|
+
def get_instance_view(vm_name, ext_name, rgroup = armrest_configuration.resource_group)
|
81
|
+
raise ArgumentError, "no resource group provided" unless rgroup
|
82
|
+
get(vm_name, ext_name, rgroup, true)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Retrieves a list of extensions on the VM in the provided resource group.
|
86
|
+
# If the +instance_view+ option is true, it will retrieve a list of instance
|
87
|
+
# view information instead.
|
88
|
+
#
|
89
|
+
# NOTE: As of August 2015, this is not currently supported because the
|
90
|
+
# MS SDK does not support it.
|
44
91
|
#--
|
45
|
-
#
|
92
|
+
# BUG: https://github.com/Azure/azure-xplat-cli/issues/1826
|
46
93
|
#
|
47
|
-
def
|
48
|
-
|
49
|
-
url
|
50
|
-
url
|
51
|
-
url
|
94
|
+
def list(vm_name, rgroup = armrest_configuration.resource_group, instance_view = false)
|
95
|
+
raise ArgumentError, "no resource group provided" unless rgroup
|
96
|
+
url = build_url(rgroup, vm_name)
|
97
|
+
url << "&expand=instanceView" if instance_view
|
98
|
+
response = rest_get(url)
|
99
|
+
JSON.parse(response)['value'].map{ |hash| Azure::Armrest::VirtualMachineExtension.new(hash) }
|
100
|
+
end
|
101
|
+
|
102
|
+
# Shortcut to get a list in model view.
|
103
|
+
def list_model_view(vmname, rgroup = armrest_configuration.resource_group)
|
104
|
+
raise ArgumentError, "no resource group provided" unless rgroup
|
105
|
+
list(vmname, false, rgroup)
|
52
106
|
end
|
53
107
|
|
54
|
-
#
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
108
|
+
# Shortcut to get a list in instance view.
|
109
|
+
def list_instance_view(vmname, rgroup = armrest_configuration.resource_group)
|
110
|
+
raise ArgumentError, "no resource group provided" unless rgroup
|
111
|
+
list(vmname, true, rgroup)
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
# Builds a URL based on subscription_id an resource_group and any other
|
117
|
+
# arguments provided, and appends it with the api_version.
|
118
|
+
#
|
119
|
+
def build_url(resource_group, vm, *args)
|
120
|
+
url = File.join(
|
121
|
+
Azure::Armrest::COMMON_URI,
|
122
|
+
armrest_configuration.subscription_id,
|
123
|
+
'resourceGroups',
|
124
|
+
resource_group,
|
125
|
+
'providers',
|
126
|
+
@provider,
|
127
|
+
'virtualMachines',
|
128
|
+
vm,
|
129
|
+
'extensions'
|
130
|
+
)
|
131
|
+
|
132
|
+
url = File.join(url, *args) unless args.empty?
|
133
|
+
url << "?api-version=#{@api_version}"
|
60
134
|
end
|
61
135
|
end
|
62
136
|
end
|