vagrant-azure 1.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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/Gemfile +19 -0
  4. data/LICENSE +4 -0
  5. data/README.md +9 -0
  6. data/Rakefile +14 -0
  7. data/lib/vagrant-azure.rb +24 -0
  8. data/lib/vagrant-azure/action.rb +249 -0
  9. data/lib/vagrant-azure/action/connect_azure.rb +41 -0
  10. data/lib/vagrant-azure/action/provision.rb +40 -0
  11. data/lib/vagrant-azure/action/rdp.rb +62 -0
  12. data/lib/vagrant-azure/action/read_ssh_info.rb +51 -0
  13. data/lib/vagrant-azure/action/read_state.rb +46 -0
  14. data/lib/vagrant-azure/action/restart_vm.rb +27 -0
  15. data/lib/vagrant-azure/action/run_instance.rb +111 -0
  16. data/lib/vagrant-azure/action/start_instance.rb +35 -0
  17. data/lib/vagrant-azure/action/stop_instance.rb +38 -0
  18. data/lib/vagrant-azure/action/terminate_instance.rb +34 -0
  19. data/lib/vagrant-azure/action/wait_for_state.rb +49 -0
  20. data/lib/vagrant-azure/command/rdp/command.rb +21 -0
  21. data/lib/vagrant-azure/config.rb +147 -0
  22. data/lib/vagrant-azure/driver.rb +79 -0
  23. data/lib/vagrant-azure/plugin.rb +87 -0
  24. data/lib/vagrant-azure/provider.rb +70 -0
  25. data/lib/vagrant-azure/provisioner/puppet.rb +109 -0
  26. data/lib/vagrant-azure/scripts/check_winrm.ps1 +41 -0
  27. data/lib/vagrant-azure/scripts/export_vm.ps1 +31 -0
  28. data/lib/vagrant-azure/scripts/file_sync.ps1 +145 -0
  29. data/lib/vagrant-azure/scripts/host_info.ps1 +25 -0
  30. data/lib/vagrant-azure/scripts/hyperv_manager.ps1 +36 -0
  31. data/lib/vagrant-azure/scripts/run_in_remote.ps1 +32 -0
  32. data/lib/vagrant-azure/scripts/upload_file.ps1 +95 -0
  33. data/lib/vagrant-azure/scripts/utils/create_session.ps1 +34 -0
  34. data/lib/vagrant-azure/scripts/utils/write_messages.ps1 +18 -0
  35. data/lib/vagrant-azure/version.rb +10 -0
  36. data/locales/en.yml +14 -0
  37. data/vagrant-azure.gemspec +58 -0
  38. metadata +167 -0
