knife-azure 3.0.0 → 4.0.0

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/azure/custom_errors.rb +1 -1
  3. data/lib/azure/resource_management/ARM_deployment_template.rb +5 -5
  4. data/lib/azure/resource_management/ARM_interface.rb +8 -12
  5. data/lib/azure/resource_management/windows_credentials.rb +7 -8
  6. data/lib/chef/knife/azurerm_server_create.rb +2 -2
  7. data/lib/chef/knife/azurerm_server_delete.rb +1 -1
  8. data/lib/chef/knife/bootstrap/bootstrapper.rb +10 -11
  9. data/lib/chef/knife/bootstrap_azurerm.rb +1 -1
  10. data/lib/chef/knife/helpers/azurerm_base.rb +17 -19
  11. data/lib/knife-azure/version.rb +1 -1
  12. metadata +30 -43
  13. data/lib/azure/service_management/ASM_interface.rb +0 -310
  14. data/lib/azure/service_management/ag.rb +0 -99
  15. data/lib/azure/service_management/certificate.rb +0 -235
  16. data/lib/azure/service_management/connection.rb +0 -102
  17. data/lib/azure/service_management/deploy.rb +0 -221
  18. data/lib/azure/service_management/disk.rb +0 -68
  19. data/lib/azure/service_management/host.rb +0 -184
  20. data/lib/azure/service_management/image.rb +0 -94
  21. data/lib/azure/service_management/loadbalancer.rb +0 -78
  22. data/lib/azure/service_management/rest.rb +0 -125
  23. data/lib/azure/service_management/role.rb +0 -717
  24. data/lib/azure/service_management/storageaccount.rb +0 -127
  25. data/lib/azure/service_management/utility.rb +0 -40
  26. data/lib/azure/service_management/vnet.rb +0 -134
  27. data/lib/chef/knife/azure_ag_create.rb +0 -73
  28. data/lib/chef/knife/azure_ag_list.rb +0 -35
  29. data/lib/chef/knife/azure_image_list.rb +0 -56
  30. data/lib/chef/knife/azure_internal-lb_create.rb +0 -74
  31. data/lib/chef/knife/azure_internal-lb_list.rb +0 -35
  32. data/lib/chef/knife/azure_server_create.rb +0 -531
  33. data/lib/chef/knife/azure_server_delete.rb +0 -136
  34. data/lib/chef/knife/azure_server_list.rb +0 -38
  35. data/lib/chef/knife/azure_server_show.rb +0 -41
  36. data/lib/chef/knife/azure_vnet_create.rb +0 -74
  37. data/lib/chef/knife/azure_vnet_list.rb +0 -35
  38. data/lib/chef/knife/bootstrap_azure.rb +0 -191
  39. data/lib/chef/knife/helpers/azure_base.rb +0 -394
