azure-armrest 0.3.11 → 0.3.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +9 -0
- data/lib/azure/armrest.rb +1 -0
- data/lib/azure/armrest/armrest_service.rb +3 -0
- data/lib/azure/armrest/insights/diagnostic_service.rb +96 -0
- data/lib/azure/armrest/model/base_model.rb +1 -0
- data/lib/azure/armrest/model/storage_account.rb +1 -1
- data/lib/azure/armrest/storage_account_service.rb +39 -2
- data/lib/azure/armrest/version.rb +1 -1
- data/lib/azure/armrest/virtual_machine_service.rb +170 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5022f64bbe2cfc12d269a9b1ef34eda423076aff
|
4
|
+
data.tar.gz: 86f456d2c2e7eb2724599da6d2239f3dc1839e7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 516af488cfffe832df8e468c19201ab59253130023d0eddc1c0bba2dbe6ddb269b51ff781f5218c6090a37450d8d057f5ccf0083b737941c2830e67988a32f2b
|
7
|
+
data.tar.gz: 2ef615e16a7809c5418becdcf17439c9303a3f05119c2a26925319ba16194f028e7599537fb4c940b6a29d0b3833e24a89e05d2aff67fb09f11ae58c978fd16e
|
data/CHANGES
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
= 0.3.12 - 15-Nov-2016
|
2
|
+
* Added the Insights::DiagnosticService class.
|
3
|
+
* Added the get_from_vm and get_os_disk methods to StorageAccountService.
|
4
|
+
* Added the delete_associated_resources method to VirtualMachineService.
|
5
|
+
* The output of StorageAccount#blob_properties method now includes the blob
|
6
|
+
name and the container name.
|
7
|
+
* Added a service_name accessor to the ArmrestService base class.
|
8
|
+
* The list_all method in StorageAccountService now supports a filter.
|
9
|
+
|
1
10
|
= 0.3.11 - 8-Nov-2016
|
2
11
|
* Fixed the regex for the internal method parse_id_string, making the
|
3
12
|
get_associated_resource method more robust.
|
data/lib/azure/armrest.rb
CHANGED
@@ -39,6 +39,7 @@ require 'azure/armrest/resource_service'
|
|
39
39
|
require 'azure/armrest/resource_group_service'
|
40
40
|
require 'azure/armrest/resource_provider_service'
|
41
41
|
require 'azure/armrest/insights/alert_service'
|
42
|
+
require 'azure/armrest/insights/diagnostic_service'
|
42
43
|
require 'azure/armrest/insights/event_service'
|
43
44
|
require 'azure/armrest/insights/metrics_service'
|
44
45
|
require 'azure/armrest/network/load_balancer_service'
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Azure
|
2
|
+
module Armrest
|
3
|
+
module Insights
|
4
|
+
# Base class for managing diagnostics
|
5
|
+
class DiagnosticService < ArmrestService
|
6
|
+
def initialize(armrest_configuration, options = {})
|
7
|
+
super(armrest_configuration, 'diagnosticSettings', 'Microsoft.Insights', options)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Get diagnostic information for the given +resource_id+. Note that
|
11
|
+
# this information is only available for a limited subset of resources.
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
#
|
15
|
+
# ids = Azure::Armrest::Insights::DiagnosticService.new(config)
|
16
|
+
# nsg = Azure::Armrest::Network::NetworkSecurityGroupService.new(config)
|
17
|
+
#
|
18
|
+
# sgrp = nsg.get(your_security_group, your_resource_group)
|
19
|
+
# p ids.get(sgrp.id)
|
20
|
+
#
|
21
|
+
def get(resource_id)
|
22
|
+
url = build_url(resource_id)
|
23
|
+
response = rest_get(url)
|
24
|
+
Diagnostic.new(JSON.parse(response))
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create or update a diagnostic setting for the given +resource_id+.
|
28
|
+
#
|
29
|
+
# Example:
|
30
|
+
#
|
31
|
+
# # Update network security group log settings
|
32
|
+
# ids = Azure::Armrest::Insights::DiagnosticService.new(config)
|
33
|
+
# sas = Azure::Armrest::StorageAccountService.new(config)
|
34
|
+
# nsg = Azure::Armrest::Network::NetworkSecurityGroupService.new(config)
|
35
|
+
#
|
36
|
+
# acct = sas.get(your_storage, your_resource_group)
|
37
|
+
# sgrp = nsg.get(your_network_security_group, your_resource_group)
|
38
|
+
#
|
39
|
+
# options = {
|
40
|
+
# :properties => {
|
41
|
+
# :storageAccountId => acct.id,
|
42
|
+
# :logs => [
|
43
|
+
# {
|
44
|
+
# :category => "NetworkSecurityGroupEvent",
|
45
|
+
# :enabled => true,
|
46
|
+
# :retentionPolicy => {
|
47
|
+
# :enabled => true,
|
48
|
+
# :days => 3
|
49
|
+
# }
|
50
|
+
# },
|
51
|
+
# {
|
52
|
+
# :category => "NetworkSecurityGroupRuleCounter",
|
53
|
+
# :enabled => true,
|
54
|
+
# :retentionPolicy => {
|
55
|
+
# :enabled => true,
|
56
|
+
# :days => 3
|
57
|
+
# }
|
58
|
+
# }
|
59
|
+
# ]
|
60
|
+
# }
|
61
|
+
# }
|
62
|
+
#
|
63
|
+
# ids.set(sgrp.id, options)
|
64
|
+
#
|
65
|
+
def create(resource_id, options = {})
|
66
|
+
url = build_url(resource_id)
|
67
|
+
body = options.merge(:id => resource_id).to_json
|
68
|
+
response = rest_put(url, body)
|
69
|
+
|
70
|
+
headers = Azure::Armrest::ResponseHeaders.new(response.headers)
|
71
|
+
headers.response_code = response.code
|
72
|
+
|
73
|
+
headers
|
74
|
+
end
|
75
|
+
|
76
|
+
alias update create
|
77
|
+
alias set create
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def build_url(resource_id)
|
82
|
+
url = File.join(
|
83
|
+
Azure::Armrest::RESOURCE,
|
84
|
+
resource_id,
|
85
|
+
'providers',
|
86
|
+
provider,
|
87
|
+
'diagnosticSettings',
|
88
|
+
'service'
|
89
|
+
)
|
90
|
+
|
91
|
+
url + "?api-version=#{api_version}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -214,7 +214,7 @@ module Azure
|
|
214
214
|
:ssl_verify => ssl_verify
|
215
215
|
)
|
216
216
|
|
217
|
-
BlobProperty.new(response.headers)
|
217
|
+
BlobProperty.new(response.headers.merge(:container => container, :name => blob))
|
218
218
|
end
|
219
219
|
|
220
220
|
# Return a list of blobs for the given +container+ using the given +key+
|
@@ -32,8 +32,8 @@ module Azure
|
|
32
32
|
|
33
33
|
# Same as other resource based list_all methods, but also sets the proxy on each model object.
|
34
34
|
#
|
35
|
-
def list_all
|
36
|
-
super.each do |m|
|
35
|
+
def list_all(filter = {})
|
36
|
+
super(filter).each do |m|
|
37
37
|
m.proxy = configuration.proxy
|
38
38
|
m.ssl_version = configuration.ssl_version
|
39
39
|
m.ssl_verify = configuration.ssl_verify
|
@@ -203,6 +203,43 @@ module Azure
|
|
203
203
|
get_private_images(storage_accounts)
|
204
204
|
end
|
205
205
|
|
206
|
+
# Return the storage account for the virtual machine model +vm+.
|
207
|
+
#
|
208
|
+
def get_from_vm(vm)
|
209
|
+
uri = Addressable::URI.parse(vm.properties.storage_profile.os_disk.vhd.uri)
|
210
|
+
|
211
|
+
# The uri looks like https://foo123.blob.core.windows.net/vhds/something123.vhd
|
212
|
+
name = uri.host.split('.').first # storage name, e.g. 'foo123'
|
213
|
+
|
214
|
+
# Look for the storage account in the VM's resource group first. If
|
215
|
+
# it's not found, look through all the storage accounts.
|
216
|
+
begin
|
217
|
+
acct = get(name, vm.resource_group)
|
218
|
+
rescue Azure::Armrest::NotFoundException => err
|
219
|
+
acct = list_all(:name => name).first
|
220
|
+
raise err unless acct
|
221
|
+
end
|
222
|
+
|
223
|
+
acct
|
224
|
+
end
|
225
|
+
|
226
|
+
# Get information for the underlying VHD file based on the properties
|
227
|
+
# of the virtual machine model +vm+.
|
228
|
+
#
|
229
|
+
def get_os_disk(vm)
|
230
|
+
uri = Addressable::URI.parse(vm.properties.storage_profile.os_disk.vhd.uri)
|
231
|
+
|
232
|
+
# The uri looks like https://foo123.blob.core.windows.net/vhds/something123.vhd
|
233
|
+
disk = File.basename(uri.to_s) # disk name, e.g. 'something123.vhd'
|
234
|
+
path = File.dirname(uri.path)[1..-1] # container, e.g. 'vhds'
|
235
|
+
|
236
|
+
acct = get_from_vm(vm)
|
237
|
+
keys = list_account_keys(acct.name, acct.resource_group)
|
238
|
+
key = keys['key1'] || keys['key2']
|
239
|
+
|
240
|
+
acct.blob_properties(path, disk, key)
|
241
|
+
end
|
242
|
+
|
206
243
|
def accounts_by_name
|
207
244
|
@accounts_by_name ||= list_all.each_with_object({}) { |sa, sah| sah[sa.name] = sa }
|
208
245
|
end
|
@@ -121,12 +121,173 @@ module Azure
|
|
121
121
|
vm_operate('powerOff', vmname, group)
|
122
122
|
end
|
123
123
|
|
124
|
+
# Delete the VM and associated resources. By default, this will
|
125
|
+
# delete the VM, its NIC, the associated IP address, and the
|
126
|
+
# image files (.vhd and .status) for the VM.
|
127
|
+
#
|
128
|
+
# If you want to delete other associated resources, such as any
|
129
|
+
# attached disks, the VM's underlying storage account, or associated
|
130
|
+
# network security groups you must explicitly specify them as an option.
|
131
|
+
#
|
132
|
+
# An attempt to delete a resource that cannot be deleted because it's
|
133
|
+
# still associated with some other resource will be logged and skipped.
|
134
|
+
#
|
135
|
+
# If the :verbose option is set to true, then additional messages are
|
136
|
+
# sent to your configuration log, or stdout if no log was specified.
|
137
|
+
#
|
138
|
+
# Note that if all of your related resources are in a self-contained
|
139
|
+
# resource group, you do not necessarily need this method. You could
|
140
|
+
# just delete the resource group itself, which would automatically
|
141
|
+
# delete all of its resources.
|
142
|
+
#
|
143
|
+
def delete_associated_resources(vmname, vmgroup, options = {})
|
144
|
+
options = {
|
145
|
+
:network_interfaces => true,
|
146
|
+
:ip_addresses => true,
|
147
|
+
:os_disk => true,
|
148
|
+
:network_security_groups => false,
|
149
|
+
:storage_account => false,
|
150
|
+
:verbose => false
|
151
|
+
}.merge(options)
|
152
|
+
|
153
|
+
Azure::Armrest::Configuration.log ||= STDOUT if options[:verbose]
|
154
|
+
|
155
|
+
vm = get(vmname, vmgroup)
|
156
|
+
|
157
|
+
delete_and_wait(self, vmname, vmgroup, options)
|
158
|
+
|
159
|
+
# Must delete network interfaces first if you want to delete
|
160
|
+
# IP addresses or network security groups.
|
161
|
+
if options[:network_interfaces] || options[:ip_addresses] || options[:network_security_groups]
|
162
|
+
delete_associated_nics(vm, options)
|
163
|
+
end
|
164
|
+
|
165
|
+
if options[:os_disk] || options[:storage_account]
|
166
|
+
delete_associated_disk(vm, options)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
124
170
|
def model_class
|
125
171
|
VirtualMachineModel
|
126
172
|
end
|
127
173
|
|
128
174
|
private
|
129
175
|
|
176
|
+
# Deletes any NIC's associated with the VM, and optionally any public IP addresses
|
177
|
+
# and network security groups.
|
178
|
+
#
|
179
|
+
def delete_associated_nics(vm, options)
|
180
|
+
nis = Azure::Armrest::Network::NetworkInterfaceService.new(configuration)
|
181
|
+
nics = vm.properties.network_profile.network_interfaces.map(&:id)
|
182
|
+
|
183
|
+
if options[:ip_addresses]
|
184
|
+
ips = Azure::Armrest::Network::IpAddressService.new(configuration)
|
185
|
+
end
|
186
|
+
|
187
|
+
if options[:network_security_groups]
|
188
|
+
nsgs = Azure::Armrest::Network::NetworkSecurityGroupService.new(configuration)
|
189
|
+
end
|
190
|
+
|
191
|
+
nics.each do |nic_id_string|
|
192
|
+
nic = get_associated_resource(nic_id_string)
|
193
|
+
delete_and_wait(nis, nic.name, nic.resource_group, options)
|
194
|
+
|
195
|
+
if options[:ip_addresses]
|
196
|
+
nic.properties.ip_configurations.each do |ip|
|
197
|
+
ip = get_associated_resource(ip.properties.public_ip_address.id)
|
198
|
+
delete_and_wait(ips, ip.name, ip.resource_group, options)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
if options[:network_security_groups]
|
203
|
+
nic.properties.network_security_group
|
204
|
+
nsg = get_associated_resource(nic.properties.network_security_group.id)
|
205
|
+
delete_and_wait(nsgs, nsg.name, nsg.resource_group, options)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# This deletes the OS disk from the storage account that's backing the
|
211
|
+
# virtual machine, along with the .status file. This does NOT delete
|
212
|
+
# copies of the disk.
|
213
|
+
#
|
214
|
+
# If the option to delete the entire storage account was selected, then
|
215
|
+
# it will not bother with deleting invidual files from the storage
|
216
|
+
# account first.
|
217
|
+
#
|
218
|
+
def delete_associated_disk(vm, options)
|
219
|
+
sas = Azure::Armrest::StorageAccountService.new(configuration)
|
220
|
+
|
221
|
+
storage_account = sas.get_from_vm(vm)
|
222
|
+
|
223
|
+
# Deleting the storage account does not require deleting the disks
|
224
|
+
# first, so skip that if deletion of the storage account was requested.
|
225
|
+
if options[:storage_account]
|
226
|
+
delete_and_wait(sas, storage_account.name, storage_account.resource_group, options)
|
227
|
+
else
|
228
|
+
keys = sas.list_account_keys(storage_account.name, storage_account.resource_group)
|
229
|
+
key = keys['key1'] || keys['key2']
|
230
|
+
disk = sas.get_os_disk(vm)
|
231
|
+
|
232
|
+
# There's a short delay between deleting the VM and unlocking the underlying
|
233
|
+
# .vhd file by Azure. Therefore we sleep up to two minutes while checking.
|
234
|
+
if disk.x_ms_lease_status.casecmp('unlocked') != 0
|
235
|
+
sleep_time = 0
|
236
|
+
|
237
|
+
while sleep_time < 120
|
238
|
+
sleep 10
|
239
|
+
sleep_time += 10
|
240
|
+
disk = sas.get_os_disk(vm)
|
241
|
+
break if disk.x_ms_lease_status.casecmp('unlocked') != 0
|
242
|
+
end
|
243
|
+
|
244
|
+
# In the unlikely event it did not unlock, just log and skip.
|
245
|
+
if disk.x_ms_lease_status.casecmp('unlocked') != 0
|
246
|
+
log_message("Unable to delete disk #{disk.container}/#{disk.name}", 'warn')
|
247
|
+
return
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
storage_account.delete_blob(disk.container, disk.name, key)
|
252
|
+
log_message("Deleted blob #{disk.container}/#{disk.name}") if options[:verbose]
|
253
|
+
|
254
|
+
begin
|
255
|
+
status_file = File.basename(disk.name, '.vhd') + '.status'
|
256
|
+
storage_account.delete_blob(disk.container, status_file, key)
|
257
|
+
rescue Azure::Armrest::NotFoundException
|
258
|
+
# Ignore, does not always exist.
|
259
|
+
else
|
260
|
+
log_message("Deleted blob #{disk.container}/#{status_file}") if options[:verbose]
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Delete a +service+ type resource using its name and resource group,
|
266
|
+
# and wait for the operation to complete before returning.
|
267
|
+
#
|
268
|
+
# If the operation fails because a dependent resource is still attached,
|
269
|
+
# then the error is logged (in verbose mode) and ignored.
|
270
|
+
#
|
271
|
+
def delete_and_wait(service, name, group, options)
|
272
|
+
resource_type = service.class.to_s.sub('Service', '').split('::').last
|
273
|
+
|
274
|
+
log_message("Deleting #{resource_type} #{name}/#{group}") if options[:verbose]
|
275
|
+
|
276
|
+
headers = service.delete(name, group)
|
277
|
+
|
278
|
+
loop do
|
279
|
+
status = wait(headers)
|
280
|
+
break if status.downcase.start_with?('succ') # Succeeded, Success, etc.
|
281
|
+
end
|
282
|
+
|
283
|
+
log_message("Deleted #{resource_type} #{name}/#{group}") if options[:verbose]
|
284
|
+
rescue Azure::Armrest::BadRequestException, Azure::Armrest::PreconditionFailedException => err
|
285
|
+
if options[:verbose]
|
286
|
+
msg = "Unable to delete #{resource_type} #{name}/#{group}, skipping. Message: #{err.message}"
|
287
|
+
log_message(msg, 'warn')
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
130
291
|
def vm_operate(action, vmname, group, options = {})
|
131
292
|
raise ArgumentError, "must specify resource group" unless group
|
132
293
|
raise ArgumentError, "must specify name of the vm" unless vmname
|
@@ -135,6 +296,15 @@ module Azure
|
|
135
296
|
rest_post(url)
|
136
297
|
nil
|
137
298
|
end
|
299
|
+
|
300
|
+
# Simple log messager. Use the Configuration.log if defined.
|
301
|
+
def log_message(msg, level = 'info')
|
302
|
+
if Azure::Armrest::Configuration.log
|
303
|
+
Azure::Armrest::Configuration.log.send(level.to_sym, msg)
|
304
|
+
else
|
305
|
+
warn msg
|
306
|
+
end
|
307
|
+
end
|
138
308
|
end
|
139
309
|
end
|
140
310
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: azure-armrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2016-11-
|
14
|
+
date: 2016-11-15 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: json
|
@@ -240,6 +240,7 @@ files:
|
|
240
240
|
- lib/azure/armrest/configuration.rb
|
241
241
|
- lib/azure/armrest/exception.rb
|
242
242
|
- lib/azure/armrest/insights/alert_service.rb
|
243
|
+
- lib/azure/armrest/insights/diagnostic_service.rb
|
243
244
|
- lib/azure/armrest/insights/event_service.rb
|
244
245
|
- lib/azure/armrest/insights/metrics_service.rb
|
245
246
|
- lib/azure/armrest/model/base_model.rb
|