knife-azure 2.0.11 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/azure/azure_interface.rb +1 -1
- data/lib/azure/custom_errors.rb +1 -1
- data/lib/azure/helpers.rb +1 -1
- data/lib/azure/resource_management/ARM_deployment_template.rb +1 -1
- data/lib/azure/resource_management/ARM_interface.rb +12 -14
- data/lib/azure/resource_management/vnet_config.rb +2 -2
- data/lib/azure/resource_management/windows_credentials.rb +5 -6
- data/lib/azure/service_management/ASM_interface.rb +1 -1
- data/lib/azure/service_management/ag.rb +1 -1
- data/lib/azure/service_management/certificate.rb +4 -4
- data/lib/azure/service_management/connection.rb +1 -1
- data/lib/azure/service_management/deploy.rb +1 -1
- data/lib/azure/service_management/disk.rb +1 -1
- data/lib/azure/service_management/host.rb +1 -1
- data/lib/azure/service_management/image.rb +1 -1
- data/lib/azure/service_management/loadbalancer.rb +1 -1
- data/lib/azure/service_management/rest.rb +1 -1
- data/lib/azure/service_management/role.rb +1 -1
- data/lib/azure/service_management/storageaccount.rb +1 -1
- data/lib/azure/service_management/utility.rb +1 -1
- data/lib/azure/service_management/vnet.rb +1 -1
- data/lib/chef/knife/azure_ag_create.rb +5 -5
- data/lib/chef/knife/azure_ag_list.rb +2 -2
- data/lib/chef/knife/azure_image_list.rb +4 -4
- data/lib/chef/knife/azure_internal-lb_create.rb +6 -6
- data/lib/chef/knife/azure_internal-lb_list.rb +2 -2
- data/lib/chef/knife/azure_server_create.rb +71 -71
- data/lib/chef/knife/azure_server_delete.rb +8 -8
- data/lib/chef/knife/azure_server_list.rb +2 -2
- data/lib/chef/knife/azure_server_show.rb +2 -2
- data/lib/chef/knife/azure_vnet_create.rb +6 -6
- data/lib/chef/knife/azure_vnet_list.rb +2 -2
- data/lib/chef/knife/azurerm_server_create.rb +45 -45
- data/lib/chef/knife/azurerm_server_delete.rb +9 -9
- data/lib/chef/knife/azurerm_server_list.rb +4 -4
- data/lib/chef/knife/azurerm_server_show.rb +4 -4
- data/lib/chef/knife/bootstrap/bootstrapper.rb +29 -35
- data/lib/chef/knife/bootstrap/common_bootstrap_options.rb +3 -5
- data/lib/chef/knife/bootstrap_azure.rb +16 -16
- data/lib/chef/knife/bootstrap_azurerm.rb +7 -7
- data/lib/chef/knife/{azure_base.rb → helpers/azure_base.rb} +48 -59
- data/lib/chef/knife/{azurerm_base.rb → helpers/azurerm_base.rb} +40 -51
- data/lib/knife-azure/version.rb +2 -2
- metadata +15 -29
@@ -2,7 +2,7 @@
|
|
2
2
|
# Author:: Barry Davis (barryd@jetstreamsoftware.com)
|
3
3
|
# Author:: Adam Jacob (<adam@chef.io>)
|
4
4
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
5
|
-
# Copyright:: Copyright
|
5
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
6
6
|
# License:: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# limitations under the License.
|
19
19
|
#
|
20
20
|
|
21
|
-
require_relative "azurerm_base"
|
21
|
+
require_relative "helpers/azurerm_base"
|
22
22
|
|
23
23
|
class Chef
|
24
24
|
class Knife
|
@@ -30,7 +30,7 @@ class Chef
|
|
30
30
|
# These two are needed for the '--purge' deletion case
|
31
31
|
require "chef/node"
|
32
32
|
require "chef/api_client"
|
33
|
-
include Knife::AzurermBase
|
33
|
+
include Knife::AzurermBase
|
34
34
|
end
|
35
35
|
|
36
36
|
banner "knife azurerm server delete SERVER [SERVER] (options)"
|
@@ -51,7 +51,7 @@ class Chef
|
|
51
51
|
long: "--delete-resource-group",
|
52
52
|
boolean: true,
|
53
53
|
default: false,
|
54
|
-
description: "Deletes corresponding resource group along with
|
54
|
+
description: "Deletes corresponding resource group along with Virtual Machine."
|
55
55
|
|
56
56
|
# Extracted from Chef::Knife.delete_object, because it has a
|
57
57
|
# confirmation step built in... By specifying the '--purge'
|
@@ -74,10 +74,10 @@ class Chef
|
|
74
74
|
validate_arm_keys!(:azure_resource_group_name)
|
75
75
|
@vm_name = @name_args[0]
|
76
76
|
|
77
|
-
if
|
77
|
+
if config[:delete_resource_group]
|
78
78
|
delete_resource_group
|
79
79
|
else
|
80
|
-
service.delete_server(
|
80
|
+
service.delete_server(config[:azure_resource_group_name], @vm_name)
|
81
81
|
end
|
82
82
|
|
83
83
|
if config[:purge]
|
@@ -90,18 +90,18 @@ class Chef
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def delete_resource_group
|
93
|
-
resource_group_name =
|
93
|
+
resource_group_name = config[:azure_resource_group_name]
|
94
94
|
ui.warn "Deleting resource group will delete all the virtual_machines inside it."
|
95
95
|
begin
|
96
96
|
ui.confirm("Do you really want to delete resource group")
|
97
97
|
rescue SystemExit # Need to handle this as confirming with N/n raises SystemExit exception
|
98
98
|
server = nil # Cleanup is implicitly performed in other cloud plugins
|
99
99
|
ui.warn "Resource group not deleted. Proceeding for server delete ..."
|
100
|
-
service.delete_server(
|
100
|
+
service.delete_server(config[:azure_resource_group_name], @vm_name)
|
101
101
|
exit
|
102
102
|
end
|
103
103
|
ui.info "Deleting Resource Group " + resource_group_name + " and Virtual Machine " + @vm_name + " .."
|
104
|
-
service.delete_resource_group(
|
104
|
+
service.delete_resource_group(config[:azure_resource_group_name])
|
105
105
|
ui.warn "Deleted resource_group_name #{resource_group_name} and #{@vm_name}"
|
106
106
|
end
|
107
107
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Adam Jacob (<adam@chef.io>)
|
3
|
-
# Copyright:: Copyright
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -16,7 +16,7 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require_relative "azurerm_base"
|
19
|
+
require_relative "helpers/azurerm_base"
|
20
20
|
|
21
21
|
class Chef
|
22
22
|
class Knife
|
@@ -27,7 +27,7 @@ class Chef
|
|
27
27
|
banner "knife azurerm server list (options)"
|
28
28
|
|
29
29
|
deps do
|
30
|
-
include Knife::AzurermBase
|
30
|
+
include Knife::AzurermBase
|
31
31
|
end
|
32
32
|
|
33
33
|
def run
|
@@ -36,7 +36,7 @@ class Chef
|
|
36
36
|
get_azure_cli_version
|
37
37
|
validate_arm_keys!
|
38
38
|
begin
|
39
|
-
service.list_servers(
|
39
|
+
service.list_servers(config[:azure_resource_group_name])
|
40
40
|
rescue => error
|
41
41
|
service.common_arm_rescue_block(error)
|
42
42
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Meera Navale (meera.navale@msystechnologies.com)
|
3
|
-
# Copyright:: Copyright
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -16,7 +16,7 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require_relative "azurerm_base"
|
19
|
+
require_relative "helpers/azurerm_base"
|
20
20
|
|
21
21
|
class Chef
|
22
22
|
class Knife
|
@@ -27,7 +27,7 @@ class Chef
|
|
27
27
|
banner "knife azurerm server show SERVER (options)"
|
28
28
|
|
29
29
|
deps do
|
30
|
-
include Knife::AzurermBase
|
30
|
+
include Knife::AzurermBase
|
31
31
|
end
|
32
32
|
|
33
33
|
def run
|
@@ -36,7 +36,7 @@ class Chef
|
|
36
36
|
get_azure_cli_version
|
37
37
|
validate_arm_keys!(:azure_resource_group_name)
|
38
38
|
begin
|
39
|
-
service.show_server(@name_args[0],
|
39
|
+
service.show_server(@name_args[0], config[:azure_resource_group_name])
|
40
40
|
rescue => error
|
41
41
|
service.common_arm_rescue_block(error)
|
42
42
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Aliasgar Batterywala (aliasgar.batterywala@clogeny.com)
|
3
|
-
# Copyright:: Copyright
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -16,6 +16,8 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
+
require_relative "../../../azure/resource_management/ARM_interface"
|
20
|
+
|
19
21
|
class Chef
|
20
22
|
class Knife
|
21
23
|
class Bootstrap
|
@@ -39,13 +41,13 @@ class Chef
|
|
39
41
|
|
40
42
|
# get latest version
|
41
43
|
def get_chef_extension_version(chef_extension_name = nil)
|
42
|
-
if
|
43
|
-
|
44
|
+
if config[:azure_chef_extension_version]
|
45
|
+
config[:azure_chef_extension_version]
|
44
46
|
else
|
45
47
|
chef_extension_name ||= get_chef_extension_name
|
46
48
|
if @service.instance_of? Azure::ResourceManagement::ARMInterface
|
47
49
|
service.get_latest_chef_extension_version(
|
48
|
-
azure_service_location:
|
50
|
+
azure_service_location: config[:azure_service_location],
|
49
51
|
chef_extension_publisher: get_chef_extension_publisher,
|
50
52
|
chef_extension: chef_extension_name
|
51
53
|
)
|
@@ -57,7 +59,7 @@ class Chef
|
|
57
59
|
end
|
58
60
|
|
59
61
|
def ohai_hints
|
60
|
-
hint_values =
|
62
|
+
hint_values = config[:ohai_hints]
|
61
63
|
if hint_values.casecmp("default") == 0
|
62
64
|
default_hint_options
|
63
65
|
else
|
@@ -67,47 +69,39 @@ class Chef
|
|
67
69
|
|
68
70
|
def get_chef_extension_public_params
|
69
71
|
pub_config = {}
|
70
|
-
if
|
71
|
-
pub_config[:client_rb] = File.read(File.expand_path(
|
72
|
+
if config[:azure_extension_client_config]
|
73
|
+
pub_config[:client_rb] = File.read(File.expand_path(config[:azure_extension_client_config]))
|
72
74
|
else
|
73
75
|
pub_config[:client_rb] = "chef_server_url \t #{Chef::Config[:chef_server_url].to_json}\nvalidation_client_name\t#{Chef::Config[:validation_client_name].to_json}"
|
74
76
|
end
|
75
77
|
|
76
|
-
pub_config[:runlist] =
|
77
|
-
pub_config[:custom_json_attr] =
|
78
|
-
pub_config[:extendedLogs] =
|
79
|
-
pub_config[:hints] = ohai_hints if @service.instance_of?(Azure::ResourceManagement::ARMInterface) && !
|
80
|
-
pub_config[:chef_daemon_interval] =
|
81
|
-
pub_config[:daemon] =
|
78
|
+
pub_config[:runlist] = config[:run_list].empty? ? "" : config[:run_list].join(",").to_json
|
79
|
+
pub_config[:custom_json_attr] = config[:json_attributes] || {}
|
80
|
+
pub_config[:extendedLogs] = config[:extended_logs] ? "true" : "false"
|
81
|
+
pub_config[:hints] = ohai_hints if @service.instance_of?(Azure::ResourceManagement::ARMInterface) && !config[:ohai_hints].nil?
|
82
|
+
pub_config[:chef_daemon_interval] = config[:chef_daemon_interval] if config[:chef_daemon_interval]
|
83
|
+
pub_config[:daemon] = config[:daemon] if config[:daemon]
|
82
84
|
|
83
85
|
# bootstrap attributes
|
84
86
|
pub_config[:bootstrap_options] = {}
|
85
|
-
pub_config[:bootstrap_options][:environment] =
|
86
|
-
pub_config[:bootstrap_options][:chef_node_name] =
|
87
|
+
pub_config[:bootstrap_options][:environment] = config[:environment] if config[:environment]
|
88
|
+
pub_config[:bootstrap_options][:chef_node_name] = config[:chef_node_name] if config[:chef_node_name]
|
87
89
|
pub_config[:bootstrap_options][:chef_server_url] = Chef::Config[:chef_server_url] if Chef::Config[:chef_server_url]
|
88
90
|
pub_config[:bootstrap_options][:validation_client_name] = Chef::Config[:validation_client_name] if Chef::Config[:validation_client_name]
|
89
|
-
pub_config[:bootstrap_options][:node_verify_api_cert] =
|
90
|
-
pub_config[:bootstrap_options][:bootstrap_version] =
|
91
|
-
pub_config[:bootstrap_options][:node_ssl_verify_mode] =
|
92
|
-
pub_config[:bootstrap_options][:bootstrap_proxy] =
|
91
|
+
pub_config[:bootstrap_options][:node_verify_api_cert] = config[:node_verify_api_cert] ? "true" : "false" if config.key?(:node_verify_api_cert)
|
92
|
+
pub_config[:bootstrap_options][:bootstrap_version] = config[:bootstrap_version] if config[:bootstrap_version]
|
93
|
+
pub_config[:bootstrap_options][:node_ssl_verify_mode] = config[:node_ssl_verify_mode] if config[:node_ssl_verify_mode]
|
94
|
+
pub_config[:bootstrap_options][:bootstrap_proxy] = config[:bootstrap_proxy] if config[:bootstrap_proxy]
|
93
95
|
pub_config
|
94
96
|
end
|
95
97
|
|
96
98
|
def load_correct_secret
|
97
|
-
|
98
|
-
|
99
|
-
cli_secret_file = config[:encrypted_data_bag_secret_file]
|
100
|
-
cli_secret = config[:encrypted_data_bag_secret]
|
101
|
-
|
102
|
-
# The value set in knife.rb gets set in config object too
|
103
|
-
# That's why setting cli objects to nil if the values are specified in knife.rb
|
104
|
-
cli_secret_file = nil if cli_secret_file == knife_secret_file
|
105
|
-
cli_secret = nil if cli_secret == knife_secret
|
99
|
+
secret_file = config[:encrypted_data_bag_secret_file]
|
100
|
+
secret = config[:encrypted_data_bag_secret]
|
106
101
|
|
107
|
-
|
108
|
-
knife_secret_file = Chef::EncryptedDataBagItem.load_secret(knife_secret_file) unless knife_secret_file.nil?
|
102
|
+
secret_file = Chef::EncryptedDataBagItem.load_secret(secret_file) unless secret_file.nil?
|
109
103
|
|
110
|
-
|
104
|
+
secret_file || secret
|
111
105
|
end
|
112
106
|
|
113
107
|
def create_node_and_client_pem
|
@@ -115,7 +109,7 @@ class Chef
|
|
115
109
|
require "chef/knife/bootstrap/client_builder"
|
116
110
|
Chef::Knife::Bootstrap::ClientBuilder.new(
|
117
111
|
chef_config: Chef::Config,
|
118
|
-
|
112
|
+
config: config,
|
119
113
|
ui: ui
|
120
114
|
)
|
121
115
|
end
|
@@ -153,9 +147,9 @@ class Chef
|
|
153
147
|
end
|
154
148
|
|
155
149
|
# SSL cert bootstrap support
|
156
|
-
if
|
157
|
-
if File.exist?(File.expand_path(
|
158
|
-
pri_config[:chef_server_crt] = File.read(File.expand_path(
|
150
|
+
if config[:cert_path]
|
151
|
+
if File.exist?(File.expand_path(config[:cert_path]))
|
152
|
+
pri_config[:chef_server_crt] = File.read(File.expand_path(config[:cert_path]))
|
159
153
|
else
|
160
154
|
ui.error("Specified SSL certificate does not exist.")
|
161
155
|
exit 1
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Aliasgar Batterywala (aliasgar.batterywala@clogeny.com)
|
3
|
-
# Copyright:: Copyright
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -46,8 +46,7 @@ class Chef
|
|
46
46
|
short: "-m LOCATION",
|
47
47
|
long: "--azure-service-location LOCATION",
|
48
48
|
description: "Required if not using an Affinity Group. Specifies the geographic location - the name of the data center location that is valid for your subscription.
|
49
|
-
Eg: West US, East US, East Asia, Southeast Asia, North Europe, West Europe"
|
50
|
-
proc: Proc.new { |lo| Chef::Config[:knife][:azure_service_location] = lo }
|
49
|
+
Eg: West US, East US, East Asia, Southeast Asia, North Europe, West Europe"
|
51
50
|
|
52
51
|
option :azure_storage_account,
|
53
52
|
short: "-a NAME",
|
@@ -69,8 +68,7 @@ class Chef
|
|
69
68
|
long: "--azure-vm-size SIZE",
|
70
69
|
description: "Optional. Size of virtual machine. Default is Standard_A1_v2.
|
71
70
|
Eg: Standard_A1_v2, Standard_F2, Standard_G1 etc.",
|
72
|
-
default: "Standard_A1_v2"
|
73
|
-
proc: Proc.new { |si| Chef::Config[:knife][:azure_vm_size] = si }
|
71
|
+
default: "Standard_A1_v2"
|
74
72
|
|
75
73
|
deprecated_option :bootstrap_protocol,
|
76
74
|
replacement: :connection_protocol,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Aliasgar Batterywala (aliasgar.batterywala@clogeny.com)
|
3
|
-
# Copyright:: Copyright
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -16,7 +16,7 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require_relative "azure_base"
|
19
|
+
require_relative "helpers/azure_base"
|
20
20
|
require "chef/knife/bootstrap"
|
21
21
|
require_relative "bootstrap/common_bootstrap_options"
|
22
22
|
require_relative "bootstrap/bootstrapper"
|
@@ -52,7 +52,7 @@ class Chef
|
|
52
52
|
def plugin_create_instance!
|
53
53
|
if @name_args.length == 1
|
54
54
|
service.add_extension(@name_args[0], set_ext_params)
|
55
|
-
if
|
55
|
+
if config[:extended_logs]
|
56
56
|
print "\n\nWaiting for the Chef Extension to become available/ready"
|
57
57
|
wait_until_extension_available(Time.now, 10)
|
58
58
|
print "\n\nWaiting for the first chef-client run"
|
@@ -89,20 +89,20 @@ class Chef
|
|
89
89
|
ui.info "Looking for the server #{@name_args[0]}..."
|
90
90
|
server = service.find_server(
|
91
91
|
name: @name_args[0],
|
92
|
-
azure_dns_name:
|
92
|
+
azure_dns_name: config[:azure_dns_name]
|
93
93
|
)
|
94
94
|
|
95
95
|
## if azure_dns_name value not passed by user then set it using the hostedservicename attribute from the retrieved server's object ##
|
96
|
-
config[:azure_dns_name] = server.hostedservicename if
|
96
|
+
config[:azure_dns_name] = server.hostedservicename if config[:azure_dns_name].nil? && (server.instance_of? Azure::Role)
|
97
97
|
unless server.instance_of? Azure::Role
|
98
98
|
if server.nil?
|
99
|
-
if !
|
100
|
-
raise "Hosted service #{
|
99
|
+
if !config[:azure_dns_name].nil?
|
100
|
+
raise "Hosted service #{config[:azure_dns_name]} does not exist."
|
101
101
|
else
|
102
102
|
raise "Server #{@name_args[0]} does not exist."
|
103
103
|
end
|
104
104
|
else
|
105
|
-
raise "Server #{@name_args[0]} does not exist under the hosted service #{
|
105
|
+
raise "Server #{@name_args[0]} does not exist under the hosted service #{config[:azure_dns_name]}."
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
@@ -122,7 +122,7 @@ class Chef
|
|
122
122
|
raise "OS type #{server.os_type} is not supported."
|
123
123
|
end
|
124
124
|
|
125
|
-
ext_params[:azure_dns_name] = server.hostedservicename ||
|
125
|
+
ext_params[:azure_dns_name] = server.hostedservicename || config[:azure_dns_name]
|
126
126
|
ext_params[:deploy_name] = server.deployname
|
127
127
|
ext_params[:role_xml] = server.role_xml
|
128
128
|
ext_params[:azure_vm_name] = @name_args[0]
|
@@ -139,10 +139,10 @@ class Chef
|
|
139
139
|
ext_params
|
140
140
|
end
|
141
141
|
|
142
|
-
def wait_until_extension_available(extension_deploy_start_time,
|
143
|
-
|
144
|
-
if
|
145
|
-
## extension
|
142
|
+
def wait_until_extension_available(extension_deploy_start_time, extension_availability_wait_timeout)
|
143
|
+
extension_availability_wait_time = ((Time.now - extension_deploy_start_time) / 60).round
|
144
|
+
if extension_availability_wait_time <= extension_availability_wait_timeout
|
145
|
+
## extension availability wait time has not exceeded the maximum threshold set for the wait timeout ##
|
146
146
|
my_role = nil
|
147
147
|
sleep_and_wait = false
|
148
148
|
deployment = fetch_deployment
|
@@ -178,12 +178,12 @@ class Chef
|
|
178
178
|
sleep 30
|
179
179
|
wait_until_extension_available(
|
180
180
|
extension_deploy_start_time,
|
181
|
-
|
181
|
+
extension_availability_wait_timeout
|
182
182
|
)
|
183
183
|
end
|
184
184
|
else
|
185
|
-
## extension
|
186
|
-
raise "\nUnable to fetch chef-client run logs as Chef Extension seems to be unavailable even after #{
|
185
|
+
## extension availability wait time exceeded maximum threshold set for the wait timeout ##
|
186
|
+
raise "\nUnable to fetch chef-client run logs as Chef Extension seems to be unavailable even after #{extension_availability_wait_timeout} minutes of its deployment.\n"
|
187
187
|
end
|
188
188
|
end
|
189
189
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Nimisha Sharad (nimisha.sharad@clogeny.com)
|
3
|
-
# Copyright:: Copyright
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -16,7 +16,7 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require_relative "azurerm_base"
|
19
|
+
require_relative "helpers/azurerm_base"
|
20
20
|
require "chef/knife/bootstrap"
|
21
21
|
require_relative "bootstrap/common_bootstrap_options"
|
22
22
|
require_relative "bootstrap/bootstrapper"
|
@@ -30,7 +30,7 @@ class Chef
|
|
30
30
|
|
31
31
|
deps do
|
32
32
|
require "time"
|
33
|
-
include Knife::AzurermBase
|
33
|
+
include Knife::AzurermBase
|
34
34
|
end
|
35
35
|
|
36
36
|
banner "knife bootstrap azurerm SERVER (options)"
|
@@ -87,7 +87,7 @@ class Chef
|
|
87
87
|
#### run() execution ends ####
|
88
88
|
|
89
89
|
def set_ext_params
|
90
|
-
server = service.find_server(
|
90
|
+
server = service.find_server(config[:azure_resource_group_name], name_args[0])
|
91
91
|
|
92
92
|
if server
|
93
93
|
if service.extension_already_installed?(server)
|
@@ -107,16 +107,16 @@ class Chef
|
|
107
107
|
raise "OS type #{server.storage_profile.os_disk.os_type} is not supported."
|
108
108
|
end
|
109
109
|
|
110
|
-
ext_params[:azure_resource_group_name] =
|
110
|
+
ext_params[:azure_resource_group_name] = config[:azure_resource_group_name]
|
111
111
|
ext_params[:azure_vm_name] = @name_args[0]
|
112
|
-
ext_params[:azure_service_location] =
|
112
|
+
ext_params[:azure_service_location] = config[:azure_service_location]
|
113
113
|
ext_params[:chef_extension_publisher] = get_chef_extension_publisher
|
114
114
|
ext_params[:chef_extension_version] = get_chef_extension_version(ext_params[:chef_extension])
|
115
115
|
ext_params[:chef_extension_public_param] = get_chef_extension_public_params
|
116
116
|
ext_params[:chef_extension_private_param] = get_chef_extension_private_params
|
117
117
|
end
|
118
118
|
else
|
119
|
-
raise "The given server '#{@name_args[0]}' does not exist under resource group '#{
|
119
|
+
raise "The given server '#{@name_args[0]}' does not exist under resource group '#{config[:azure_resource_group_name]}'"
|
120
120
|
end
|
121
121
|
|
122
122
|
ext_params
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Author:: Barry Davis (barryd@jetstreamsoftware.com)
|
2
2
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
3
|
-
# Copyright:: Copyright
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -29,26 +29,23 @@ class Chef
|
|
29
29
|
deps do
|
30
30
|
require "readline"
|
31
31
|
require "chef/json_compat"
|
32
|
-
require_relative "
|
32
|
+
require_relative "../../../azure/service_management/ASM_interface"
|
33
33
|
end
|
34
34
|
|
35
35
|
option :azure_subscription_id,
|
36
36
|
short: "-S ID",
|
37
37
|
long: "--azure-subscription-id ID",
|
38
|
-
description: "Your Azure subscription ID"
|
39
|
-
proc: proc { |key| Chef::Config[:knife][:azure_subscription_id] = key }
|
38
|
+
description: "Your Azure subscription ID"
|
40
39
|
|
41
40
|
option :azure_mgmt_cert,
|
42
41
|
short: "-p FILENAME",
|
43
42
|
long: "--azure-mgmt-cert FILENAME",
|
44
|
-
description: "Your Azure PEM file name"
|
45
|
-
proc: proc { |key| Chef::Config[:knife][:azure_mgmt_cert] = key }
|
43
|
+
description: "Your Azure PEM file name"
|
46
44
|
|
47
45
|
option :azure_api_host_name,
|
48
46
|
short: "-H HOSTNAME",
|
49
47
|
long: "--azure-api-host-name HOSTNAME",
|
50
|
-
description: "Your Azure host name"
|
51
|
-
proc: proc { |key| Chef::Config[:knife][:azure_api_host_name] = key }
|
48
|
+
description: "Your Azure host name"
|
52
49
|
|
53
50
|
option :verify_ssl_cert,
|
54
51
|
long: "--verify-ssl-cert",
|
@@ -58,40 +55,34 @@ class Chef
|
|
58
55
|
|
59
56
|
option :azure_publish_settings_file,
|
60
57
|
long: "--azure-publish-settings-file FILENAME",
|
61
|
-
description: "Your Azure Publish Settings File"
|
62
|
-
proc: proc { |key| Chef::Config[:knife][:azure_publish_settings_file] = key }
|
58
|
+
description: "Your Azure Publish Settings File"
|
63
59
|
end
|
64
60
|
end
|
65
61
|
|
66
62
|
def is_image_windows?
|
67
63
|
images = service.list_images
|
68
|
-
target_image = images.select { |i| i.name ==
|
64
|
+
target_image = images.select { |i| i.name == config[:azure_source_image] }
|
69
65
|
if target_image[0].nil?
|
70
66
|
ui.error('Invalid image. Use the command "knife azure image list" to verify the image name')
|
71
67
|
exit 1
|
72
68
|
else
|
73
|
-
|
69
|
+
target_image[0].os == "Windows"
|
74
70
|
end
|
75
71
|
end
|
76
72
|
|
77
73
|
def service
|
78
74
|
@service ||= begin
|
79
75
|
service = Azure::ServiceManagement::ASMInterface.new(
|
80
|
-
azure_subscription_id:
|
81
|
-
azure_mgmt_cert:
|
82
|
-
azure_api_host_name:
|
83
|
-
verify_ssl_cert:
|
76
|
+
azure_subscription_id: config[:azure_subscription_id],
|
77
|
+
azure_mgmt_cert: config[:azure_mgmt_cert],
|
78
|
+
azure_api_host_name: config[:azure_api_host_name],
|
79
|
+
verify_ssl_cert: config[:verify_ssl_cert]
|
84
80
|
)
|
85
81
|
end
|
86
82
|
@service.ui = ui
|
87
83
|
@service
|
88
84
|
end
|
89
85
|
|
90
|
-
def locate_config_value(key)
|
91
|
-
key = key.to_sym
|
92
|
-
config[key] || Chef::Config[:knife][key]
|
93
|
-
end
|
94
|
-
|
95
86
|
def msg_pair(label, value, color = :cyan)
|
96
87
|
if value && !value.to_s.empty?
|
97
88
|
puts "#{ui.color(label, color)}: #{value}"
|
@@ -103,16 +94,16 @@ class Chef
|
|
103
94
|
msg_pair("DNS Name", server.hostedservicename + ".cloudapp.net")
|
104
95
|
msg_pair("VM Name", server.name)
|
105
96
|
msg_pair("Size", server.size)
|
106
|
-
msg_pair("Azure Source Image",
|
107
|
-
msg_pair("Azure Service Location",
|
97
|
+
msg_pair("Azure Source Image", config[:azure_source_image])
|
98
|
+
msg_pair("Azure Service Location", config[:azure_service_location])
|
108
99
|
msg_pair("Public Ip Address", server.publicipaddress)
|
109
100
|
msg_pair("Private Ip Address", server.ipaddress)
|
110
101
|
msg_pair("SSH Port", server.sshport) unless server.sshport.nil?
|
111
102
|
msg_pair("WinRM Port", server.winrmport) unless server.winrmport.nil?
|
112
103
|
msg_pair("TCP Ports", server.tcpports) unless server.tcpports.nil? || server.tcpports.empty?
|
113
104
|
msg_pair("UDP Ports", server.udpports) unless server.udpports.nil? || server.udpports.empty?
|
114
|
-
msg_pair("Environment",
|
115
|
-
msg_pair("Runlist",
|
105
|
+
msg_pair("Environment", config[:environment] || "_default")
|
106
|
+
msg_pair("Runlist", config[:run_list]) unless config[:run_list].empty?
|
116
107
|
puts "\n"
|
117
108
|
end
|
118
109
|
|
@@ -121,61 +112,61 @@ class Chef
|
|
121
112
|
end
|
122
113
|
|
123
114
|
# validate command pre-requisites (cli options)
|
124
|
-
# (
|
115
|
+
# (config[:connection_password].length <= 6 && config[:connection_password].length >= 72)
|
125
116
|
def validate_params!
|
126
|
-
if
|
117
|
+
if config[:connection_password] && !config[:connection_password].length.between?(6, 72)
|
127
118
|
ui.error("The supplied connection password must be 6-72 characters long and meet password complexity requirements")
|
128
119
|
exit 1
|
129
120
|
end
|
130
121
|
|
131
|
-
if
|
122
|
+
if config[:azure_connect_to_existing_dns] && config[:azure_vm_name].nil?
|
132
123
|
ui.error("Specify the VM name using --azure-vm-name option, since you are connecting to existing dns")
|
133
124
|
exit 1
|
134
125
|
end
|
135
126
|
|
136
|
-
unless !!
|
127
|
+
unless !!config[:azure_service_location] ^ !!config[:azure_affinity_group]
|
137
128
|
ui.error("Specify either --azure-service-location or --azure-affinity-group")
|
138
129
|
exit 1
|
139
130
|
end
|
140
131
|
|
141
|
-
unless service.valid_image?(
|
142
|
-
ui.error("Image '#{
|
132
|
+
unless service.valid_image?(config[:azure_source_image])
|
133
|
+
ui.error("Image '#{config[:azure_source_image]}' is invalid")
|
143
134
|
exit 1
|
144
135
|
end
|
145
136
|
|
146
137
|
# Validate join domain requirements.
|
147
|
-
if
|
148
|
-
if
|
138
|
+
if config[:azure_domain_name] || config[:azure_domain_user]
|
139
|
+
if config[:azure_domain_user].nil? || config[:azure_domain_passwd].nil?
|
149
140
|
ui.error("Must specify both --azure-domain-user and --azure-domain-passwd.")
|
150
141
|
exit 1
|
151
142
|
end
|
152
143
|
end
|
153
144
|
|
154
|
-
if
|
145
|
+
if config[:winrm_ssl] && config[:thumbprint].nil? && config[:winrm_no_verify_cert].nil?
|
155
146
|
ui.error("The SSL transport was specified without the --thumbprint option. Specify a thumbprint, or alternatively set the --winrm-no-verify-cert option to skip verification.")
|
156
147
|
exit 1
|
157
148
|
end
|
158
149
|
|
159
|
-
if
|
150
|
+
if config[:extended_logs] && config[:connection_protocol] != "cloud-api"
|
160
151
|
ui.error("--extended-logs option only works with --bootstrap-protocol cloud-api")
|
161
152
|
exit 1
|
162
153
|
end
|
163
154
|
|
164
|
-
if
|
155
|
+
if config[:connection_protocol] == "cloud-api" && config[:azure_vm_name].nil? && config[:azure_dns_name].nil?
|
165
156
|
ui.error("Specifying the DNS name using --azure-dns-name or VM name using --azure-vm-name option is required with --bootstrap-protocol cloud-api")
|
166
157
|
exit 1
|
167
158
|
end
|
168
159
|
|
169
|
-
if
|
160
|
+
if config[:daemon]
|
170
161
|
unless is_image_windows?
|
171
162
|
raise ArgumentError, "The daemon option is only supported for Windows nodes."
|
172
163
|
end
|
173
164
|
|
174
|
-
unless
|
165
|
+
unless config[:connection_protocol] == "cloud-api"
|
175
166
|
raise ArgumentError, "The --daemon option requires the use of --bootstrap-protocol cloud-api"
|
176
167
|
end
|
177
168
|
|
178
|
-
unless %w{none service task}.include?(
|
169
|
+
unless %w{none service task}.include?(config[:daemon].downcase)
|
179
170
|
raise ArgumentError, "Invalid value for --daemon option. Valid values are 'none', 'service' and 'task'."
|
180
171
|
end
|
181
172
|
end
|
@@ -185,7 +176,7 @@ class Chef
|
|
185
176
|
def validate!(keys)
|
186
177
|
errors = []
|
187
178
|
keys.each do |k|
|
188
|
-
if
|
179
|
+
if config[k].nil?
|
189
180
|
errors << "You did not provide a valid '#{pretty_key(k)}' value. Please set knife[:#{k}] in your knife.rb or pass as an option."
|
190
181
|
end
|
191
182
|
end
|
@@ -197,13 +188,13 @@ class Chef
|
|
197
188
|
mandatory_keys = %i{azure_subscription_id azure_mgmt_cert azure_api_host_name}
|
198
189
|
keys.concat(mandatory_keys)
|
199
190
|
|
200
|
-
unless
|
201
|
-
config[:azure_mgmt_cert] = File.read find_file(
|
191
|
+
unless config[:azure_mgmt_cert].nil?
|
192
|
+
config[:azure_mgmt_cert] = File.read find_file(config[:azure_mgmt_cert])
|
202
193
|
end
|
203
194
|
|
204
|
-
if !
|
205
|
-
parse_publish_settings_file(
|
206
|
-
elsif
|
195
|
+
if !config[:azure_publish_settings_file].nil?
|
196
|
+
parse_publish_settings_file(config[:azure_publish_settings_file])
|
197
|
+
elsif config[:azure_subscription_id].nil? && config[:azure_mgmt_cert].nil? && config[:azure_api_host_name].nil?
|
207
198
|
azureprofile_file = get_azure_profile_file_path
|
208
199
|
if File.exist?(File.expand_path(azureprofile_file))
|
209
200
|
errors = parse_azure_profile(azureprofile_file, errors)
|
@@ -224,15 +215,15 @@ class Chef
|
|
224
215
|
# check given PublishSettings XML file format.Currently PublishSettings file have two different XML format
|
225
216
|
if profile.attribute("SchemaVersion").nil?
|
226
217
|
management_cert = OpenSSL::PKCS12.new(Base64.decode64(profile.attribute("ManagementCertificate").value))
|
227
|
-
|
218
|
+
config[:azure_api_host_name] = URI(profile.attribute("Url").value).host
|
228
219
|
elsif profile.attribute("SchemaVersion").value == "2.0"
|
229
220
|
management_cert = OpenSSL::PKCS12.new(Base64.decode64(subscription.attribute("ManagementCertificate").value))
|
230
|
-
|
221
|
+
config[:azure_api_host_name] = URI(subscription.attribute("ServiceManagementUrl").value).host
|
231
222
|
else
|
232
223
|
ui.error("Publish settings file Schema not supported - " + filename)
|
233
224
|
end
|
234
|
-
|
235
|
-
|
225
|
+
config[:azure_mgmt_cert] = management_cert.certificate.to_pem + management_cert.key.to_pem
|
226
|
+
config[:azure_subscription_id] = doc.at_css("Subscription").attribute("Id").value
|
236
227
|
rescue
|
237
228
|
ui.error("Incorrect publish settings file - " + filename)
|
238
229
|
exit 1
|
@@ -252,11 +243,11 @@ class Chef
|
|
252
243
|
default_subscription = get_default_subscription(azure_profile)
|
253
244
|
if default_subscription.key?("id") && default_subscription.key?("managementCertificate") && default_subscription.key?("managementEndpointUrl")
|
254
245
|
|
255
|
-
|
246
|
+
config[:azure_subscription_id] = default_subscription["id"]
|
256
247
|
mgmt_key = OpenSSL::PKey::RSA.new(default_subscription["managementCertificate"]["key"]).to_pem
|
257
248
|
mgmt_cert = OpenSSL::X509::Certificate.new(default_subscription["managementCertificate"]["cert"]).to_pem
|
258
|
-
|
259
|
-
|
249
|
+
config[:azure_mgmt_cert] = mgmt_key + mgmt_cert
|
250
|
+
config[:azure_api_host_name] = URI(default_subscription["managementEndpointUrl"]).host
|
260
251
|
else
|
261
252
|
errors << "Check if values set for 'id', 'managementCertificate', 'managementEndpointUrl' in -> #{filename} for 'defaultSubscription'. \n OR "
|
262
253
|
end
|
@@ -300,10 +291,8 @@ class Chef
|
|
300
291
|
end
|
301
292
|
|
302
293
|
def fetch_deployment
|
303
|
-
deployment_name = service.deployment_name(
|
304
|
-
|
305
|
-
|
306
|
-
deployment
|
294
|
+
deployment_name = service.deployment_name(config[:azure_dns_name])
|
295
|
+
service.deployment("hostedservices/#{config[:azure_dns_name]}/deployments/#{deployment_name}")
|
307
296
|
end
|
308
297
|
|
309
298
|
def fetch_role
|
@@ -312,7 +301,7 @@ class Chef
|
|
312
301
|
if deployment.at_css("Deployment Name") != nil
|
313
302
|
role_list_xml = deployment.css("RoleInstanceList RoleInstance")
|
314
303
|
role_list_xml.each do |role|
|
315
|
-
if role.at_css("RoleName").text == (
|
304
|
+
if role.at_css("RoleName").text == (config[:azure_vm_name] || @name_args[0])
|
316
305
|
return role
|
317
306
|
end
|
318
307
|
end
|
@@ -391,11 +380,11 @@ class Chef
|
|
391
380
|
end
|
392
381
|
else
|
393
382
|
## Chef Extension could not be found ##
|
394
|
-
ui.error("Unable to find Chef extension under role #{
|
383
|
+
ui.error("Unable to find Chef extension under role #{config[:azure_vm_name] || @name_args[0]}.")
|
395
384
|
end
|
396
385
|
else
|
397
386
|
## server could not be found ##
|
398
|
-
ui.error("chef-client run logs could not be fetched since role #{
|
387
|
+
ui.error("chef-client run logs could not be fetched since role #{config[:azure_vm_name] || @name_args[0]} could not be found.")
|
399
388
|
end
|
400
389
|
end
|
401
390
|
end
|