kitchen-oci 1.26.0 → 1.27.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/api.rb +36 -7
- data/lib/kitchen/driver/oci/blockstorage.rb +64 -20
- data/lib/kitchen/driver/oci/config.rb +29 -4
- data/lib/kitchen/driver/oci/instance/common.rb +8 -2
- data/lib/kitchen/driver/oci/instance/compute.rb +13 -1
- data/lib/kitchen/driver/oci/instance/database.rb +12 -1
- data/lib/kitchen/driver/oci/instance/db_home.rb +9 -1
- data/lib/kitchen/driver/oci/instance/dbaas.rb +21 -6
- data/lib/kitchen/driver/oci/instance.rb +63 -17
- data/lib/kitchen/driver/oci/mixin/actions.rb +99 -0
- data/lib/kitchen/driver/oci/mixin/models.rb +70 -0
- data/lib/kitchen/driver/oci/mixin/volumes.rb +88 -0
- data/lib/kitchen/driver/oci/models/compute.rb +76 -7
- data/lib/kitchen/driver/oci/models/dbaas.rb +28 -11
- data/lib/kitchen/driver/oci/models/iscsi.rb +14 -4
- data/lib/kitchen/driver/oci/models/paravirtual.rb +14 -4
- data/lib/kitchen/driver/oci.rb +21 -46
- data/lib/kitchen/driver/oci_version.rb +3 -1
- metadata +26 -5
- data/lib/kitchen/driver/oci/models.rb +0 -48
- data/lib/kitchen/driver/oci/volumes.rb +0 -54
@@ -23,69 +23,85 @@ module Kitchen
|
|
23
23
|
module Driver
|
24
24
|
class Oci
|
25
25
|
class Instance
|
26
|
-
#
|
26
|
+
# Setter methods that populate the details of OCI::Database::Models::LaunchDbSystemDetails.
|
27
|
+
#
|
28
|
+
# @author Justin Steele <justin.steele@oracle.com>
|
27
29
|
module DbaasLaunchDetails
|
28
30
|
include DatabaseDetails
|
29
31
|
include DbHomeDetails
|
30
32
|
#
|
31
33
|
# TODO: add support for the #domain property
|
32
34
|
#
|
35
|
+
|
36
|
+
# Adds the db_home property to the launch_details.
|
33
37
|
def db_home
|
34
38
|
launch_details.db_home = db_home_details
|
35
39
|
end
|
36
40
|
|
41
|
+
# Adds the subnet_id property to the launch_details.
|
37
42
|
def subnet_id
|
38
43
|
launch_details.subnet_id = config[:subnet_id]
|
39
44
|
end
|
40
45
|
|
46
|
+
# Adds the nsg_ids property to the launch_details.
|
41
47
|
def nsg_ids
|
42
48
|
launch_details.nsg_ids = config[:nsg_ids]
|
43
49
|
end
|
44
50
|
|
51
|
+
# Adds the hostname property to the launch_details.
|
52
|
+
# The hostname must begin with an alphabetic character, and can contain alphanumeric characters and hyphens (-).
|
53
|
+
# The maximum length of the hostname is 16 characters.
|
45
54
|
def hostname
|
46
|
-
# The hostname must begin with an alphabetic character, and can contain alphanumeric characters and hyphens (-).
|
47
|
-
# The maximum length of the hostname is 16 characters
|
48
55
|
long_name = [hostname_prefix, long_hostname_suffix].compact.join("-")
|
49
56
|
trimmed_name = [hostname_prefix[0, 12], random_string(3)].compact.join("-")
|
50
57
|
launch_details.hostname = [long_name, trimmed_name].min { |l, t| l.size <=> t.size }
|
51
58
|
end
|
52
59
|
|
60
|
+
# Adds the display_name property to the launch details.
|
61
|
+
# The user-friendly name for the DB system. The name does not have to be unique.
|
53
62
|
def display_name
|
54
|
-
# The user-friendly name for the DB system. The name does not have to be unique.
|
55
63
|
launch_details.display_name = [config[:hostname_prefix], random_string(4), random_number(2)].compact.join("-")
|
56
64
|
end
|
57
65
|
|
66
|
+
# Adds the node_count property to the launch_details.
|
58
67
|
def node_count
|
59
68
|
launch_details.node_count = 1
|
60
69
|
end
|
61
70
|
|
71
|
+
# Adds the ssh_public_keys property to the launch_details.
|
62
72
|
def pubkey
|
63
73
|
result = []
|
64
74
|
result << read_public_key
|
65
75
|
launch_details.ssh_public_keys = result
|
66
76
|
end
|
67
77
|
|
78
|
+
# Adds the cpu_core_count property to the launch_details.
|
68
79
|
def cpu_core_count
|
69
80
|
launch_details.cpu_core_count = config[:dbaas][:cpu_core_count] ||= 2
|
70
81
|
end
|
71
82
|
|
83
|
+
# Adds the license_model property to the launch_details.
|
72
84
|
def license_model
|
73
85
|
license = config[:dbaas][:license_model] ||= OCI::Database::Models::DbSystem::LICENSE_MODEL_BRING_YOUR_OWN_LICENSE
|
74
86
|
launch_details.license_model = license
|
75
87
|
end
|
76
88
|
|
89
|
+
# Adds the initial_data_size_in_gb property to the launch_details.
|
77
90
|
def initial_data_storage_size_in_gb
|
78
91
|
launch_details.initial_data_storage_size_in_gb = config[:dbaas][:initial_data_storage_size_in_gb] ||= 256
|
79
92
|
end
|
80
93
|
|
94
|
+
# Adds the database_edition property to the launch_details.
|
81
95
|
def database_edition
|
82
96
|
db_edition = config[:dbaas][:database_edition] ||= OCI::Database::Models::DbSystem::DATABASE_EDITION_ENTERPRISE_EDITION
|
83
97
|
launch_details.database_edition = db_edition
|
84
98
|
end
|
85
99
|
|
100
|
+
# Adds the cluster_name property to the launch_details.
|
101
|
+
# 11 character limit for cluster_name in DBaaS.
|
86
102
|
def cluster_name
|
87
103
|
prefix = config[:hostname_prefix].split("-")[0]
|
88
|
-
|
104
|
+
|
89
105
|
cn = if prefix.length >= 11
|
90
106
|
prefix[0, 11]
|
91
107
|
else
|
@@ -98,4 +114,3 @@ module Kitchen
|
|
98
114
|
end
|
99
115
|
end
|
100
116
|
end
|
101
|
-
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
3
|
# Author:: Justin Steele (<justin.steele@oracle.com>)
|
5
4
|
#
|
6
5
|
# Copyright (C) 2024, Stephen Pearson
|
@@ -20,7 +19,9 @@
|
|
20
19
|
module Kitchen
|
21
20
|
module Driver
|
22
21
|
class Oci
|
23
|
-
#
|
22
|
+
# Base class for instance models.
|
23
|
+
#
|
24
|
+
# @author Justin Steele <justin.steele@oracle.com>
|
24
25
|
class Instance < Oci # rubocop:disable Metrics/ClassLength
|
25
26
|
require_relative "api"
|
26
27
|
require_relative "config"
|
@@ -39,41 +40,35 @@ module Kitchen
|
|
39
40
|
@logger = opts[:logger]
|
40
41
|
end
|
41
42
|
|
42
|
-
#
|
43
|
-
# The config provided by the driver
|
43
|
+
# The config provided by the driver.
|
44
44
|
#
|
45
45
|
# @return [Kitchen::LazyHash]
|
46
|
-
#
|
47
46
|
attr_accessor :config
|
48
47
|
|
49
|
-
#
|
50
|
-
# The definition of the state of the instance from the statefile
|
48
|
+
# The definition of the state of the instance from the statefile.
|
51
49
|
#
|
52
50
|
# @return [Hash]
|
53
|
-
#
|
54
51
|
attr_accessor :state
|
55
52
|
|
56
|
-
#
|
57
|
-
# The config object that contains properties of the authentication to OCI
|
53
|
+
# The config object that contains properties of the authentication to OCI.
|
58
54
|
#
|
59
55
|
# @return [Kitchen::Driver::Oci::Config]
|
60
|
-
#
|
61
56
|
attr_accessor :oci
|
62
57
|
|
63
|
-
#
|
64
|
-
# The API object that contains each of the authenticated clients for interfacing with OCI
|
58
|
+
# The API object that contains each of the authenticated clients for interfacing with OCI.
|
65
59
|
#
|
66
60
|
# @return [Kitchen::Driver::Oci::Api]
|
67
|
-
#
|
68
61
|
attr_accessor :api
|
69
62
|
|
70
|
-
#
|
71
|
-
# The instance of Kitchen::Logger in use by the active Kitchen::Instance
|
63
|
+
# The instance of Kitchen::Logger in use by the active Kitchen::Instance.
|
72
64
|
#
|
73
65
|
# @return [Kitchen::Logger]
|
74
|
-
#
|
75
66
|
attr_accessor :logger
|
76
67
|
|
68
|
+
# Adds the instance info into the state.
|
69
|
+
#
|
70
|
+
# @param state [Hash] The state from kitchen.
|
71
|
+
# @return [Hash]
|
77
72
|
def final_state(state, instance_id)
|
78
73
|
state.store(:server_id, instance_id)
|
79
74
|
state.store(:hostname, instance_ip(instance_id))
|
@@ -82,6 +77,9 @@ module Kitchen
|
|
82
77
|
|
83
78
|
private
|
84
79
|
|
80
|
+
# Calls all of the setter methods for the self.
|
81
|
+
#
|
82
|
+
# @return [OCI::Core::Models::LaunchInstanceDetails, OCI::Database::Models::LaunchDbSystemDetails] the fully populated launch details for the specific instance type.
|
85
83
|
def launch_instance_details
|
86
84
|
launch_methods = []
|
87
85
|
self.class.ancestors.reverse.select { |m| m.is_a?(Module) && m.name.start_with?("#{self.class.superclass}::") }.each do |klass|
|
@@ -91,11 +89,17 @@ module Kitchen
|
|
91
89
|
launch_details
|
92
90
|
end
|
93
91
|
|
92
|
+
# Checks if public IP addresses are allowed in the specified subnet.
|
93
|
+
#
|
94
|
+
# @return [Boolean]
|
94
95
|
def public_ip_allowed?
|
95
96
|
subnet = api.network.get_subnet(config[:subnet_id]).data
|
96
97
|
!subnet.prohibit_public_ip_on_vnic
|
97
98
|
end
|
98
99
|
|
100
|
+
# Returns the location of the public ssh key.
|
101
|
+
#
|
102
|
+
# @return [String]
|
99
103
|
def public_key_file
|
100
104
|
if config[:ssh_keygen]
|
101
105
|
"#{config[:kitchen_root]}/.kitchen/.ssh/#{config[:instance_name]}_rsa.pub"
|
@@ -104,10 +108,14 @@ module Kitchen
|
|
104
108
|
end
|
105
109
|
end
|
106
110
|
|
111
|
+
# Returns the name of the private key file.
|
112
|
+
#
|
113
|
+
# @return [String]
|
107
114
|
def private_key_file
|
108
115
|
public_key_file.gsub(".pub", "")
|
109
116
|
end
|
110
117
|
|
118
|
+
# Generates an RSA key pair to be used to SSH to the instance and updates the state with the full path to the private key.
|
111
119
|
def gen_key_pair
|
112
120
|
FileUtils.mkdir_p("#{config[:kitchen_root]}/.kitchen/.ssh")
|
113
121
|
rsa_key = OpenSSL::PKey::RSA.new(4096)
|
@@ -116,16 +124,25 @@ module Kitchen
|
|
116
124
|
state.store(:ssh_key, private_key_file)
|
117
125
|
end
|
118
126
|
|
127
|
+
# Writes the private key.
|
128
|
+
#
|
129
|
+
# @param rsa_key [OpenSSL::PKey::RSA] the generated RSA key.
|
119
130
|
def write_private_key(rsa_key)
|
120
131
|
File.open(private_key_file, "wb") { |k| k.write(rsa_key.to_pem) }
|
121
132
|
File.chmod(0600, private_key_file)
|
122
133
|
end
|
123
134
|
|
135
|
+
# Writes the encoded private key as a public key.
|
136
|
+
#
|
137
|
+
# @param rsa_key [OpenSSL::PKey::RSA] the generated RSA key.
|
124
138
|
def write_public_key(rsa_key)
|
125
139
|
File.open(public_key_file, "wb") { |k| k.write("ssh-rsa #{encode_private_key(rsa_key)} #{config[:instance_name]}") }
|
126
140
|
File.chmod(0600, public_key_file)
|
127
141
|
end
|
128
142
|
|
143
|
+
# Encodes the private key.
|
144
|
+
#
|
145
|
+
# @param rsa_key [OpenSSL::PKey::RSA] the generated RSA key.
|
129
146
|
def encode_private_key(rsa_key)
|
130
147
|
prefix = "#{[7].pack("N")}ssh-rsa"
|
131
148
|
exponent = rsa_key.e.to_s(0)
|
@@ -133,6 +150,10 @@ module Kitchen
|
|
133
150
|
["#{prefix}#{exponent}#{modulus}"].pack("m0")
|
134
151
|
end
|
135
152
|
|
153
|
+
# Generates a random password.
|
154
|
+
#
|
155
|
+
# @param special_chars [Array] an array of special characters to include in the random password.
|
156
|
+
# @return [String]
|
136
157
|
def random_password(special_chars)
|
137
158
|
(Array.new(5) { special_chars.sample } +
|
138
159
|
Array.new(5) { ("a".."z").to_a.sample } +
|
@@ -140,14 +161,25 @@ module Kitchen
|
|
140
161
|
Array.new(5) { ("0".."9").to_a.sample }).shuffle.join
|
141
162
|
end
|
142
163
|
|
164
|
+
# Generates a random string of letters.
|
165
|
+
#
|
166
|
+
# @param length [Integer] how many characters to randomize.
|
167
|
+
# @return [String]
|
143
168
|
def random_string(length)
|
144
169
|
Array.new(length) { ("a".."z").to_a.sample }.join
|
145
170
|
end
|
146
171
|
|
172
|
+
# Generates a random string of numbers.
|
173
|
+
#
|
174
|
+
# @param length [Integer] how many numbers to randomize.
|
175
|
+
# @return [String]
|
147
176
|
def random_number(length)
|
148
177
|
Array.new(length) { ("0".."9").to_a.sample }.join
|
149
178
|
end
|
150
179
|
|
180
|
+
# Parses freeform tags to be added to the instance by the setter method.
|
181
|
+
#
|
182
|
+
# @return [Hash]
|
151
183
|
def process_freeform_tags
|
152
184
|
tags = %w{run_list policyfile}
|
153
185
|
fft = config[:freeform_tags]
|
@@ -161,6 +193,9 @@ module Kitchen
|
|
161
193
|
fft
|
162
194
|
end
|
163
195
|
|
196
|
+
# Encodes specified user_data to be added to cloud-init.
|
197
|
+
#
|
198
|
+
# @return [Base64]
|
164
199
|
def user_data
|
165
200
|
case config[:user_data]
|
166
201
|
when Array
|
@@ -170,6 +205,9 @@ module Kitchen
|
|
170
205
|
end
|
171
206
|
end
|
172
207
|
|
208
|
+
# GZips processed user_data prior to being encoded to allow for multi-part inclusions.
|
209
|
+
#
|
210
|
+
# @return [Zlib::GzipWriter]
|
173
211
|
def multi_part_user_data
|
174
212
|
boundary = "MIMEBOUNDARY_#{random_string(20)}"
|
175
213
|
msg = ["Content-Type: multipart/mixed; boundary=\"#{boundary}\"",
|
@@ -180,6 +218,10 @@ module Kitchen
|
|
180
218
|
gzip << txt
|
181
219
|
end
|
182
220
|
|
221
|
+
# Joins all of the bits provided by each itema in user_data with the provided boundary and content headers.
|
222
|
+
#
|
223
|
+
# @param boundary [String]
|
224
|
+
# @return [Array]
|
183
225
|
def mime_parts(boundary)
|
184
226
|
msg = []
|
185
227
|
config[:user_data].each do |m|
|
@@ -193,6 +235,10 @@ module Kitchen
|
|
193
235
|
msg
|
194
236
|
end
|
195
237
|
|
238
|
+
# Reads either the specified file or the text provided inline.
|
239
|
+
#
|
240
|
+
# @param part [Hash] the current item in the user_data hash being processed.
|
241
|
+
# @return [Array]
|
196
242
|
def read_part(part)
|
197
243
|
if part[:path]
|
198
244
|
content = File.read part[:path]
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Author:: Justin Steele (<justin.steele@oracle.com>)
|
5
|
+
#
|
6
|
+
# Copyright (C) 2025, 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
|
+
module Mixin
|
24
|
+
# Actions that can be performed on an instance.
|
25
|
+
#
|
26
|
+
# @author Justin Steele <justin.steele@oracle.com>
|
27
|
+
module Actions
|
28
|
+
# Launches an instance.
|
29
|
+
#
|
30
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
31
|
+
# @param inst [Class] the specific class of instance being launched.
|
32
|
+
def launch(state, inst)
|
33
|
+
state_details = inst.launch
|
34
|
+
state.merge!(state_details)
|
35
|
+
instance.transport.connection(state).wait_until_ready
|
36
|
+
end
|
37
|
+
|
38
|
+
# Executes the post script on the instance.
|
39
|
+
#
|
40
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
41
|
+
def execute_post_create_script(state)
|
42
|
+
return if config[:post_create_script].nil?
|
43
|
+
|
44
|
+
if config[:post_create_script].is_a?(String)
|
45
|
+
execute_post_create_string(state)
|
46
|
+
elsif config[:post_create_script].is_a?(Array)
|
47
|
+
execute_post_create_file(state)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Executes the post create script from a String.
|
52
|
+
#
|
53
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
54
|
+
def execute_post_create_string(state)
|
55
|
+
info("Running post create script")
|
56
|
+
script = config[:post_create_script]
|
57
|
+
instance.transport.connection(state).execute(script)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Reads the specified file and executes as a post create script.
|
61
|
+
#
|
62
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
63
|
+
def execute_post_create_file(state)
|
64
|
+
config[:post_create_script].each do |script|
|
65
|
+
info("Running post create script #{File.basename(script)}")
|
66
|
+
script = File.read script
|
67
|
+
instance.transport.connection(state).execute(script)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Reboots an instance.
|
72
|
+
#
|
73
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
74
|
+
# @param inst [Class] the specific class of instance being rebooted.
|
75
|
+
def reboot(state, inst)
|
76
|
+
return unless config[:post_create_reboot]
|
77
|
+
|
78
|
+
instance.transport.connection(state).close
|
79
|
+
inst.reboot
|
80
|
+
instance.transport.connection(state).wait_until_ready
|
81
|
+
end
|
82
|
+
|
83
|
+
# Terminates an instance.
|
84
|
+
#
|
85
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
86
|
+
# @param inst [Class] the specific class of instance being launched.
|
87
|
+
def terminate(state, inst)
|
88
|
+
instance.transport.connection(state).close
|
89
|
+
inst.terminate
|
90
|
+
if state[:ssh_key]
|
91
|
+
FileUtils.rm_f(state[:ssh_key])
|
92
|
+
FileUtils.rm_f("#{state[:ssh_key]}.pub")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,70 @@
|
|
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
|
+
module Mixin
|
24
|
+
# Instantiates the class of the specified model.
|
25
|
+
#
|
26
|
+
# @author Justin Steele <justin.steele@oracle.com>
|
27
|
+
module Models
|
28
|
+
require_relative "../instance"
|
29
|
+
require_relative "../blockstorage"
|
30
|
+
|
31
|
+
# Instantiates an instance model.
|
32
|
+
#
|
33
|
+
# @param config [Kitchen::LazyHash] The config provided by the driver.
|
34
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
35
|
+
# @param oci [Kitchen::Driver::Oci::Config] a populated OCI config class.
|
36
|
+
# @param api [Kitchen::Driver::Oci::Api] an authenticated API class.
|
37
|
+
# @return [Class] the instantiated model class.
|
38
|
+
def instance_class(config, state, oci, api, action)
|
39
|
+
Oci::Models.const_get(config[:instance_type].capitalize).new(config: config, state: state, oci: oci, api: api, action: action, logger: instance.logger)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Instantiates a blockstorage volume model.
|
43
|
+
#
|
44
|
+
# @param type [String] The type of volume that will be created.
|
45
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
46
|
+
# @param oci [Kitchen::Driver::Oci::Config] a populated OCI config class.
|
47
|
+
# @param api [Kitchen::Driver::Oci::Api] an authenticated API class.
|
48
|
+
# @return [Class] the instantiated model class.
|
49
|
+
def volume_class(type, config, state, oci, api)
|
50
|
+
Oci::Models.const_get(volume_attachment_type(type)).new(config: config, state: state, oci: oci, api: api, logger: instance.logger)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Returns the class name of the attachment type.
|
56
|
+
#
|
57
|
+
# @param type [String, nil]
|
58
|
+
# @return [String]
|
59
|
+
def volume_attachment_type(type)
|
60
|
+
if type.nil?
|
61
|
+
"Paravirtual"
|
62
|
+
else
|
63
|
+
type.capitalize
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,88 @@
|
|
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
|
+
module Mixin
|
24
|
+
# Mixins for working with volumes and attachments.
|
25
|
+
#
|
26
|
+
# @author Justin Steele <justin.steele@oracle.com>
|
27
|
+
module Volumes
|
28
|
+
# Create and attach volumes.
|
29
|
+
#
|
30
|
+
# @param config [Kitchen::LazyHash] The config provided by the driver.
|
31
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
32
|
+
# @param oci [Kitchen::Driver::Oci::Config] a populated OCI config class.
|
33
|
+
# @param api [Kitchen::Driver::Oci::Api] an authenticated API class.
|
34
|
+
def create_and_attach_volumes(config, state, oci, api)
|
35
|
+
return if config[:volumes].empty?
|
36
|
+
|
37
|
+
volume_state = process_volumes(config, state, oci, api)
|
38
|
+
state.merge!(volume_state)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Detatch and delete volumes.
|
42
|
+
#
|
43
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
44
|
+
# @param oci [Kitchen::Driver::Oci::Config] a populated OCI config class.
|
45
|
+
# @param api [Kitchen::Driver::Oci::Api] an authenticated API class.
|
46
|
+
def detatch_and_delete_volumes(state, oci, api)
|
47
|
+
return unless state[:volumes]
|
48
|
+
|
49
|
+
bls = Blockstorage.new(config: config, state: state, oci: oci, api: api, action: :destroy, logger: instance.logger)
|
50
|
+
state[:volume_attachments].each { |att| bls.detatch_volume(att) }
|
51
|
+
state[:volumes].each { |vol| bls.delete_volume(vol) }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Process volumes specified in the kitchen config.
|
55
|
+
#
|
56
|
+
# @param config [Kitchen::LazyHash] The config provided by the driver.
|
57
|
+
# @param state [Hash] (see Kitchen::StateFile)
|
58
|
+
# @param oci [Kitchen::Driver::Oci::Config] a populated OCI config class.
|
59
|
+
# @param api [Kitchen::Driver::Oci::Api] an authenticated API class.
|
60
|
+
# @return [Hash] the finalized state after the volume(s) have been created and attached.
|
61
|
+
def process_volumes(config, state, oci, api)
|
62
|
+
volume_state = { volumes: [], volume_attachments: [] }
|
63
|
+
config[:volumes].each do |volume|
|
64
|
+
vol = volume_class(volume[:type], config, state, oci, api)
|
65
|
+
volume_details, vol_state = create_volume(vol, volume)
|
66
|
+
attach_state = vol.attach_volume(volume_details, state[:server_id], volume)
|
67
|
+
volume_state[:volumes] << vol_state
|
68
|
+
volume_state[:volume_attachments] << attach_state
|
69
|
+
end
|
70
|
+
volume_state
|
71
|
+
end
|
72
|
+
|
73
|
+
# Creates or clones the volume.
|
74
|
+
#
|
75
|
+
# @param vol [OCI::Core::Models::Volume] the volume that has been created.
|
76
|
+
# @param volume [Hash] the state of the current volume being cloned.
|
77
|
+
def create_volume(vol, volume)
|
78
|
+
if volume.key?(:volume_id)
|
79
|
+
vol.create_clone_volume(volume)
|
80
|
+
else
|
81
|
+
vol.create_volume(volume)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|