kitchen-oci 1.3.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2a70532be3d2bb13fb4f14823c577e28ccf33c126045f35514a6602861ec14e
4
- data.tar.gz: 9c6503cc8d90881f673a3360d6686c3fa821b8ba8163214e0b9e01af679810ba
3
+ metadata.gz: c4dd215b5958470a2f202e142bf34fe8240ffda92b5a055eade44c7e4dc7a209
4
+ data.tar.gz: 88368ba6aff34472d1f693f926285ec65a442d52f25d2fd86dce82821ee73dd0
5
5
  SHA512:
6
- metadata.gz: 96886c41404b3d2879148e28190a019838aacdd90a7f05e72cdd86578e61e4980826a640ccc66309d752c2e543fba5ca31615bdee3963d18c6afd4fa7701f6cc
7
- data.tar.gz: 9629493a7909ac7d09eaa0e0ad4ec00566cc566db5cdc638a33ae183d4324516c67793e1636216cf956c747a12025d307f5af073714f6a80851243ff834af821
6
+ metadata.gz: 97d6980612c64c73e3c7ff1962819d6448d7271883c283828401e6f7aca6f497c930c50b946048a2ef5603c2efa1f7cb9142098053c51b9043dabc7910a4aac0
7
+ data.tar.gz: c5509ac799c5fe2436f29dbbef0ffc1e27a7fdbf157fcba518df2847f50793cd0ec34b892b5e8fc2f9f91a1e84ce5649f0930e24176fbec4b0db4bddbe133f3e
@@ -1,3 +1,5 @@
1
- ## 0.1.0 / Unreleased
1
+ ## 1.5.0 Windows support
2
2
 
3
- * Initial release
3
+ - Added cloud-init support.
4
+ - Added support for Windows targets.
5
+ - Can inject powershell script to set a random password and enable WinRM
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
- Author:: Stephen Pearson (<stevieweavie@gmail.com>)
1
+ Author:: Stephen Pearson (<stephen.pearson@oracle.com>)
2
2
 
3
- Copyright (C) 2017, Stephen Pearson
3
+ Copyright (C) 2019, Stephen Pearson
4
4
 
5
5
  Licensed under the Apache License, Version 2.0 (the "License");
6
6
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -60,6 +60,12 @@ These settings are optional:
60
60
  - ssh\_keypath, SSH public key, default is ~/.ssh/id\_rsa.pub
61
61
  - post\_create\_script, run a script on compute\_instance after deployment
62
62
  - proxy\_url, Connect via the specified proxy URL
63
+ - user\_data, Add user data scripts
64
+
65
+ Optional settings for WinRM support in Windows:
66
+
67
+ - setup\_winrm, Inject Windows powershell to set password and enable WinRM, default false.
68
+ - winrm\_username, Used to set the WinRM transport username, defaults to 'opc'.
63
69
 
64
70
  The use\_private\_ip influences whether the public or private IP will be used by Kitchen to connect to the instance. If it is set to false (the default) then it will connect to the public IP, otherwise it'll use the private IP.
65
71
 
@@ -107,6 +113,26 @@ suites:
107
113
  attributes:
108
114
  ```
109
115
 
116
+ ## Support for user data scripts and cloud-init
117
+
118
+ The driver has support for adding user data that can be executed as scripts by cloud-init. These can either be specified inline or by referencing a file. Examples:
119
+
120
+ ```
121
+ user_data:
122
+ - type: x-shellscript
123
+ inline: |
124
+ #!/bin/bash
125
+ touch /tmp/foo.txt
126
+ filename: init.sh
127
+ - type: x-shellscript
128
+ path: myscript.sh
129
+ filename: myscript.sh
130
+ ```
131
+
132
+ The `filename` parameter must be specified for each entry, and determines the destination filename for the script. If the user data is to be read from a file then the `path` parameter should be specified to indicate where the file is to be read from.
133
+
134
+ The scripts will be encoded into a gzipped, base64 encoded multipart mime message and added as user data when launching the instance.
135
+
110
136
  ## Proxy support
111
137
 
112
138
  If running Kitchen on a private subnet with no public IPs permitted, it may be necessary to connect to the OCI API via a web proxy. The proxy URL can either be specified on the command line:
@@ -134,7 +160,67 @@ transport:
134
160
  ssh_http_proxy_password: <proxy_password>
135
161
  ```
136
162
 