@@ -1,74 +0,0 @@
1
- #
2
- # Author:: Aiman Alsari (aiman.alsari@gmail.com)
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require_relative "helpers/azure_base"
20
-
21
- class Chef
22
- class Knife
23
- class AzureInternalLbCreate < Knife
24
- include Knife::AzureBase
25
-
26
- banner "knife azure internal lb create (options)"
27
-
28
- option :azure_load_balancer,
29
- short: "-n NAME",
30
- long: "--azure-load-balancer NAME",
31
- description: "Required. Specifies new load balancer name."
32
-
33
- option :azure_lb_static_vip,
34
- long: "--azure-lb-static-vip VIP",
35
- description: "Optional. The Virtual IP that will be used for the load balancer."
36
-
37
- option :azure_subnet_name,
38
- long: "--azure-subnet-name SUBNET_NAME",
39
- description: "Required if static VIP is set. Specifies the subnet name "\
40
- "the load balancer is located in."
41
-
42
- option :azure_dns_name,
43
- long: "--azure-dns-name DNS_NAME",
44
- description: "The DNS prefix name that will be used to add this load balancer to. This must be an existing service/deployment."
45
-
46
- def run
47
- $stdout.sync = true
48
-
49
- Chef::Log.info("validating...")
50
- validate_asm_keys!(:azure_load_balancer)
51
-
52
- params = {
53
- azure_load_balancer: config[:azure_load_balancer],
54
- azure_lb_static_vip: config[:azure_lb_static_vip],
55
- azure_subnet_name: config[:azure_subnet_name],
56
- azure_dns_name: config[:azure_dns_name],
57
- }
58
-
59
- rsp = service.create_internal_lb(params)
60
- print "\n"
61
- if rsp.at_css("Status").nil?
62
- if rsp.at_css("Code").nil? || rsp.at_css("Message").nil?
63
- puts "Unknown Error. try -VV"
64
- else
65
- puts "#{rsp.at_css("Code").content}: "\
66
- "#{rsp.at_css("Message").content}"
67
- end
68
- else
69
- puts "Creation status: #{rsp.at_css("Status").content}"
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,35 +0,0 @@
1
- #
2
- # Author:: Aiman Alsari (aiman.alsari@gmail.com)
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require_relative "helpers/azure_base"
20
-
21
- class Chef
22
- class Knife
23
- class AzureInternalLbList < Knife
24
- include Knife::AzureBase
25
-
26
- banner "knife azure internal lb list (options)"
27
-
28
- def run
29
- $stdout.sync = true
30
- validate_asm_keys!
31
- service.list_internal_lb
32
- end
33
- end
34
- end
35
- end
@@ -1,531 +0,0 @@
1
- #
2
- # Author:: Barry Davis (barryd@jetstreamsoftware.com)
3
- # Author:: Adam Jacob (<adam@chef.io>)
4
- # Author:: Seth Chisamore (<schisamo@chef.io>)
5
- # Copyright:: Copyright (c) Chef Software Inc.
6
- # License:: Apache License, Version 2.0
7
- #
8
- # Licensed under the Apache License, Version 2.0 (the "License");
9
- # you may not use this file except in compliance with the License.
10
- # You may obtain a copy of the License at
11
- #
12
- # http://www.apache.org/licenses/LICENSE-2.0
13
- #
14
- # Unless required by applicable law or agreed to in writing, software
15
- # distributed under the License is distributed on an "AS IS" BASIS,
16
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- # See the License for the specific language governing permissions and
18
- # limitations under the License.
19
- #
20
-
21
- require_relative "helpers/azure_base"
22
- require "chef/knife/bootstrap"
23
- require "chef/knife/bootstrap/client_builder"
24
- require_relative "bootstrap/common_bootstrap_options"
25
- require_relative "bootstrap/bootstrapper"
26
-
27
- class Chef
28
- class Knife
29
- class AzureServerCreate < Knife::Bootstrap
30
- include Knife::AzureBase
31
- include Knife::Bootstrap::CommonBootstrapOptions
32
- include Knife::Bootstrap::Bootstrapper
33
-
34
- deps do
35
- require "securerandom"
36
- require "readline"
37
- require "chef/json_compat"
38
- require "chef/knife/bootstrap"
39
- require "chef/knife/core/windows_bootstrap_context"
40
- Chef::Knife::Bootstrap.load_deps
41
- end
42
-
43
- banner "knife azure server create (options)"
44
-
45
- SUPPORTED_CONNECTION_PROTOCOLS = %w{ssh winrm cloud-api}.freeze
46
-
47
- attr_accessor :initial_sleep_delay
48
-
49
- option :azure_affinity_group,
50
- short: "-a GROUP",
51
- long: "--azure-affinity-group GROUP",
52
- description: "Required if not using a Service Location. Specifies Affinity Group the VM should belong to."
53
-
54
- option :azure_dns_name,
55
- short: "-d DNS_NAME",
56
- long: "--azure-dns-name DNS_NAME",
57
- description: "The DNS prefix name that can be used to access the cloud service which is unique within Windows Azure. Default is 'azure-dns-any_random_text'(e.g: azure-dns-be9b0f6f-7dda-456f-b2bf-4e28a3bc0add).
58
- If you want to add new VM to an existing service/deployment, specify an exiting dns-name,
59
- along with --azure-connect-to-existing-dns option.
60
- Otherwise a new deployment is created. For example, if the DNS of cloud service is MyService you could access the cloud service
61
- by calling: http://DNS_NAME.cloudapp.net"
62
-
63
- option :azure_source_image,
64
- short: "-I IMAGE",
65
- long: "--azure-source-image IMAGE",
66
- description: "Required. Specifies the name of the disk image to use to create the virtual machine.
67
- Do a \"knife azure image list\" to see a list of available images."
68
-
69
- option :udp_endpoints,
70
- short: "-u PORT_LIST",
71
- long: "--udp-endpoints PORT_LIST",
72
- description: "Comma-separated list of UDP local and public ports to open e.g. '80:80,433:5000'"
73
-
74
- option :azure_connect_to_existing_dns,
75
- short: "-c",
76
- long: "--azure-connect-to-existing-dns",
77
- boolean: true,
78
- default: false,
79
- description: "Set this flag to add the new VM to an existing deployment/service. Must give the name of the existing
80
- DNS correctly in the --dns-name option"
81
-
82
- option :azure_network_name,
83
- long: "--azure-network-name NETWORK_NAME",
84
- description: "Optional. Specifies the network of virtual machine"
85
-
86
- option :azure_subnet_name,
87
- long: "--azure-subnet-name SUBNET_NAME",
88
- description: "Optional. Specifies the subnet of virtual machine"
89
-
90
- option :azure_vm_startup_timeout,
91
- long: "--azure-vm-startup-timeout TIMEOUT",
92
- description: "The number of minutes that knife-azure will wait for the virtual machine to reach the 'provisioning' state. Default is 10.",
93
- default: 10
94
-
95
- option :azure_vm_ready_timeout,
96
- long: "--azure-vm-ready-timeout TIMEOUT",
97
- description: "The number of minutes that knife-azure will wait for the virtual machine state to transition from 'provisioning' to 'ready'. Default is 15.",
98
- default: 15
99
-
100
- option :auth_timeout,
101
- long: "--windows-auth-timeout MINUTES",
102
- description: "The maximum time in minutes to wait to for authentication over the transport to the node to succeed. The default value is 25 minutes.",
103
- default: 25
104
-
105
- option :identity_file_passphrase,
106
- long: "--identity-file-passphrase PASSWORD",
107
- description: "SSH key passphrase. Optional, specify if passphrase for identity-file exists"
108
-
109
- option :winrm_max_timeout,
110
- long: "--winrm-max-timeout MINUTES",
111
- description: "Set winrm maximum command timeout in minutes, useful for long bootstraps"
112
-
113
- option :winrm_max_memory_per_shell,
114
- long: "--winrm-max-memory-per-shell",
115
- description: "Set winrm max memory per shell in MB"
116
-
117
- option :azure_domain_name,
118
- long: "--azure-domain-name DOMAIN_NAME",
119
- description: 'Optional. Specifies the domain name to join. If the domains name is not specified, --azure-domain-user must specify the user principal name (UPN) format (user@fully-qualified-DNS-domain) or the fully-qualified-DNS-domain\\username format'
120
-
121
- option :azure_domain_ou_dn,
122
- long: "--azure-domain-ou-dn DOMAIN_OU_DN",
123
- description: "Optional. Specifies the (LDAP) X 500-distinguished name of the organizational unit (OU) in which the computer account is created. This account is in Active Directory on a domain controller in the domain to which the computer is being joined. Example: OU=HR,dc=opscode,dc=com"
124
-
125
- option :azure_domain_user,
126
- long: "--azure-domain-user DOMAIN_USER_NAME",
127
- description: 'Optional. Specifies the username who has access to join the domain.
128
- Supported format: username(if domain is already specified in --azure-domain-name option),
129
- fully-qualified-DNS-domain\username, user@fully-qualified-DNS-domain'
130
-
131
- option :azure_domain_passwd,
132
- long: "--azure-domain-passwd DOMAIN_PASSWD",
133
- description: "Optional. Specifies the password for domain user who has access to join the domain."
134
-
135
- # Overriding this option to provide "cloud-api" in SUPPORTED_CONNECTION_PROTOCOLS
136
- option :connection_protocol,
137
- short: "-o PROTOCOL",
138
- long: "--connection-protocol PROTOCOL",
139
- description: "The protocol to use to connect to the target node.",
140
- in: SUPPORTED_CONNECTION_PROTOCOLS
141
-
142
- # run() would be executing from parent class
143
- # Chef::Knife::Bootstrap, defined in core.
144
- # Required methods have been overridden here
145
- #### run() execution begins ####
146
-
147
- def plugin_setup!; end
148
-
149
- def validate_name_args!; end
150
-
151
- # Ensure a valid protocol is provided for target host connection
152
- #
153
- # The method call will cause the program to exit(1) if:
154
- # * Conflicting protocols are given via the target URI and the --protocol option
155
- # * The protocol is not a supported protocol
156
- #
157
- # @note we are overriding this method here to consider "cloud-api" as valid protocol
158
- #
159
- # @return [TrueClass] If options are valid.
160
- def validate_protocol!
161
- from_cli = config[:connection_protocol]
162
- if from_cli && connection_protocol != from_cli
163
- # Hanging indent to align with the ERROR: prefix
164
- ui.error <<~EOM
165
- The URL '#{host_descriptor}' indicates protocol is '#{connection_protocol}'
166
- while the --protocol flag specifies '#{from_cli}'. Please include
167
- only one or the other.
168
- EOM
169
- exit 1
170
- end
171
-
172
- unless SUPPORTED_CONNECTION_PROTOCOLS.include?(connection_protocol)
173
- ui.error <<~EOM
174
- Unsupported protocol '#{connection_protocol}'.
175
-
176
- Supported protocols are: #{SUPPORTED_CONNECTION_PROTOCOLS.join(" ")}
177
- EOM
178
- exit 1
179
- end
180
- true
181
- end
182
-
183
- def plugin_validate_options!
184
- Chef::Log.info("Validating...")
185
- validate_asm_keys!(:azure_source_image)
186
- validate_params!
187
- end
188
-
189
- def plugin_create_instance!
190
- Chef::Log.info("Creating...")
191
- set_defaults
192
- server_def = create_server_def
193
- vm_details = service.create_server(server_def)
194
-
195
- wait_until_virtual_machine_ready
196
-
197
- config[:connection_port] = server_def[:port]
198
- config[:connection_protocol] = server_def[:connection_protocol]
199
- config[:chef_node_name] = config[:chef_node_name] || server_name
200
- rescue => error
201
- ui.error("Something went wrong. Please use -VV option for more details.")
202
- Chef::Log.debug(error.backtrace.join("\n").to_s)
203
- exit 1
204
- end
205
-
206
- def server_name
207
- @server_name ||= if @server.nil?
208
- nil
209
- elsif !@server.hostedservicename.nil?
210
- @server.hostedservicename + ".cloudapp.net"
211
- else
212
- @server.ipaddress
213
- end
214
- end
215
-
216
- alias host_descriptor server_name
217
-
218
- def plugin_finalize
219
- if config[:connection_protocol] == "cloud-api" && config[:extended_logs]
220
- print "\nWaiting for the first chef-client run"
221
- fetch_chef_client_logs(Time.now, 30)
222
- end
223
- msg_server_summary(@server)
224
- end
225
-
226
- #### run() execution ends ####
227
-
228
- def wait_until_virtual_machine_ready(retry_interval_in_seconds = 30)
229
- vm_status = nil
230
- begin
231
- azure_vm_startup_timeout = config[:azure_vm_startup_timeout].to_i
232
- azure_vm_ready_timeout = config[:azure_vm_ready_timeout].to_i
233
- vm_status = wait_for_virtual_machine_state(:vm_status_provisioning, azure_vm_startup_timeout, retry_interval_in_seconds)
234
- if vm_status != :vm_status_ready
235
- begin
236
- wait_for_virtual_machine_state(:vm_status_ready, azure_vm_ready_timeout, retry_interval_in_seconds)
237
- rescue Chef::Exceptions::CommandTimeout => e
238
- ui.warn("\n#{e.message}")
239
- ui.warn("Ignoring failure to reach 'ready' with bootstrap.")
240
- end
241
- end
242
-
243
- msg_server_summary(@server)
244
-
245
- if config[:connection_protocol] == "cloud-api"
246
- extension_status = wait_for_resource_extension_state(:wagent_provisioning, 5, retry_interval_in_seconds)
247
-
248
- if extension_status != :extension_installing
249
- extension_status = wait_for_resource_extension_state(:extension_installing, 5, retry_interval_in_seconds)
250
- end
251
-
252
- if extension_status != :extension_provisioning
253
- extension_status = wait_for_resource_extension_state(:extension_provisioning, 10, retry_interval_in_seconds)
254
- end
255
-
256
- if extension_status != :extension_ready
257
- wait_for_resource_extension_state(:extension_ready, 5, retry_interval_in_seconds)
258
- end
259
- end
260
- rescue Exception => e
261
- Chef::Log.error("#{e}")
262
- raise "Verify connectivity to Azure and subscription resource limit compliance (e.g. maximum CPU core limits) and try again."
263
- end
264
- end
265
-
266
- def wait_for_virtual_machine_state(vm_status_goal, total_wait_time_in_minutes, retry_interval_in_seconds)
267
- vm_status_ordering = { vm_status_not_detected: 0, vm_status_provisioning: 1, vm_status_ready: 2 }
268
- vm_status_description = { vm_status_not_detected: "any", vm_status_provisioning: "provisioning", vm_status_ready: "ready" }
269
-
270
- print ui.color("\nWaiting for virtual machine to reach status '#{vm_status_description[vm_status_goal]}'\n", :magenta)
271
-
272
- total_wait_time_in_seconds = total_wait_time_in_minutes * 60
273
- max_polling_attempts = total_wait_time_in_seconds / retry_interval_in_seconds
274
- polling_attempts = 0
275
-
276
- wait_start_time = Time.now
277
-
278
- begin
279
- vm_status = get_virtual_machine_status
280
- vm_ready = vm_status_ordering[vm_status] >= vm_status_ordering[vm_status_goal]
281
- print "."
282
- sleep retry_interval_in_seconds unless vm_ready
283
- polling_attempts += 1
284
- end until vm_ready || polling_attempts >= max_polling_attempts
285
-
286
- unless vm_ready
287
- raise Chef::Exceptions::CommandTimeout, "Virtual machine state '#{vm_status_description[vm_status_goal]}' not reached after #{total_wait_time_in_minutes} minutes."
288
- end
289
-
290
- elapsed_time_in_minutes = ((Time.now - wait_start_time) / 60).round(2)
291
- print ui.color("\nvm state '#{vm_status_description[vm_status_goal]}' reached after #{elapsed_time_in_minutes} minutes.\n", :cyan)
292
- vm_status
293
- end
294
-
295
- def wait_for_resource_extension_state(extension_status_goal, total_wait_time_in_minutes, retry_interval_in_seconds)
296
- extension_status_ordering = { extension_status_not_detected: 0, wagent_provisioning: 1, extension_installing: 2, extension_provisioning: 3, extension_ready: 4 }
297
-
298
- status_description = { extension_status_not_detected: "any", wagent_provisioning: "wagent provisioning", extension_installing: "installing", extension_provisioning: "provisioning", extension_ready: "ready" }
299
-
300
- print ui.color("\nWaiting for Resource Extension to reach status '#{status_description[extension_status_goal]}'\n", :magenta)
301
-
302
- max_polling_attempts = (total_wait_time_in_minutes * 60) / retry_interval_in_seconds
303
- polling_attempts = 0
304
-
305
- wait_start_time = Time.now
306
-
307
- begin
308
- extension_status = get_extension_status
309
- extension_ready = extension_status_ordering[extension_status[:status]] >= extension_status_ordering[extension_status_goal]
310
- print "."
311
- sleep retry_interval_in_seconds unless extension_ready
312
- polling_attempts += 1
313
- end until extension_ready || polling_attempts >= max_polling_attempts
314
-
315
- unless extension_ready
316
- raise Chef::Exceptions::CommandTimeout, "Resource extension state '#{status_description[extension_status_goal]}' not reached after #{total_wait_time_in_minutes} minutes. #{extension_status[:message]}"
317
- end
318
-
319
- elapsed_time_in_minutes = ((Time.now - wait_start_time) / 60).round(2)
320
- print ui.color("\nResource extension state '#{status_description[extension_status_goal]}' reached after #{elapsed_time_in_minutes} minutes.\n", :cyan)
321
-
322
- extension_status[:status]
323
- end
324
-
325
- def get_virtual_machine_status
326
- @server = service.get_role_server(config[:azure_dns_name], config[:azure_vm_name])
327
- if @server.nil?
328
- :vm_status_not_detected
329
- else
330
- Chef::Log.debug("Role status is #{@server.status}")
331
- case @server.status.to_s
332
- when "ReadyRole"
333
- :vm_status_ready
334
- when "Provisioning"
335
- :vm_status_provisioning
336
- else
337
- :vm_status_not_detected
338
- end
339
- end
340
- end
341
-
342
- def get_extension_status
343
- deployment_name = service.deployment_name(config[:azure_dns_name])
344
- deployment = service.deployment("hostedservices/#{config[:azure_dns_name]}/deployments/#{deployment_name}")
345
- extension_status = {}
346
-
347
- if deployment.at_css("Deployment Name") != nil
348
- role_list_xml = deployment.css("RoleInstanceList RoleInstance")
349
- role_list_xml.each do |role|
350
- if role.at_css("RoleName").text == config[:azure_vm_name]
351
- lnx_waagent_fail_msg = "Failed to deserialize the status reported by the Guest Agent"
352
- waagent_status_msg = role.at_css("GuestAgentStatus FormattedMessage Message").text
353
- if role.at_css("GuestAgentStatus Status").text == "Ready"
354
- extn_status = role.at_css("ResourceExtensionStatusList Status").text
355
- Chef::Log.debug("Resource extension status is #{extn_status}")
356
- if extn_status == "Installing"
357
- extension_status[:status] = :extension_installing
358
- extension_status[:message] = role.at_css("ResourceExtensionStatusList FormattedMessage Message").text
359
- elsif extn_status == "NotReady"
360
- extension_status[:status] = :extension_provisioning
361
- extension_status[:message] = role.at_css("ResourceExtensionStatusList FormattedMessage Message").text
362
- elsif extn_status == "Ready"
363
- extension_status[:status] = :extension_ready
364
- extension_status[:message] = role.at_css("ResourceExtensionStatusList FormattedMessage Message").text
365
- else
366
- extension_status[:status] = :extension_status_not_detected
367
- end
368
- # This fix is for linux waagent issue: api unable to deserialize the waagent status.
369
- elsif (role.at_css("GuestAgentStatus Status").text == "NotReady") && (waagent_status_msg == lnx_waagent_fail_msg)
370
- extension_status[:status] = :extension_ready
371
- else
372
- extension_status[:status] = :wagent_provisioning
373
- extension_status[:message] = role.at_css("GuestAgentStatus Message").text
374
- end
375
- else
376
- extension_status[:status] = :extension_status_not_detected
377
- end
378
- end
379
- else
380
- extension_status[:status] = :extension_status_not_detected
381
- end
382
- extension_status
383
- end
384
-
385
- def create_server_def
386
- server_def = {
387
- azure_storage_account: config[:azure_storage_account],
388
- azure_api_host_name: config[:azure_api_host_name],
389
- azure_dns_name: config[:azure_dns_name],
390
- azure_vm_name: config[:azure_vm_name],
391
- azure_service_location: config[:azure_service_location],
392
- azure_os_disk_name: config[:azure_os_disk_name],
393
- azure_source_image: config[:azure_source_image],
394
- azure_vm_size: config[:azure_vm_size],
395
- tcp_endpoints: config[:tcp_endpoints],
396
- udp_endpoints: config[:udp_endpoints],
397
- connection_protocol: config[:connection_protocol],
398
- azure_connect_to_existing_dns: config[:azure_connect_to_existing_dns],
399
- connection_user: config[:connection_user],
400
- azure_availability_set: config[:azure_availability_set],
401
- azure_affinity_group: config[:azure_affinity_group],
402
- azure_network_name: config[:azure_network_name],
403
- azure_subnet_name: config[:azure_subnet_name],
404
- ssl_cert_fingerprint: config[:thumbprint],
405
- cert_path: config[:cert_path],
406
- cert_password: config[:cert_passphrase],
407
- winrm_ssl: config[:winrm_ssl],
408
- winrm_max_timeout: config[:winrm_max_timeout].to_i * 60 * 1000, # converting minutes to milliseconds
409
- winrm_max_memory_per_shell: config[:winrm_max_memory_per_shell],
410
- }
411
-
412
- if config[:connection_protocol] == "cloud-api"
413
- server_def[:chef_extension] = get_chef_extension_name
414
- server_def[:chef_extension_publisher] = get_chef_extension_publisher
415
- server_def[:chef_extension_version] = get_chef_extension_version
416
- server_def[:chef_extension_public_param] = get_chef_extension_public_params
417
- server_def[:chef_extension_private_param] = get_chef_extension_private_params
418
- else
419
- if is_image_windows?
420
- # We can specify the AdminUsername after API version 2013-03-01. However, in this API version,
421
- # the AdminUsername is a required parameter.
422
- # Also, the user name cannot be Administrator, Admin, Admin1 etc, for enhanced security (provided by Azure)
423
- if config[:connection_user].nil? || config[:connection_user].downcase =~ /admin*/
424
- ui.error("Connection User is compulsory parameter and it cannot be named 'admin*'")
425
- exit 1
426
- # take cares of when user name contains domain
427
- # azure add role api doesn't support '\\' in user name
428
- elsif config[:connection_user].split('\\').length.eql?(2)
429
- server_def[:connection_user] = config[:connection_user].split('\\')[1]
430
- end
431
- else
432
- unless config[:connection_user]
433
- ui.error("Connection User is compulsory parameter")
434
- exit 1
435
- end
436
- unless config[:connection_password] || config[:ssh_identity_file]
437
- ui.error("Specify either SSH Key or SSH Password")
438
- exit 1
439
- end
440
- end
441
- end
442
-
443
- if is_image_windows?
444
- server_def[:os_type] = "Windows"
445
- server_def[:admin_password] = config[:connection_password]
446
- server_def[:connection_protocol] = config[:connection_protocol] || "winrm"
447
- else
448
- server_def[:os_type] = "Linux"
449
- server_def[:connection_protocol] = config[:connection_protocol].nil? || config[:connection_protocol] == "winrm" ? "ssh" : config[:connection_protocol]
450
- server_def[:connection_user] = config[:connection_user]
451
- server_def[:connection_password] = config[:connection_password]
452
- server_def[:ssh_identity_file] = config[:ssh_identity_file]
453
- server_def[:identity_file_passphrase] = config[:identity_file_passphrase]
454
- end
455
-
456
- azure_connect_to_existing_dns = config[:azure_connect_to_existing_dns]
457
- if is_image_windows? && server_def[:connection_protocol] == "winrm"
458
- port = config[:connection_port] || "5985"
459
- port = config[:connection_port] || Random.rand(64000) + 1000 if azure_connect_to_existing_dns
460
- elsif server_def[:connection_protocol] == "ssh"
461
- port = config[:connection_port] || "22"
462
- port = config[:connection_port] || Random.rand(64000) + 1000 if azure_connect_to_existing_dns
463
- end
464
-
465
- server_def[:port] = port
466
-
467
- server_def[:is_vm_image] = service.vm_image?(config[:azure_source_image])
468
- server_def[:azure_domain_name] = config[:azure_domain_name] if config[:azure_domain_name]
469
-
470
- if config[:azure_domain_user]
471
- # extract domain name since it should be part of username
472
- case config[:azure_domain_user]
473
- when /(\S+)\\(.+)/ # format - fully-qualified-DNS-domain\username
474
- server_def[:azure_domain_name] = $1 if config[:azure_domain_name].nil?
475
- server_def[:azure_user_domain_name] = $1
476
- server_def[:azure_domain_user] = $2
477
- when /(.+)@(\S+)/ # format - user@fully-qualified-DNS-domain
478
- server_def[:azure_domain_name] = $2 if config[:azure_domain_name].nil?
479
- server_def[:azure_user_domain_name] = $2
480
- server_def[:azure_domain_user] = $1
481
- else
482
- if config[:azure_domain_name].nil?
483
- ui.error('--azure-domain-name should be specified if --azure-domain-user is not in one of the following formats: fully-qualified-DNS-domain\username, user@fully-qualified-DNS-domain')
484
- exit 1
485
- end
486
- server_def[:azure_domain_user] = config[:azure_domain_user]
487
- end
488
- end
489
- server_def[:azure_domain_passwd] = config[:azure_domain_passwd]
490
- server_def[:azure_domain_ou_dn] = config[:azure_domain_ou_dn]
491
-
492
- server_def
493
- end
494
-
495
- private
496
-
497
- def set_defaults
498
- set_configs
499
- end
500
-
501
- def set_configs
502
- unless config[:connection_user].nil?
503
- config[:connection_user] = config[:connection_user]
504
- end
505
-
506
- unless config[:connection_password].nil?
507
- config[:connection_password] = config[:connection_password]
508
- end
509
-
510
- config[:azure_dns_name] = get_dns_name(config[:azure_dns_name])
511
- config[:azure_vm_name] = config[:azure_dns_name] unless config[:azure_vm_name]
512
- config[:chef_node_name] = config[:azure_vm_name] unless config[:chef_node_name]
513
- end
514
-
515
- # This is related to Windows VM's specifically and computer name
516
- # length limits for legacy computer accounts
517
- MAX_VM_NAME_CHARACTERS = 15
518
-
519
- # generate a random dns_name if azure_dns_name is empty
520
- def get_dns_name(azure_dns_name, prefix = "az-")
521
- return azure_dns_name unless azure_dns_name.nil?
522
-
523
- if config[:azure_vm_name].nil?
524
- (prefix + SecureRandom.hex((MAX_VM_NAME_CHARACTERS - prefix.length) / 2))
525
- else
526
- config[:azure_vm_name]
527
- end
528
- end
529
- end
530
- end
531
- end