kitchen-rackspace 0.21.2 → 0.22.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/.github/workflows/publish.yaml +1 -1
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +1 -3
- data/.yamllint +6 -0
- data/.yardopts +11 -0
- data/CHANGELOG.md +104 -3
- data/CONTRIBUTING.md +175 -0
- data/Gemfile +7 -5
- data/README.md +305 -58
- data/Rakefile +18 -2
- data/helpers/dump_flavor_list.rb +46 -0
- data/helpers/dump_image_list.rb +97 -66
- data/kitchen-rackspace.gemspec +6 -4
- data/lib/kitchen/driver/rackspace.rb +178 -11
- data/lib/kitchen/driver/rackspace_version.rb +4 -1
- data/spec/kitchen/driver/rackspace_spec.rb +123 -2
- metadata +12 -11
- data/.github/dependabot.yml +0 -8
data/kitchen-rackspace.gemspec
CHANGED
|
@@ -10,16 +10,18 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.description = "A Test Kitchen Rackspace driver"
|
|
11
11
|
spec.summary = "A Test Kitchen Rackspace driver built on Fog"
|
|
12
12
|
spec.homepage = "https://github.com/test-kitchen/kitchen-rackspace"
|
|
13
|
-
spec.license = "Apache"
|
|
13
|
+
spec.license = "Apache-2.0"
|
|
14
14
|
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
|
16
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
17
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
17
|
spec.require_paths = %w{lib}
|
|
19
18
|
|
|
20
19
|
spec.required_ruby_version = ">= 3.1"
|
|
21
20
|
|
|
22
21
|
spec.add_dependency "fog-rackspace", "~> 0.1.6"
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
# fog-rackspace 0.1.6 registers a service literally named "CDN v2"; fog-core
|
|
23
|
+
# 2.3.0+ passes that through const_defined?, which rejects it as an invalid
|
|
24
|
+
# constant name, so `require "fog/rackspace"` raises NameError.
|
|
25
|
+
spec.add_dependency "fog-core", ">= 1.35", "< 2.3"
|
|
26
|
+
spec.add_dependency "test-kitchen", ">= 3.0", "< 5.0"
|
|
25
27
|
end
|
|
@@ -4,12 +4,35 @@ require "kitchen"
|
|
|
4
4
|
require "etc" unless defined?(Etc)
|
|
5
5
|
require "socket" unless defined?(Socket)
|
|
6
6
|
require "json" unless defined?(JSON)
|
|
7
|
+
require "time" unless defined?(Time.now.iso8601)
|
|
8
|
+
require_relative "rackspace_version"
|
|
7
9
|
|
|
8
10
|
module Kitchen
|
|
11
|
+
# Test Kitchen's driver plugins.
|
|
9
12
|
module Driver
|
|
10
|
-
|
|
13
|
+
# Test Kitchen driver for Rackspace Cloud Servers.
|
|
14
|
+
#
|
|
15
|
+
# Creates a Cloud Server for the instance under test, waits for it to
|
|
16
|
+
# become reachable, and destroys it afterwards. Talking to the server is
|
|
17
|
+
# the transport's job; this driver only tells Test Kitchen where it is and
|
|
18
|
+
# who to log in as.
|
|
19
|
+
#
|
|
20
|
+
# Rackspace can run post-build automation -- RackConnect and Managed
|
|
21
|
+
# Service Level -- that keeps modifying a server after it first reports
|
|
22
|
+
# +ready+, including changing its public address. Set +rackconnect_wait+
|
|
23
|
+
# or +servicelevel_wait+ so the driver waits for that to finish before
|
|
24
|
+
# handing the server over, or the transport will connect to an address
|
|
25
|
+
# that is about to change.
|
|
26
|
+
class Rackspace < Kitchen::Driver::Base
|
|
27
|
+
kitchen_driver_api_version 2
|
|
28
|
+
|
|
29
|
+
plugin_version Kitchen::Driver::RACKSPACE_VERSION
|
|
30
|
+
|
|
31
|
+
# Server states Rackspace reports for a server that is up and reachable.
|
|
32
|
+
LIVE_STATES = %w{ACTIVE}.freeze
|
|
33
|
+
|
|
11
34
|
default_config :version, "v2"
|
|
12
|
-
default_config :flavor_id, "
|
|
35
|
+
default_config :flavor_id, "general1-2"
|
|
13
36
|
default_config :username, "root"
|
|
14
37
|
default_config :port, "22"
|
|
15
38
|
default_config :wait_for, 600
|
|
@@ -51,11 +74,22 @@ module Kitchen
|
|
|
51
74
|
required_config :image_id
|
|
52
75
|
required_config :public_key_path
|
|
53
76
|
|
|
77
|
+
# @param config [Hash] the driver configuration
|
|
54
78
|
def initialize(config)
|
|
55
79
|
super
|
|
56
80
|
Fog.timeout = config[:wait_for].to_i
|
|
57
81
|
end
|
|
58
82
|
|
|
83
|
+
# Creates the Cloud Server and waits until it can be logged into.
|
|
84
|
+
#
|
|
85
|
+
# Waits for the server to report ready, then optionally for RackConnect
|
|
86
|
+
# and Managed Service Level automation, then for the transport to accept
|
|
87
|
+
# a connection.
|
|
88
|
+
#
|
|
89
|
+
# @param state [Hash] mutable instance state; gains +server_id+,
|
|
90
|
+
# +hostname+, +username+, and +port+
|
|
91
|
+
# @return [void]
|
|
92
|
+
# @raise [Kitchen::ActionFailed] if the Rackspace API rejects the build
|
|
59
93
|
def create(state)
|
|
60
94
|
server = create_server
|
|
61
95
|
state[:server_id] = server.id
|
|
@@ -65,11 +99,18 @@ module Kitchen
|
|
|
65
99
|
rackconnect_check(server) if config[:rackconnect_wait]
|
|
66
100
|
servicelevel_check(server) if config[:servicelevel_wait]
|
|
67
101
|
state[:hostname] = hostname(server)
|
|
102
|
+
state[:username] = config[:username]
|
|
103
|
+
state[:port] = config[:port] if config[:port]
|
|
68
104
|
tcp_check(state)
|
|
69
105
|
rescue Fog::Errors::Error, Excon::Errors::Error => ex
|
|
70
106
|
raise ActionFailed, ex.message
|
|
71
107
|
end
|
|
72
108
|
|
|
109
|
+
# Destroys the Cloud Server, if one was created.
|
|
110
|
+
#
|
|
111
|
+
# @param state [Hash] mutable instance state; +server_id+ and +hostname+
|
|
112
|
+
# are removed
|
|
113
|
+
# @return [void]
|
|
73
114
|
def destroy(state)
|
|
74
115
|
return if state[:server_id].nil?
|
|
75
116
|
|
|
@@ -80,18 +121,24 @@ module Kitchen
|
|
|
80
121
|
state.delete(:hostname)
|
|
81
122
|
end
|
|
82
123
|
|
|
124
|
+
# Looks up the base image for the platform under test.
|
|
125
|
+
#
|
|
126
|
+
# @return [String, nil] the Rackspace image ID, or nil when the platform
|
|
127
|
+
# is not one the bundled image list knows about, in which case
|
|
128
|
+
# +image_id+ must be set explicitly
|
|
83
129
|
def default_image
|
|
84
130
|
images[instance.platform.name]
|
|
85
131
|
end
|
|
86
132
|
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
133
|
+
# Generates a server name that is unique per run and fits Rackspace's
|
|
134
|
+
# 63-character limit.
|
|
135
|
+
#
|
|
136
|
+
# The budget is spent as base name 15, username 15, hostname 23, random
|
|
137
|
+
# suffix 7, and three separators, for 63 exactly. Each part is stripped
|
|
138
|
+
# of non-word characters and truncated to its share, so a long login or
|
|
139
|
+
# hostname cannot push the result over.
|
|
140
|
+
#
|
|
141
|
+
# @return [String] e.g. +default-alice-buildbox01-x7f2p9q+
|
|
95
142
|
def default_name
|
|
96
143
|
[
|
|
97
144
|
instance.name.gsub(/\W/, "")[0..14],
|
|
@@ -101,8 +148,79 @@ module Kitchen
|
|
|
101
148
|
].join("-")
|
|
102
149
|
end
|
|
103
150
|
|
|
151
|
+
# Reports what Rackspace currently thinks of the server.
|
|
152
|
+
#
|
|
153
|
+
# @param state [Hash] instance state naming the server
|
|
154
|
+
# @return [Hash] a Test Kitchen status hash, or the base implementation's
|
|
155
|
+
# answer when there is no server or Rackspace does not know it
|
|
156
|
+
def status(state)
|
|
157
|
+
return super unless state[:server_id]
|
|
158
|
+
|
|
159
|
+
server = lookup_server(state[:server_id])
|
|
160
|
+
return super unless server
|
|
161
|
+
|
|
162
|
+
{
|
|
163
|
+
live: LIVE_STATES.include?(server.state),
|
|
164
|
+
state: server.state,
|
|
165
|
+
source: "driver",
|
|
166
|
+
resource_id: state[:server_id],
|
|
167
|
+
message: "Rackspace reports the server as #{server.state}",
|
|
168
|
+
checked_at: Time.now.utc.iso8601,
|
|
169
|
+
}
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Checks the configuration for the mistakes that only show up as a
|
|
173
|
+
# confusing failure part way through +create+.
|
|
174
|
+
#
|
|
175
|
+
# @param state [Hash] mutable instance and driver state
|
|
176
|
+
# @return [Boolean] true when a problem was reported
|
|
177
|
+
def doctor(state) # rubocop:disable Lint/UnusedMethodArgument
|
|
178
|
+
problems = []
|
|
179
|
+
|
|
180
|
+
if config[:image_id].nil?
|
|
181
|
+
problems << "No image_id is set and #{instance.platform.name} is not " \
|
|
182
|
+
"in the bundled image list. Set image_id explicitly."
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
if config[:public_key_path].nil?
|
|
186
|
+
problems << "No public key was found in ~/.ssh. Set public_key_path " \
|
|
187
|
+
"to the key Rackspace should install on the server."
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
problems.concat(credential_problems)
|
|
191
|
+
|
|
192
|
+
problems.each { |problem| warn(problem) }
|
|
193
|
+
!problems.empty?
|
|
194
|
+
end
|
|
195
|
+
|
|
104
196
|
private
|
|
105
197
|
|
|
198
|
+
# Confirms the configured credentials can actually talk to Rackspace,
|
|
199
|
+
# which is cheaper to learn here than half way through a converge.
|
|
200
|
+
#
|
|
201
|
+
# @return [Array<String>] a problem description, or an empty array
|
|
202
|
+
def credential_problems
|
|
203
|
+
compute.servers.summary
|
|
204
|
+
[]
|
|
205
|
+
rescue Fog::Errors::Error, Excon::Errors::Error => e
|
|
206
|
+
["Rackspace rejected the configured credentials for region " \
|
|
207
|
+
"#{config[:rackspace_region]}: #{e.message}"]
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Looks a server up without turning a missing one into a failure.
|
|
211
|
+
#
|
|
212
|
+
# @param server_id [String] the Rackspace server ID
|
|
213
|
+
# @return [Fog::Compute::RackspaceV2::Server, nil] the server, or nil
|
|
214
|
+
# when Rackspace does not know it or cannot be reached
|
|
215
|
+
def lookup_server(server_id)
|
|
216
|
+
compute.servers.get(server_id)
|
|
217
|
+
rescue Fog::Errors::Error, Excon::Errors::Error
|
|
218
|
+
nil
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Builds the fog compute connection from the configured credentials.
|
|
222
|
+
#
|
|
223
|
+
# @return [Fog::Compute] a Rackspace compute connection
|
|
106
224
|
def compute
|
|
107
225
|
server_def = { provider: "Rackspace" }
|
|
108
226
|
opts = %i{version rackspace_username rackspace_api_key
|
|
@@ -113,6 +231,13 @@ module Kitchen
|
|
|
113
231
|
Fog::Compute.new(server_def)
|
|
114
232
|
end
|
|
115
233
|
|
|
234
|
+
# Bootstraps the Cloud Server from the configured options.
|
|
235
|
+
#
|
|
236
|
+
# RackConnect and Managed Service Level both need the root password left
|
|
237
|
+
# unlocked to do their work, so +no_passwd_lock+ is forced on whenever
|
|
238
|
+
# either wait is requested, regardless of how it was configured.
|
|
239
|
+
#
|
|
240
|
+
# @return [Fog::Compute::RackspaceV2::Server] the newly built server
|
|
116
241
|
def create_server
|
|
117
242
|
server_def = { name: config[:server_name], networks: }
|
|
118
243
|
%i{image_id flavor_id public_key_path no_passwd_lock user_data config_drive}.each do |opt|
|
|
@@ -124,6 +249,9 @@ module Kitchen
|
|
|
124
249
|
compute.servers.bootstrap(server_def)
|
|
125
250
|
end
|
|
126
251
|
|
|
252
|
+
# The bundled platform-name to image-ID map.
|
|
253
|
+
#
|
|
254
|
+
# @return [Hash{String => String}] parsed from +data/images.json+
|
|
127
255
|
def images
|
|
128
256
|
@images ||= begin
|
|
129
257
|
json_file = File.expand_path("../../../data/images.json", __dir__)
|
|
@@ -131,14 +259,36 @@ module Kitchen
|
|
|
131
259
|
end
|
|
132
260
|
end
|
|
133
261
|
|
|
262
|
+
# Waits until the server will accept a login.
|
|
263
|
+
#
|
|
264
|
+
# The TCP check does not honour +ssh_config+, which some setups need, so
|
|
265
|
+
# +no_ssh_tcp_check+ swaps the check for a fixed sleep of
|
|
266
|
+
# +no_ssh_tcp_check_sleep+ seconds instead.
|
|
267
|
+
#
|
|
268
|
+
# @param state [Hash] instance state describing how to connect
|
|
269
|
+
# @return [void]
|
|
134
270
|
def tcp_check(state)
|
|
135
271
|
# allow driver config to bypass SSH tcp check -- because
|
|
136
272
|
# it doesn't respect ssh_config values that might be required
|
|
137
|
-
wait_for_sshd(state
|
|
273
|
+
wait_for_sshd(state) unless config[:no_ssh_tcp_check]
|
|
138
274
|
sleep(config[:no_ssh_tcp_check_sleep]) if config[:no_ssh_tcp_check]
|
|
139
275
|
puts "(ssh ready)"
|
|
140
276
|
end
|
|
141
277
|
|
|
278
|
+
# Kitchen::Driver::SSHBase used to supply this; the configured transport
|
|
279
|
+
# knows how to wait for the instance to accept connections.
|
|
280
|
+
def wait_for_sshd(state)
|
|
281
|
+
instance.transport.connection(state, &:wait_until_ready)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# Waits for RackConnect automation to finish.
|
|
285
|
+
#
|
|
286
|
+
# The server is refreshed afterwards, because RackConnect assigns a new
|
|
287
|
+
# public address as part of its work and the stale one would otherwise
|
|
288
|
+
# be handed to the transport.
|
|
289
|
+
#
|
|
290
|
+
# @param server [Fog::Compute::RackspaceV2::Server] the server to poll
|
|
291
|
+
# @return [void]
|
|
142
292
|
def rackconnect_check(server)
|
|
143
293
|
server.wait_for \
|
|
144
294
|
{ metadata.all["rackconnect_automation_status"] == "DEPLOYED" }
|
|
@@ -146,12 +296,21 @@ module Kitchen
|
|
|
146
296
|
server.update # refresh accessIPv4 with new IP
|
|
147
297
|
end
|
|
148
298
|
|
|
299
|
+
# Waits for Managed Service Level automation to finish.
|
|
300
|
+
#
|
|
301
|
+
# @param server [Fog::Compute::RackspaceV2::Server] the server to poll
|
|
302
|
+
# @return [void]
|
|
149
303
|
def servicelevel_check(server)
|
|
150
304
|
server.wait_for \
|
|
151
305
|
{ metadata.all["rax_service_level_automation"] == "Complete" }
|
|
152
306
|
puts "(service level automation complete)"
|
|
153
307
|
end
|
|
154
308
|
|
|
309
|
+
# Picks the address Test Kitchen should connect to.
|
|
310
|
+
#
|
|
311
|
+
# @param server [Fog::Compute::RackspaceV2::Server] the built server
|
|
312
|
+
# @return [String] the private address when +servicenet+ is set,
|
|
313
|
+
# otherwise the public one
|
|
155
314
|
def hostname(server)
|
|
156
315
|
if config[:servicenet] == false
|
|
157
316
|
server.public_ip_address
|
|
@@ -160,6 +319,14 @@ module Kitchen
|
|
|
160
319
|
end
|
|
161
320
|
end
|
|
162
321
|
|
|
322
|
+
# Builds the network list for the new server.
|
|
323
|
+
#
|
|
324
|
+
# Rackspace's PublicNet and ServiceNet have fixed, well-known IDs. Any
|
|
325
|
+
# configured networks are added to those two rather than replacing them,
|
|
326
|
+
# since dropping PublicNet would leave the server unreachable.
|
|
327
|
+
#
|
|
328
|
+
# @return [Array<String>, nil] network IDs, or nil to let Rackspace
|
|
329
|
+
# apply its own defaults
|
|
163
330
|
def networks
|
|
164
331
|
base_nets = %w{
|
|
165
332
|
00000000-0000-0000-0000-000000000000
|
|
@@ -27,6 +27,121 @@ describe Kitchen::Driver::Rackspace do
|
|
|
27
27
|
ENV["RACKSPACE_API_KEY"] = "key"
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
describe "plugin metadata" do
|
|
31
|
+
it "declares the driver API version" do
|
|
32
|
+
expect(described_class.instance_variable_get(:@api_version)).to eq(2)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "reports its own gem version to kitchen diagnose" do
|
|
36
|
+
expect(driver.diagnose_plugin[:version])
|
|
37
|
+
.to eq(Kitchen::Driver::RACKSPACE_VERSION)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "#status" do
|
|
42
|
+
let(:server) { double(state: "ACTIVE") }
|
|
43
|
+
let(:servers) { double }
|
|
44
|
+
|
|
45
|
+
before(:each) do
|
|
46
|
+
allow(driver).to receive(:compute).and_return(double(servers:))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context "with no server in state" do
|
|
50
|
+
it "reports an unknown status" do
|
|
51
|
+
expect(driver.status({})).to include(live: nil, state: "unknown")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context "with a server Rackspace does not know" do
|
|
56
|
+
it "reports an unknown status" do
|
|
57
|
+
expect(servers).to receive(:get).with("gone").and_return(nil)
|
|
58
|
+
|
|
59
|
+
expect(driver.status(server_id: "gone")).to include(state: "unknown")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "with a live server" do
|
|
64
|
+
before(:each) do
|
|
65
|
+
allow(servers).to receive(:get).with("s-1").and_return(server)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "reports the server as live" do
|
|
69
|
+
expect(driver.status(server_id: "s-1")).to include(
|
|
70
|
+
live: true, state: "ACTIVE", source: "driver", resource_id: "s-1"
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "stamps when the check happened" do
|
|
75
|
+
expect(driver.status(server_id: "s-1")[:checked_at])
|
|
76
|
+
.to match(/\A\d{4}-\d{2}-\d{2}T/)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context "with a server that is not active" do
|
|
81
|
+
it "reports the server as not live" do
|
|
82
|
+
allow(servers).to receive(:get)
|
|
83
|
+
.with("s-1").and_return(double(state: "ERROR"))
|
|
84
|
+
|
|
85
|
+
expect(driver.status(server_id: "s-1"))
|
|
86
|
+
.to include(live: false, state: "ERROR")
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
context "when Rackspace cannot be reached" do
|
|
91
|
+
it "reports an unknown status rather than raising" do
|
|
92
|
+
allow(servers).to receive(:get)
|
|
93
|
+
.and_raise(Fog::Errors::Error.new("boom"))
|
|
94
|
+
|
|
95
|
+
expect(driver.status(server_id: "s-1")).to include(state: "unknown")
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe "#doctor" do
|
|
101
|
+
let(:config) do
|
|
102
|
+
{ image_id: "img-1", public_key_path: "/home/user/.ssh/id_rsa.pub" }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
before(:each) do
|
|
106
|
+
allow(driver).to receive(:compute)
|
|
107
|
+
.and_return(double(servers: double(summary: [])))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "reports no problem when the configuration is complete" do
|
|
111
|
+
expect(driver.doctor(state)).to eq(false)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context "with no resolvable image" do
|
|
115
|
+
let(:config) { { public_key_path: "/key.pub" } }
|
|
116
|
+
|
|
117
|
+
it "reports a problem" do
|
|
118
|
+
allow(driver).to receive(:default_image).and_return(nil)
|
|
119
|
+
|
|
120
|
+
expect(driver.doctor(state)).to eq(true)
|
|
121
|
+
expect(logged_output.string).to match(/No image_id is set/)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
context "with no public key" do
|
|
126
|
+
let(:config) { { image_id: "img-1", public_key_path: nil } }
|
|
127
|
+
|
|
128
|
+
it "reports a problem" do
|
|
129
|
+
expect(driver.doctor(state)).to eq(true)
|
|
130
|
+
expect(logged_output.string).to match(/No public key was found/)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context "with credentials Rackspace rejects" do
|
|
135
|
+
it "reports a problem" do
|
|
136
|
+
allow(driver).to receive(:compute)
|
|
137
|
+
.and_raise(Fog::Errors::Error.new("unauthorized"))
|
|
138
|
+
|
|
139
|
+
expect(driver.doctor(state)).to eq(true)
|
|
140
|
+
expect(logged_output.string).to match(/rejected the configured credentials/)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
30
145
|
describe "#initialize" do
|
|
31
146
|
before(:each) do
|
|
32
147
|
allow(Fog).to receive(:timeout=)
|
|
@@ -37,8 +152,8 @@ describe Kitchen::Driver::Rackspace do
|
|
|
37
152
|
expect(driver[:version]).to eq("v2")
|
|
38
153
|
end
|
|
39
154
|
|
|
40
|
-
it "defaults to
|
|
41
|
-
expect(driver[:flavor_id]).to eq("
|
|
155
|
+
it "defaults to a 2 GB general purpose flavor" do
|
|
156
|
+
expect(driver[:flavor_id]).to eq("general1-2")
|
|
42
157
|
end
|
|
43
158
|
|
|
44
159
|
it "defaults to local user's SSH public key" do
|
|
@@ -160,6 +275,12 @@ describe Kitchen::Driver::Rackspace do
|
|
|
160
275
|
ENV["OS_REGION_NAME"] = "os_region"
|
|
161
276
|
end
|
|
162
277
|
|
|
278
|
+
after(:each) do
|
|
279
|
+
ENV.delete("OS_USERNAME")
|
|
280
|
+
ENV.delete("OS_PASSWORD")
|
|
281
|
+
ENV.delete("OS_REGION_NAME")
|
|
282
|
+
end
|
|
283
|
+
|
|
163
284
|
it "gets to username from $OS_USERNAME" do
|
|
164
285
|
expect(driver[:rackspace_username]).to eq("os_user")
|
|
165
286
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kitchen-rackspace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.22.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jonathan Hartman
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: fog-rackspace
|
|
@@ -33,7 +33,7 @@ dependencies:
|
|
|
33
33
|
version: '1.35'
|
|
34
34
|
- - "<"
|
|
35
35
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: 2.
|
|
36
|
+
version: '2.3'
|
|
37
37
|
type: :runtime
|
|
38
38
|
prerelease: false
|
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -43,14 +43,14 @@ dependencies:
|
|
|
43
43
|
version: '1.35'
|
|
44
44
|
- - "<"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 2.
|
|
46
|
+
version: '2.3'
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
48
|
name: test-kitchen
|
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
53
|
+
version: '3.0'
|
|
54
54
|
- - "<"
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
56
|
version: '5.0'
|
|
@@ -60,7 +60,7 @@ dependencies:
|
|
|
60
60
|
requirements:
|
|
61
61
|
- - ">="
|
|
62
62
|
- !ruby/object:Gem::Version
|
|
63
|
-
version: '
|
|
63
|
+
version: '3.0'
|
|
64
64
|
- - "<"
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
66
|
version: '5.0'
|
|
@@ -72,19 +72,22 @@ extensions: []
|
|
|
72
72
|
extra_rdoc_files: []
|
|
73
73
|
files:
|
|
74
74
|
- ".github/CODEOWNERS"
|
|
75
|
-
- ".github/dependabot.yml"
|
|
76
75
|
- ".github/workflows/linters.yml"
|
|
77
76
|
- ".github/workflows/publish.yaml"
|
|
78
77
|
- ".gitignore"
|
|
79
78
|
- ".markdownlint.yaml"
|
|
80
79
|
- ".release-please-manifest.json"
|
|
81
80
|
- ".rubocop.yml"
|
|
81
|
+
- ".yamllint"
|
|
82
|
+
- ".yardopts"
|
|
82
83
|
- CHANGELOG.md
|
|
84
|
+
- CONTRIBUTING.md
|
|
83
85
|
- Gemfile
|
|
84
86
|
- LICENSE
|
|
85
87
|
- README.md
|
|
86
88
|
- Rakefile
|
|
87
89
|
- data/images.json
|
|
90
|
+
- helpers/dump_flavor_list.rb
|
|
88
91
|
- helpers/dump_image_list.rb
|
|
89
92
|
- kitchen-rackspace.gemspec
|
|
90
93
|
- lib/kitchen/driver/rackspace.rb
|
|
@@ -95,7 +98,7 @@ files:
|
|
|
95
98
|
- spec/spec_helper.rb
|
|
96
99
|
homepage: https://github.com/test-kitchen/kitchen-rackspace
|
|
97
100
|
licenses:
|
|
98
|
-
- Apache
|
|
101
|
+
- Apache-2.0
|
|
99
102
|
metadata: {}
|
|
100
103
|
post_install_message:
|
|
101
104
|
rdoc_options: []
|
|
@@ -116,6 +119,4 @@ rubygems_version: 3.5.9
|
|
|
116
119
|
signing_key:
|
|
117
120
|
specification_version: 4
|
|
118
121
|
summary: A Test Kitchen Rackspace driver built on Fog
|
|
119
|
-
test_files:
|
|
120
|
-
- spec/kitchen/driver/rackspace_spec.rb
|
|
121
|
-
- spec/spec_helper.rb
|
|
122
|
+
test_files: []
|