137
- Created and maintained by Stephen Pearson (<stevieweavie@gmail.com>)
163
+ ## Windows Support
164
+
165
+ When launching Oracle provided Windows images, it may be helpful to allow Kitchen-oci to inject powershell to configure WinRM and to set a randomized password that does not need to be changed on first login. If the `setup_winrm` parameter is set to true then the following steps will happen:
166
+
167
+ - A random password will be generated and stored into the Kitchen state
168
+ - A powershell script will be generated which sets the password for whatever username is defined in the transport section.
169
+ - The script, along with any other user data, will be added to the user data and passed to the new instance.
170
+ - The random password will be injected into the WinRM transport.
171
+
172
+ Make sure that the transport name is set to `winrm` and that the os\_type in the driver is set to `windows`. See the following example.
173
+
174
+ Full example (.kitchen.yml):
175
+
176
+ ```
177
+ ---
178
+ driver:
179
+ name: oci
180
+
181
+ provisioner:
182
+ name: chef_zero
183
+ always_update_cookbooks: true
184
+
185
+ verifier:
186
+ name: inspec
187
+
188
+ platforms:
189
+ - name: windows
190
+ os_type: windows
191
+ driver:
192
+ # These are mandatory
193
+ compartment_id: ocid1.compartment.oc1..aaaaaaaa...
194
+ availability_domain: UhTe:PHX-AD-1
195
+ image_id: ocid1.image.oc1.phx.aaaaaaaa...
196
+ shape: VM.Standard2.2
197
+ subnet_id: ocid1.subnet.oc1.phx.aaaaaaaa...
198
+
199
+ # These are optional
200
+ use_private_ip: false
201
+ oci_config_file: ~/.oci/config
202
+ oci_profile_name: DEFAULT
203
+ ssh_keypath: "/home/<user>/.ssh/id_rsa.pub"
204
+
205
+ # This optional, but for Windows only
206
+ setup_winrm: true
207
+ winrm_username: opc
208
+ transport:
209
+ name: winrm
210
+
211
+ suites:
212
+ - name: default
213
+ run_list:
214
+ - recipe[my_cookbook::default]
215
+ verifier:
216
+ inspec_tests:
217
+ - test/smoke/default
218
+ attributes:
219
+ ```
220
+
221
+ ## Maintainer
222
+
223
+ Created and maintained by Stephen Pearson (<stephen.pearson@oracle.com>)
138
224
 
139
225
  ## License
140
226
 
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.name = 'kitchen-oci'
9
9
  spec.version = Kitchen::Driver::OCI_VERSION
10
10
  spec.authors = ['Stephen Pearson']
11
- spec.email = ['stevieweavie@gmail.com']
11
+ spec.email = ['stephen.pearson@oracle.com']
12
12
  spec.description = 'A Test Kitchen Driver for Oracle OCI'
13
13
  spec.summary = spec.description
14
14
  spec.homepage = ''
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
22
  spec.require_paths = ['lib']
23
23
 
24
- spec.add_dependency 'oci', '~> 2.1'
24
+ spec.add_dependency 'oci', '~> 2.5'
25
25
  spec.add_dependency 'test-kitchen'
26
26
 
27
27
  spec.add_development_dependency 'bundler'
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #
4
- # Author:: Stephen Pearson (<stevieweavie@gmail.com>)
4
+ # Author:: Stephen Pearson (<stephen.pearson@oracle.com>)
5
5
  #
6
- # Copyright (C) 2017, Stephen Pearson
6
+ # Copyright (C) 2019, Stephen Pearson
7
7
  #
8
8
  # Licensed under the Apache License, Version 2.0 (the "License");
9
9
  # you may not use this file except in compliance with the License.
@@ -17,15 +17,18 @@
17
17
  # See the License for the specific language governing permissions and
18
18
  # limitations under the License.
19
19
 
20
+ require 'base64'
21
+ require 'erb'
20
22
  require 'kitchen'
21
23
  require 'oci'
22
24
  require 'uri'
25
+ require 'zlib'
23
26
 
24
27
  module Kitchen
25
28
  module Driver
26
29
  # Oracle OCI driver for Kitchen.
27
30
  #
28
- # @author Stephen Pearson <stevieweavie@gmail.com>
31
+ # @author Stephen Pearson <stephen.pearson@oracle.com>
29
32
  class Oci < Kitchen::Driver::Base # rubocop:disable Metrics/ClassLength
30
33
  required_config :compartment_id
31
34
  required_config :availability_domain
@@ -40,11 +43,26 @@ module Kitchen
40
43
  default_config :ssh_keypath, default_keypath
41
44
  default_config :post_create_script, nil
42
45
  default_config :proxy_url, nil
