kitchen-oci 1.25.0 → 1.26.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.
- checksums.yaml +4 -4
- data/lib/kitchen/driver/oci/blockstorage.rb +24 -16
- data/lib/kitchen/driver/oci/instance/dbaas.rb +1 -1
- data/lib/kitchen/driver/oci/instance.rb +50 -5
- data/lib/kitchen/driver/oci/models/compute.rb +14 -6
- data/lib/kitchen/driver/oci/models/dbaas.rb +9 -1
- data/lib/kitchen/driver/oci/models/iscsi.rb +1 -1
- data/lib/kitchen/driver/oci/models/paravirtual.rb +1 -1
- data/lib/kitchen/driver/oci/models.rb +2 -2
- data/lib/kitchen/driver/oci/volumes.rb +54 -0
- data/lib/kitchen/driver/oci.rb +9 -29
- data/lib/kitchen/driver/oci_version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d223f52ef9973e25f1185d4646a7d1728f5eb0b760bcbe85c8b5cbe150f47bd
|
4
|
+
data.tar.gz: fbe86e8e26c0cb4cae838bc58e277e7e3c4c06e2850ad73b6b5ff9be46f30f00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39140520616c5ee302c3ba7766437598bb93ba2199aa1ea9cfe3e5525e972daacb7aacd40e95b39a9a72be9dad333d5f22c8b8cbb812d14f800e360527ce72d1
|
7
|
+
data.tar.gz: 86bbbecc3e66a2ec67607d889570d5c55ce88c45579903741d8021679b1cba1e83f9c00a3da974e3e68fd86ecb9c9457d1b9fdc913198b37a911f364565fe77c
|
@@ -26,15 +26,16 @@ module Kitchen
|
|
26
26
|
require_relative "models/iscsi"
|
27
27
|
require_relative "models/paravirtual"
|
28
28
|
|
29
|
-
def initialize(
|
29
|
+
def initialize(opts = {})
|
30
30
|
super()
|
31
|
-
@config = config
|
32
|
-
@state = state
|
33
|
-
@oci = oci
|
34
|
-
@api = api
|
31
|
+
@config = opts[:config]
|
32
|
+
@state = opts[:state]
|
33
|
+
@oci = opts[:oci]
|
34
|
+
@api = opts[:api]
|
35
|
+
@logger = opts[:logger]
|
35
36
|
@volume_state = {}
|
36
37
|
@volume_attachment_state = {}
|
37
|
-
oci.compartment if action == :create
|
38
|
+
oci.compartment if opts[:action] == :create
|
38
39
|
end
|
39
40
|
|
40
41
|
#
|
@@ -65,6 +66,13 @@ module Kitchen
|
|
65
66
|
#
|
66
67
|
attr_accessor :api
|
67
68
|
|
69
|
+
#
|
70
|
+
# The instance of Kitchen::Logger in use by the active Kitchen::Instance
|
71
|
+
#
|
72
|
+
# @return [Kitchen::Logger]
|
73
|
+
#
|
74
|
+
attr_accessor :logger
|
75
|
+
|
68
76
|
# The definition of the state of a volume
|
69
77
|
#
|
70
78
|
# @return [Hash]
|
@@ -78,44 +86,44 @@ module Kitchen
|
|
78
86
|
attr_accessor :volume_attachment_state
|
79
87
|
|
80
88
|
def create_volume(volume)
|
81
|
-
info("Creating <#{volume[:name]}>...")
|
89
|
+
logger.info("Creating <#{volume[:name]}>...")
|
82
90
|
result = api.blockstorage.create_volume(volume_details(volume))
|
83
91
|
response = volume_response(result.data.id)
|
84
|
-
info("Finished creating <#{volume[:name]}>.")
|
92
|
+
logger.info("Finished creating <#{volume[:name]}>.")
|
85
93
|
[response, final_state(response)]
|
86
94
|
end
|
87
95
|
|
88
96
|
def create_clone_volume(volume)
|
89
97
|
clone_volume_name = clone_volume_display_name(volume[:volume_id])
|
90
|
-
info("Creating <#{clone_volume_name}>...")
|
98
|
+
logger.info("Creating <#{clone_volume_name}>...")
|
91
99
|
result = api.blockstorage.create_volume(volume_clone_details(volume, clone_volume_name))
|
92
100
|
response = volume_response(result.data.id)
|
93
|
-
info("Finished creating <#{clone_volume_name}>.")
|
101
|
+
logger.info("Finished creating <#{clone_volume_name}>.")
|
94
102
|
[response, final_state(response)]
|
95
103
|
end
|
96
104
|
|
97
105
|
def attach_volume(volume_details, server_id, volume_config)
|
98
|
-
info("Attaching <#{volume_details.display_name}>...")
|
106
|
+
logger.info("Attaching <#{volume_details.display_name}>...")
|
99
107
|
attach_volume = api.compute.attach_volume(attachment_details(volume_details, server_id, volume_config))
|
100
108
|
response = attachment_response(attach_volume.data.id)
|
101
|
-
info("Finished attaching <#{volume_details.display_name}>.")
|
109
|
+
logger.info("Finished attaching <#{volume_details.display_name}>.")
|
102
110
|
final_state(response)
|
103
111
|
end
|
104
112
|
|
105
113
|
def delete_volume(volume)
|
106
|
-
info("Deleting <#{volume[:display_name]}>...")
|
114
|
+
logger.info("Deleting <#{volume[:display_name]}>...")
|
107
115
|
api.blockstorage.delete_volume(volume[:id])
|
108
116
|
api.blockstorage.get_volume(volume[:id])
|
109
117
|
.wait_until(:lifecycle_state, OCI::Core::Models::Volume::LIFECYCLE_STATE_TERMINATED)
|
110
|
-
info("Finished deleting <#{volume[:display_name]}>.")
|
118
|
+
logger.info("Finished deleting <#{volume[:display_name]}>.")
|
111
119
|
end
|
112
120
|
|
113
121
|
def detatch_volume(volume_attachment)
|
114
|
-
info("Detaching <#{attachment_name(volume_attachment)}>...")
|
122
|
+
logger.info("Detaching <#{attachment_name(volume_attachment)}>...")
|
115
123
|
api.compute.detach_volume(volume_attachment[:id])
|
116
124
|
api.compute.get_volume_attachment(volume_attachment[:id])
|
117
125
|
.wait_until(:lifecycle_state, OCI::Core::Models::VolumeAttachment::LIFECYCLE_STATE_DETACHED)
|
118
|
-
info("Finished detaching <#{attachment_name(volume_attachment)}>.")
|
126
|
+
logger.info("Finished detaching <#{attachment_name(volume_attachment)}>.")
|
119
127
|
end
|
120
128
|
|
121
129
|
def final_state(response)
|
@@ -30,12 +30,13 @@ module Kitchen
|
|
30
30
|
|
31
31
|
include CommonLaunchDetails
|
32
32
|
|
33
|
-
def initialize(
|
33
|
+
def initialize(opts = {})
|
34
34
|
super()
|
35
|
-
@config = config
|
36
|
-
@state = state
|
37
|
-
@oci = oci
|
38
|
-
@api = api
|
35
|
+
@config = opts[:config]
|
36
|
+
@state = opts[:state]
|
37
|
+
@oci = opts[:oci]
|
38
|
+
@api = opts[:api]
|
39
|
+
@logger = opts[:logger]
|
39
40
|
end
|
40
41
|
|
41
42
|
#
|
@@ -66,6 +67,13 @@ module Kitchen
|
|
66
67
|
#
|
67
68
|
attr_accessor :api
|
68
69
|
|
70
|
+
#
|
71
|
+
# The instance of Kitchen::Logger in use by the active Kitchen::Instance
|
72
|
+
#
|
73
|
+
# @return [Kitchen::Logger]
|
74
|
+
#
|
75
|
+
attr_accessor :logger
|
76
|
+
|
69
77
|
def final_state(state, instance_id)
|
70
78
|
state.store(:server_id, instance_id)
|
71
79
|
state.store(:hostname, instance_ip(instance_id))
|
@@ -88,6 +96,43 @@ module Kitchen
|
|
88
96
|
!subnet.prohibit_public_ip_on_vnic
|
89
97
|
end
|
90
98
|
|
99
|
+
def public_key_file
|
100
|
+
if config[:ssh_keygen]
|
101
|
+
"#{config[:kitchen_root]}/.kitchen/.ssh/#{config[:instance_name]}_rsa.pub"
|
102
|
+
else
|
103
|
+
config[:ssh_keypath]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def private_key_file
|
108
|
+
public_key_file.gsub(".pub", "")
|
109
|
+
end
|
110
|
+
|
111
|
+
def gen_key_pair
|
112
|
+
FileUtils.mkdir_p("#{config[:kitchen_root]}/.kitchen/.ssh")
|
113
|
+
rsa_key = OpenSSL::PKey::RSA.new(4096)
|
114
|
+
write_private_key(rsa_key)
|
115
|
+
write_public_key(rsa_key)
|
116
|
+
state.store(:ssh_key, private_key_file)
|
117
|
+
end
|
118
|
+
|
119
|
+
def write_private_key(rsa_key)
|
120
|
+
File.open(private_key_file, "wb") { |k| k.write(rsa_key.to_pem) }
|
121
|
+
File.chmod(0600, private_key_file)
|
122
|
+
end
|
123
|
+
|
124
|
+
def write_public_key(rsa_key)
|
125
|
+
File.open(public_key_file, "wb") { |k| k.write("ssh-rsa #{encode_private_key(rsa_key)} #{config[:instance_name]}") }
|
126
|
+
File.chmod(0600, public_key_file)
|
127
|
+
end
|
128
|
+
|
129
|
+
def encode_private_key(rsa_key)
|
130
|
+
prefix = "#{[7].pack("N")}ssh-rsa"
|
131
|
+
exponent = rsa_key.e.to_s(0)
|
132
|
+
modulus = rsa_key.n.to_s(0)
|
133
|
+
["#{prefix}#{exponent}#{modulus}"].pack("m0")
|
134
|
+
end
|
135
|
+
|
91
136
|
def random_password(special_chars)
|
92
137
|
(Array.new(5) { special_chars.sample } +
|
93
138
|
Array.new(5) { ("a".."z").to_a.sample } +
|
@@ -26,7 +26,7 @@ module Kitchen
|
|
26
26
|
class Compute < Instance # rubocop:disable Metrics/ClassLength
|
27
27
|
include ComputeLaunchDetails
|
28
28
|
|
29
|
-
def initialize(
|
29
|
+
def initialize(opts = {})
|
30
30
|
super
|
31
31
|
@launch_details = OCI::Core::Models::LaunchInstanceDetails.new
|
32
32
|
end
|
@@ -102,10 +102,10 @@ module Kitchen
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def clone_boot_volume
|
105
|
-
info("Cloning boot volume...")
|
105
|
+
logger.info("Cloning boot volume...")
|
106
106
|
cbv = api.blockstorage.create_boot_volume(clone_boot_volume_details)
|
107
107
|
api.blockstorage.get_boot_volume(cbv.data.id).wait_until(:lifecycle_state, OCI::Core::Models::BootVolume::LIFECYCLE_STATE_AVAILABLE)
|
108
|
-
info("Finished cloning boot volume.")
|
108
|
+
logger.info("Finished cloning boot volume.")
|
109
109
|
cbv.data.id
|
110
110
|
end
|
111
111
|
|
@@ -159,15 +159,19 @@ module Kitchen
|
|
159
159
|
end
|
160
160
|
|
161
161
|
def pubkey
|
162
|
-
|
162
|
+
if config[:ssh_keygen]
|
163
|
+
logger.info("Generating public/private rsa key pair")
|
164
|
+
gen_key_pair
|
165
|
+
end
|
166
|
+
File.readlines(public_key_file).first.chomp
|
163
167
|
end
|
164
168
|
|
165
169
|
def metadata
|
166
170
|
md = {}
|
167
171
|
inject_powershell
|
168
172
|
config[:custom_metadata]&.each { |k, v| md.store(k, v) }
|
169
|
-
md.store("ssh_authorized_keys", pubkey)
|
170
|
-
md.store("user_data", user_data) if
|
173
|
+
md.store("ssh_authorized_keys", pubkey) unless config[:setup_winrm]
|
174
|
+
md.store("user_data", user_data) if user_data?
|
171
175
|
md
|
172
176
|
end
|
173
177
|
|
@@ -182,6 +186,10 @@ module Kitchen
|
|
182
186
|
config[:setup_winrm] && config[:password].nil? && state[:password].nil?
|
183
187
|
end
|
184
188
|
|
189
|
+
def user_data?
|
190
|
+
config[:user_data] && !config[:user_data].empty?
|
191
|
+
end
|
192
|
+
|
185
193
|
def winrm_ps1
|
186
194
|
filename = File.join(__dir__, %w{.. .. .. .. .. tpl setup_winrm.ps1.erb})
|
187
195
|
tpl = ERB.new(File.read(filename))
|
@@ -26,7 +26,7 @@ module Kitchen
|
|
26
26
|
class Dbaas < Instance # rubocop:disable Metrics/ClassLength
|
27
27
|
include DbaasLaunchDetails
|
28
28
|
|
29
|
-
def initialize(
|
29
|
+
def initialize(opts = {})
|
30
30
|
super
|
31
31
|
@launch_details = OCI::Database::Models::LaunchDbSystemDetails.new
|
32
32
|
@database_details = OCI::Database::Models::CreateDatabaseDetails.new
|
@@ -97,6 +97,14 @@ module Kitchen
|
|
97
97
|
def long_hostname_suffix
|
98
98
|
[random_string(25 - hostname_prefix.length), random_string(3)].compact.join("-")
|
99
99
|
end
|
100
|
+
|
101
|
+
def read_public_key
|
102
|
+
if config[:ssh_keygen]
|
103
|
+
logger.info("Generating public/private rsa key pair")
|
104
|
+
gen_key_pair
|
105
|
+
end
|
106
|
+
File.readlines(public_key_file).first.chomp
|
107
|
+
end
|
100
108
|
end
|
101
109
|
end
|
102
110
|
end
|
@@ -26,11 +26,11 @@ module Kitchen
|
|
26
26
|
require_relative "blockstorage"
|
27
27
|
|
28
28
|
def instance_class(config, state, oci, api, action)
|
29
|
-
Oci::Models.const_get(config[:instance_type].capitalize).new(config, state, oci, api, action)
|
29
|
+
Oci::Models.const_get(config[:instance_type].capitalize).new(config: config, state: state, oci: oci, api: api, action: action, logger: instance.logger)
|
30
30
|
end
|
31
31
|
|
32
32
|
def volume_class(type, config, state, oci, api)
|
33
|
-
Oci::Models.const_get(volume_attachment_type(type)).new(config, state, oci, api)
|
33
|
+
Oci::Models.const_get(volume_attachment_type(type)).new(config: config, state: state, oci: oci, api: api, logger: instance.logger)
|
34
34
|
end
|
35
35
|
|
36
36
|
private
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Author:: Justin Steele (<justin.steele@oracle.com>)
|
5
|
+
#
|
6
|
+
# Copyright (C) 2024, Stephen Pearson
|
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
|
+
module Kitchen
|
21
|
+
module Driver
|
22
|
+
class Oci
|
23
|
+
# mixin for working with volumes and attachments
|
24
|
+
module Volumes
|
25
|
+
def create_and_attach_volumes(config, state, oci, api)
|
26
|
+
return if config[:volumes].empty?
|
27
|
+
|
28
|
+
volume_state = process_volumes(config, state, oci, api)
|
29
|
+
state.merge!(volume_state)
|
30
|
+
end
|
31
|
+
|
32
|
+
def process_volumes(config, state, oci, api)
|
33
|
+
volume_state = { volumes: [], volume_attachments: [] }
|
34
|
+
config[:volumes].each do |volume|
|
35
|
+
vol = volume_class(volume[:type], config, state, oci, api)
|
36
|
+
volume_details, vol_state = create_volume(vol, volume)
|
37
|
+
attach_state = vol.attach_volume(volume_details, state[:server_id], volume)
|
38
|
+
volume_state[:volumes] << vol_state
|
39
|
+
volume_state[:volume_attachments] << attach_state
|
40
|
+
end
|
41
|
+
volume_state
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_volume(vol, volume)
|
45
|
+
if volume.key?(:volume_id)
|
46
|
+
vol.create_clone_volume(volume)
|
47
|
+
else
|
48
|
+
vol.create_volume(volume)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/kitchen/driver/oci.rb
CHANGED
@@ -35,9 +35,10 @@ module Kitchen
|
|
35
35
|
class Oci < Kitchen::Driver::Base # rubocop:disable Metrics/ClassLength
|
36
36
|
require_relative "oci_version"
|
37
37
|
require_relative "oci/models"
|
38
|
+
require_relative "oci/volumes"
|
38
39
|
|
39
40
|
plugin_version Kitchen::Driver::OCI_VERSION
|
40
|
-
kitchen_driver_api_version
|
41
|
+
kitchen_driver_api_version 2
|
41
42
|
|
42
43
|
# required config items
|
43
44
|
required_config :availability_domain
|
@@ -63,6 +64,7 @@ module Kitchen
|
|
63
64
|
default_config :display_name, nil
|
64
65
|
default_keypath = File.expand_path(File.join(%w{~ .ssh id_rsa.pub}))
|
65
66
|
default_config :ssh_keypath, default_keypath
|
67
|
+
default_config :ssh_keygen, false
|
66
68
|
default_config :post_create_script, nil
|
67
69
|
default_config :proxy_url, nil
|
68
70
|
default_config :user_data, nil
|
@@ -114,6 +116,7 @@ module Kitchen
|
|
114
116
|
end
|
115
117
|
|
116
118
|
include Kitchen::Driver::Oci::Models
|
119
|
+
include Kitchen::Driver::Oci::Volumes
|
117
120
|
|
118
121
|
def create(state)
|
119
122
|
return if state[:server_id]
|
@@ -151,33 +154,6 @@ module Kitchen
|
|
151
154
|
instance.transport.connection(state).wait_until_ready
|
152
155
|
end
|
153
156
|
|
154
|
-
def create_and_attach_volumes(config, state, oci, api)
|
155
|
-
return if config[:volumes].empty?
|
156
|
-
|
157
|
-
volume_state = process_volumes(config, state, oci, api)
|
158
|
-
state.merge!(volume_state)
|
159
|
-
end
|
160
|
-
|
161
|
-
def process_volumes(config, state, oci, api)
|
162
|
-
volume_state = { volumes: [], volume_attachments: [] }
|
163
|
-
config[:volumes].each do |volume|
|
164
|
-
vol = volume_class(volume[:type], config, state, oci, api)
|
165
|
-
volume_details, vol_state = create_volume(vol, volume)
|
166
|
-
attach_state = vol.attach_volume(volume_details, state[:server_id], volume)
|
167
|
-
volume_state[:volumes] << vol_state
|
168
|
-
volume_state[:volume_attachments] << attach_state
|
169
|
-
end
|
170
|
-
volume_state
|
171
|
-
end
|
172
|
-
|
173
|
-
def create_volume(vol, volume)
|
174
|
-
if volume.key?(:volume_id)
|
175
|
-
vol.create_clone_volume(volume)
|
176
|
-
else
|
177
|
-
vol.create_volume(volume)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
157
|
def process_post_script(state)
|
182
158
|
return if config[:post_create_script].nil?
|
183
159
|
|
@@ -197,7 +173,7 @@ module Kitchen
|
|
197
173
|
def detatch_and_delete_volumes(state, oci, api)
|
198
174
|
return unless state[:volumes]
|
199
175
|
|
200
|
-
bls = Blockstorage.new(config, state, oci, api, :destroy)
|
176
|
+
bls = Blockstorage.new(config: config, state: state, oci: oci, api: api, action: :destroy, logger: instance.logger)
|
201
177
|
state[:volume_attachments].each { |att| bls.detatch_volume(att) }
|
202
178
|
state[:volumes].each { |vol| bls.delete_volume(vol) }
|
203
179
|
end
|
@@ -205,6 +181,10 @@ module Kitchen
|
|
205
181
|
def terminate(state, inst)
|
206
182
|
instance.transport.connection(state).close
|
207
183
|
inst.terminate
|
184
|
+
if state[:ssh_key]
|
185
|
+
FileUtils.rm_f(state[:ssh_key])
|
186
|
+
FileUtils.rm_f("#{state[:ssh_key]}.pub")
|
187
|
+
end
|
208
188
|
end
|
209
189
|
end
|
210
190
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitchen-oci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Pearson
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-01-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: oci
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- lib/kitchen/driver/oci/models/dbaas.rb
|
134
134
|
- lib/kitchen/driver/oci/models/iscsi.rb
|
135
135
|
- lib/kitchen/driver/oci/models/paravirtual.rb
|
136
|
+
- lib/kitchen/driver/oci/volumes.rb
|
136
137
|
- lib/kitchen/driver/oci_version.rb
|
137
138
|
- tpl/setup_winrm.ps1.erb
|
138
139
|
homepage: https://github.com/stephenpearson/kitchen-oci
|