knife-azure 1.4.0.rc.0 → 1.4.0.rc.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.
- checksums.yaml +8 -8
- data/README.md +16 -12
- data/lib/azure/certificate.rb +114 -0
- data/lib/azure/deploy.rb +4 -0
- data/lib/azure/vnet.rb +43 -14
- data/lib/chef/knife/azure_server_create.rb +47 -13
- data/lib/chef/knife/azure_vnet_create.rb +6 -0
- data/lib/knife-azure/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzljMjVkNDdjMGI2MWJmMjBlZmU1ZWYxNTY4MDcxY2IxMDI1YzU3YQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDg0MDc2ZTcwMTA4MTViYzI0MWVhYTkwZmZjNzUyOGUxMDcxYzI1ZA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OWRhN2NiMjQ3ZjRlM2NiMDVhZTYwMjI5MGY3YjIwMmEyMTJjM2E2MGZkZTUw
|
10
|
+
YzU3NDU4ZDY3NjkzYzQwZjFlMmRjYTQyYzRkNWUyMzA3YjUzMjM4NzgwNGQ5
|
11
|
+
ZGZhMjdjYzY2YTZhZDZlYjYyZjgyMzJjNmQ5Zjk0YTQ3M2NkNzY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NjQ1NWFiYzZjMTU3ZWU0YmNlY2JmYzM0MDI2ZDdlZWNmZTJkZTcxY2IwYzU4
|
14
|
+
NGY0MzMyNTE5MjZlNmRlMjI4YmM1Y2RkOTNjZWQyMmE0NGYzNTY4YTE3YWNm
|
15
|
+
NDI5ODU3ZTllNWNkM2QwMTcyMGMwNzAyMjk2NWRhMjBiMzdhOWE=
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Knife Azure
|
2
2
|
|
3
3
|
## Description
|
4
|
-
A [knife] (http://docs.
|
4
|
+
A [knife] (http://docs.chef.io/knife.html) plugin to create,
|
5
5
|
delete, and enumerate
|
6
|
-
[
|
6
|
+
[Microsoft Azure] (https://azure.microsoft.com)
|
7
7
|
resources to be managed by Chef.
|
8
8
|
|
9
9
|
## Installation
|
@@ -46,13 +46,17 @@ location in your knife.rb:
|
|
46
46
|
|
47
47
|
# List all VM's (including those not be managed by Chef)
|
48
48
|
$ knife azure server list
|
49
|
-
|
49
|
+
|
50
|
+
# Create and bootstrap a Windows VM over winrm (winrm is the default for Windows)
|
51
|
+
$ knife azure server create --azure-dns-name MyNewServerName --azure-vm-size Medium -I a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201412.01-en.us-127GB.vhd --azure-service-location 'West US' --winrm-user myuser --winrm-password 'mypassword'
|
52
|
+
|
50
53
|
# Create and bootstrap an Ubuntu VM over ssh
|
51
54
|
$ knife azure server create -N MyNewNode --azure-vm-size Medium -I b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB -m 'West US' --ssh-user myuser --identity-file ~/.ssh/myprivatekey_rsa
|
52
|
-
|
53
|
-
# Create and bootstrap
|
54
|
-
|
55
|
-
|
55
|
+
|
56
|
+
# Create and bootstrap an Windows VM through the Azure API --
|
57
|
+
# No winrm or ssh transport or Internet access required
|
58
|
+
$ knife azure server create --azure-dns-name MyNewServerName --azure-vm-size Medium -I a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201412.01-en.us-127GB.vhd --azure-service-location 'West US' --winrm-user myuser --winrm-password 'mypassword' --bootstrap-protocol winrm --bootstrap-protocol cloud-api
|
59
|
+
|
56
60
|
# Delete a server and purge it from the Chef server
|
57
61
|
$ knife azure server delete MyNewNode --purge -y
|
58
62
|
|
@@ -84,18 +88,18 @@ Outputs a list of all linux images that are available to use for provisioning. Y
|
|
84
88
|
This subcommand provisions a new server in Azure and then performs a Chef bootstrap. The goal of the bootstrap is to get Chef installed on the target system so it can run Chef Client with a Chef Server.
|
85
89
|
|
86
90
|
#### Windows Bootstrapping Requirements
|
87
|
-
knife-azure depends on knife-windows: https://github.com/
|
91
|
+
knife-azure depends on knife-windows: https://github.com/chef/knife-windows
|
88
92
|
to bootstrap Windows machines via winrm (Basic, NTLM and Kerberos authentication) or ssh.
|
89
93
|
|
90
|
-
The distro/template to be used for bootstrapping is: https://github.com/
|
94
|
+
The distro/template to be used for bootstrapping is: https://github.com/chef/knife-windows/blob/master/lib/chef/knife/bootstrap/windows-chef-client-msi.erb
|
91
95
|
|
92
96
|
Windows source images should have the WinRM service enabled and the
|
93
97
|
authentication should be set accordingly (Basic, NTLM and Kerberos). Firewall rules should be added accordingly to the source images. Refer to the link to configure this:
|
94
|
-
https://github.com/
|
98
|
+
https://github.com/chef/knife-windows#nodes
|
95
99
|
|
96
100
|
#### Azure-specific Options
|
97
101
|
:azure_dns_name Required. The DNS prefix name that can be used to access the cloud
|
98
|
-
service which is unique within
|
102
|
+
service which is unique within Microsoft Azure. If you want to add
|
99
103
|
new VM to an existing service/deployment, specify an exiting
|
100
104
|
dns-name, along with --azure-connect-to-existing-dns option. Otherwise
|
101
105
|
a new deployment is created.
|
@@ -105,7 +109,7 @@ https://github.com/opscode/knife-windows#nodes
|
|
105
109
|
:azure_source_image Required. Specifies the name of the disk image to use to create
|
106
110
|
the virtual machine. Do a "knife azure image list" to see a
|
107
111
|
list of available images.
|
108
|
-
:azure_storage_account A name for the storage account that is unique within
|
112
|
+
:azure_storage_account A name for the storage account that is unique within Microsoft Azure.
|
109
113
|
Storage account names must be between 3 and 24 characters in
|
110
114
|
length and use numbers and lower-case letters only. This name is
|
111
115
|
the DNS prefix name and can be used to access blobs, queues, and
|
data/lib/azure/certificate.rb
CHANGED
@@ -29,6 +29,13 @@ class Azure
|
|
29
29
|
certificate = Certificate.new(@connection)
|
30
30
|
certificate.add_certificate certificate_data, certificate_password, certificate_format, dns_name
|
31
31
|
end
|
32
|
+
|
33
|
+
def create_ssl_certificate(azure_dns_name)
|
34
|
+
cert_params = { output_file: 'winrm', key_length: 2048, cert_validity: 24,
|
35
|
+
azure_dns_name: azure_dns_name }
|
36
|
+
certificate = Certificate.new(@connection)
|
37
|
+
thumbprint = certificate.create_ssl_certificate(cert_params)
|
38
|
+
end
|
32
39
|
end
|
33
40
|
end
|
34
41
|
|
@@ -92,5 +99,112 @@ class Azure
|
|
92
99
|
@connection.query_azure("hostedservices/#{dns_name}/certificates", "post", builder.to_xml)
|
93
100
|
end
|
94
101
|
|
102
|
+
######## SSL certificate generation for knife-azure ssl bootstrap ######
|
103
|
+
|
104
|
+
def create_ssl_certificate cert_params
|
105
|
+
file_path = cert_params[:output_file].sub(/\.(\w+)$/,'')
|
106
|
+
path = prompt_for_file_path
|
107
|
+
file_path = File.join(path, file_path) unless path.empty?
|
108
|
+
cert_params[:domain] = prompt_for_domain
|
109
|
+
|
110
|
+
rsa_key = generate_keypair cert_params[:key_length]
|
111
|
+
cert = generate_certificate(rsa_key, cert_params)
|
112
|
+
write_certificate_to_file cert, file_path, rsa_key, cert_params
|
113
|
+
puts "*"*70
|
114
|
+
puts "Generated Certificates:"
|
115
|
+
puts "- #{file_path}.pfx - PKCS12 format keypair. Contains both the public and private keys, usually used on the server."
|
116
|
+
puts "- #{file_path}.b64 - Base64 encoded PKCS12 keypair. Contains both the public and private keys, for upload to the Azure REST API."
|
117
|
+
puts "- #{file_path}.pem - Base64 encoded public certificate only. Required by the client to connect to the server."
|
118
|
+
puts "Certificate Thumbprint: #{@thumbprint.to_s.upcase}"
|
119
|
+
puts "*"*70
|
120
|
+
|
121
|
+
Chef::Config[:knife][:ca_trust_file] = file_path + ".pem" if Chef::Config[:knife][:ca_trust_file].nil?
|
122
|
+
cert_data = File.read (file_path + ".b64")
|
123
|
+
add_certificate cert_data, @winrm_cert_passphrase, 'pfx', cert_params[:azure_dns_name]
|
124
|
+
@thumbprint
|
125
|
+
end
|
126
|
+
|
127
|
+
def generate_keypair key_length
|
128
|
+
OpenSSL::PKey::RSA.new(key_length.to_i)
|
129
|
+
end
|
130
|
+
|
131
|
+
def prompt_for_passphrase
|
132
|
+
passphrase = ""
|
133
|
+
begin
|
134
|
+
print "Passphrases do not match. Try again.\n" unless passphrase.empty?
|
135
|
+
print "Enter certificate passphrase (empty for no passphrase):"
|
136
|
+
passphrase = STDIN.gets
|
137
|
+
return passphrase.strip if passphrase == "\n"
|
138
|
+
print "Enter same passphrase again:"
|
139
|
+
confirm_passphrase = STDIN.gets
|
140
|
+
end until passphrase == confirm_passphrase
|
141
|
+
passphrase.strip
|
142
|
+
end
|
143
|
+
|
144
|
+
def prompt_for_file_path
|
145
|
+
file_path = ''
|
146
|
+
counter = 0
|
147
|
+
begin
|
148
|
+
print "Invalid location! \n" unless file_path.empty?
|
149
|
+
print 'Enter the file path for certificates e.g. C:\Windows (empty for current location):'
|
150
|
+
file_path = STDIN.gets
|
151
|
+
stripped_file_path = file_path.strip
|
152
|
+
return stripped_file_path if file_path == "\n"
|
153
|
+
counter += 1
|
154
|
+
exit(1) if counter == 3
|
155
|
+
end until File.directory?(stripped_file_path)
|
156
|
+
stripped_file_path
|
157
|
+
end
|
158
|
+
|
159
|
+
def prompt_for_domain
|
160
|
+
counter = 0
|
161
|
+
begin
|
162
|
+
print 'Enter the domain (mandatory):'
|
163
|
+
domain = STDIN.gets
|
164
|
+
domain = domain.strip
|
165
|
+
counter += 1
|
166
|
+
exit(1) if counter == 3
|
167
|
+
end until !domain.empty?
|
168
|
+
domain
|
169
|
+
end
|
170
|
+
|
171
|
+
def generate_certificate(rsa_key, cert_params)
|
172
|
+
@hostname = "*"
|
173
|
+
if cert_params[:domain]
|
174
|
+
@hostname = "*." + cert_params[:domain]
|
175
|
+
end
|
176
|
+
|
177
|
+
#Create a self-signed X509 certificate from the rsa_key (unencrypted)
|
178
|
+
cert = OpenSSL::X509::Certificate.new
|
179
|
+
cert.version = 2
|
180
|
+
cert.serial = Random.rand(65534) + 1 # 2 digit byte range random number for better security aspect
|
181
|
+
|
182
|
+
cert.subject = OpenSSL::X509::Name.parse "/CN=#{@hostname}"
|
183
|
+
cert.issuer = cert.subject
|
184
|
+
cert.public_key = rsa_key.public_key
|
185
|
+
cert.not_before = Time.now
|
186
|
+
cert.not_after = cert.not_before + 2 * 365 * cert_params[:cert_validity].to_i * 60 * 60 # 2 years validity
|
187
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
188
|
+
ef.subject_certificate = cert
|
189
|
+
ef.issuer_certificate = cert
|
190
|
+
cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
191
|
+
cert.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
|
192
|
+
cert.add_extension(ef.create_extension("extendedKeyUsage", "1.3.6.1.5.5.7.3.1", false))
|
193
|
+
cert.sign(rsa_key, OpenSSL::Digest::SHA1.new)
|
194
|
+
@thumbprint = OpenSSL::Digest::SHA1.new(cert.to_der)
|
195
|
+
cert
|
196
|
+
end
|
197
|
+
|
198
|
+
def write_certificate_to_file cert, file_path, rsa_key, cert_params
|
199
|
+
File.open(file_path + ".pem", "wb") { |f| f.print cert.to_pem }
|
200
|
+
@winrm_cert_passphrase = prompt_for_passphrase unless @winrm_cert_passphrase
|
201
|
+
pfx = OpenSSL::PKCS12.create("#{cert_params[:winrm_cert_passphrase]}", "winrmcert", rsa_key, cert)
|
202
|
+
File.open(file_path + ".pfx", "wb") { |f| f.print pfx.to_der }
|
203
|
+
File.open(file_path + ".b64", "wb") { |f| f.print Base64.strict_encode64(pfx.to_der) }
|
204
|
+
end
|
205
|
+
|
206
|
+
########## SSL certificate generation ends ###########
|
207
|
+
|
208
|
+
|
95
209
|
end
|
96
210
|
end
|
data/lib/azure/deploy.rb
CHANGED
@@ -81,7 +81,11 @@ class Azure
|
|
81
81
|
if params[:cert_path]
|
82
82
|
cert_data = File.read (params[:cert_path])
|
83
83
|
@connection.certificates.add cert_data, params[:cert_password], 'pfx', params[:azure_dns_name]
|
84
|
+
elsif(params[:winrm_transport] == "ssl")
|
85
|
+
thumbprint = @connection.certificates.create_ssl_certificate params[:azure_dns_name]
|
86
|
+
params[:ssl_cert_fingerprint] = thumbprint.to_s.upcase
|
84
87
|
end
|
88
|
+
|
85
89
|
params['deploy_name'] = get_deploy_name_for_hostedservice(params[:azure_dns_name])
|
86
90
|
|
87
91
|
if params['deploy_name'] != nil
|
data/lib/azure/vnet.rb
CHANGED
@@ -63,26 +63,55 @@ class Azure
|
|
63
63
|
|
64
64
|
def parse(image)
|
65
65
|
@name = image.at_css('Name').content
|
66
|
-
@affinity_group = image.at_css('AffinityGroup').content
|
66
|
+
@affinity_group = image.at_css('AffinityGroup') ? image.at_css('AffinityGroup').content : ""
|
67
67
|
@state = image.at_css('State').content
|
68
68
|
self
|
69
69
|
end
|
70
70
|
|
71
71
|
def create(params)
|
72
72
|
response = @connection.query_azure('networking/media')
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
73
|
+
if response.at_css("Error") && response.at_css('Code').text == "ResourceNotFound"
|
74
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
75
|
+
xml.NetworkConfiguration(
|
76
|
+
'xmlns'=>'http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration'
|
77
|
+
) {
|
78
|
+
|
79
|
+
xml.VirtualNetworkConfiguration {
|
80
|
+
xml.VirtualNetworkSites {
|
81
|
+
xml.VirtualNetworkSite('name' => params[:azure_vnet_name], 'AffinityGroup' => params[:azure_ag_name]) {
|
82
|
+
if params[:azure_address_space]
|
83
|
+
xml.AddressSpace {
|
84
|
+
xml.AddressPrefix params[:azure_address_space]
|
85
|
+
}
|
86
|
+
end
|
87
|
+
xml.Subnets{
|
88
|
+
xml.Subnet('name' => params[:azure_subnet_name]) {
|
89
|
+
xml.AddressPrefix params[:azure_address_space]
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
end
|
97
|
+
puts("Creating New Virtual Network: #{params[:azure_vnet_name]}...")
|
98
|
+
response = builder
|
99
|
+
else
|
100
|
+
vnets = response.css('VirtualNetworkSite')
|
101
|
+
vnet = nil
|
102
|
+
vnets.each { |vn| vnet = vn if vn['name'] == params[:azure_vnet_name] }
|
103
|
+
add = vnet.nil?
|
104
|
+
vnet = Nokogiri::XML::Node.new('VirtualNetworkSite', response) if add
|
105
|
+
vnet['name'] = params[:azure_vnet_name]
|
106
|
+
vnet['AffinityGroup'] = params[:azure_ag_name]
|
107
|
+
addr_space = Nokogiri::XML::Node.new('AddressSpace', response)
|
108
|
+
addr_prefix = Nokogiri::XML::Node.new('AddressPrefix', response)
|
109
|
+
addr_prefix.content = params[:azure_address_space]
|
110
|
+
addr_space.children = addr_prefix
|
111
|
+
vnet.children = addr_space
|
112
|
+
vnets.last.add_next_sibling(vnet) if add
|
113
|
+
puts("Updating existing Virtual Network: #{params[:azure_vnet_name]}...")
|
114
|
+
end
|
86
115
|
@connection.query_azure('networking/media', 'put', response.to_xml)
|
87
116
|
end
|
88
117
|
end
|
@@ -40,6 +40,7 @@ class Chef
|
|
40
40
|
|
41
41
|
def load_winrm_deps
|
42
42
|
require 'winrm'
|
43
|
+
require 'em-winrm'
|
43
44
|
require 'chef/knife/winrm'
|
44
45
|
require 'chef/knife/bootstrap_windows_winrm'
|
45
46
|
end
|
@@ -71,8 +72,7 @@ class Chef
|
|
71
72
|
|
72
73
|
option :ssh_port,
|
73
74
|
:long => "--ssh-port PORT",
|
74
|
-
:description => "The ssh port. Default is 22."
|
75
|
-
:default => '22'
|
75
|
+
:description => "The ssh port. Default is 22. If --azure-connect-to-existing-dns set then default SSH port is random"
|
76
76
|
|
77
77
|
option :prerelease,
|
78
78
|
:long => "--prerelease",
|
@@ -190,6 +190,16 @@ class Chef
|
|
190
190
|
:long => "--azure-subnet-name SUBNET_NAME",
|
191
191
|
:description => "Optional. Specifies the subnet of virtual machine"
|
192
192
|
|
193
|
+
option :azure_vm_startup_timeout,
|
194
|
+
:long => "--azure-vm-startup-timeout TIMEOUT",
|
195
|
+
:description => "The number of minutes that knife-azure will wait for the virtual machine to reach the 'provisioning' state. Default is 10.",
|
196
|
+
:default => 10
|
197
|
+
|
198
|
+
option :azure_vm_ready_timeout,
|
199
|
+
:long => "--azure-vm-ready-timeout TIMEOUT",
|
200
|
+
:description => "The number of minutes that knife-azure will wait for the virtual machine state to transition from 'provisioning' to 'ready'. Default is 15.",
|
201
|
+
:default => 15
|
202
|
+
|
193
203
|
option :identity_file,
|
194
204
|
:long => "--identity-file FILENAME",
|
195
205
|
:description => "SSH identity file for authentication, optional. It is the RSA private key path. Specify either ssh-password or identity-file"
|
@@ -225,6 +235,12 @@ class Chef
|
|
225
235
|
:long => "--cert-path PATH",
|
226
236
|
:description => "SSL Certificate Path"
|
227
237
|
|
238
|
+
option :auto_update_client,
|
239
|
+
:long => "--auto-update-client",
|
240
|
+
:boolean => true,
|
241
|
+
:default => false,
|
242
|
+
:description => "Set this flag to enable auto chef client update in azure chef extension. This flag should be used with cloud-api bootstrap protocol only"
|
243
|
+
|
228
244
|
def strip_non_ascii(string)
|
229
245
|
string.gsub(/[^0-9a-z ]/i, '')
|
230
246
|
end
|
@@ -236,12 +252,15 @@ class Chef
|
|
236
252
|
def wait_until_virtual_machine_ready(retry_interval_in_seconds = 30)
|
237
253
|
|
238
254
|
vm_status = nil
|
255
|
+
|
239
256
|
puts
|
240
257
|
|
241
258
|
begin
|
242
|
-
|
259
|
+
azure_vm_startup_timeout = locate_config_value(:azure_vm_startup_timeout).to_i
|
260
|
+
azure_vm_ready_timeout = locate_config_value(:azure_vm_ready_timeout).to_i
|
261
|
+
vm_status = wait_for_virtual_machine_state(:vm_status_provisioning, azure_vm_startup_timeout, retry_interval_in_seconds)
|
243
262
|
if vm_status != :vm_status_ready
|
244
|
-
wait_for_virtual_machine_state(:vm_status_ready,
|
263
|
+
wait_for_virtual_machine_state(:vm_status_ready, azure_vm_ready_timeout, retry_interval_in_seconds)
|
245
264
|
end
|
246
265
|
|
247
266
|
msg_server_summary(get_role_server())
|
@@ -590,7 +609,7 @@ class Chef
|
|
590
609
|
bootstrap.config[:winrm_user] = locate_config_value(:winrm_user) || 'Administrator'
|
591
610
|
bootstrap.config[:winrm_password] = locate_config_value(:winrm_password)
|
592
611
|
bootstrap.config[:winrm_transport] = locate_config_value(:winrm_transport)
|
593
|
-
|
612
|
+
bootstrap.config[:winrm_authentication_protocol] = locate_config_value(:winrm_authentication_protocol)
|
594
613
|
bootstrap.config[:winrm_port] = port
|
595
614
|
|
596
615
|
elsif locate_config_value(:bootstrap_protocol) == 'ssh'
|
@@ -653,6 +672,7 @@ class Chef
|
|
653
672
|
ui.error("Specify the VM name using --azure-vm-name option, since you are connecting to existing dns")
|
654
673
|
exit 1
|
655
674
|
end
|
675
|
+
|
656
676
|
if locate_config_value(:azure_service_location) && locate_config_value(:azure_affinity_group)
|
657
677
|
ui.error("Cannot specify both --azure-service-location and --azure-affinity-group, use one or the other.")
|
658
678
|
exit 1
|
@@ -661,6 +681,11 @@ class Chef
|
|
661
681
|
exit 1
|
662
682
|
end
|
663
683
|
|
684
|
+
if locate_config_value(:winrm_authentication_protocol) && ! %w{basic negotiate kerberos}.include?(locate_config_value(:winrm_authentication_protocol))
|
685
|
+
ui.error("Invalid value for --winrm-authentication-protocol option. Use valid protocol values i.e [basic, negotiate, kerberos]")
|
686
|
+
exit 1
|
687
|
+
end
|
688
|
+
|
664
689
|
if !(connection.images.exists?(locate_config_value(:azure_source_image)))
|
665
690
|
ui.error("Image provided is invalid")
|
666
691
|
exit 1
|
@@ -687,19 +712,22 @@ class Chef
|
|
687
712
|
:azure_subnet_name => locate_config_value(:azure_subnet_name),
|
688
713
|
:ssl_cert_fingerprint => locate_config_value(:thumbprint),
|
689
714
|
:cert_path => locate_config_value(:cert_path),
|
690
|
-
:cert_password => locate_config_value(:cert_passphrase)
|
715
|
+
:cert_password => locate_config_value(:cert_passphrase),
|
716
|
+
:winrm_transport => locate_config_value(:winrm_transport)
|
691
717
|
}
|
692
718
|
# If user is connecting a new VM to an existing dns, then
|
693
719
|
# the VM needs to have a unique public port. Logic below takes care of this.
|
694
720
|
if !is_image_windows? or locate_config_value(:bootstrap_protocol) == 'ssh'
|
695
|
-
|
696
|
-
|
697
|
-
|
721
|
+
if locate_config_value(:azure_connect_to_existing_dns)
|
722
|
+
port = locate_config_value(:ssh_port) || Random.rand(64000) + 1000
|
723
|
+
else
|
724
|
+
port = locate_config_value(:ssh_port) || '22'
|
698
725
|
end
|
699
726
|
else
|
700
|
-
|
701
|
-
|
702
|
-
|
727
|
+
if locate_config_value(:azure_connect_to_existing_dns)
|
728
|
+
port = locate_config_value(:winrm_port) || Random.rand(64000) + 1000
|
729
|
+
else
|
730
|
+
port = locate_config_value(:winrm_port) || '5985'
|
703
731
|
end
|
704
732
|
end
|
705
733
|
|
@@ -724,6 +752,11 @@ class Chef
|
|
724
752
|
ui.error("WinRM User is compulsory parameter and it cannot be named 'admin*'")
|
725
753
|
exit 1
|
726
754
|
end
|
755
|
+
# take cares of when user name contains domain
|
756
|
+
# azure add role api doesn't support '\\' in user name
|
757
|
+
if locate_config_value(:winrm_user) && locate_config_value(:winrm_user).split("\\").length.eql?(2)
|
758
|
+
server_def[:winrm_user] = locate_config_value(:winrm_user).split("\\")[1]
|
759
|
+
end
|
727
760
|
else
|
728
761
|
if not locate_config_value(:ssh_user)
|
729
762
|
ui.error("SSH User is compulsory parameter")
|
@@ -763,13 +796,14 @@ class Chef
|
|
763
796
|
# get latest version
|
764
797
|
def get_chef_extension_version
|
765
798
|
extensions = @connection.query_azure("resourceextensions/#{get_chef_extension_publisher}/#{get_chef_extension_name}")
|
766
|
-
extensions.css("Version").max.text.
|
799
|
+
extensions.css("Version").max.text.split(".").first + ".*"
|
767
800
|
end
|
768
801
|
|
769
802
|
def get_chef_extension_public_params
|
770
803
|
pub_config = Hash.new
|
771
804
|
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}"
|
772
805
|
pub_config[:runlist] = locate_config_value(:run_list).empty? ? "" : locate_config_value(:run_list).join(",").to_json
|
806
|
+
pub_config[:autoUpdateClient] = locate_config_value(:auto_update_client) ? "true" : "false"
|
773
807
|
Base64.encode64(pub_config.to_json)
|
774
808
|
end
|
775
809
|
|
@@ -42,6 +42,11 @@ class Chef
|
|
42
42
|
:description =>
|
43
43
|
'Specifies the address space of the vnet using CIDR notation.'
|
44
44
|
|
45
|
+
option :azure_subnet_name,
|
46
|
+
:long => '--azure-subnet-name CIDR',
|
47
|
+
:description =>
|
48
|
+
'Specifies the Subnet Name.'
|
49
|
+
|
45
50
|
def run
|
46
51
|
$stdout.sync = true
|
47
52
|
|
@@ -57,6 +62,7 @@ class Chef
|
|
57
62
|
azure_vnet_name: locate_config_value(:azure_network_name),
|
58
63
|
azure_ag_name: locate_config_value(:azure_affinity_group),
|
59
64
|
azure_address_space: locate_config_value(:azure_address_space),
|
65
|
+
azure_subnet_name: locate_config_value(:azure_subnet_name) || "Subnet-#{Random.rand(10)}"
|
60
66
|
}
|
61
67
|
|
62
68
|
rsp = connection.vnets.create(params)
|
data/lib/knife-azure/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-azure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.0.rc.
|
4
|
+
version: 1.4.0.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Barry Davis
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-02-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -46,6 +46,9 @@ dependencies:
|
|
46
46
|
- - ! '>='
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: 11.8.2
|
49
|
+
- - <
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '12'
|
49
52
|
type: :development
|
50
53
|
prerelease: false
|
51
54
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -53,6 +56,9 @@ dependencies:
|
|
53
56
|
- - ! '>='
|
54
57
|
- !ruby/object:Gem::Version
|
55
58
|
version: 11.8.2
|
59
|
+
- - <
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '12'
|
56
62
|
- !ruby/object:Gem::Dependency
|
57
63
|
name: mixlib-config
|
58
64
|
requirement: !ruby/object:Gem::Requirement
|