46
+ default_config :user_data, []
47
+ default_config :setup_winrm, false
48
+ default_config :winrm_user, 'opc'
49
+
50
+ def process_windows_options(state)
51
+ state[:username] = config[:winrm_user] if config[:setup_winrm]
52
+ if config[:setup_winrm] == true &&
53
+ config[:password].nil? &&
54
+ state[:password].nil?
55
+ state[:password] = random_password
56
+ end
57
+ state
58
+ end
43
59
 
44
60
  def create(state) # rubocop:disable Metrics/AbcSize
45
61
  return if state[:server_id]
46
62
 
47
- instance_id = launch_instance
63
+ state = process_windows_options(state)
64
+
65
+ instance_id = launch_instance(state)
48
66
  state[:server_id] = instance_id
49
67
  state[:hostname] = instance_ip(instance_id)
50
68
 
@@ -93,6 +111,7 @@ module Kitchen
93
111
  def api_proxy
94
112
  prx = proxy_config
95
113
  return nil unless prx
114
+
96
115
  if prx.user
97
116
  OCI::ApiClientProxySettings.new(prx.host, prx.port, prx.user,
98
117
  prx.password)
@@ -118,8 +137,8 @@ module Kitchen
118
137
  generic_api(OCI::Core::VirtualNetworkClient)
119
138
  end
120
139
 
121
- def launch_instance
122
- request = compute_instance_request
140
+ def launch_instance(state)
141
+ request = compute_instance_request(state)
123
142
 
124
143
  response = comp_api.launch_instance(request)
125
144
  instance_id = response.data.id
@@ -135,7 +154,9 @@ module Kitchen
135
154
  config[:compartment_id],
136
155
  instance_id: instance_id
137
156
  ).data
157
+
138
158
  raise 'Could not find any VNIC attachments' unless att.any?
159
+
139
160
  att
140
161
  end
141
162
 
@@ -179,22 +200,95 @@ module Kitchen
179
200
  )
180
201
  end
181
202
 
182
- def compute_instance_request # rubocop:disable Metrics/AbcSize
183
- hostname = random_hostname(instance.name)
203
+ def winrm_ps1(state)
204
+ filename = File.join(__dir__, %w[.. .. .. tpl setup_winrm.ps1.erb])
205
+ tpl = ERB.new(File.read(filename))
206
+ tpl.result(binding)
207
+ end
208
+
209
+ def read_part(part)
210
+ if part[:path]
211
+ content = File.read part[:path]
212
+ elsif part[:inline]
213
+ content = part[:inline]
214
+ else
215
+ raise 'Invalid user data'
216
+ end
217
+ content.split("\n")
218
+ end
219
+
220
+ def mime_parts(boundary) # rubocop:disable Metrics/AbcSize
221
+ msg = []
222
+ config[:user_data].each do |m|
223
+ msg << "--#{boundary}"
224
+ msg << "Content-Disposition: attachment; filename=\"#{m[:filename]}\""
225
+ msg << 'Content-Transfer-Encoding: 7bit'
226
+ msg << "Content-Type: text/#{m[:type]}" << 'Mime-Version: 1.0' << ''
227
+ msg << read_part(m) << ''
228
+ end
229
+ msg << "--#{boundary}--"
230
+ msg
231
+ end
232
+
233
+ def user_data
234
+ boundary = "MIMEBOUNDARY_#{random_string(20)}"
235
+ msg = ["Content-Type: multipart/mixed; boundary=\"#{boundary}\"",
236
+ 'MIME-Version: 1.0', '']
237
+ msg += mime_parts(boundary)
238
+ txt = msg.join("\n") + "\n"
239
+ gzip = Zlib::GzipWriter.new(StringIO.new)
240
+ gzip << txt
241
+ Base64.encode64(gzip.close.string).delete("\n")
242
+ end
243
+
244
+ def inject_powershell(state)
245
+ data = winrm_ps1(state)
246
+ config[:user_data] ||= []
247
+ config[:user_data] << {
248
+ type: 'x-shellscript',
249
+ inline: data,
250
+ filename: 'setup_winrm.ps1'
251
+ }
252
+ end
253
+
254
+ def base_oci_launch_details
184
255
  request = OCI::Core::Models::LaunchInstanceDetails.new
256
+ hostname = random_hostname(instance.name)
185
257
  request.availability_domain = config[:availability_domain]
186
258
  request.compartment_id = config[:compartment_id]
187
259
  request.display_name = hostname
188
260
  request.source_details = instance_source_details
189
261
  request.shape = config[:shape]
190
262
  request.create_vnic_details = create_vnic_details(hostname)