@@ -0,0 +1,51 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'log4r'
6
+
7
+ module VagrantPlugins
8
+ module WinAzure
9
+ module Action
10
+ class ReadSSHInfo
11
+ def initialize(app, env, port = 22)
12
+ @app = app
13
+ @port = port
14
+ @logger = Log4r::Logger.new('vagrant_azure::action::read_ssh_info')
15
+ end
16
+
17
+ def call(env)
18
+ env[:ui].info "Looking for #{@port}"
19
+
20
+ env[:machine_ssh_info] = read_ssh_info(
21
+ env[:azure_vm_service],
22
+ env[:machine]
23
+ )
24
+
25
+ @app.call(env)
26
+ end
27
+
28
+ def read_ssh_info(azure, machine)
29
+ return nil if machine.id.nil?
30
+ machine.id =~ /@/
31
+ vm = azure.get_virtual_machine($`, $')
32
+
33
+ if vm.nil? || !vm.instance_of?(Azure::VirtualMachineManagement::VirtualMachine)
34
+ # Machine cannot be found
35
+ @logger.info 'Machine not found. Assuming it was destroyed'
36
+ machine.id = nil
37
+ return nil
38
+ end
39
+
40
+ vm.tcp_endpoints.each do |endpoint|
41
+ if endpoint[:local_port] == "#{@port}"
42
+ return { :host => "#{vm.cloud_service_name}.cloudapp.net", :port => endpoint[:public_port] }
43
+ end
44
+ end
45
+
46
+ return nil
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,46 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'log4r'
6
+
7
+ module VagrantPlugins
8
+ module WinAzure
9
+ module Action
10
+ class ReadState
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new('vagrant_azure::action::read_state')
14
+ end
15
+
16
+ def call(env)
17
+ env[:machine_state_id] = read_state(env)
18
+
19
+ @app.call(env)
20
+ end
21
+
22
+ def read_state(env)
23
+ env[:machine].id = "#{env[:machine].provider_config.vm_name}@#{env[:machine].provider_config.cloud_service_name}" unless env[:machine].id
24
+
25
+ env[:machine].id =~ /@/
26
+
27
+ env[:ui].info "Attempting to read state for #{$`} in #{$'}"
28
+
29
+ vm = env[:azure_vm_service].get_virtual_machine($`, $')
30
+
31
+ if vm.nil? || \
32
+ !vm.instance_of?(Azure::VirtualMachineManagement::VirtualMachine) || \
33
+ [ :DeletingVM ].include?(vm.status.to_sym)
34
+ # Machine can't be found
35
+ @logger.info 'Machine cannot be found'
36
+ env[:machine].id = nil
37
+ return :NotCreated
38
+ end
39
+
40
+ env[:ui].info "VM Status: #{vm.status.to_sym}"
41
+ return vm.status.to_sym
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,27 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'log4r'
6
+
7
+ module VagrantPlugins
8
+ module WinAzure
9
+ module Action
10
+ class RestartVM
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new('vagrant_azure::action::restart_vm')
14
+ end
15
+
16
+ def call(env)
17
+ env[:machine].id =~ /@/
18
+
19
+ env[:ui].info "Restarting #{$`} in #{$'}"
20
+ env[:azure_vm_service].restart_virtual_machine($`, $')
21
+
22
+ @app.call(env)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,111 @@
1
+ #---------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'log4r'
6
+ require 'json'
7
+ require 'azure'
8
+
9
+ require 'vagrant/util/retryable'
10
+
11
+ module VagrantPlugins
12
+ module WinAzure
13
+ module Action
14
+ class RunInstance
15
+ include Vagrant::Util::Retryable
16
+
17
+ def initialize(app, env)
18
+ @app = app
19
+ @logger = Log4r::Logger.new('vagrant_azure::action::run_instance')
20
+ end
21
+
22
+ def call(env)
23
+ config = env[:machine].provider_config
24
+
25
+ # Add the mandatory parameters and options
26
+ params = {
27
+ vm_name: config.vm_name,
28
+ vm_user: config.vm_user,
29
+ image: config.vm_image
30
+ }
31
+
32
+ options = {
33
+ cloud_service_name: config.cloud_service_name
34
+ }
35
+
36
+
37
+ # Add the optional parameters and options if not nil
38
+ params[:password] = config.vm_password unless config.vm_password.nil?
39
+ params[:location] = config.vm_location unless config.vm_location.nil?
40
+ params[:affinity_group] = config.vm_affinity_group unless \
41
+ config.vm_affinity_group.nil?
42
+
43
+ options[:storage_account_name] = config.storage_acct_name unless \
44
+ config.storage_acct_name.nil?
45
+ options[:deployment_name] = config.deployment_name unless \
46
+ config.deployment_name.nil?
47
+ options[:tcp_endpoints] = config.tcp_endpoints unless \
48
+ config.tcp_endpoints.nil?
49
+ options[:private_key_file] = config.ssh_private_key_file unless \
50
+ config.ssh_private_key_file.nil?
51
+ options[:certificate_file] = config.ssh_certificate_file unless \
52
+ config.ssh_certificate_file.nil?
53
+ options[:ssh_port] = config.ssh_port unless \
54
+ config.ssh_port.nil?
55
+ options[:vm_size] = config.vm_size unless \
56
+ config.vm_size.nil?
57
+ options[:winrm_transport] = config.winrm_transport unless \
58
+ config.winrm_transport.nil?
59
+ options[:winrm_http_port] = config.winrm_http_port unless \
60
+ config.winrm_http_port.nil?
61
+ options[:winrm_https_port] = config.winrm_https_port unless \
62
+ config.winrm_https_port.nil?
63
+ options[:availability_set_name] = config.availability_set_name unless \
64
+ config.availability_set_name.nil?
65
+
66
+ add_role = false
67
+
68
+ env[:ui].info(params.inspect)
69
+ env[:ui].info(options.inspect)
70
+
71
+ # Check if the cloud service exists and if yes, does it contain
72
+ # a deployment.
73
+ if config.cloud_service_name && !config.cloud_service_name.empty?
74
+ begin
75
+ cloud_service = ManagementHttpRequest.new(
76
+ :get,
77
+ "/services/hostedservices/#{config.cloud_service_name}?embed-detail=true"
78
+ ).call
79
+
80
+ deployments = cloud_service.css 'HostedService Deployments Deployment'
81
+
82
+ # Lets see if any deployments exist. Set add_role = true if yes.
83
+ # We're not worried about deployment slots, because the SDK has
84
+ # hard coded 'Production' as deployment slot and you can have only
85
+ # one deployment per deployment slot.
86
+ add_role = deployments.length == 1
87
+ rescue Exception => e
88
+ add_role = false
89
+ end
90
+ end
91
+ env[:ui].info("Add Role? - #{add_role}")
92
+
93
+ server = env[:azure_vm_service].create_virtual_machine(
94
+ params, options, add_role
95
+ )
96
+
97
+ # TODO: Exception/Error Handling
98
+
99
+ if server.instance_of? String
100
+ env[:ui].info "Server not created. Error is: #{server}"
101
+ raise "#{server}"
102
+ end
103
+
104
+ env[:machine].id = "#{server.vm_name}@#{server.cloud_service_name}"
105
+
106
+ @app.call(env)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,35 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'log4r'
6
+
7
+ # require 'vagrant/util/retryable'
8
+
9
+ # Barebones basic implemenation. This a work in progress in very early stages
10
+ module VagrantPlugins
11
+ module WinAzure
12
+ module Action
13
+ # This starts a stopped instance
14
+ class StartInstance
15
+ # include Vagrant:Util::Retryable
16
+
17
+ def initialize(app, env)
18
+ @app = app
19
+ @logger = Log4r::Logger.new('vagrant_azure:action::start_instance')
20
+ end
21
+
22
+ def call(env)
23
+ env[:machine].id = "#{env[:machine].provider_config.vm_name}@#{env[:machine].provider_config.cloud_service_name}" unless env[:machine].id
24
+ env[:machine].id =~ /@/
25
+
26
+ env[:ui].info "Attempting to start '#{$`}' in '#{$'}'"
27
+
28
+ env[:azure_vm_service].start_virtual_machine($`, $')
29
+
30
+ @app.call(env)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'log4r'
6
+
7
+ # Barebones basic implemenation. This a work in progress in very early stages
8
+ module VagrantPlugins
9
+ module WinAzure
10
+ module Action
11
+ class StopInstance
12
+ def initialize(app, env)
13
+ @app = app
14
+ @logger = Log4r::Logger.new('vagrant_azure::action::stop_instance')
15
+ end
16
+
17
+ def call(env)
18
+ if env[:machine].state.id == :StoppedDeallocated
19
+ env[:ui].info(
20
+ I18n.t('vagrant_azure.already_status', :status => 'stopped.')
21
+ )
22
+ else
23
+ env[:machine].id =~ /@/
24
+ env[:ui].info(
25
+ I18n.t(
26
+ 'vagrant_azure.stopping',
27
+ :vm_name => $`,
28
+ :cloud_service_name => $'
29
+ )
30
+ )
31
+ env[:azure_vm_service].shutdown_virtual_machine($`, $')
32
+ end
33
+ @app.call(env)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'log4r'
6
+
7
+ module VagrantPlugins
8
+ module WinAzure
9
+ module Action
10
+ class TerminateInstance
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new('vagrant_azure::action::terminate_instance')
14
+ end
15
+
16
+ def call(env)
17
+ env[:machine].id =~ /@/
18
+
19
+ vm = env[:azure_vm_service].get_virtual_machine($`, $')
20
+
21
+ if vm.nil?
22
+ # machine not found. assuming it was not created or destroyed
23
+ env[:ui].info (I18n.t('vagrant_azure.not_created'))
24
+ else
25
+ env[:azure_vm_service].delete_virtual_machine($`, $')
26
+ env[:machine].id = nil
27
+ end
28
+
29
+ @app.call(env)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'log4r'
6
+ require 'timeout'
7
+
8
+ module VagrantPlugins
9
+ module WinAzure
10
+ module Action
11
+ class WaitForState
12
+ def initialize(app, env, state)
13
+ @app = app
14
+ @state = state
15
+ @logger = Log4r::Logger.new("vagrant_azure::action::wait_for_state")
16
+ end
17
+
18
+ def call(env)
19
+ env[:result] = true
20
+
21
+ if env[:machine].state.id == @state
22
+ @logger.info(
23
+ I18n.t('vagrant_azure.already_status', :status => @state)
24
+ )
25
+ else
26
+ timeout = env[:machine].provider_config.state_read_timeout
27
+
28
+ env[:ui].info "Waiting for machine to reach state #{@state}"
29
+ @logger.info("Waiting for machine to reach state #{@state}")
30
+
31
+ begin
32
+ Timeout.timeout(timeout) do
33
+ until env[:machine].state.id == @state
34
+ sleep 30
35
+ end
36
+ end
37
+ env[:ui].success "Machine reached state #{@state}"
38
+ rescue Timeout::Error
39
+ env[:ui].error "Machine failed to reached state '#{@state}' in '#{timeout}' seconds."
40
+ env[:result] = false # couldn't reach state in time
41
+ end
42
+ end
43
+
44
+ @app.call(env)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,21 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ module VagrantPlugins
6
+ module WinAzure
7
+ class Command < Vagrant.plugin('2', :command)
8
+ def self.synopsis
9
+ 'Opens an RDP session for a vagrant machine'
10
+ end
11
+
12
+ def execute
13
+ with_target_vms do |vm|
14
+ vm.action(:rdp)
15
+ end
16
+
17
+ 0
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,147 @@
1
+ #--------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+ require 'vagrant'
6
+ require 'azure'
7
+
8
+ module VagrantPlugins
9
+ module WinAzure
10
+ class Config < Vagrant.plugin('2', :config)
11
+ attr_accessor :mgmt_certificate
12
+ attr_accessor :mgmt_endpoint
13
+ attr_accessor :subscription_id
14
+ attr_accessor :storage_acct_name
15
+ attr_accessor :storage_access_key
16
+
17
+ attr_accessor :vm_name
18
+ attr_accessor :vm_user
19
+ attr_accessor :vm_password
20
+ attr_accessor :vm_image
21
+ attr_accessor :vm_location
22
+ attr_accessor :vm_affinity_group
23
+
24
+ attr_accessor :cloud_service_name
25
+ attr_accessor :deployment_name
26
+ attr_accessor :tcp_endpoints
27
+ attr_accessor :ssh_private_key_file
28
+ attr_accessor :ssh_certificate_file
29
+ attr_accessor :ssh_port
30
+ attr_accessor :vm_size
31
+ attr_accessor :winrm_transport
32
+ attr_accessor :winrm_http_port
33
+ attr_accessor :winrm_https_port
34
+ attr_accessor :availability_set_name
35
+
36
+ attr_accessor :state_read_timeout
37
+
38
+ def initialize
39
+ @storage_acct_name = UNSET_VALUE
40
+ @storage_access_key = UNSET_VALUE
41
+ @mgmt_certificate = UNSET_VALUE
42
+ @mgmt_endpoint = UNSET_VALUE
43
+ @subscription_id = UNSET_VALUE
44
+
45
+ @vm_name = UNSET_VALUE
46
+ @vm_user = UNSET_VALUE
47
+ @vm_password = UNSET_VALUE
48
+ @vm_image = UNSET_VALUE
49
+ @vm_location = UNSET_VALUE
50
+ @vm_affinity_group = UNSET_VALUE
51
+
52
+ @cloud_service_name = UNSET_VALUE
53
+ @deployment_name = UNSET_VALUE
54
+ @tcp_endpoints = UNSET_VALUE
55
+ @ssh_private_key_file = UNSET_VALUE
56
+ @ssh_certificate_file = UNSET_VALUE
57
+ @ssh_port = UNSET_VALUE
58
+ @vm_size = UNSET_VALUE
59
+ @winrm_transport = UNSET_VALUE
60
+ @winrm_http_port = UNSET_VALUE
61
+ @winrm_https_port = UNSET_VALUE
62
+ @availability_set_name = UNSET_VALUE
63
+ @state_read_timeout = UNSET_VALUE
64
+ end
65
+
66
+ def finalize!
67
+ @storage_acct_name = ENV["AZURE_STORAGE_ACCOUNT"] if \
68
+ @storage_acct_name == UNSET_VALUE
69
+ @storage_access_key = ENV["AZURE_STORAGE_ACCESS_KEY"] if \
70
+ @storage_access_key == UNSET_VALUE
71
+ @mgmt_certificate = ENV["AZURE_MANAGEMENT_CERTIFICATE"] if \
72
+ @mgmt_certificate == UNSET_VALUE
73
+ @mgmt_endpoint = ENV["AZURE_MANAGEMENT_ENDPOINT"] if \
74
+ @mgmt_endpoint == UNSET_VALUE
75
+ @subscription_id = ENV["AZURE_SUBSCRIPTION_ID"] if \
76
+ @subscription_id == UNSET_VALUE
77
+
78
+ @vm_name = nil if @vm_name == UNSET_VALUE
79
+ @vm_user = 'vagrant' if @vm_user == UNSET_VALUE
80
+ @vm_password = nil if @vm_password == UNSET_VALUE
81
+ @vm_image = nil if @vm_image == UNSET_VALUE
82
+ @vm_location = nil if @vm_location == UNSET_VALUE
83
+ @vm_affinity_group = nil if @vm_affinity_group == UNSET_VALUE
84
+
85
+ @cloud_service_name = nil if @cloud_service_name == UNSET_VALUE
86
+ @deployment_name = nil if @deployment_name == UNSET_VALUE
87
+ @tcp_endpoints = nil if @tcp_endpoints == UNSET_VALUE
88
+ @ssh_private_key_file = nil if @ssh_private_key_file == UNSET_VALUE
89
+ @ssh_certificate_file = nil if @ssh_certificate_file == UNSET_VALUE
90
+ @ssh_port = nil if @ssh_port == UNSET_VALUE
91
+ @vm_size = nil if @vm_size == UNSET_VALUE
92
+ @winrm_transport = nil if @winrm_transport == UNSET_VALUE
93
+ @winrm_http_port = nil if @winrm_http_port == UNSET_VALUE
94
+ @winrm_https_port = nil if @winrm_https_port == UNSET_VALUE
95
+ @availability_set_name = nil if @availability_set_name == UNSET_VALUE
96
+
97
+ @state_read_timeout = 360 if @state_read_timeout == UNSET_VALUE
98
+
99
+ # This done due to a bug in Ruby SDK - it doesn't generate a storage
100
+ # account name if add_role = true
101
+ if @storage_acct_name.nil? || @storage_acct_name.empty?
102
+ @storage_acct_name = Azure::Core::Utility.random_string(
103
+ "#{@vm_name}storage"
104
+ ).gsub(/[^0-9a-z ]/i, '').downcase[0..23]
105
+ end
106
+
107
+ if @cloud_service_name.nil? || @cloud_service_name.empty?
108
+ @cloud_service_name = Azure::Core::Utility.random_string(
109
+ "#{@vm_name}-service-"
110
+ )
111
+ end
112
+ end
113
+
114
+ def merge(other)
115
+ super.tap do |result|
116
+ result.mgmt_certificate = other.mgmt_certificate || \
117
+ self.mgmt_certificate
118
+ result.mgmt_endpoint = other.mgmt_endpoint || \
119
+ self.mgmt_endpoint
120
+ result.subscription_id = other.subscription_id || \
121
+ self.subscription_id
122
+ result.storage_account_name = other.storage_acct_name || \
123
+ self.storage_acct_name
124
+ result.storage_access_key = other.storage_access_key || \
125
+ self.storage_access_key
126
+ end
127
+ end
128
+
129
+ def validate(machine)
130
+ errors = _detected_errors
131
+
132
+ # Azure connection properties related validation.
133
+ errors << "vagrant_azure.subscription_id.required" if \
134
+ @subscription_id.nil?
135
+ errors << "vagrant_azure.mgmt_certificate.required" if \
136
+ @mgmt_certificate.nil?
137
+ errors << "vagrant_azure.mgmt_endpoint.required" if \
138
+ @mgmt_endpoint.nil?
139
+
140
+ # Azure Virtual Machine related validation
141
+ errors << "vagrant_azure.vm_name.required" if @vm_name.nil?
142
+
143
+ { "Windows Azure Provider" => errors }
144
+ end
145
+ end
146
+ end
147
+ end