vagrant-azure 1.3.0 → 2.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +5 -6
  5. data/LICENSE +21 -4
  6. data/README.md +36 -178
  7. data/Rakefile +3 -5
  8. data/example_box/Vagrantfile +7 -8
  9. data/lib/vagrant-azure/action/connect_azure.rb +9 -30
  10. data/lib/vagrant-azure/action/is_created.rb +19 -0
  11. data/lib/vagrant-azure/action/is_stopped.rb +19 -0
  12. data/lib/vagrant-azure/action/message_already_created.rb +19 -0
  13. data/lib/vagrant-azure/action/message_not_created.rb +19 -0
  14. data/lib/vagrant-azure/action/message_will_not_destroy.rb +19 -0
  15. data/lib/vagrant-azure/action/read_ssh_info.rb +13 -33
  16. data/lib/vagrant-azure/action/read_state.rb +28 -26
  17. data/lib/vagrant-azure/action/restart_vm.rb +11 -11
  18. data/lib/vagrant-azure/action/run_instance.rb +164 -80
  19. data/lib/vagrant-azure/action/start_instance.rb +34 -15
  20. data/lib/vagrant-azure/action/stop_instance.rb +36 -21
  21. data/lib/vagrant-azure/action/terminate_instance.rb +18 -14
  22. data/lib/vagrant-azure/action/wait_for_state.rb +17 -23
  23. data/lib/vagrant-azure/action.rb +49 -124
  24. data/lib/vagrant-azure/config.rb +107 -111
  25. data/lib/vagrant-azure/errors.rb +9 -11
  26. data/lib/vagrant-azure/plugin.rb +8 -32
  27. data/lib/vagrant-azure/provider.rb +7 -29
  28. data/lib/vagrant-azure/services/azure_resource_manager.rb +80 -0
  29. data/lib/vagrant-azure/util/machine_id_helper.rb +20 -0
  30. data/lib/vagrant-azure/util/timer.rb +15 -0
  31. data/lib/vagrant-azure/util/vm_await.rb +36 -0
  32. data/lib/vagrant-azure/util/vm_status_translator.rb +59 -0
  33. data/lib/vagrant-azure/version.rb +5 -7
  34. data/lib/vagrant-azure.rb +4 -9
  35. data/locales/en.yml +74 -3
  36. data/spec/spec_helper.rb +40 -0
  37. data/spec/vagrant-azure/config_spec.rb +18 -0
  38. data/spec/vagrant-azure/services/azure_resource_manager_spec.rb +19 -0
  39. data/templates/arm/deployment.json.erb +264 -0
  40. data/vagrant-azure.gemspec +19 -14
  41. metadata +96 -51
  42. data/lib/vagrant-azure/action/os_type.rb +0 -34
  43. data/lib/vagrant-azure/action/powershell_run.rb +0 -28
  44. data/lib/vagrant-azure/action/rdp.rb +0 -63
  45. data/lib/vagrant-azure/action/read_winrm_info.rb +0 -57
  46. data/lib/vagrant-azure/action/sync_folders.rb +0 -64
  47. data/lib/vagrant-azure/action/vagrant_azure_service.rb +0 -44
  48. data/lib/vagrant-azure/capabilities/winrm.rb +0 -12
  49. data/lib/vagrant-azure/command/powershell.rb +0 -43
  50. data/lib/vagrant-azure/command/rdp.rb +0 -24
  51. data/lib/vagrant-azure/driver.rb +0 -48
  52. data/lib/vagrant-azure/monkey_patch/winrm.rb +0 -12
@@ -1,8 +1,6 @@
1
- #--------------------------------------------------------------------------
2
- # Copyright (c) Microsoft Open Technologies, Inc.
3
- # All Rights Reserved. Licensed under the Apache License, Version 2.0.
4
- # See License.txt in the project root for license information.
5
- #--------------------------------------------------------------------------
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
6
4
  begin
7
5
  require 'vagrant'
8
6
  rescue LoadError
@@ -16,12 +14,12 @@ if Vagrant::VERSION < '1.6.0'
16
14
  end
17
15
 
18
16
  module VagrantPlugins
19
- module WinAzure
17
+ module Azure
20
18
  class Plugin < Vagrant.plugin('2')
21
- name 'azure'
19
+ name 'Azure'
22
20
  description <<-DESC
23
21
  This plugin installs a provider that allows Vagrant to manage
24
- machines in Windows Azure.
22
+ machines in Microsoft Azure.
25
23
  DESC
26
24
 
27
25
  config(:azure, :provider) do
@@ -33,38 +31,16 @@ module VagrantPlugins
33
31
  # Setup logging and i18n
