knife-openstack 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/README.md +16 -1
- data/knife-openstack.gemspec +4 -0
- data/lib/chef/knife/openstack_server_create.rb +87 -19
- data/lib/knife-openstack/version.rb +1 -1
- data/spec/spec_helper.rb +4 -0
- data/spec/unit/openstack_server_create_spec.rb +164 -0
- metadata +87 -3
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Knife OpenStack
|
2
2
|
===============
|
3
3
|
|
4
|
-
This is the official Opscode Knife plugin for OpenStack Compute (Nova). This plugin gives knife the ability to create, bootstrap and manage instances in OpenStack Compute clouds. It has been tested against the `Diablo` through
|
4
|
+
This is the official Opscode Knife plugin for OpenStack Compute (Nova). This plugin gives knife the ability to create, bootstrap and manage instances in OpenStack Compute clouds. It has been tested against the `Diablo` through `Grizzly` releases in configurations using Keystone against the OpenStack API (as opposed to the EC2 API).
|
5
5
|
|
6
6
|
Please refer to the [CHANGELOG](CHANGELOG.md) for version history and known issues.
|
7
7
|
|
@@ -54,6 +54,19 @@ Additionally the following options may be set in your `knife.rb`:
|
|
54
54
|
|
55
55
|
To use a floating IP address while bootstrapping nodes, use the `-a` or `--floating-ip` option. For the node to have the floating IP address after bootstrapping, it is required to use the new `openstack.rb` Ohai plugin, waiting for the next Ohai release or installed using the [ohai cookbook](https://github.com/opscode-cookbooks/ohai). https://github.com/mattray/ohai/tree/OHAI-381 is the ticket for this.
|
56
56
|
|
57
|
+
# Working with Windows Images #
|
58
|
+
|
59
|
+
Provisioning and bootstrapping for Windows 2003/2008 images is now supported. The Windows images need to have WinRM enabled with Basic Authentication configured. Current support does not support Kerberos Authentication.
|
60
|
+
|
61
|
+
Example:
|
62
|
+
|
63
|
+
knife openstack server create -I <Image_ID> -f <Flavor_ID> -S <keypair_name> --bootstrap-protocol winrm -P <Administrator_Password> -x Administrator -N <chef_node_name> --template windows-chef-client-msi.erb
|
64
|
+
|
65
|
+
NOTE:
|
66
|
+
* Bootstrap Protocol (`--bootstrap-protocol`) is required to be set to `winrm`.
|
67
|
+
* Administrator Username (`--winrm-user` or `-x`) and Password (`-P`) are required parameters.
|
68
|
+
* If the Template File (`--template`) is not specified it defaults to a Linux distro (most likely Ubuntu).
|
69
|
+
|
57
70
|
# Subcommands #
|
58
71
|
|
59
72
|
This plugin provides the following Knife subcommands. Specific command options can be found by invoking the subcommand with a `--help` option.
|
@@ -94,6 +107,8 @@ Author:: Seth Chisamore (<schisamo@opscode.com>)
|
|
94
107
|
|
95
108
|
Author:: Matt Ray (<matt@opscode.com>)
|
96
109
|
|
110
|
+
Author:: Chirag Jog (<chirag@clogeny.com>)
|
111
|
+
|
97
112
|
Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
|
98
113
|
|
99
114
|
License:: Apache License, Version 2.0
|
data/knife-openstack.gemspec
CHANGED
@@ -21,4 +21,8 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.add_dependency "fog", ">= 1.10.0"
|
23
23
|
s.add_dependency "chef", ">= 0.10.10"
|
24
|
+
s.add_dependency "knife-windows"
|
25
|
+
|
26
|
+
%w(rspec-core rspec-expectations rspec-mocks rspec_junit_formatter).each { |gem| s.add_development_dependency gem }
|
27
|
+
s.require_paths = ["lib"]
|
24
28
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Seth Chisamore (<schisamo@opscode.com>)
|
3
3
|
# Author:: Matt Ray (<matt@opscode.com>)
|
4
|
+
# Author:: Chirag Jog (<chirag@clogeny.com>)
|
4
5
|
# Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
|
5
6
|
# License:: Apache License, Version 2.0
|
6
7
|
#
|
@@ -18,12 +19,14 @@
|
|
18
19
|
#
|
19
20
|
|
20
21
|
require 'chef/knife/openstack_base'
|
22
|
+
require 'chef/knife/winrm_base'
|
21
23
|
|
22
24
|
class Chef
|
23
25
|
class Knife
|
24
26
|
class OpenstackServerCreate < Knife
|
25
27
|
|
26
28
|
include Knife::OpenstackBase
|
29
|
+
include Chef::Knife::WinrmBase
|
27
30
|
|
28
31
|
deps do
|
29
32
|
require 'fog'
|
@@ -130,6 +133,22 @@ class Chef
|
|
130
133
|
:boolean => true,
|
131
134
|
:default => true
|
132
135
|
|
136
|
+
option :bootstrap_protocol,
|
137
|
+
:long => "--bootstrap-protocol protocol",
|
138
|
+
:description => "Protocol to bootstrap Windows servers. options: winrm",
|
139
|
+
:default => nil
|
140
|
+
|
141
|
+
option :bootstrap_proxy,
|
142
|
+
:long => "--bootstrap-proxy PROXY_URL",
|
143
|
+
:description => "The proxy server for the node being bootstrapped",
|
144
|
+
:proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_proxy] = v }
|
145
|
+
|
146
|
+
option :server_create_timeout,
|
147
|
+
:long => "--server-create-timeout timeout",
|
148
|
+
:description => "How long to wait until the server is ready; default is 600 seconds",
|
149
|
+
:default => 600,
|
150
|
+
:proc => Proc.new { |v| Chef::Config[:knife][:server_create_timeouts] = v}
|
151
|
+
|
133
152
|
def tcp_test_ssh(hostname)
|
134
153
|
tcp_socket = TCPSocket.new(hostname, 22)
|
135
154
|
readable = IO.select([tcp_socket], nil, nil, 5)
|
@@ -157,11 +176,41 @@ class Chef
|
|
157
176
|
tcp_socket && tcp_socket.close
|
158
177
|
end
|
159
178
|
|
179
|
+
def tcp_test_winrm(hostname, port)
|
180
|
+
TCPSocket.new(hostname, port)
|
181
|
+
return true
|
182
|
+
rescue SocketError
|
183
|
+
sleep 2
|
184
|
+
false
|
185
|
+
rescue Errno::ETIMEDOUT
|
186
|
+
false
|
187
|
+
rescue Errno::EPERM
|
188
|
+
false
|
189
|
+
rescue Errno::ECONNREFUSED
|
190
|
+
sleep 2
|
191
|
+
false
|
192
|
+
rescue Errno::EHOSTUNREACH
|
193
|
+
sleep 2
|
194
|
+
false
|
195
|
+
rescue Errno::ENETUNREACH
|
196
|
+
sleep 2
|
197
|
+
false
|
198
|
+
end
|
199
|
+
|
200
|
+
def load_winrm_deps
|
201
|
+
require 'winrm'
|
202
|
+
require 'em-winrm'
|
203
|
+
require 'chef/knife/bootstrap_windows_winrm'
|
204
|
+
require 'chef/knife/core/windows_bootstrap_context'
|
205
|
+
require 'chef/knife/winrm'
|
206
|
+
end
|
160
207
|
def run
|
161
208
|
$stdout.sync = true
|
162
209
|
|
163
210
|
validate!
|
164
|
-
|
211
|
+
if locate_config_value(:bootstrap_protocol) == 'winrm'
|
212
|
+
load_winrm_deps
|
213
|
+
end
|
165
214
|
#servers require a name, generate one if not passed
|
166
215
|
node_name = get_node_name(config[:chef_node_name])
|
167
216
|
|
@@ -204,7 +253,7 @@ class Chef
|
|
204
253
|
print "\n#{ui.color("Waiting for server", :magenta)}"
|
205
254
|
|
206
255
|
# wait for it to be ready to do stuff
|
207
|
-
server.wait_for { print "."; ready? }
|
256
|
+
server.wait_for(Integer(locate_config_value(:server_create_timeout))) { print "."; ready? }
|
208
257
|
|
209
258
|
puts("\n")
|
210
259
|
|
@@ -253,15 +302,18 @@ class Chef
|
|
253
302
|
exit 1
|
254
303
|
end
|
255
304
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
305
|
+
if locate_config_value(:bootstrap_protocol) == 'winrm'
|
306
|
+
print "\n#{ui.color("Waiting for winrm", :magenta)}"
|
307
|
+
print(".") until tcp_test_winrm(bootstrap_ip_address, locate_config_value(:winrm_port))
|
308
|
+
bootstrap_for_windows_node(server, bootstrap_ip_address).run
|
309
|
+
else
|
310
|
+
print "\n#{ui.color("Waiting for sshd", :magenta)}"
|
311
|
+
print(".") until tcp_test_ssh(bootstrap_ip_address) {
|
312
|
+
sleep @initial_sleep_delay ||= 10
|
313
|
+
puts("done")
|
314
|
+
}
|
315
|
+
bootstrap_for_node(server, bootstrap_ip_address).run
|
316
|
+
end
|
265
317
|
puts "\n"
|
266
318
|
msg_pair("Instance Name", server.name)
|
267
319
|
msg_pair("Instance ID", server.id)
|
@@ -275,27 +327,43 @@ class Chef
|
|
275
327
|
msg_pair("Run List", config[:run_list].join(', '))
|
276
328
|
end
|
277
329
|
|
278
|
-
def
|
279
|
-
bootstrap = Chef::Knife::
|
330
|
+
def bootstrap_for_windows_node(server, bootstrap_ip_address)
|
331
|
+
bootstrap = Chef::Knife::BootstrapWindowsWinrm.new
|
280
332
|
bootstrap.name_args = [bootstrap_ip_address]
|
333
|
+
bootstrap.config[:winrm_user] = locate_config_value(:winrm_user) || 'Administrator'
|
334
|
+
bootstrap.config[:winrm_password] = locate_config_value(:winrm_password)
|
335
|
+
bootstrap.config[:winrm_transport] = locate_config_value(:winrm_transport)
|
336
|
+
bootstrap.config[:winrm_port] = locate_config_value(:winrm_port)
|
337
|
+
bootstrap_common_params(bootstrap, server.name)
|
338
|
+
end
|
339
|
+
|
340
|
+
def bootstrap_common_params(bootstrap, server_name)
|
341
|
+
bootstrap.config[:chef_node_name] = config[:chef_node_name] || server_name
|
281
342
|
bootstrap.config[:run_list] = config[:run_list]
|
282
|
-
bootstrap.config[:ssh_user] = config[:ssh_user]
|
283
|
-
bootstrap.config[:ssh_password] = server.password
|
284
|
-
bootstrap.config[:identity_file] = config[:identity_file]
|
285
|
-
bootstrap.config[:host_key_verify] = config[:host_key_verify]
|
286
|
-
bootstrap.config[:chef_node_name] = server.name
|
287
343
|
bootstrap.config[:prerelease] = config[:prerelease]
|
288
344
|
bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
|
289
345
|
bootstrap.config[:distro] = locate_config_value(:distro)
|
290
|
-
bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
|
291
346
|
bootstrap.config[:template_file] = locate_config_value(:template_file)
|
347
|
+
bootstrap.config[:bootstrap_proxy] = locate_config_value(:bootstrap_proxy)
|
292
348
|
bootstrap.config[:environment] = config[:environment]
|
349
|
+
bootstrap.config[:encrypted_data_bag_secret] = config[:encrypted_data_bag_secret]
|
350
|
+
bootstrap.config[:encrypted_data_bag_secret_file] = config[:encrypted_data_bag_secret_file]
|
293
351
|
# let ohai know we're using OpenStack
|
294
352
|
Chef::Config[:knife][:hints] ||= {}
|
295
353
|
Chef::Config[:knife][:hints]['openstack'] ||= {}
|
296
354
|
bootstrap
|
297
355
|
end
|
298
356
|
|
357
|
+
def bootstrap_for_node(server, bootstrap_ip_address)
|
358
|
+
bootstrap = Chef::Knife::Bootstrap.new
|
359
|
+
bootstrap.name_args = [bootstrap_ip_address]
|
360
|
+
bootstrap.config[:ssh_user] = config[:ssh_user]
|
361
|
+
bootstrap.config[:identity_file] = config[:identity_file]
|
362
|
+
bootstrap.config[:host_key_verify] = config[:host_key_verify]
|
363
|
+
bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
|
364
|
+
bootstrap_common_params(bootstrap, server.name)
|
365
|
+
end
|
366
|
+
|
299
367
|
def flavor
|
300
368
|
@flavor ||= connection.flavors.get(locate_config_value(:flavor))
|
301
369
|
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Mukta Aphale (<mukta.aphale@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
4
|
+
|
5
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
6
|
+
require 'fog'
|
7
|
+
require 'chef/knife/bootstrap'
|
8
|
+
require 'chef/knife/bootstrap_windows_winrm'
|
9
|
+
|
10
|
+
describe Chef::Knife::OpenstackServerCreate do
|
11
|
+
before do
|
12
|
+
|
13
|
+
@openstack_connection = mock(Fog::Compute::OpenStack)
|
14
|
+
@openstack_connection.stub_chain(:flavors, :get).and_return ('flavor_id')
|
15
|
+
@openstack_connection.stub_chain(:images, :get).and_return mock('image_id')
|
16
|
+
@openstack_connection.stub_chain(:addresses).and_return [mock('addresses', {
|
17
|
+
:instance_id => nil,
|
18
|
+
:ip => '111.111.111.111',
|
19
|
+
:fixed_ip => true
|
20
|
+
})]
|
21
|
+
|
22
|
+
@knife_openstack_create = Chef::Knife::OpenstackServerCreate.new
|
23
|
+
@knife_openstack_create.initial_sleep_delay = 0
|
24
|
+
@knife_openstack_create.stub(:tcp_test_ssh).and_return(true)
|
25
|
+
@knife_openstack_create.stub(:tcp_test_winrm).and_return(true)
|
26
|
+
|
27
|
+
{
|
28
|
+
:image => 'image',
|
29
|
+
:openstack_username => 'openstack_username',
|
30
|
+
:openstack_password => 'openstack_password',
|
31
|
+
:openstack_auth_url => 'openstack_auth_url',
|
32
|
+
:server_create_timeout => 1000
|
33
|
+
}.each do |key, value|
|
34
|
+
Chef::Config[:knife][key] = value
|
35
|
+
end
|
36
|
+
|
37
|
+
@knife_openstack_create.stub(:msg_pair)
|
38
|
+
@knife_openstack_create.stub(:puts)
|
39
|
+
@knife_openstack_create.stub(:print)
|
40
|
+
|
41
|
+
|
42
|
+
@openstack_servers = mock()
|
43
|
+
@new_openstack_server = mock()
|
44
|
+
|
45
|
+
@openstack_server_attribs = { :name => 'Mock Server',
|
46
|
+
:id => 'id-123456',
|
47
|
+
:key_name => 'key_name',
|
48
|
+
:flavor => 'flavor_id',
|
49
|
+
:image => 'image_id',
|
50
|
+
:addresses => {
|
51
|
+
'public' => [{'addr' => '75.101.253.10'}],
|
52
|
+
'private' => [{'addr' => '10.251.75.20'}]
|
53
|
+
},
|
54
|
+
:password => 'password'
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
@openstack_server_attribs.each_pair do |attrib, value|
|
59
|
+
@new_openstack_server.stub(attrib).and_return(value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "run" do
|
64
|
+
before do
|
65
|
+
@openstack_servers.should_receive(:create).and_return(@new_openstack_server)
|
66
|
+
@openstack_connection.should_receive(:servers).and_return(@openstack_servers)
|
67
|
+
Fog::Compute::OpenStack.should_receive(:new).and_return(@openstack_connection)
|
68
|
+
@bootstrap = Chef::Knife::Bootstrap.new
|
69
|
+
Chef::Knife::Bootstrap.stub(:new).and_return(@bootstrap)
|
70
|
+
@bootstrap.should_receive(:run)
|
71
|
+
@knife_openstack_create.config[:run_list] = []
|
72
|
+
@knife_openstack_create.config[:floating_ip] = '-1'
|
73
|
+
end
|
74
|
+
|
75
|
+
it "Creates an OpenStack instance and bootstraps it" do
|
76
|
+
@new_openstack_server.should_receive(:wait_for).and_return(true)
|
77
|
+
@knife_openstack_create.run
|
78
|
+
end
|
79
|
+
|
80
|
+
it "Creates an OpenStack instance for Windows and bootstraps it" do
|
81
|
+
@bootstrap_win = Chef::Knife::BootstrapWindowsWinrm.new
|
82
|
+
Chef::Knife::BootstrapWindowsWinrm.stub(:new).and_return(@bootstrap_win)
|
83
|
+
Chef::Config[:knife][:bootstrap_protocol] = 'winrm'
|
84
|
+
@new_openstack_server.should_receive(:wait_for).and_return(true)
|
85
|
+
@knife_openstack_create.run
|
86
|
+
end
|
87
|
+
|
88
|
+
it "creates an OpenStack instance, assigns existing floating ip and bootstraps it" do
|
89
|
+
@knife_openstack_create.config[:floating_ip] = "111.111.111.111"
|
90
|
+
@new_openstack_server.should_receive(:wait_for).and_return(true)
|
91
|
+
@new_openstack_server.should_receive(:associate_address).with('111.111.111.111')
|
92
|
+
@knife_openstack_create.run
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "when configuring the bootstrap process" do
|
97
|
+
before do
|
98
|
+
@knife_openstack_create.config[:ssh_user] = "ubuntu"
|
99
|
+
@knife_openstack_create.config[:identity_file] = "~/.ssh/key.pem"
|
100
|
+
@knife_openstack_create.config[:chef_node_name] = "blarf"
|
101
|
+
@knife_openstack_create.config[:template_file] = '~/.chef/templates/my-bootstrap.sh.erb'
|
102
|
+
@knife_openstack_create.config[:distro] = 'ubuntu-10.04-magic-sparkles'
|
103
|
+
@knife_openstack_create.config[:run_list] = ['role[base]']
|
104
|
+
|
105
|
+
@bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server,
|
106
|
+
@new_openstack_server.addresses['public'].last['addr'])
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should set the bootstrap 'name argument' to the hostname of the OpenStack server" do
|
110
|
+
@bootstrap.name_args.should == ['75.101.253.10']
|
111
|
+
end
|
112
|
+
|
113
|
+
it "configures sets the bootstrap's run_list" do
|
114
|
+
@bootstrap.config[:run_list].should == ['role[base]']
|
115
|
+
end
|
116
|
+
|
117
|
+
it "configures the bootstrap to use the correct ssh_user login" do
|
118
|
+
@bootstrap.config[:ssh_user].should == 'ubuntu'
|
119
|
+
end
|
120
|
+
|
121
|
+
it "configures the bootstrap to use the correct ssh identity file" do
|
122
|
+
@bootstrap.config[:identity_file].should == "~/.ssh/key.pem"
|
123
|
+
end
|
124
|
+
|
125
|
+
it "configures the bootstrap to use the configured node name if provided" do
|
126
|
+
@bootstrap.config[:chef_node_name].should == 'blarf'
|
127
|
+
end
|
128
|
+
|
129
|
+
it "configures the bootstrap to use the OpenStack server id if no explicit node name is set" do
|
130
|
+
@knife_openstack_create.config[:chef_node_name] = nil
|
131
|
+
|
132
|
+
bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server,
|
133
|
+
@new_openstack_server.addresses['public'].last['addr'])
|
134
|
+
bootstrap.config[:chef_node_name].should == @new_openstack_server.name
|
135
|
+
end
|
136
|
+
|
137
|
+
it "configures the bootstrap to use prerelease versions of chef if specified" do
|
138
|
+
@bootstrap.config[:prerelease].should be_false
|
139
|
+
|
140
|
+
@knife_openstack_create.config[:prerelease] = true
|
141
|
+
|
142
|
+
bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server,
|
143
|
+
@new_openstack_server.addresses['public'].last['addr'])
|
144
|
+
bootstrap.config[:prerelease].should be_true
|
145
|
+
end
|
146
|
+
|
147
|
+
it "configures the bootstrap to use the desired distro-specific bootstrap script" do
|
148
|
+
@bootstrap.config[:distro].should == 'ubuntu-10.04-magic-sparkles'
|
149
|
+
end
|
150
|
+
|
151
|
+
it "configures the bootstrap to use sudo" do
|
152
|
+
@bootstrap.config[:use_sudo].should be_true
|
153
|
+
end
|
154
|
+
|
155
|
+
it "configured the bootstrap to use the desired template" do
|
156
|
+
@bootstrap.config[:template_file].should == '~/.chef/templates/my-bootstrap.sh.erb'
|
157
|
+
end
|
158
|
+
|
159
|
+
it "configured the bootstrap to set an openstack hint (via Chef::Config)" do
|
160
|
+
Chef::Config[:knife][:hints]['openstack'].should_not be_nil
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-openstack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-05-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: fog
|
@@ -44,6 +44,86 @@ dependencies:
|
|
44
44
|
- - ! '>='
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 0.10.10
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: knife-windows
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rspec-core
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: rspec-expectations
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
type: :development
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: rspec-mocks
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec_junit_formatter
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
47
127
|
description: OpenStack Compute Support for Chef's Knife Command
|
48
128
|
email:
|
49
129
|
- schisamo@opscode.com
|
@@ -69,6 +149,8 @@ files:
|
|
69
149
|
- lib/chef/knife/openstack_server_delete.rb
|
70
150
|
- lib/chef/knife/openstack_server_list.rb
|
71
151
|
- lib/knife-openstack/version.rb
|
152
|
+
- spec/spec_helper.rb
|
153
|
+
- spec/unit/openstack_server_create_spec.rb
|
72
154
|
homepage: https://github.com/opscode/knife-openstack
|
73
155
|
licenses: []
|
74
156
|
post_install_message:
|
@@ -93,4 +175,6 @@ rubygems_version: 1.8.24
|
|
93
175
|
signing_key:
|
94
176
|
specification_version: 3
|
95
177
|
summary: OpenStack Compute Support for Chef's Knife Command
|
96
|
-
test_files:
|
178
|
+
test_files:
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
- spec/unit/openstack_server_create_spec.rb
|