vagrant-azure 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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