191
- request.metadata = { 'ssh_authorized_keys' => pubkey }
263
+ request
264
+ end
265
+
266
+ def compute_instance_request(state)
267
+ request = base_oci_launch_details
268
+
269
+ inject_powershell(state) if config[:setup_winrm] == true
270
+
271
+ metadata = {}
272
+ metadata.store('ssh_authorized_keys', pubkey)
273
+ data = user_data
274
+ metadata.store('user_data', data) if config[:user_data].any?
275
+ request.metadata = metadata
192
276
  request
193
277
  end
194
278
 
195
279
  def random_hostname(prefix)
196
- randstr = Array.new(6) { ('a'..'z').to_a.sample }.join
197
- "#{prefix}-#{randstr}"
280
+ "#{prefix}-#{random_string(6)}"
281
+ end
282
+
283
+ def random_password # rubocop:disable Metrics/AbcSize
284
+ (Array.new(5) { %w[! " # & ( ) * + , - . /].sample } +
285
+ Array.new(5) { ('a'..'z').to_a.sample } +
286
+ Array.new(5) { ('A'..'Z').to_a.sample } +
287
+ Array.new(5) { ('0'..'9').to_a.sample }).shuffle.join
288
+ end
289
+
290
+ def random_string(length)
291
+ Array.new(length) { ('a'..'z').to_a.sample }.join
198
292
  end
199
293
  end
200
294
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #
4
- # Author:: Stephen Pearson (<stevieweavie@gmail.com>)
4
+ # Author:: Stephen Pearson (<stephen.pearson@oracle.com>)
5
5
  #
6
- # Copyright (C) 2017, Stephen Pearson
6
+ # Copyright (C) 2019, Stephen Pearson
7
7
  #
8
8
  # Licensed under the Apache License, Version 2.0 (the "License");
9
9
  # you may not use this file except in compliance with the License.
@@ -20,6 +20,6 @@
20
20
  module Kitchen
21
21
  module Driver
22
22
  # Version string for Oracle OCI Kitchen driver
23
- OCI_VERSION = '1.3.1'
23
+ OCI_VERSION = '1.5.0'
24
24
  end
25
25
  end
@@ -0,0 +1,25 @@
1
+ #ps1_sysnative
2
+
3
+ Write-Output "Setting <%= state[:username] %> password"
4
+ net user <%= state[:username] %> '<%= state[:password] %>'
5
+
6
+ Write-Output "Configuring WinRM"
7
+ Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP" -RemoteAddress Any
8
+ winrm set winrm/config/service '@{AllowUnencrypted="true"}'
9
+ winrm quickconfig -quiet
10
+ Enable-PSRemoting -Force
11
+
12
+ winrm set winrm/config/client/auth '@{Basic="true"}'
13
+ winrm set winrm/config/service/auth '@{Basic="true"}'
14
+ winrm set winrm/config/service '@{AllowUnencrypted="true"}'
15
+ winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}'
16
+ winrm set winrm/config '@{MaxTimeoutms="1800000"}'
17
+
18
+ netsh advfirewall firewall add rule name="WinRM HTTP" protocol=TCP dir=in profile=any localport=5985 remoteip=any localip=any action=allow
19
+ netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in profile=any localport=5986 remoteip=any localip=any action=allow
20
+
21
+ net stop winrm
22
+ sc.exe config winrm start=auto
23
+ net start winrm
24
+
25
+ Write-Output "Configured WinRM"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-oci
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Pearson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-25 00:00:00.000000000 Z
11
+ date: 2019-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oci
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.1'
19
+ version: '2.5'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.1'
26
+ version: '2.5'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: test-kitchen
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -110,7 +110,7 @@ dependencies:
110
110
  version: '0'
111
111
  description: A Test Kitchen Driver for Oracle OCI
112
112
  email:
113
- - stevieweavie@gmail.com
113
+ - stephen.pearson@oracle.com
114
114
  executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
@@ -126,6 +126,7 @@ files:
126
126
  - kitchen-oci.gemspec
127
127
  - lib/kitchen/driver/oci.rb
128
128
  - lib/kitchen/driver/oci_version.rb
129
+ - tpl/setup_winrm.ps1.erb
129
130
  homepage: ''
130
131
  licenses:
131
132
  - Apache-2.0
@@ -145,8 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
146
  - !ruby/object:Gem::Version
146
147
  version: '0'
147
148
  requirements: []
148
- rubyforge_project:
149
- rubygems_version: 2.7.6
149
+ rubygems_version: 3.0.1
150
150
  signing_key:
151
151
  specification_version: 4
152
152
  summary: A Test Kitchen Driver for Oracle OCI