kitchen-softlayer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +13 -0
- data/LICENSE.txt +13 -0
- data/README.md +137 -0
- data/kitchen-softlayer.gemspec +24 -0
- data/lib/kitchen/driver/softlayer.rb +333 -0
- data/lib/kitchen/driver/softlayer_version.rb +20 -0
- metadata +92 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a4968babda5beee11922c354ef309c24370736ca
|
4
|
+
data.tar.gz: 501dab415d0b3b622b9ec4ddeba644794c8b24af
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bfeb3f59a937cde441bc39c5760aee572b120fb7845ed4e521308230d7a599dac822808b9c0d9da6a1b8a65fc41ee35fc80dbd62ecfd9ba5dc093be728600bb2
|
7
|
+
data.tar.gz: 4c2394ecfb7a1cf5bc2456378274fbb6c85bedb411118e16b6dd1b99c31db81bd98805771e14ff645a481d58c99fe6993f4ff4de8a9d0ece293d385760c24b2a
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Author:: Neill Turner (<neillwturner.com>)
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/kitchen-softlayer.svg)](http://badge.fury.io/rb/kitchen-softlayer)
|
2
|
+
[![Gem Downloads](http://ruby-gem-downloads-badge.herokuapp.com/kitchen-softlayer?type=total&color=brightgreen)](https://rubygems.org/gems/kitchen-softlayer)
|
3
|
+
[![Build Status](https://travis-ci.org/neillturner/kitchen-softlayer.png)](https://travis-ci.org/neillturner/kitchen-softlayer)
|
4
|
+
|
5
|
+
# Kitchen::Softlayer
|
6
|
+
|
7
|
+
A Test Kitchen Driver for Softlayer
|
8
|
+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'kitchen-softlayer'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install kitchen-softlayer
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
By default set the following environment variables to your softlayer credentials:
|
27
|
+
|
28
|
+
```
|
29
|
+
softlayer_username
|
30
|
+
softlayer_api_key
|
31
|
+
softlayer_default_datacenter (optional)
|
32
|
+
softlayer_default_domain (optional)
|
33
|
+
```
|
34
|
+
|
35
|
+
So you don't need to code these in the .kitchen.yml file which is much better from a security point
|
36
|
+
of view as the kitchen.yml file can be checked in to source control without containing key data.
|
37
|
+
|
38
|
+
|
39
|
+
An example of the driver options in your `.kitchen.yml` file:
|
40
|
+
|
41
|
+
```yaml
|
42
|
+
driver:
|
43
|
+
name: softlayer
|
44
|
+
key_name: 'myuploadedsshkeylabel'
|
45
|
+
ssh_key: C:/mykeys/my_private_sshkey.pem
|
46
|
+
username: root
|
47
|
+
server_name: 'myserver-test'
|
48
|
+
hostname: 'MyProject-test01'
|
49
|
+
flavor_id: m1.tiny
|
50
|
+
# image_id: '3b235124-a190-40b5-9720-c020e61b99e1'
|
51
|
+
os_code: 'CENTOS_7_64'
|
52
|
+
domain: softlayer.com
|
53
|
+
private_network_only: true
|
54
|
+
cpu: 1,
|
55
|
+
ram: 1024,
|
56
|
+
datacenter: lon02
|
57
|
+
```
|
58
|
+
|
59
|
+
### os_code and image_id
|
60
|
+
you need to either specify softlayer's operating System Reference Code via parameter os_code
|
61
|
+
or an image_id.
|
62
|
+
|
63
|
+
### private_network_only
|
64
|
+
By default this parameter is set to false so no public network with be created.
|
65
|
+
For test-kitchen to access the server via ssh it needs to be on the softlayer private VPN. See:
|
66
|
+
|
67
|
+
[Using SSL VPN](http://knowledgelayer.softlayer.com/procedure/using-ssl-vpn)
|
68
|
+
|
69
|
+
### ssh_key
|
70
|
+
Currently the driver only supports using SSH keys to access servers. This requires that you upload an SSH Key in Softlayer see:
|
71
|
+
|
72
|
+
[SSH Keys](http://knowledgelayer.softlayer.com/procedure/ssh-keys-0)
|
73
|
+
|
74
|
+
in the kitchen.yml file specify the label of the ssh key as the parameter key_name
|
75
|
+
and specify the private key for the uploaded public key as parameter ssh_key.
|
76
|
+
|
77
|
+
The `image_ref` and `flavor_ref` options can be specified as an exact id,
|
78
|
+
an exact name, or as a regular expression matching the name of the image or flavor.
|
79
|
+
|
80
|
+
### hostname
|
81
|
+
|
82
|
+
the driver checks for a server with the hostname and will use that server instead of creating another one.
|
83
|
+
|
84
|
+
### disable_ssl_validation
|
85
|
+
|
86
|
+
the driver uses the fog-softlayer ruby client to communicate with softlayer.
|
87
|
+
If you get SSL certificate validation errors then the workaround is to set disable SSL cert validation to true
|
88
|
+
however it is better to set the environment variable 'SSL_CERT_FILE' to a valid certificate file.
|
89
|
+
|
90
|
+
# Softlayer Driver Options
|
91
|
+
|
92
|
+
key | default value | Notes
|
93
|
+
----|---------------|--------
|
94
|
+
softlayer_username | ENV['softlayer_username']
|
95
|
+
softlayer_api_key | ENV['softlayer_api_key']
|
96
|
+
softlayer_default_datacenter | ENV['softlayer_default_datacenter']
|
97
|
+
softlayer_default_domain | ENV['softlayer_default_domain']
|
98
|
+
server_name | nil | Server Name
|
99
|
+
key_name | nil | the label of the uploaded key
|
100
|
+
ssh_key| nil | file location of private key
|
101
|
+
disable_ssl_validation | false | ssl validation for fg softlayer api
|
102
|
+
username | 'root' | server's administration user
|
103
|
+
password | nil | server's administration password
|
104
|
+
port | '22' | ssh port of servef
|
105
|
+
hostname| nil | hostname of server
|
106
|
+
domain | ENV['softlayer_default_domain'] | domain nane of server
|
107
|
+
fqdn | nil | fully qualified domain name
|
108
|
+
cpu | nil | no of cpus
|
109
|
+
ram | nil | memory size
|
110
|
+
disk | nil | disk size
|
111
|
+
flavor_id | nil | type of server i.e. m1.tiny
|
112
|
+
bare_metal | false | server to be created on bare metal (takes longer)
|
113
|
+
os_code | nil | softlayer's operating System Reference Code
|
114
|
+
image_id | nil | image id for server
|
115
|
+
ephemeral_storage | nil | storage
|
116
|
+
network_components | nil | network
|
117
|
+
ssh_timeout | 300 | timeout to ssh when server starting
|
118
|
+
account_id | nil | softlayer account id
|
119
|
+
datacenter | ENV['softlayer_default_datacenter'] | datacenter code
|
120
|
+
single_tenant | false | don't share server
|
121
|
+
global_identifier | nil | softlayer global id
|
122
|
+
hourly_billing_flag | true
|
123
|
+
tags | [] | tags for the server
|
124
|
+
private_network_only | true | if only a private network
|
125
|
+
user_data | nil | user data for server
|
126
|
+
uid | nil | softlayer global id
|
127
|
+
vlan | nil | numeric id of private_vlan for server
|
128
|
+
private_vlan | nil | numeric id of private_vlan for server
|
129
|
+
|
130
|
+
## Contributing
|
131
|
+
|
132
|
+
1. Fork it
|
133
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
134
|
+
3. Run style checks and RSpec tests (`bundle exec rake`)
|
135
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
136
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
137
|
+
6. Create new Pull Request
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Encoding: UTF-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'kitchen/driver/softlayer_version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'kitchen-softlayer'
|
9
|
+
spec.version = Kitchen::Driver::SOFTLAYER_VERSION
|
10
|
+
spec.authors = ['Neill Turner']
|
11
|
+
spec.email = ['neillwturner@gmail.com']
|
12
|
+
spec.description = 'A Test Kitchen Softlayer driver'
|
13
|
+
spec.summary = 'Test Kitchen Softlayer driver'
|
14
|
+
spec.homepage = 'https://github.com/test-kitchen/kitchen-softlayer'
|
15
|
+
spec.license = 'Apache'
|
16
|
+
candidates = Dir.glob('{lib}/**/*') + ['README.md', 'LICENSE.txt']
|
17
|
+
candidates += ['CHANGELOG.md', 'kitchen-softlayer.gemspec']
|
18
|
+
spec.files = candidates.sort
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
spec.required_ruby_version = '>= 1.9.3'
|
21
|
+
spec.add_dependency 'test-kitchen', '~> 1.4'
|
22
|
+
spec.add_dependency 'fog', '~> 1.18'
|
23
|
+
spec.add_dependency 'fog-softlayer', '~> 0.4'
|
24
|
+
end
|
@@ -0,0 +1,333 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'fog'
|
16
|
+
require 'kitchen'
|
17
|
+
require 'socket'
|
18
|
+
require 'fog/softlayer'
|
19
|
+
|
20
|
+
module Kitchen
|
21
|
+
module Driver
|
22
|
+
# Softlayer driver for Kitchen.
|
23
|
+
# rubocop:disable Metrics/LineLength
|
24
|
+
class Softlayer < Kitchen::Driver::SSHBase
|
25
|
+
default_config :server_name, nil
|
26
|
+
default_config :key_name, nil
|
27
|
+
required_config :key_name
|
28
|
+
default_config :ssh_key do
|
29
|
+
%w(id_rsa id_dsa).map do |k|
|
30
|
+
f = File.expand_path("~/.ssh/#{k}")
|
31
|
+
f if File.exist?(f)
|
32
|
+
end.compact.first
|
33
|
+
end
|
34
|
+
|
35
|
+
required_config :ssh_key
|
36
|
+
default_config :disable_ssl_validation, false
|
37
|
+
default_config :username, 'root'
|
38
|
+
default_config :password, nil
|
39
|
+
default_config :port, '22'
|
40
|
+
default_config :hostname, nil
|
41
|
+
default_config :domain, ENV['softlayer_default_domain']
|
42
|
+
default_config :fqdn, nil
|
43
|
+
default_config :cpu, nil
|
44
|
+
default_config :ram, nil
|
45
|
+
default_config :disk, nil
|
46
|
+
default_config :flavor_id, nil
|
47
|
+
default_config :bare_metal, false
|
48
|
+
default_config :os_code, nil
|
49
|
+
default_config :image_id, nil
|
50
|
+
default_config :ephemeral_storage, nil
|
51
|
+
# keypair found from keyname
|
52
|
+
# default_config :key_pairs, nil
|
53
|
+
default_config :network_components, nil
|
54
|
+
default_config :softlayer_username, ENV['softlayer_username']
|
55
|
+
default_config :softlayer_api_key, ENV['softlayer_api_key']
|
56
|
+
default_config :softlayer_default_datacenter, ENV['softlayer_default_datacenter']
|
57
|
+
default_config :softlayer_default_domain, ENV['softlayer_default_domain']
|
58
|
+
default_config :ssh_timeout, 300
|
59
|
+
default_config :account_id, nil
|
60
|
+
default_config :datacenter, ENV['softlayer_default_datacenter']
|
61
|
+
default_config :single_tenant, false
|
62
|
+
default_config :global_identifier, nil
|
63
|
+
default_config :hourly_billing_flag, true
|
64
|
+
default_config :tags, nil
|
65
|
+
default_config :private_network_only, true
|
66
|
+
default_config :user_data, nil
|
67
|
+
default_config :uid, nil
|
68
|
+
default_config :tags, []
|
69
|
+
default_config :vlan, nil
|
70
|
+
default_config :private_vlan, nil
|
71
|
+
|
72
|
+
def create(state)
|
73
|
+
config[:server_name] = default_name unless config[:server_name]
|
74
|
+
config[:disable_ssl_validation] && disable_ssl_validation
|
75
|
+
server = find_server(config[:hostname])
|
76
|
+
server = create_server unless server
|
77
|
+
state[:server_id] = server.id
|
78
|
+
info "Softlayer instance <#{state[:server_id]}> created."
|
79
|
+
server.wait_for do
|
80
|
+
print '.'
|
81
|
+
ready?
|
82
|
+
end
|
83
|
+
info "\n(server ready)"
|
84
|
+
tag_server(server)
|
85
|
+
state[:hostname] = get_ip(server)
|
86
|
+
setup_ssh(server, state)
|
87
|
+
wait_for_ssh_key_access(state)
|
88
|
+
rescue Fog::Errors::Error, Excon::Errors::Error => ex
|
89
|
+
raise ActionFailed, ex.message
|
90
|
+
end
|
91
|
+
|
92
|
+
def destroy(state)
|
93
|
+
return if state[:server_id].nil?
|
94
|
+
|
95
|
+
config[:disable_ssl_validation] && disable_ssl_validation
|
96
|
+
server = compute.servers.get(state[:server_id])
|
97
|
+
server.destroy unless server.nil?
|
98
|
+
info "Softlayer instance <#{state[:server_id]}> destroyed."
|
99
|
+
state.delete(:server_id)
|
100
|
+
state.delete(:hostname)
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def wait_for_ssh_key_access(state)
|
106
|
+
new_state = build_ssh_args(state)
|
107
|
+
new_state[2][:number_of_password_prompts] = 0
|
108
|
+
info 'Checking ssh key authentication'
|
109
|
+
|
110
|
+
(config[:ssh_timeout].to_i).times do
|
111
|
+
ssh = Fog::SSH.new(*new_state)
|
112
|
+
begin
|
113
|
+
ssh.run([%(uname -a)])
|
114
|
+
rescue => e
|
115
|
+
info "Server not yet accepting SSH key: #{e.message}"
|
116
|
+
sleep 1
|
117
|
+
else
|
118
|
+
info 'SSH key authetication successful'
|
119
|
+
return
|
120
|
+
end
|
121
|
+
end
|
122
|
+
fail "#{config[:ssh_timeout]} seconds went by and we couldn't connect, somethings broken"
|
123
|
+
end
|
124
|
+
|
125
|
+
def compute
|
126
|
+
@compute_connection ||= Fog::Compute.new(
|
127
|
+
provider: :softlayer,
|
128
|
+
softlayer_username: config[:softlayer_username],
|
129
|
+
softlayer_api_key: config[:softlayer_api_key],
|
130
|
+
softlayer_default_datacenter: config[:softlayer_datacenter],
|
131
|
+
softlayer_default_domain: config[:softlayer_domain]
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
def network
|
136
|
+
@network_connection ||= Fog::Network.new(
|
137
|
+
provider: :softlayer,
|
138
|
+
softlayer_username: config[:softlayer_username],
|
139
|
+
softlayer_api_key: config[:softlayer_api_key]
|
140
|
+
)
|
141
|
+
end
|
142
|
+
|
143
|
+
def find_server(hostname)
|
144
|
+
s = nil
|
145
|
+
servers = compute.servers.all
|
146
|
+
servers.each do |server|
|
147
|
+
if server.name == hostname
|
148
|
+
s = server
|
149
|
+
info "Server with hostname #{hostname} already created"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
s
|
153
|
+
end
|
154
|
+
|
155
|
+
def create_server
|
156
|
+
server_def = init_configuration
|
157
|
+
# TODO: figure out network options
|
158
|
+
# if config[:network_ref]
|
159
|
+
# networks = [].concat([config[:network_ref]])
|
160
|
+
# server_def[:nics] = networks.flatten.map do |net|
|
161
|
+
# { 'net_id' => find_network(net).id }
|
162
|
+
# end
|
163
|
+
# end
|
164
|
+
[
|
165
|
+
:username,
|
166
|
+
:password,
|
167
|
+
:port,
|
168
|
+
:domain,
|
169
|
+
:fqdn,
|
170
|
+
:cpu,
|
171
|
+
:ram,
|
172
|
+
:disk,
|
173
|
+
:flavor_id,
|
174
|
+
:bare_metal,
|
175
|
+
:os_code,
|
176
|
+
:image_id,
|
177
|
+
:ephemeral_storage,
|
178
|
+
:network_components,
|
179
|
+
:account_id,
|
180
|
+
:single_tenant,
|
181
|
+
:global_identifier,
|
182
|
+
:tags,
|
183
|
+
:user_data,
|
184
|
+
:uid,
|
185
|
+
:vlan,
|
186
|
+
:private_vlan
|
187
|
+
].each do |c|
|
188
|
+
server_def[c] = optional_config(c) if config[c]
|
189
|
+
end
|
190
|
+
debug "server_def: #{server_def}"
|
191
|
+
compute.servers.create(server_def)
|
192
|
+
end
|
193
|
+
|
194
|
+
def init_configuration
|
195
|
+
{
|
196
|
+
name: config[:server_name],
|
197
|
+
key_pairs: [compute.key_pairs.by_label(config[:key_name])],
|
198
|
+
hostname: config[:hostname],
|
199
|
+
datacenter: config[:datacenter],
|
200
|
+
hourly_billing_flag: config[:hourly_billing_flag],
|
201
|
+
private_network_only: config[:private_network_only]
|
202
|
+
}
|
203
|
+
end
|
204
|
+
|
205
|
+
def optional_config(c)
|
206
|
+
case c
|
207
|
+
when :user_data
|
208
|
+
File.open(config[c]).read if File.exist?(config[c])
|
209
|
+
else
|
210
|
+
config[c]
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# Generate what should be a unique server name up to 63 total chars
|
215
|
+
# Base name: 15
|
216
|
+
# Username: 15
|
217
|
+
# Hostname: 23
|
218
|
+
# Random string: 7
|
219
|
+
# Separators: 3
|
220
|
+
# ================
|
221
|
+
# Total: 63
|
222
|
+
def default_name
|
223
|
+
[
|
224
|
+
instance.name.gsub(/\W/, '')[0..14],
|
225
|
+
(Etc.getlogin || 'nologin').gsub(/\W/, '')[0..14],
|
226
|
+
Socket.gethostname.gsub(/\W/, '')[0..22],
|
227
|
+
Array.new(7) { rand(36).to_s(36) }.join
|
228
|
+
].join('-')
|
229
|
+
end
|
230
|
+
|
231
|
+
# TODO: code has support for multiple ips but not used.
|
232
|
+
|
233
|
+
def get_public_private_ips(server)
|
234
|
+
pub = server.public_ip
|
235
|
+
priv = server.private_ip
|
236
|
+
[pub, priv]
|
237
|
+
end
|
238
|
+
|
239
|
+
def get_ip(server)
|
240
|
+
pub, priv = get_public_private_ips(server)
|
241
|
+
pub, priv = parse_ips(pub, priv)
|
242
|
+
pub[config[:public_ip_order].to_i] ||
|
243
|
+
priv[config[:private_ip_order].to_i] ||
|
244
|
+
fail(ActionFailed, 'Could not find an IP')
|
245
|
+
if config[:private_network_only]
|
246
|
+
return priv[0]
|
247
|
+
else
|
248
|
+
return pub[0]
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def parse_ips(pub, priv)
|
253
|
+
pub = Array(pub)
|
254
|
+
priv = Array(priv)
|
255
|
+
if config[:use_ipv6]
|
256
|
+
[pub, priv].each { |n| n.select! { |i| IPAddr.new(i).ipv6? } }
|
257
|
+
else
|
258
|
+
[pub, priv].each { |n| n.select! { |i| IPAddr.new(i).ipv4? } }
|
259
|
+
end
|
260
|
+
[pub, priv]
|
261
|
+
end
|
262
|
+
|
263
|
+
def setup_ssh(server, state)
|
264
|
+
tcp_check(state)
|
265
|
+
info "Using Softlayer keypair <#{config[:key_name]}>"
|
266
|
+
info "Using private SSH key <#{config[:ssh_key]}>"
|
267
|
+
state[:ssh_key] = config[:ssh_key]
|
268
|
+
# we don't call this as key_name must be set.
|
269
|
+
do_ssh_setup(state, config, server) unless config[:key_name]
|
270
|
+
end
|
271
|
+
|
272
|
+
def tcp_check(state)
|
273
|
+
# allow driver config to bypass SSH tcp check -- because
|
274
|
+
# it doesn't respect ssh_config values that might be required
|
275
|
+
if config[:no_ssh_tcp_check]
|
276
|
+
sleep(config[:no_ssh_tcp_check_sleep])
|
277
|
+
else
|
278
|
+
debug("wait_for_sshd hostname: #{state[:hostname]},username: #{config[:username]},port: #{config[:port]}")
|
279
|
+
wait_for_sshd(state[:hostname],
|
280
|
+
config[:username],
|
281
|
+
port: config[:port])
|
282
|
+
end
|
283
|
+
info '(ssh ready)'
|
284
|
+
end
|
285
|
+
|
286
|
+
def disable_ssl_validation
|
287
|
+
require 'excon'
|
288
|
+
Excon.defaults[:ssl_verify_peer] = false
|
289
|
+
end
|
290
|
+
|
291
|
+
def tag_server(server)
|
292
|
+
server.add_tags(config[:tags])
|
293
|
+
end
|
294
|
+
|
295
|
+
# TODO: add these checks
|
296
|
+
# def find_image(image_ref)
|
297
|
+
# image = find_matching(compute.images, image_ref)
|
298
|
+
# fail(ActionFailed, 'Image not found') unless image
|
299
|
+
# debug "Selected image: #{image.id} #{image.name}"
|
300
|
+
# image
|
301
|
+
# end
|
302
|
+
|
303
|
+
# def find_flavor(flavor_ref)
|
304
|
+
# flavor = find_matching(compute.flavors, flavor_ref)
|
305
|
+
# fail(ActionFailed, 'Flavor not found') unless flavor
|
306
|
+
# debug "Selected flavor: #{flavor.id} #{flavor.name}"
|
307
|
+
# flavor
|
308
|
+
# end
|
309
|
+
|
310
|
+
# def find_network(network_ref)
|
311
|
+
# net = find_matching(network.networks.all, network_ref)
|
312
|
+
# fail(ActionFailed, 'Network not found') unless net
|
313
|
+
# debug "Selected net: #{net.id} #{net.name}"
|
314
|
+
# net
|
315
|
+
# end
|
316
|
+
|
317
|
+
# def find_matching(collection, name)
|
318
|
+
# name = name.to_s
|
319
|
+
# if name.start_with?('/') && name.end_with?('/')
|
320
|
+
# regex = Regexp.new(name[1...-1])
|
321
|
+
# # check for regex name match
|
322
|
+
# collection.each { |single| return single if regex =~ single.name }
|
323
|
+
# else
|
324
|
+
# # check for exact id match
|
325
|
+
# collection.each { |single| return single if single.id == name }
|
326
|
+
# # check for exact name match
|
327
|
+
# collection.each { |single| return single if single.name == name }
|
328
|
+
# end
|
329
|
+
# nil
|
330
|
+
# end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Kitchen
|
16
|
+
# Version string for Softlayer Kitchen driver
|
17
|
+
module Driver
|
18
|
+
SOFTLAYER_VERSION = '0.0.1'
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kitchen-softlayer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Neill Turner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: test-kitchen
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fog
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.18'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.18'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: fog-softlayer
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.4'
|
55
|
+
description: A Test Kitchen Softlayer driver
|
56
|
+
email:
|
57
|
+
- neillwturner@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- CHANGELOG.md
|
63
|
+
- LICENSE.txt
|
64
|
+
- README.md
|
65
|
+
- kitchen-softlayer.gemspec
|
66
|
+
- lib/kitchen/driver/softlayer.rb
|
67
|
+
- lib/kitchen/driver/softlayer_version.rb
|
68
|
+
homepage: https://github.com/test-kitchen/kitchen-softlayer
|
69
|
+
licenses:
|
70
|
+
- Apache
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.9.3
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.2.2
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: Test Kitchen Softlayer driver
|
92
|
+
test_files: []
|