azure-armrest 0.0.1

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.
@@ -0,0 +1,359 @@
1
+ # Azure namespace
2
+ module Azure
3
+ # Armrest namespace
4
+ module Armrest
5
+ # Base class for managing virtual machines
6
+ class VirtualMachineManager < ArmrestManager
7
+
8
+ # The provider used in requests when gathering VM information.
9
+ attr_reader :provider
10
+
11
+ # Create and return a new VirtualMachineManager (VMM) instance. Most
12
+ # methods for a VMM instance will return one or more VirtualMachine
13
+ # instances.
14
+ #
15
+ # This subclass accepts the additional :provider option as well. The
16
+ # default is 'Microsoft.ClassicCompute'. You may need to set this to
17
+ # 'Microsoft.Compute' for your purposes.
18
+ #
19
+ def initialize(options = {})
20
+ super
21
+
22
+ @provider = options[:provider] || 'Microsoft.Compute'
23
+
24
+ # Typically only empty in testing.
25
+ unless @@providers.empty?
26
+ @api_version = @@providers[@provider]['virtualMachines']['api_version']
27
+ end
28
+ end
29
+
30
+ # Set a new provider to use the default for other methods. This may alter
31
+ # the api_version used for future requests. In practice, only
32
+ # 'Microsoft.Compute' or 'Microsoft.ClassicCompute' should be used.
33
+ #
34
+ def provider=(name)
35
+ @api_version = @@providers[name]['virtualMachines']['api_version']
36
+ @provider = name
37
+ end
38
+
39
+ # Return a list of available VM series (aka sizes, flavors, etc), such
40
+ # as "Basic_A1", though information is included as well.
41
+ #
42
+ def series(location)
43
+ unless @@providers[@provider] && @@providers[@provider]['locations/vmSizes']
44
+ raise ArgumentError, "Invalid provider '#{provider}'"
45
+ end
46
+
47
+ version = @@providers[@provider]['locations/vmSizes']['api_version']
48
+
49
+ url = url_with_api_version(
50
+ version, @base_url, 'subscriptions', subscription_id, 'providers',
51
+ provider, 'locations', location, 'vmSizes'
52
+ )
53
+
54
+ JSON.parse(rest_get(url))['value']
55
+ end
56
+
57
+ alias sizes series
58
+
59
+ # Returns a list of available virtual machines for the given subscription
60
+ # for the provided +group+, or all resource groups if none is provided.
61
+ #
62
+ # Examples:
63
+ #
64
+ # # Get VM's for all resource groups
65
+ # vmm.list
66
+ #
67
+ # # Get VM's only for a specific group
68
+ # vmm.list('some_group')
69
+ #--
70
+ # The specific hashes we can grab are:
71
+ # p JSON.parse(resp.body)["value"][0]["properties"]["instanceView"]
72
+ # p JSON.parse(resp.body)["value"][0]["properties"]["hardwareProfile"]
73
+ # p JSON.parse(resp.body)["value"][0]["properties"]["storageProfile"]
74
+ #
75
+ def list(group = nil)
76
+ array = []
77
+ if group
78
+ url = build_url(group)
79
+ array << JSON.parse(rest_get(url))['value']
80
+ else
81
+ threads = []
82
+ mutex = Mutex.new
83
+
84
+ resource_groups.each do |group|
85
+ url = build_url(group['name'])
86
+
87
+ threads << Thread.new(url) do |thread_url|
88
+ response = rest_get(thread_url)
89
+ result = JSON.parse(response)['value']
90
+ mutex.synchronize{ array << result if result }
91
+ end
92
+ end
93
+
94
+ threads.each(&:join)
95
+
96
+ array = array.flatten
97
+ end
98
+
99
+ add_network_profile(array)
100
+ end
101
+
102
+ alias get_vms list
103
+
104
+ def add_network_profile(vms)
105
+ vms.each { |vm|
106
+ vm['properties']['networkProfile']['networkInterfaces'].each { |net|
107
+ get_nic_profile(net)
108
+ }
109
+ }
110
+ end
111
+
112
+ def get_nic_profile(nic)
113
+ url = File.join(
114
+ Azure::Armrest::RESOURCE,
115
+ nic['id'],
116
+ "?api-version=#{api_version}"
117
+ )
118
+
119
+ nic['properties'] = JSON.parse(rest_get(url))['properties']['ipConfigurations']
120
+ nic['properties'].each do |n|
121
+ next if n['properties']['publicIPAddress'].nil?
122
+
123
+ # public IP is a URI so we need to make another rest call to get it.
124
+ url = File.join(
125
+ Azure::Armrest::RESOURCE,
126
+ n['properties']['publicIPAddress']['id'],
127
+ "?api-version=#{api_version}"
128
+ )
129
+
130
+ public_ip = JSON.parse(rest_get(url))['properties']['ipAddress']
131
+ n['properties']['publicIPAddress'] = public_ip
132
+ end
133
+ end
134
+
135
+ # Captures the +vmname+ and associated disks into a reusable CSM template.
136
+ #--
137
+ # POST
138
+ def capture(vmname, action = 'capture')
139
+ uri = @uri + "/#{vmname}/#{action}?api-version=#{api_version}"
140
+ uri
141
+ end
142
+
143
+ # Creates a new virtual machine (or updates an existing one). Pass a hash
144
+ # of options to configure the VM as you see fit. Some options are
145
+ # mandatory. The following are a list of possible options:
146
+ #
147
+ # - :name
148
+ # Required. The name of the virtual machine. The name must be unique
149
+ # within the availability set that it belongs to.
150
+ #
151
+ # - :location
152
+ # Required. The location where the VM should be created, e.g. "West US".
153
+ #
154
+ # - :tags
155
+ # Optional. Specifies an identifier for the availability set.
156
+ #
157
+ # - :hardwareprofile
158
+ # Required. Contains a collection of hardware settings for the VM.
159
+ #
160
+ # - :vmsize
161
+ # Required. Specifies the size of the virtual machine. Possible
162
+ # sizes are Standard_A0..Standard_A4.
163
+ #
164
+ # - :osprofile
165
+ # Required. Contains a collection of settings for the OS configuration
166
+ # which must contain all of the following:
167
+ #
168
+ # - :computername
169
+ # - :adminusername
170
+ # - :adminpassword
171
+ # - :username
172
+ # - :password
173
+ #
174
+ # - :storageprofile
175
+ # Required. Contains a collection of settings for storage and disk
176
+ # settings for the VM. You must specify an :osdisk and :name. The
177
+ # :datadisks setting is optional.
178
+ #
179
+ # - :osdisk
180
+ # Required. Contains a collection of settings for the operating
181
+ # system disk.
182
+ #
183
+ # - :name
184
+ # - :ostype
185
+ # - :caching
186
+ # - :image
187
+ # - :vhd
188
+ #
189
+ # - :datadisks
190
+ # Optional. Contains a collection of settings for data disks.
191
+ #
192
+ # - :name
193
+ # - :image
194
+ # - :vhd
195
+ # - :lun
196
+ # - :caching
197
+ #
198
+ # - :name
199
+ # Required. Specifies the name of the disk.
200
+ #
201
+ # For clarity, we recommend using the update method for existing VM's.
202
+ #
203
+ # Example:
204
+ #
205
+ # vmm = VirtualMachineManager.new(x, y, z)
206
+ #
207
+ # vm = vmm.create(
208
+ # :name => 'test1',
209
+ # :location => 'West US',
210
+ # :hardwareprofile => {:vmsize => 'Standard_A0'},
211
+ # :osprofile => {
212
+ # :computername => 'some_name',
213
+ # :adminusername => 'admin_user',
214
+ # :adminpassword => 'adminxxxxxx',
215
+ # :username => 'some_user',
216
+ # :password => 'userpassxxxxxx',
217
+ # },
218
+ # :storageprofile => {
219
+ # :osdisk => {
220
+ # :ostype => 'Windows',
221
+ # :caching => 'Read'
222
+ # }
223
+ # }
224
+ # )
225
+ #--
226
+ # PUT operation
227
+ #
228
+ def create(options = {})
229
+ #name = options.fetch(:name)
230
+ #location = options.fetch(:location)
231
+ #tags = option[:tags]
232
+ vmsize = options.fetch(:vmsize)
233
+
234
+ unless VALID_VM_SIZES.include?(vmsize)
235
+ raise ArgumentError, "Invalid vmsize '#{vmsize}'"
236
+ end
237
+ end
238
+
239
+ alias update create
240
+
241
+ # Stop the VM +vmname+ in +group+ and deallocate the tenant in Fabric.
242
+ #
243
+ def deallocate(vmname, group = vmname)
244
+ url = build_url(group, vmname, 'deallocate')
245
+ response = rest_post(url)
246
+ response.return!
247
+ end
248
+
249
+ # Deletes the +vmname+ in +group+ that you specify. Note that associated
250
+ # disks are not deleted.
251
+ #
252
+ def delete(vmname, group = vmname)
253
+ url = build_url(group, vmname)
254
+ response = rest_delete(url)
255
+ response.return!
256
+ end
257
+
258
+ # Sets the OSState for the +vmname+ in +group+ to 'Generalized'.
259
+ #
260
+ def generalize(vmname, group = vmname)
261
+ url = build_url(group, vmname, 'generalize')
262
+ response = rest_post(url)
263
+ response.return!
264
+ end
265
+
266
+ # Retrieves the settings of the VM named +vmname+ in resource group
267
+ # +group+, which will default to the same as the name of the VM.
268
+ #
269
+ # By default this method will retrieve the model view. If the +model_view+
270
+ # parameter is false, it will retrieve an instance view. The difference is
271
+ # in the details of the information retrieved.
272
+ #
273
+ def get(vmname, group = vmname, model_view = true)
274
+ if model_view
275
+ url = build_url(group, vmname)
276
+ else
277
+ url = build_url(group, vmname, 'instanceView')
278
+ end
279
+
280
+ JSON.parse(rest_get(url))
281
+ end
282
+
283
+ # Convenient wrapper around the get method that retrieves the model view
284
+ # for +vmname+ in resource_group +group+.
285
+ #
286
+ def get_model_view(vmname, group = vmname)
287
+ get(vmname, group, true)
288
+ end
289
+
290
+ # Convenient wrapper around the get method that retrieves the instance view
291
+ # for +vmname+ in resource_group +group+.
292
+ #
293
+ def get_instance_view(vmname, group = vmname)
294
+ get(vmname, group, false)
295
+ end
296
+
297
+ # Restart the VM +vmname+ for the given +group+, which will default
298
+ # to the same as the vmname.
299
+ #
300
+ # This is an asynchronous operation that returns a response object
301
+ # which you can inspect, such as response.code or response.headers.
302
+ #
303
+ def restart(vmname, group = vmname)
304
+ url = build_url(group, vmname, 'restart')
305
+ response = rest_post(url)
306
+ response.return!
307
+ end
308
+
309
+ # Start the VM +vmname+ for the given +group+, which will default
310
+ # to the same as the vmname.
311
+ #
312
+ # This is an asynchronous operation that returns a response object
313
+ # which you can inspect, such as response.code or response.headers.
314
+ #
315
+ def start(vmname, group = vmname)
316
+ url = build_url(group, vmname, 'start')
317
+ response = rest_post(url)
318
+ response.return!
319
+ end
320
+
321
+ # Stop the VM +vmname+ for the given +group+ gracefully. However,
322
+ # a forced shutdown will occur after 15 minutes.
323
+ #
324
+ # This is an asynchronous operation that returns a response object
325
+ # which you can inspect, such as response.code or response.headers.
326
+ #
327
+ def stop(vmname, group = vmname)
328
+ url = build_url(group, vmname, 'powerOff')
329
+ response = rest_post(url)
330
+ response.return!
331
+ end
332
+
333
+ private
334
+
335
+ # If no default subscription is set, then use the first one found.
336
+ def set_default_subscription
337
+ @subscription_id ||= subscriptions.first['subscriptionId']
338
+ end
339
+
340
+ # Builds a URL based on subscription_id an resource_group and any other
341
+ # arguments provided, and appends it with the api_version.
342
+ #
343
+ def build_url(resource_group, *args)
344
+ url = File.join(
345
+ Azure::Armrest::COMMON_URI,
346
+ subscription_id,
347
+ 'resourceGroups',
348
+ resource_group,
349
+ 'providers',
350
+ @provider,
351
+ 'virtualMachines',
352
+ )
353
+
354
+ url = File.join(url, *args) unless args.empty?
355
+ url << "?api-version=#{api_version}"
356
+ end
357
+ end
358
+ end
359
+ end
@@ -0,0 +1,62 @@
1
+ # Azure namespace
2
+ module Azure
3
+ # Armrest namespace
4
+ module Armrest
5
+ # Base class for managing virtual networks
6
+ class VirtualNetworkManager < ArmrestManager
7
+
8
+ # Create and return a new VirtualNetworkManager instance. Most
9
+ # methods for a VirtualNetworkManager instance will return one or
10
+ # more VirtualNetwork instances.
11
+ #
12
+ def initialize(options = {})
13
+ super
14
+
15
+ @base_url += "resourceGroups/#{@resource_group}/"
16
+ @base_url += "providers/Microsoft.Network/virtualNetworks"
17
+ end
18
+
19
+ # Creates a new virtual network using the given +options+. The possible
20
+ # options are:
21
+ #
22
+ # :name
23
+ # :id
24
+ # :location
25
+ # :tags
26
+ # :etag
27
+ # :properties
28
+ # :address_space
29
+ # :address_prefixes
30
+ # :dhcp_options
31
+ # :dns_servers
32
+ # :subnets
33
+ # :name
34
+ # :id
35
+ # :etag
36
+ # :provisioning_state
37
+ # :address_prefix
38
+ # :dhcp_options
39
+ # :ip_configurations
40
+ # :id
41
+ #--
42
+ def create(network_name, options = {})
43
+ @uri += "/#{network_name}?api-version=#{api_version}"
44
+ end
45
+
46
+ # Deletes the +network_name+ availability set.
47
+ def delete(network_name)
48
+ @uri += "/#{network_name}?api-version=#{api_version}"
49
+ end
50
+
51
+ # Retrieves the options of an availability set.
52
+ def get(network_name)
53
+ @uri += "/#{network_name}?api-version=#{api_version}"
54
+ end
55
+
56
+ # List availability sets.
57
+ def list
58
+ @uri += "?api-version=#{api_version}"
59
+ end
60
+ end
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: azure-armrest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Daniel J. Berger
8
+ - Bronagh Sorota
9
+ - Greg Blomquist
10
+ autorequire:
11
+ bindir: exe
12
+ cert_chain: []
13
+ date: 2015-08-13 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '10.0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '10.0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rspec
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '3.0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '3.0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: codeclimate-test-reporter
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: json
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: rest-client
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ type: :runtime
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ description: |
100
+ This is a Ruby interface for Azure using the newer REST API. This is
101
+ different than the current azure gem, which uses the older (XML) interface
102
+ behind the scenes.
103
+ email:
104
+ - dberger@redhat.com
105
+ - bsorota@redhat.com
106
+ - gblomqui@redhat.com
107
+ executables: []
108
+ extensions: []
109
+ extra_rdoc_files: []
110
+ files:
111
+ - ".gitignore"
112
+ - ".rspec"
113
+ - ".travis.yml"
114
+ - CHANGES
115
+ - Gemfile
116
+ - LICENSE
117
+ - README.md
118
+ - Rakefile
119
+ - azure-armrest.gemspec
120
+ - lib/azure-armrest.rb
121
+ - lib/azure/armrest.rb
122
+ - lib/azure/armrest/armrest_manager.rb
123
+ - lib/azure/armrest/availability_set_manager.rb
124
+ - lib/azure/armrest/event_manager.rb
125
+ - lib/azure/armrest/storage_account_manager.rb
126
+ - lib/azure/armrest/subnet_manager.rb
127
+ - lib/azure/armrest/version.rb
128
+ - lib/azure/armrest/virtual_machine_extension_manager.rb
129
+ - lib/azure/armrest/virtual_machine_image_manager.rb
130
+ - lib/azure/armrest/virtual_machine_manager.rb
131
+ - lib/azure/armrest/virtual_network_manager.rb
132
+ homepage: http://github.com/ManageIQ/azure-armrest
133
+ licenses:
134
+ - Apache 2.0
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.4.8
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: An interface for ARM/JSON Azure REST API
156
+ test_files: []
157
+ has_rdoc: