knife-openstack 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +31 -10
- data/README.md +14 -5
- data/knife-openstack.gemspec +1 -1
- data/lib/chef/knife/openstack_base.rb +40 -7
- data/lib/chef/knife/openstack_flavor_list.rb +12 -6
- data/lib/chef/knife/openstack_group_list.rb +57 -0
- data/lib/chef/knife/openstack_image_list.rb +30 -21
- data/lib/chef/knife/openstack_server_create.rb +113 -61
- data/lib/chef/knife/openstack_server_delete.rb +9 -7
- data/lib/chef/knife/openstack_server_list.rb +34 -29
- data/lib/knife-openstack/version.rb +1 -1
- metadata +8 -8
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
## v0.7.0
|
2
|
+
* Update dependency on to Fog 1.10.0
|
3
|
+
* 'delay-loading' changes to reduce load-time (Mohit Sethi)
|
4
|
+
* Use the hint with the bootstrap method instead of assuming the :personality works with the server.create method (KNIFE-201)
|
5
|
+
* Added 'knife openstack group list' for listing security groups and their rules (KNIFE-227)
|
6
|
+
* Filter out extraneous images from knife openstack image list and added '--disable-filter' to disable
|
7
|
+
* Fixed minor issue for public ip addresses (Edmund Haselwanter)
|
8
|
+
* Fixed security groups, adding `-G` support (KNIFE-230)
|
9
|
+
* Added snapshots as a new column in image list
|
10
|
+
* "knife openstack image list" fails with empty image name (KNIFE-83)(Simon Belluzzo)
|
11
|
+
* excon / fog errors are a JSON blob, Rescue fog errors (KNIFE-87)(Bryan McLellan)
|
12
|
+
* Better error handling for connection errors.
|
13
|
+
* Pass ssh_password to bootstrap (KNIFE-88)(David Petzel)
|
14
|
+
* Catch Net Unreachable error (E.J. Finneran)
|
15
|
+
* Allow an option to ignore the SSL cert (KNIFE-225)(BK Box)
|
16
|
+
* Attach to floating IPs (Mohit Sethi)
|
17
|
+
* Key pair is not required (KNIFE-226)(BK Box)
|
18
|
+
* Fog 1.10.0 changes API for OpenStack IP addresses (KNIFE-248)
|
19
|
+
|
1
20
|
## v0.6.2
|
2
21
|
* Use less pessimistic fog version constraint.
|
3
22
|
* Add guards to protect against nil values for private_ip_address
|
@@ -20,20 +39,22 @@
|
|
20
39
|
* Added support for `--no-host-key-verify` (Lamont Granquist)
|
21
40
|
* Added support for `--private-network` for bootstrapping private network
|
22
41
|
|
23
|
-
##
|
42
|
+
## V0.5.2
|
24
43
|
* initial Cactus release using EC2 API
|
25
44
|
|
26
45
|
# BACKLOG/ISSUES #
|
27
|
-
This is a list of features
|
46
|
+
This is a list of missing(?) features and open questions currently under development consideration:
|
28
47
|
|
29
|
-
*
|
48
|
+
* Basic availability zones support (Jarek Zmudzinski) NEED TESTING ACCESS FOR AVAILABILITY ZONES
|
49
|
+
* Windows bootstrapping (winrm-based) support for knife-openstack (KNIFE-221) winrm branch, UGLY WARNINGS NEED RESOLUTION
|
30
50
|
* purge only works when names match up with clients
|
31
|
-
* `knife openstack floating list|associate|
|
32
|
-
*
|
33
|
-
*
|
34
|
-
*
|
35
|
-
*
|
36
|
-
*
|
37
|
-
*
|
51
|
+
* `knife openstack floating list|associate|release NODE` with --floating-ip-pool also
|
52
|
+
* Allow specifying the name of the pool when using floating IPs (KNIFE-229)
|
53
|
+
* attempt to allocate a floating ipaddress if none if free, currently missing in Fog
|
54
|
+
* take either the flavor ID or the flavor name (KNIFE-76)
|
55
|
+
* take either the image ID or the image name (similar for KNIFE-76)
|
56
|
+
* server create with expired password hangs (KNIFE-86)
|
57
|
+
* added ability to specify arbitrary network ID (KNIFE-231)
|
38
58
|
* assumption of only single floating IP (and fog uses the last as the public_ip_address)
|
39
59
|
* probably other places public network is assumed that could cause issues
|
60
|
+
* fog is putting the original public IP address into the private_ip_address method when you get a floating_ip, this is wrong. Remove KNIFE-248 code once fixed.
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
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`
|
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 pre-`Grizzly` releases in configurations using Keystone against the OpenStack API (as opposed to the EC2 API).
|
5
5
|
|
6
|
-
Please refer to the CHANGELOG.md for version history and known
|
6
|
+
Please refer to the [CHANGELOG](CHANGELOG.md) for version history and known issues.
|
7
7
|
|
8
8
|
# Installation #
|
9
9
|
|
@@ -34,6 +34,10 @@ If your knife.rb file will be checked into a SCM system (ie readable by others)
|
|
34
34
|
knife[:openstack_auth_url] = "#{ENV['OS_AUTH_URL']}"
|
35
35
|
knife[:openstack_tenant] = "#{ENV['OS_TENANT_NAME']}"
|
36
36
|
|
37
|
+
If your OpenStack deployment is over SSL, but does not have a valid certificate, you can add the following option to bypass SSL check:
|
38
|
+
|
39
|
+
knife[:openstack_insecure] = true
|
40
|
+
|
37
41
|
You also have the option of passing your OpenStack API Username/Password into the individual knife subcommands using the `-A` (or `--openstack-username`) `-K` (or `--openstack-password`) command options
|
38
42
|
|
39
43
|
# provision a new image named kb01
|
@@ -72,12 +76,17 @@ Outputs a list of all servers in the currently configured OpenStack Compute clou
|
|
72
76
|
knife openstack flavor list
|
73
77
|
---------------------------
|
74
78
|
|
75
|
-
Outputs a list of all available flavors (available hardware configuration for a server) available to the currently configured OpenStack Compute cloud account. Each flavor has a unique combination of virtual cpus, disk space and memory capacity. This data
|
79
|
+
Outputs a list of all available flavors (available hardware configuration for a server) available to the currently configured OpenStack Compute cloud account. Each flavor has a unique combination of virtual cpus, disk space and memory capacity. This data may be useful when choosing a flavor id to pass to the `knife openstack server create` subcommand.
|
76
80
|
|
77
81
|
knife openstack image list
|
78
82
|
--------------------------
|
79
83
|
|
80
|
-
Outputs a list of all available images available to the currently configured OpenStack Compute cloud account. An image is a collection of files used to create or rebuild a server. This data
|
84
|
+
Outputs a list of all available images and snapshots available to the currently configured OpenStack Compute cloud account. An image is a collection of files used to create or rebuild a server. The retuned list filters out image names ending in 'initrd', 'kernel', 'loader', 'virtual' or 'vmlinuz' (this may be disabled with `--disable-filter`). This data may be useful when choosing an image id to pass to the `knife openstack server create` subcommand.
|
85
|
+
|
86
|
+
knife openstack group list
|
87
|
+
--------------------
|
88
|
+
|
89
|
+
Outputs a list of the security groups available to the currently configured OpenStack Compute cloud account. Each group may have multiple rules. This data may be useful when choosing your security group(s) to pass to the `knife openstack server create` subcommand.
|
81
90
|
|
82
91
|
# License #
|
83
92
|
|
@@ -85,7 +94,7 @@ Author:: Seth Chisamore (<schisamo@opscode.com>)
|
|
85
94
|
|
86
95
|
Author:: Matt Ray (<matt@opscode.com>)
|
87
96
|
|
88
|
-
Copyright:: Copyright (c) 2011-
|
97
|
+
Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
|
89
98
|
|
90
99
|
License:: Apache License, Version 2.0
|
91
100
|
|
data/knife-openstack.gemspec
CHANGED
@@ -19,6 +19,6 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_dependency "fog", "
|
22
|
+
s.add_dependency "fog", ">= 1.10.0"
|
23
23
|
s.add_dependency "chef", ">= 0.10.10"
|
24
24
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Seth Chisamore (<schisamo@opscode.com>)
|
3
3
|
# Author:: Matt Ray (<matt@opscode.com>)
|
4
|
-
# Copyright:: Copyright (c) 2011-
|
4
|
+
# Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -17,7 +17,7 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
|
20
|
-
require '
|
20
|
+
require 'fog'
|
21
21
|
|
22
22
|
class Chef
|
23
23
|
class Knife
|
@@ -30,9 +30,10 @@ class Chef
|
|
30
30
|
includer.class_eval do
|
31
31
|
|
32
32
|
deps do
|
33
|
-
require 'fog'
|
34
|
-
require 'readline'
|
35
33
|
require 'chef/json_compat'
|
34
|
+
require 'chef/knife'
|
35
|
+
require 'readline'
|
36
|
+
Chef::Knife.load_deps
|
36
37
|
end
|
37
38
|
|
38
39
|
option :openstack_username,
|
@@ -57,6 +58,13 @@ class Chef
|
|
57
58
|
:long => "--openstack-api-endpoint ENDPOINT",
|
58
59
|
:description => "Your OpenStack API endpoint",
|
59
60
|
:proc => Proc.new { |endpoint| Chef::Config[:knife][:openstack_auth_url] = endpoint }
|
61
|
+
|
62
|
+
option :openstack_insecure,
|
63
|
+
:long => "--insecure",
|
64
|
+
:description => "Ignore SSL certificate on the Auth URL",
|
65
|
+
:boolean => true,
|
66
|
+
:default => false,
|
67
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:openstack_insecure] = key }
|
60
68
|
end
|
61
69
|
end
|
62
70
|
|
@@ -64,15 +72,26 @@ class Chef
|
|
64
72
|
Chef::Log.debug("openstack_username #{Chef::Config[:knife][:openstack_username]}")
|
65
73
|
Chef::Log.debug("openstack_auth_url #{Chef::Config[:knife][:openstack_auth_url]}")
|
66
74
|
Chef::Log.debug("openstack_tenant #{Chef::Config[:knife][:openstack_tenant]}")
|
75
|
+
Chef::Log.debug("openstack_insecure #{Chef::Config[:knife][:openstack_insecure].to_s}")
|
76
|
+
|
67
77
|
@connection ||= begin
|
68
78
|
connection = Fog::Compute.new(
|
69
79
|
:provider => 'OpenStack',
|
70
80
|
:openstack_username => Chef::Config[:knife][:openstack_username],
|
71
81
|
:openstack_api_key => Chef::Config[:knife][:openstack_password],
|
72
82
|
:openstack_auth_url => Chef::Config[:knife][:openstack_auth_url],
|
73
|
-
:openstack_tenant => Chef::Config[:knife][:openstack_tenant]
|
74
|
-
|
75
|
-
|
83
|
+
:openstack_tenant => Chef::Config[:knife][:openstack_tenant],
|
84
|
+
:connection_options => {
|
85
|
+
:ssl_verify_peer => !Chef::Config[:knife][:openstack_insecure]
|
86
|
+
}
|
87
|
+
)
|
88
|
+
rescue Excon::Errors::Unauthorized => e
|
89
|
+
ui.fatal("Connection failure, please check your OpenStack username and password.")
|
90
|
+
exit 1
|
91
|
+
rescue Excon::Errors::SocketError => e
|
92
|
+
ui.fatal("Connection failure, please check your OpenStack authentication URL.")
|
93
|
+
exit 1
|
94
|
+
end
|
76
95
|
end
|
77
96
|
|
78
97
|
def locate_config_value(key)
|
@@ -101,6 +120,20 @@ class Chef
|
|
101
120
|
end
|
102
121
|
end
|
103
122
|
|
123
|
+
# http://tickets.opscode.com/browse/KNIFE-248
|
124
|
+
def primary_private_ip_address(addresses)
|
125
|
+
if addresses['private']
|
126
|
+
return addresses['private'].last['addr']
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
#we use last since the floating IP goes there
|
131
|
+
def primary_public_ip_address(addresses)
|
132
|
+
if addresses['public']
|
133
|
+
return addresses['public'].last['addr']
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
104
137
|
end
|
105
138
|
end
|
106
139
|
end
|
@@ -38,12 +38,18 @@ class Chef
|
|
38
38
|
ui.color('RAM', :bold),
|
39
39
|
ui.color('Disk', :bold),
|
40
40
|
]
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
begin
|
42
|
+
connection.flavors.sort_by(&:id).each do |flavor|
|
43
|
+
flavor_list << flavor.id.to_s
|
44
|
+
flavor_list << flavor.name
|
45
|
+
flavor_list << flavor.vcpus.to_s
|
46
|
+
flavor_list << "#{flavor.ram.to_s} MB"
|
47
|
+
flavor_list << "#{flavor.disk.to_s} GB"
|
48
|
+
end
|
49
|
+
rescue Excon::Errors::BadRequest => e
|
50
|
+
response = Chef::JSONCompat.from_json(e.response.body)
|
51
|
+
ui.fatal("Unknown server error (#{response['badRequest']['code']}): #{response['badRequest']['message']}")
|
52
|
+
raise e
|
47
53
|
end
|
48
54
|
puts ui.list(flavor_list, :uneven_columns_across, 5)
|
49
55
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Matt Ray (<matt@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife/openstack_base'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class OpenstackGroupList < Knife
|
24
|
+
|
25
|
+
include Knife::OpenstackBase
|
26
|
+
|
27
|
+
banner "knife openstack group list (options)"
|
28
|
+
|
29
|
+
def run
|
30
|
+
|
31
|
+
validate!
|
32
|
+
|
33
|
+
group_list = [
|
34
|
+
ui.color('Name', :bold),
|
35
|
+
ui.color('Protocol', :bold),
|
36
|
+
ui.color('From', :bold),
|
37
|
+
ui.color('To', :bold),
|
38
|
+
ui.color('CIDR', :bold),
|
39
|
+
ui.color('Description', :bold),
|
40
|
+
]
|
41
|
+
connection.security_groups.sort_by(&:name).each do |group|
|
42
|
+
group.rules.each do |rule|
|
43
|
+
unless rule['ip_protocol'].nil?
|
44
|
+
group_list << group.name
|
45
|
+
group_list << rule['ip_protocol']
|
46
|
+
group_list << rule['from_port'].to_s
|
47
|
+
group_list << rule['to_port'].to_s
|
48
|
+
group_list << rule['ip_range']['cidr']
|
49
|
+
group_list << group.description
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
puts ui.list(group_list, :uneven_columns_across, 6)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Seth Chisamore (<schisamo@opscode.com>)
|
3
3
|
# Author:: Matt Ray (<matt@opscode.com>)
|
4
|
-
# Copyright:: Copyright (c) 2011-
|
4
|
+
# Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -27,6 +27,12 @@ class Chef
|
|
27
27
|
|
28
28
|
banner "knife openstack image list (options)"
|
29
29
|
|
30
|
+
option :disable_filter,
|
31
|
+
:long => "--disable-filter",
|
32
|
+
:description => "Disable filtering of the image list. Currently filters names ending with 'initrd' or 'kernel'",
|
33
|
+
:boolean => true,
|
34
|
+
:default => false
|
35
|
+
|
30
36
|
def run
|
31
37
|
|
32
38
|
validate!
|
@@ -34,28 +40,31 @@ class Chef
|
|
34
40
|
image_list = [
|
35
41
|
ui.color('ID', :bold),
|
36
42
|
ui.color('Name', :bold),
|
37
|
-
|
38
|
-
# ui.color('Architecture', :bold),
|
39
|
-
# ui.color('Root Store', :bold),
|
40
|
-
# ui.color('Location', :bold)
|
43
|
+
ui.color('Snapshot', :bold),
|
41
44
|
]
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
begin
|
46
|
+
connection.images.sort_by do |image|
|
47
|
+
[image.name.to_s.downcase, image.id].compact
|
48
|
+
end.each do |image|
|
49
|
+
unless ((image.name =~ /initrd$|kernel$|loader$|virtual$|vmlinuz$/) &&
|
50
|
+
!config[:disable_filter])
|
51
|
+
image_list << image.id
|
52
|
+
image_list << image.name
|
53
|
+
snapshot = 'no'
|
54
|
+
image.metadata.each do |datum|
|
55
|
+
if (datum.key == 'image_type') && (datum.value == 'snapshot')
|
56
|
+
snapshot = 'yes'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
image_list << snapshot
|
60
|
+
end
|
61
|
+
end
|
62
|
+
rescue Excon::Errors::BadRequest => e
|
63
|
+
response = Chef::JSONCompat.from_json(e.response.body)
|
64
|
+
ui.fatal("Unknown server error (#{response['badRequest']['code']}): #{response['badRequest']['message']}")
|
65
|
+
raise e
|
52
66
|
end
|
53
|
-
|
54
|
-
image_list = image_list.map do |item|
|
55
|
-
item.to_s
|
56
|
-
end
|
57
|
-
|
58
|
-
puts ui.list(image_list, :uneven_columns_across, 2)
|
67
|
+
puts ui.list(image_list, :uneven_columns_across, 3)
|
59
68
|
end
|
60
69
|
end
|
61
70
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Seth Chisamore (<schisamo@opscode.com>)
|
3
3
|
# Author:: Matt Ray (<matt@opscode.com>)
|
4
|
-
# Copyright:: Copyright (c) 2011-
|
4
|
+
# Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -49,12 +49,12 @@ class Chef
|
|
49
49
|
:description => "The image ID for the server",
|
50
50
|
:proc => Proc.new { |i| Chef::Config[:knife][:image] = i }
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
option :security_groups,
|
53
|
+
:short => "-G X,Y,Z",
|
54
|
+
:long => "--groups X,Y,Z",
|
55
|
+
:description => "The security groups for this server",
|
56
|
+
:default => ["default"],
|
57
|
+
:proc => Proc.new { |groups| groups.split(',') }
|
58
58
|
|
59
59
|
option :chef_node_name,
|
60
60
|
:short => "-N NAME",
|
@@ -62,11 +62,10 @@ class Chef
|
|
62
62
|
:description => "The Chef node name for your new node"
|
63
63
|
|
64
64
|
option :floating_ip,
|
65
|
-
:short => "-a",
|
66
|
-
:long => "--floating-ip",
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:description => "Request to associate a floating IP address to the new OpenStack node. Assumes IPs have been allocated to the project."
|
65
|
+
:short => "-a [IP]",
|
66
|
+
:long => "--floating-ip [IP]",
|
67
|
+
:default => "-1",
|
68
|
+
:description => "Request to associate a floating IP address to the new OpenStack node. Assumes IPs have been allocated to the project. Specific IP is optional."
|
70
69
|
|
71
70
|
option :private_network,
|
72
71
|
:long => "--private-network",
|
@@ -148,7 +147,7 @@ class Chef
|
|
148
147
|
rescue Errno::ECONNREFUSED
|
149
148
|
sleep 2
|
150
149
|
false
|
151
|
-
rescue Errno::EHOSTUNREACH
|
150
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
|
152
151
|
sleep 2
|
153
152
|
false
|
154
153
|
rescue Errno::ENETUNREACH
|
@@ -163,14 +162,6 @@ class Chef
|
|
163
162
|
|
164
163
|
validate!
|
165
164
|
|
166
|
-
connection = Fog::Compute.new(
|
167
|
-
:provider => 'OpenStack',
|
168
|
-
:openstack_username => Chef::Config[:knife][:openstack_username],
|
169
|
-
:openstack_api_key => Chef::Config[:knife][:openstack_password],
|
170
|
-
:openstack_auth_url => Chef::Config[:knife][:openstack_auth_url],
|
171
|
-
:openstack_tenant => Chef::Config[:knife][:openstack_tenant]
|
172
|
-
)
|
173
|
-
|
174
165
|
#servers require a name, generate one if not passed
|
175
166
|
node_name = get_node_name(config[:chef_node_name])
|
176
167
|
|
@@ -178,25 +169,37 @@ class Chef
|
|
178
169
|
:name => node_name,
|
179
170
|
:image_ref => locate_config_value(:image),
|
180
171
|
:flavor_ref => locate_config_value(:flavor),
|
181
|
-
|
182
|
-
:key_name =>
|
183
|
-
:personality => [{
|
184
|
-
"path" => "/etc/chef/ohai/hints/openstack.json",
|
185
|
-
"contents" => ''
|
186
|
-
}]
|
172
|
+
:security_groups => locate_config_value(:security_groups),
|
173
|
+
:key_name => locate_config_value(:openstack_ssh_key_id)
|
187
174
|
}
|
188
175
|
|
189
176
|
Chef::Log.debug("Name #{node_name}")
|
190
177
|
Chef::Log.debug("Image #{locate_config_value(:image)}")
|
191
178
|
Chef::Log.debug("Flavor #{locate_config_value(:flavor)}")
|
192
|
-
|
179
|
+
Chef::Log.debug("Requested Floating IP #{locate_config_value(:floating_ip)}")
|
180
|
+
Chef::Log.debug("Security Groups #{locate_config_value(:security_groups)}")
|
193
181
|
Chef::Log.debug("Creating server #{server_def}")
|
194
|
-
|
182
|
+
|
183
|
+
begin
|
184
|
+
server = connection.servers.create(server_def)
|
185
|
+
rescue Excon::Errors::BadRequest => e
|
186
|
+
response = Chef::JSONCompat.from_json(e.response.body)
|
187
|
+
if response['badRequest']['code'] == 400
|
188
|
+
if response['badRequest']['message'] =~ /Invalid flavorRef/
|
189
|
+
ui.fatal("Bad request (400): Invalid flavor specified: #{server_def[:flavor_ref]}")
|
190
|
+
exit 1
|
191
|
+
else
|
192
|
+
ui.fatal("Bad request (400): #{response['badRequest']['message']}")
|
193
|
+
exit 1
|
194
|
+
end
|
195
|
+
else
|
196
|
+
ui.fatal("Unknown server error (#{response['badRequest']['code']}): #{response['badRequest']['message']}")
|
197
|
+
raise e
|
198
|
+
end
|
199
|
+
end
|
195
200
|
|
196
201
|
msg_pair("Instance Name", server.name)
|
197
202
|
msg_pair("Instance ID", server.id)
|
198
|
-
# msg_pair("Security Groups", server.groups.join(", "))
|
199
|
-
msg_pair("SSH Keypair", server.key_name)
|
200
203
|
|
201
204
|
print "\n#{ui.color("Waiting for server", :magenta)}"
|
202
205
|
|
@@ -207,35 +210,44 @@ class Chef
|
|
207
210
|
|
208
211
|
msg_pair("Flavor", server.flavor['id'])
|
209
212
|
msg_pair("Image", server.image['id'])
|
210
|
-
msg_pair("
|
211
|
-
|
212
|
-
if
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
213
|
+
msg_pair("SSH Identity File", config[:identity_file])
|
214
|
+
msg_pair("SSH Keypair", server.key_name) if server.key_name
|
215
|
+
msg_pair("SSH Password", server.password) if (server.password && !server.key_name)
|
216
|
+
Chef::Log.debug("Addresses #{server.addresses}")
|
217
|
+
msg_pair("Public IP Address", primary_public_ip_address(server.addresses)) if primary_public_ip_address(server.addresses)
|
218
|
+
|
219
|
+
floating_address = locate_config_value(:floating_ip)
|
220
|
+
Chef::Log.debug("Floating IP Address requested #{floating_address}")
|
221
|
+
unless (floating_address == '-1') #no floating IP requested
|
222
|
+
addresses = connection.addresses
|
223
|
+
#floating requested without value
|
224
|
+
if floating_address.nil?
|
225
|
+
free_floating = addresses.find_index {|a| a.fixed_ip.nil?}
|
226
|
+
if free_floating.nil? #no free floating IP found
|
227
|
+
ui.error("Unable to assign a Floating IP from allocated IPs.")
|
228
|
+
exit 1
|
229
|
+
else
|
230
|
+
floating_address = addresses[free_floating].ip
|
222
231
|
end
|
223
232
|
end
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
233
|
+
server.associate_address(floating_address)
|
234
|
+
#a bit of a hack, but server.reload takes a long time
|
235
|
+
(server.addresses['public'] ||= []) << {"version"=>4,"addr"=>floating_address}
|
236
|
+
msg_pair("Floating IP Address", floating_address)
|
228
237
|
end
|
229
|
-
Chef::Log.debug("Public IP Address actual #{server.public_ip_address['addr']}") if server.public_ip_address
|
230
238
|
|
231
|
-
|
239
|
+
Chef::Log.debug("Addresses #{server.addresses}")
|
240
|
+
Chef::Log.debug("Public IP Address actual: #{primary_public_ip_address(server.addresses)}") if primary_public_ip_address(server.addresses)
|
241
|
+
|
242
|
+
msg_pair("Private IP Address", primary_private_ip_address(server.addresses)) if primary_private_ip_address(server.addresses)
|
232
243
|
|
233
244
|
#which IP address to bootstrap
|
234
|
-
bootstrap_ip_address = server.
|
245
|
+
bootstrap_ip_address = primary_public_ip_address(server.addresses) if primary_public_ip_address(server.addresses)
|
235
246
|
if config[:private_network]
|
236
|
-
bootstrap_ip_address = server.
|
247
|
+
bootstrap_ip_address = primary_private_ip_address(server.addresses)
|
237
248
|
end
|
238
|
-
|
249
|
+
|
250
|
+
Chef::Log.debug("Bootstrap IP Address: #{bootstrap_ip_address}")
|
239
251
|
if bootstrap_ip_address.nil?
|
240
252
|
ui.error("No IP address available for bootstrapping.")
|
241
253
|
exit 1
|
@@ -255,10 +267,10 @@ class Chef
|
|
255
267
|
msg_pair("Instance ID", server.id)
|
256
268
|
msg_pair("Flavor", server.flavor['id'])
|
257
269
|
msg_pair("Image", server.image['id'])
|
258
|
-
|
259
|
-
msg_pair("SSH
|
260
|
-
msg_pair("Public IP Address", server.
|
261
|
-
msg_pair("Private IP Address", server.
|
270
|
+
msg_pair("SSH Keypair", server.key_name) if server.key_name
|
271
|
+
msg_pair("SSH Password", server.password) if (server.password && !server.key_name)
|
272
|
+
msg_pair("Public IP Address", primary_public_ip_address(server.addresses)) if primary_public_ip_address(server.addresses)
|
273
|
+
msg_pair("Private IP Address", primary_private_ip_address(server.addresses)) if primary_private_ip_address(server.addresses)
|
262
274
|
msg_pair("Environment", config[:environment] || '_default')
|
263
275
|
msg_pair("Run List", config[:run_list].join(', '))
|
264
276
|
end
|
@@ -268,6 +280,7 @@ class Chef
|
|
268
280
|
bootstrap.name_args = [bootstrap_ip_address]
|
269
281
|
bootstrap.config[:run_list] = config[:run_list]
|
270
282
|
bootstrap.config[:ssh_user] = config[:ssh_user]
|
283
|
+
bootstrap.config[:ssh_password] = server.password
|
271
284
|
bootstrap.config[:identity_file] = config[:identity_file]
|
272
285
|
bootstrap.config[:host_key_verify] = config[:host_key_verify]
|
273
286
|
bootstrap.config[:chef_node_name] = server.name
|
@@ -277,19 +290,58 @@ class Chef
|
|
277
290
|
bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
|
278
291
|
bootstrap.config[:template_file] = locate_config_value(:template_file)
|
279
292
|
bootstrap.config[:environment] = config[:environment]
|
293
|
+
# let ohai know we're using OpenStack
|
294
|
+
Chef::Config[:knife][:hints] ||= {}
|
295
|
+
Chef::Config[:knife][:hints]['openstack'] ||= {}
|
280
296
|
bootstrap
|
281
297
|
end
|
282
298
|
|
283
|
-
def
|
284
|
-
@
|
299
|
+
def flavor
|
300
|
+
@flavor ||= connection.flavors.get(locate_config_value(:flavor))
|
301
|
+
end
|
302
|
+
|
303
|
+
def image
|
304
|
+
@image ||= connection.images.get(locate_config_value(:image))
|
305
|
+
end
|
306
|
+
|
307
|
+
def is_floating_ip_valid
|
308
|
+
address = locate_config_value(:floating_ip)
|
309
|
+
if address == '-1' #no floating IP requested
|
310
|
+
return true
|
311
|
+
end
|
312
|
+
addresses = connection.addresses
|
313
|
+
return false if addresses.empty? #no floating IPs
|
314
|
+
#floating requested without value
|
315
|
+
if address.nil?
|
316
|
+
if addresses.find_index {|a| a.fixed_ip.nil?}
|
317
|
+
return true
|
318
|
+
else
|
319
|
+
return false #no floating IPs available
|
320
|
+
end
|
321
|
+
end
|
322
|
+
#floating requested with value
|
323
|
+
if addresses.find_index {|a| a.ip == address}
|
324
|
+
return true
|
325
|
+
else
|
326
|
+
return false #requested floating IP does not exist
|
327
|
+
end
|
285
328
|
end
|
286
329
|
|
287
330
|
def validate!
|
331
|
+
super([:image, :openstack_username, :openstack_password, :openstack_auth_url])
|
332
|
+
|
333
|
+
if flavor.nil?
|
334
|
+
ui.error("You have not provided a valid flavor ID. Please note the options for this value are -f or --flavor.")
|
335
|
+
exit 1
|
336
|
+
end
|
288
337
|
|
289
|
-
|
338
|
+
if image.nil?
|
339
|
+
ui.error("You have not provided a valid image ID. Please note the options for this value are -I or --image.")
|
340
|
+
exit 1
|
341
|
+
end
|
290
342
|
|
291
|
-
if
|
292
|
-
ui.error("You have
|
343
|
+
if !is_floating_ip_valid
|
344
|
+
ui.error("You have either requested an invalid floating IP address or none are available.")
|
293
345
|
exit 1
|
294
346
|
end
|
295
347
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Seth Chisamore (<schisamo@opscode.com>)
|
3
3
|
# Author:: Matt Ray (<matt@opscode.com>)
|
4
|
-
# Copyright:: Copyright (c) 2011-
|
4
|
+
# Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -66,15 +66,13 @@ class Chef
|
|
66
66
|
begin
|
67
67
|
server = connection.servers.get(instance_id)
|
68
68
|
|
69
|
-
msg_pair("Instance ID", server.id)
|
70
69
|
msg_pair("Instance Name", server.name)
|
70
|
+
msg_pair("Instance ID", server.id)
|
71
71
|
msg_pair("Flavor", server.flavor['id'])
|
72
72
|
msg_pair("Image", server.image['id'])
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
msg_pair("Public IP Address", server.public_ip_address['addr']) if server.public_ip_address
|
77
|
-
msg_pair("Private IP Address", server.private_ip_address['addr']) if server.private_ip_address
|
73
|
+
msg_pair("Public IP Address", primary_public_ip_address(server.addresses)) if primary_public_ip_address(server.addresses)
|
74
|
+
msg_pair("Private IP Address", primary_private_ip_address(server.addresses)) if primary_private_ip_address(server.addresses)
|
75
|
+
|
78
76
|
|
79
77
|
puts "\n"
|
80
78
|
confirm("Do you really want to delete this server")
|
@@ -93,6 +91,10 @@ class Chef
|
|
93
91
|
|
94
92
|
rescue NoMethodError
|
95
93
|
ui.error("Could not locate server '#{instance_id}'.")
|
94
|
+
rescue Excon::Errors::BadRequest => e
|
95
|
+
response = Chef::JSONCompat.from_json(e.response.body)
|
96
|
+
ui.fatal("Unknown server error (#{response['badRequest']['code']}): #{response['badRequest']['message']}")
|
97
|
+
raise e
|
96
98
|
end
|
97
99
|
end
|
98
100
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Seth Chisamore (<schisamo@opscode.com>)
|
3
3
|
# Author:: Matt Ray (<matt@opscode.com>)
|
4
|
-
# Copyright:: Copyright (c) 2011-
|
4
|
+
# Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -42,33 +42,40 @@ class Chef
|
|
42
42
|
ui.color('Keypair', :bold),
|
43
43
|
ui.color('State', :bold)
|
44
44
|
]
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
server_list <<
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
45
|
+
|
46
|
+
begin
|
47
|
+
connection.servers.all.sort_by(&:id).each do |server|
|
48
|
+
server_list << server.id.to_s
|
49
|
+
server_list << server.name
|
50
|
+
if primary_public_ip_address(server.addresses)
|
51
|
+
server_list << primary_public_ip_address(server.addresses)
|
52
|
+
else
|
53
|
+
server_list << ''
|
54
|
+
end
|
55
|
+
if primary_private_ip_address(server.addresses)
|
56
|
+
server_list << primary_private_ip_address(server.addresses)
|
57
|
+
else
|
58
|
+
server_list << ''
|
59
|
+
end
|
60
|
+
server_list << server.flavor['id'].to_s
|
61
|
+
server_list << server.image['id'].to_s
|
62
|
+
server_list << server.key_name
|
63
|
+
server_list << begin
|
64
|
+
state = server.state.to_s.downcase
|
65
|
+
case state
|
66
|
+
when 'shutting-down','terminated','stopping','stopped','error','shutoff'
|
67
|
+
ui.color(state, :red)
|
68
|
+
when 'pending','build','paused','suspended','hard_reboot'
|
69
|
+
ui.color(state, :yellow)
|
70
|
+
else
|
71
|
+
ui.color(state, :green)
|
72
|
+
end
|
70
73
|
end
|
71
|
-
|
74
|
+
end
|
75
|
+
rescue Excon::Errors::BadRequest => e
|
76
|
+
response = Chef::JSONCompat.from_json(e.response.body)
|
77
|
+
ui.fatal("Unknown server error (#{response['badRequest']['code']}): #{response['badRequest']['message']}")
|
78
|
+
raise e
|
72
79
|
end
|
73
80
|
puts ui.list(server_list, :uneven_columns_across, 8)
|
74
81
|
|
@@ -76,5 +83,3 @@ class Chef
|
|
76
83
|
end
|
77
84
|
end
|
78
85
|
end
|
79
|
-
|
80
|
-
|
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.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,24 +10,24 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: fog
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
|
-
- -
|
20
|
+
- - ! '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 1.10.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
none: false
|
27
27
|
requirements:
|
28
|
-
- -
|
28
|
+
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version:
|
30
|
+
version: 1.10.0
|
31
31
|
- !ruby/object:Gem::Dependency
|
32
32
|
name: chef
|
33
33
|
requirement: !ruby/object:Gem::Requirement
|
@@ -63,6 +63,7 @@ files:
|
|
63
63
|
- knife-openstack.gemspec
|
64
64
|
- lib/chef/knife/openstack_base.rb
|
65
65
|
- lib/chef/knife/openstack_flavor_list.rb
|
66
|
+
- lib/chef/knife/openstack_group_list.rb
|
66
67
|
- lib/chef/knife/openstack_image_list.rb
|
67
68
|
- lib/chef/knife/openstack_server_create.rb
|
68
69
|
- lib/chef/knife/openstack_server_delete.rb
|
@@ -88,9 +89,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
89
|
version: '0'
|
89
90
|
requirements: []
|
90
91
|
rubyforge_project:
|
91
|
-
rubygems_version: 1.8.
|
92
|
+
rubygems_version: 1.8.24
|
92
93
|
signing_key:
|
93
94
|
specification_version: 3
|
94
95
|
summary: OpenStack Compute Support for Chef's Knife Command
|
95
96
|
test_files: []
|
96
|
-
has_rdoc: true
|