34
32
  setup_logging
35
33
  setup_i18n
36
- apply_patches
37
34
 
38
35
  # Return the provider
39
36
  require_relative 'provider'
40
37
  Provider
41
38
  end
42
39
 
43
- provider_capability(:azure, :winrm_info) do
44
- require_relative 'capabilities/winrm'
45
- VagrantPlugins::WinAzure::Cap::WinRM
46
- end
47
-
48
- command 'powershell' do
49
- require_relative 'command/powershell'
50
- VagrantPlugins::WinAzure::Command::PowerShell
51
- end
52
-
53
- command 'rdp' do
54
- require_relative 'command/rdp'
55
- VagrantPlugins::WinAzure::Command::RDP
56
- end
57
-
58
- def self.apply_patches
59
- lib_path = Pathname.new(File.expand_path('../../vagrant-azure', __FILE__))
60
- Vagrant.plugin('2').manager.communicators[:winrm]
61
- require lib_path.join('monkey_patch/winrm')
62
- end
63
-
64
40
  def self.setup_i18n
65
41
  I18n.load_path << File.expand_path(
66
42
  'locales/en.yml',
67
- WinAzure.source_root
43
+ Azure.source_root
68
44
  )
69
45
  I18n.load_path << File.expand_path(
70
46
  'templates/locales/en.yml',
@@ -98,7 +74,7 @@ module VagrantPlugins
98
74
  # Set the logging level on all "vagrant" namespaced logs as long as
99
75
  # we have a valid level
100
76
  if level
101
- logger = Log4r::Logger.new("vagrant_azure")
77
+ logger = Log4r::Logger.new('vagrant_azure')
102
78
  logger.outputters = Log4r::Outputter.stderr
103
79
  logger.level = level
104
80
  logger = nil
@@ -1,24 +1,15 @@
1
- #--------------------------------------------------------------------------
2
- # Copyright (c) Microsoft Open Technologies, Inc.
3
- # All Rights Reserved. Licensed under the Apache License, Version 2.0.
4
- # See License.txt in the project root for license information.
5
- #--------------------------------------------------------------------------
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
6
4
  require 'log4r'
7
5
  require 'vagrant'
8
6
 
9
7
  module VagrantPlugins
10
- module WinAzure
8
+ module Azure
11
9
  class Provider < Vagrant.plugin('2', :provider)
12
- attr_reader :driver
13
10
 
14
11
  def initialize(machine)
15
12
  @machine = machine
16
-
17
- # Load the driver
18
- machine_id_changed
19
-
20
- @machine.config.winrm.password = @machine.provider_config.vm_password || @machine.provider_config.vm_user
21
- @machine.config.winrm.username = @machine.provider_config.vm_user
22
13
  end
23
14
 
24
15
  def action(name)
@@ -30,10 +21,6 @@ module VagrantPlugins
30
21
  nil
31
22
  end
32
23
 
33
- def machine_id_changed
34
- @driver = Driver.new(@machine)
35
- end
36
-
37
24
  def ssh_info
38
25
  # Run a custom action called "read_ssh_info" which does what it
39
26
  # says and puts the resulting SSH info into the `:machine_ssh_info`
@@ -42,24 +29,15 @@ module VagrantPlugins
42
29
  env[:machine_ssh_info]
43
30
  end
44
31
 
45
- def rdp_info
46
- env = @machine.action('read_rdp_info')
47
- env[:machine_ssh_info]
48
- end
49
-
50
- def winrm_info
51
- env = @machine.action('read_winrm_info')
52
- env[:machine_winrm_info]
53
- end
54
-
55
32
  def state
56
33
  # Run a custom action we define called "read_state" which does what it
57
34
  # says. It puts the state in the `:machine_state_id` key in the env
58
35
  env = @machine.action('read_state')
59
36
  state_id = env[:machine_state_id]
60
37
 
61
- short = "Machine's current state is #{state_id}"
62
- long = ""
38
+ # Get the short and long description
39
+ short = I18n.t("vagrant_azure.states.short_#{state_id}")
40
+ long = I18n.t("vagrant_azure.states.long_#{state_id}")
63
41
 
64
42
  # Return the MachineState object
65
43
  Vagrant::MachineState.new(state_id, short, long)
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ require 'azure_mgmt_resources'
6
+ require 'azure_mgmt_compute'
7
+ require 'azure_mgmt_network'
8
+ require 'azure_mgmt_storage'
9
+
10
+ module VagrantPlugins
11
+ module Azure
12
+ module Services
13
+ class AzureResourceManager
14
+
15
+ TENANT_ID_NAME = 'AZURE_TENANT_ID'
16
+ CLIENT_ID_NAME = 'AZURE_CLIENT_ID'
17
+ CLIENT_SECRET_NAME = 'AZURE_CLIENT_SECRET'
18
+
19
+ # AzureResourceManager provides access to the Azure Resource Manager APIs
20
+ # @param [MsRest::TokenProvider] token_provider object used to procure an authentication token from Azure Active
21
+ # Directory
22
+ # @param [String] subscription_id
23
+ # @param [String] base_url
24
+ def initialize(token_provider, subscription_id, base_url = nil)
25
+ @token_provider = if token_provider.nil? || !token_provider.is_a?(MsRest::TokenProvider)
26
+ if ENV[TENANT_ID_NAME].nil? || ENV[CLIENT_ID_NAME].nil? || ENV[CLIENT_SECRET_NAME].nil?
27
+ raise ArgumentError "Either set #{TENANT_ID_NAME}, #{CLIENT_ID_NAME} or #{CLIENT_SECRET_NAME} in your environment, or pass in a MsRest::TokenProvider"
28
+ else
29
+ MsRestAzure::ApplicationTokenProvider.new(
30
+ ENV[TENANT_ID_NAME],
31
+ ENV[CLIENT_ID_NAME],
32
+ ENV[CLIENT_SECRET_NAME])
33
+ end
34
+ else
35
+ token_provider
36
+ end
37
+ @credential = MsRest::TokenCredentials.new(token_provider)
38
+ @base_url = base_url
39
+ @subscription_id = subscription_id
40
+ end
41
+
42
+ # Azure Resource Manager Compute API Client
43
+ # @return [Azure::ARM::Compute::ComputeManagementClient]
44
+ def compute
45
+ build(::Azure::ARM::Compute::ComputeManagementClient)
46
+ end
47
+
48
+ # Azure Resource Manager Generic Resource API Client
49
+ # @return [Azure::ARM::Resources::ResourceManagementClient]
50
+ def resources
51
+ build(::Azure::ARM::Resources::ResourceManagementClient)
52
+ end
53
+
54
+ # Azure Resource Manager Network API Client
55
+ # @return [Azure::ARM::Network::NetworkManagementClient]
56
+ def network
57
+ build(::Azure::ARM::Network::NetworkManagementClient)
58
+ end
59
+
60
+ # Azure Resource Manager Storage API Client
61
+ # @return [Azure::ARM::Storage::StorageManagementClient]
62
+ def storage
63
+ build(::Azure::ARM::Storage::StorageManagementClient)
64
+ end
65
+
66
+ private
67
+
68
+ def build(clazz)
69
+ instance = clazz.new(*client_params)
70
+ instance.subscription_id = @subscription_id
71
+ instance
72
+ end
73
+
74
+ def client_params
75
+ [@credential, @base_url].reject{ |i| i.nil? }
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,20 @@
1
+ module VagrantPlugins
2
+ module Azure
3
+ module Util
4
+ module MachineIdHelper
5
+ def parse_machine_id(id)
6
+ parts = id.split(':')
7
+ {
8
+ group: parts[0],
9
+ name: parts[1],
10
+ location: parts[2]
11
+ }
12
+ end
13
+
14
+ def serialize_machine_id(resource_group, vm_name, location)
15
+ [resource_group, vm_name, location].join(':')
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module VagrantPlugins
2
+ module Azure
3
+ module Util
4
+ class Timer
5
+ def self.time
6
+ start_time = Time.now.to_f
7
+ yield
8
+ end_time = Time.now.to_f
9
+
10
+ end_time - start_time
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ module VagrantPlugins
2
+ module Azure
3
+ module Util
4
+ module VMAwait
5
+
6
+ def await_true(env)
7
+ config = env[:machine].provider_config
8
+ parsed = parse_machine_id(env[:machine].id)
9
+ azure = env[:azure_arm_service]
10
+ tries = config.instance_ready_timeout / 2
11
+ count = 0
12
+ task = Concurrent::TimerTask.new(execution_interval: config.instance_check_interval ) do
13
+ task.shutdown if env[:interrupted]
14
+
15
+ if count > tries
16
+ task.shutdown
17
+ false
18
+ end
19
+
20
+ count += 1
21
+ vm = azure.compute.virtual_machines.get(parsed[:group], parsed[:name], 'instanceView').value!.body
22
+ if yield(vm)
23
+ task.shutdown
24
+ true
25
+ end
26
+ end
27
+
28
+ task.execute
29
+ task.wait_for_termination
30
+ task
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,59 @@
1
+ module VagrantPlugins
2
+ module Azure
3
+ module Util
4
+ module VMStatusTranslator
5
+
6
+ PROVISIONING_STATES = [:provisioned, :deleting]
7
+ POWER_STATES = [:running, :starting, :deallocating, :deallocated]
8
+
9
+ def vm_status_to_state(status)
10
+ code = status.code
11
+ case
12
+ when code == 'ProvisioningState/succeeded'
13
+ :provisioned
14
+ when code == 'ProvisioningState/deleting'
15
+ :deleting
16
+ when code == 'PowerState/running'
17
+ :running
18
+ when code == 'PowerState/stopping'
19
+ :stopping
20
+ when code == 'PowerState/stopped'
21
+ :stopped
22
+ when code == 'PowerState/starting'
23
+ :starting
24
+ when code == 'PowerState/deallocating'
25
+ :deallocating
26
+ when code == 'PowerState/deallocated'
27
+ :deallocated
28
+ else
29
+ :unknown
30
+ end
31
+ end
32
+
33
+ def power_state(statuses)
34
+ vm_status_to_state(statuses.select{ |s| s.code.match(/PowerState/) }.last)
35
+ end
36
+
37
+ def running?(statuses)
38
+ statuses.any?{ |s| vm_status_to_state(s) == :running }
39
+ end
40
+
41
+ def built?(statuses)
42
+ statuses.any?{ |s| vm_status_to_state(s) == :provisioned }
43
+ end
44
+
45
+ def stopped?(statuses)
46
+ statuses.any?{ |s| vm_status_to_state(s) == :stopped }
47
+ end
48
+
49
+ def stopping?(statuses)
50
+ statuses.any?{ |s| vm_status_to_state(s) == :stopping }
51
+ end
52
+
53
+ def tearing_down?(statuses)
54
+ statuses.any?{ |s| vm_status_to_state(s) == :deleting }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,11 +1,9 @@
1
- #--------------------------------------------------------------------------
2
- # Copyright (c) Microsoft Open Technologies, Inc.
3
- # All Rights Reserved. Licensed under the Apache License, Version 2.0.
4
- # See License.txt in the project root for license information.
5
- #--------------------------------------------------------------------------
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
6
4
 
7
5
  module VagrantPlugins
8
- module WinAzure
9
- VERSION = '1.3.0'
6
+ module Azure
7
+ VERSION = '2.0.0.pre1'
10
8
  end
11
9
  end
data/lib/vagrant-azure.rb CHANGED
@@ -1,19 +1,14 @@
1
- #--------------------------------------------------------------------------
2
- # Copyright (c) Microsoft Open Technologies, Inc.
3
- # All Rights Reserved. Licensed under the Apache License, Version 2.0.
4
- # See License.txt in the project root for license information.
5
- #--------------------------------------------------------------------------
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
6
4
  require 'pathname'
7
5
  require 'vagrant-azure/plugin'
8
6
 
9
7
  module VagrantPlugins
10
- module WinAzure
8
+ module Azure
11
9
  lib_path = Pathname.new(File.expand_path('../vagrant-azure', __FILE__))
12
10
  autoload :Action, lib_path.join('action')
13
11
  autoload :Errors, lib_path.join('errors')
14
- autoload :Driver, lib_path.join('driver')
15
-
16
- CLOUD_SERVICE_SEMAPHORE = Mutex.new
17
12
 
18
13
  # This returns the path to the source of this plugin.
19
14
  #
data/locales/en.yml CHANGED
@@ -1,5 +1,7 @@
1
1
  en:
2
2
  vagrant_azure:
3
+ launching_instance: |-
4
+ Launching an instance with the following settings...
3
5
  not_created: |-
4
6
  The machine does not exist. Please run `vagrant up` first.
5
7
  will_not_destroy: |-
@@ -7,13 +9,25 @@ en:
7
9
  already_status: |-
8
10
  The machine is already %{status}.
9
11
  stopping: |-
10
- Stopping '%{vm_name}' in '%{cloud_service_name}'
12
+ Stopping '%{name}' in '%{group}'
13
+ terminating: |-
14
+ Terminating '%{name}'
15
+ terminated: |-
16
+ Terminated '%{name}'
11
17
  rdp_not_ready: |-
12
18
  RDP not ready
13
- vm_started: |-
19
+ starting: |-
20
+ VM '%{name}' is starting
21
+ started: |-
14
22
  VM '%{name}' has been started
15
- vm_stopped: |-
23
+ stopping: |-
24
+ VM '%{name}' is stopping
25
+ stopped: |-
16
26
  VM '%{name}' has been stopped
27
+ restarting: |-
28
+ VM '%{name}' is restarting
29
+ restarted: |-
30
+ VM '%{name}' has been restarted
17
31
  copy_folder: |-
18
32
  Copying folder: %{hostpath} ==>
19
33
  %{guestpath}
@@ -35,3 +49,60 @@ en:
35
49
  Server not created. Error is: %{message}
36
50
  create_vm_failure: |-
37
51
  There was some error in creating the VM.
52
+ failed_starting: |-
53
+ Failed to start VM '%{name}'!!
54
+ failed_stopping: |-
55
+ Failed to stopping VM '%{name}'!!
56
+ subscription_id:
57
+ required: |-
58
+ You must provide an Azure Subscription Id either through ENV['AZURE_SUBSCRIPTION_ID'] or via Vagrantfile.
59
+ mgmt_endpoint:
60
+ required: |-
61
+ You must provide a non-nil Azure Management Endpoint either through ENV['AZURE_MANAGEMENT_ENDPOINT'] or via Vagrantfile.
62
+ auth:
63
+ required: |-
64
+ You must provide Azure Active Directory Tenant ID, Application Client ID and Application Client Secret via ENV or Vagrantfile.
65
+ states:
66
+ short_not_created: |-
67
+ not created
68
+ long_not_created: |-
69
+ The Azure instance is not created. Run `vagrant up` to create it.
70
+ short_stopped: |-
71
+ stopped
72
+ long_stopped: |-
73
+ The Azure instance is stopped. Run `vagrant up` to start it.
74
+ short_stopping: |-
75
+ stopping
76
+ long_stopping: |-
77
+ The Azure instance is stopping. Wait until is completely stopped to
78
+ run `vagrant up` and start it.
79
+ short_pending: |-
80
+ pending
81
+ long_pending: |-
82
+ The Azure instance is pending a start (i.e. this is a transition state).
83
+ short_running: |-
84
+ running
85
+ long_running: |-
86
+ The Azure instance is running. To stop this machine, you can run
87
+ `vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
88
+ short_pending: |-
89
+ pending
90
+ long_pending: |-
91
+ The Azure instance is still being initialized. To destroy this machine,
92
+ you can run `vagrant destroy`.
93
+ waiting_for_ssh: |-
94
+ Waiting for SSH to become available...
95
+ ready: |-
96
+ Machine is booted and ready for use!
97
+ public_key_path_private_key: |-
98
+ We expect the public key to be added to the Azure VM to be located at the
99
+ same place as the config.ssh.private_key_path + '.pub'. We couldn't find
100
+ any public keys for these private key paths:
101
+ private_key_not_specified: |-
102
+ Please specify a secure key to use with config.ssh.private_key_path
103
+ (see: https://www.vagrantup.com/docs/vagrantfile/ssh_settings.html).
104
+ If not, you publicly accessible Azure VM will be extremely insecure.
105
+ waiting_for_ready: |-
106
+ Waiting for instance to become "ready"...
107
+ waiting_for_stop: |-
108
+ Waiting for instance to become "stopped"...
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+ require 'vagrant-azure'
5
+
6
+ if ENV['COVERAGE'] || ENV['CI'] || ENV['TRAVIS']
7
+ require 'simplecov'
8
+ require 'coveralls'
9
+
10
+ if ENV['TRAVIS']
11
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
12
+ SimpleCov::Formatter::HTMLFormatter,
13
+ Coveralls::SimpleCov::Formatter
14
+ ]
15
+ else
16
+ SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
17
+ end
18
+
19
+ SimpleCov.start do
20
+ project_name 'vagrant-azure'
21
+ add_filter '/build-tests/'
22
+ add_filter '/coverage/'
23
+ add_filter '/locales/'
24
+ add_filter '/templates/'
25
+ add_filter '/doc/'
26
+ add_filter '/example_box/'
27
+ add_filter '/pkg/'
28
+ add_filter '/spec/'
29
+ add_filter '/tasks/'
30
+ add_filter '/yard-template/'
31
+ add_filter '/yardoc/'
32
+ end
33
+ end
34
+
35
+ # import all the support files
36
+ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require File.expand_path(f) }
37
+
38
+ RSpec.configure do |config|
39
+ config.order = 'random'
40
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ require 'vagrant'
6
+ require 'vagrant-azure/config'
7
+
8
+ module VagrantPlugins
9
+ module Azure
10
+ describe Config do
11
+
12
+ it 'should config' do
13
+
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ require 'vagrant-azure/services/azure_resource_manager'
6
+
7
+ module VagrantPlugins
8
+ module Azure
9
+ module Services
10
+ describe AzureResourceManager do
11
+
12
+ it 'should be hello world' do
13
+
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end