knife-openstack 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## v0.10.0
2
+ DONE
3
+ * KNIFE-368 Ability to specify metadata during OpenStack server create
4
+ * KNIFE-423 Add ability for knife-openstack to specify network IDs to attach
5
+ * KNIFE-428 Added Availability zone to knife openstack
6
+ * KNIFE-467 --no-network fails to find first network IP address
7
+ * KNIFE-471 Explicitly define NIC for private network when creating server
8
+ * KNIFE-474 knife openstack group list throws a fog deprecation warning
9
+ * KNIFE-475 json-attributes option wasnt actually getting passed to bootstrap
10
+ * KNIFE-477 Delete openstack instance by name
11
+ * KNIFE-478 Generated SSH password not passed to bootstrap
12
+ * add support for working with names instead of ids, updated listing accordingly
13
+
1
14
  ## v0.9.1
2
15
  * KNIFE-462 missing user_data throws stack
3
16
 
@@ -63,19 +76,3 @@
63
76
 
64
77
  ## V0.5.2
65
78
  * initial Cactus release using EC2 API
66
-
67
- # BACKLOG/ISSUES #
68
- This is a list of missing(?) features and open questions currently under development consideration:
69
-
70
- * Basic availability zones support (Jarek Zmudzinski) NEED TESTING ACCESS FOR AVAILABILITY ZONES
71
- * purge only works when names match up with clients
72
- * `knife openstack floating list|associate|release NODE` with --floating-ip-pool also
73
- * KNIFE-229 Allow specifying the name of the pool when using floating IPs
74
- * attempt to allocate a floating ipaddress if none if free, currently missing in Fog
75
- * KNIFE-76 take either the flavor ID or the flavor name
76
- * take either the image ID or the image name (similar for KNIFE-76)
77
- * KNIFE-86 server create with expired password hangs
78
- * KNIFE-231 added ability to specify arbitrary network ID
79
- * assumption of only single floating IP (and fog uses the last as the public_ip_address)
80
- * probably other places public network is assumed that could cause issues
81
- * 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,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 `Grizzly` releases in configurations using Keystone against the OpenStack API (as opposed to the EC2 API).
4
+ This is the official Chef 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 `Icehouse` 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
 
@@ -19,19 +19,19 @@ Depending on your system's configuration, you may need to run this command with
19
19
 
20
20
  # Configuration #
21
21
 
22
- In order to communicate with an OpenStack Compute cloud's OpenStack API you will need to tell Knife your OpenStack Compute API endpoint, your Dashboard username and password (tenant is optional). The easiest way to accomplish this is to create these entries in your `knife.rb` file:
22
+ In order to communicate with an OpenStack API you will need to tell Knife your OpenStack Auth API endpoint, your Dashboard username and password (tenant is optional). The easiest way to accomplish this is to create these entries in your `knife.rb` file:
23
23
 
24
- knife[:openstack_username] = "Your OpenStack Dashboard username"
25
- knife[:openstack_password] = "Your OpenStack Dashboard password"
26
24
  ### Note: If you are not proxying HTTPS to the OpenStack auth port, the scheme should be HTTP
27
25
  knife[:openstack_auth_url] = "http://cloud.mycompany.com:5000/v2.0/tokens"
26
+ knife[:openstack_username] = "Your OpenStack Dashboard username"
27
+ knife[:openstack_password] = "Your OpenStack Dashboard password"
28
28
  knife[:openstack_tenant] = "Your OpenStack tenant name"
29
29
 
30
30
  If your knife.rb file will be checked into a SCM system (ie readable by others) you may want to read the values from environment variables:
31
31
 
32
+ knife[:openstack_auth_url] = "#{ENV['OS_AUTH_URL']}"
32
33
  knife[:openstack_username] = "#{ENV['OS_USERNAME']}"
33
34
  knife[:openstack_password] = "#{ENV['OS_PASSWORD']}"
34
- knife[:openstack_auth_url] = "#{ENV['OS_AUTH_URL']}"
35
35
  knife[:openstack_tenant] = "#{ENV['OS_TENANT_NAME']}"
36
36
 
37
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:
@@ -56,15 +56,15 @@ Additionally the following options may be set in your `knife.rb`:
56
56
 
57
57
  # Working with Floating IPs #
58
58
 
59
- 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.
59
+ To use a floating IP address while bootstrapping nodes, use the `-a` or `--floating-ip` option.
60
60
 
61
61
  # Working with Windows Images #
62
62
 
63
- 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.
63
+ Provisioning and bootstrapping for Windows 2003 and later images is now supported. The Windows images need to have WinRM enabled with Basic Authentication configured. Current support does not support Kerberos Authentication.
64
64
 
65
65
  Example:
66
66
 
67
- 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
67
+ knife openstack server create -I <Image> -f <Flavor> -S <keypair_name> --bootstrap-protocol winrm -P <Administrator_Password> -x Administrator -N <chef_node_name> --template windows-chef-client-msi.erb
68
68
 
69
69
  NOTE:
70
70
  * Bootstrap Protocol (`--bootstrap-protocol`) is required to be set to `winrm`.
@@ -78,42 +78,47 @@ This plugin provides the following Knife subcommands. Specific command options c
78
78
  knife openstack server create
79
79
  -----------------------------
80
80
 
81
- Provisions a new server in an OpenStack Compute cloud and then perform a Chef bootstrap (using the SSH protocol). The goal of the bootstrap is to get Chef installed on the target system so it can run Chef Client with a Chef Server. The main assumption is a baseline OS installation exists (provided by the provisioning). It is primarily intended for Chef Client systems that talk to a Chef server. By default the server is bootstrapped using the [chef-full](https://github.com/opscode/chef/blob/master/chef/lib/chef/knife/bootstrap/chef-full.erb) template (default after the 10.10 release). This may be overridden using the `-d` or `--template-file` command options. If you do not have public IP addresses, use the `--private-network` option to use the private IP address for bootstrapping.
81
+ Provisions a new server in an OpenStack Compute cloud and then perform a Chef bootstrap (using the SSH protocol). The goal of the bootstrap is to get Chef installed on the target system so it can run Chef Client with a Chef Server. The main assumption is a baseline OS installation exists (provided by the provisioning). It is primarily intended for Chef Client systems that talk to a Chef server. By default the server is bootstrapped using the [chef-full](https://github.com/opscode/chef/blob/master/chef/lib/chef/knife/bootstrap/chef-full.erb) template (default since the 10.10 release). This may be overridden using the `-d` or `--template-file` command options. If you do not have public IP addresses, use the `--private-network` option to use the private IP address for bootstrapping or `--bootstrap-network NAME` to specify an alternate network. Please see `knife openstack server create --help` for all of the supported options.
82
82
 
83
83
  knife openstack server delete
84
84
  -----------------------------
85
85
 
86
- Deletes an existing server in the currently configured OpenStack Compute cloud account. If a floating IP address has been assigned to the node, it is disassociated automatically by the OpenStack server. <b>PLEASE NOTE</b> - this does not delete the associated node and client objects from the Chef server without using the `-P` option to purge the client.
86
+ Deletes an existing server in the currently configured OpenStack account. If a floating IP address has been assigned to the node, it is disassociated automatically by the OpenStack server. <b>PLEASE NOTE</b> - this does not delete the associated node and client objects from the Chef server without using the `-P` option to purge the client.
87
87
 
88
88
  knife openstack server list
89
89
  ---------------------------
90
90
 
91
- Outputs a list of all servers in the currently configured OpenStack Compute cloud account. <b>PLEASE NOTE</b> - this shows all instances associated with the account, some of which may not be currently managed by the Chef server.
91
+ Outputs a list of all servers in the currently configured OpenStack account. <b>PLEASE NOTE</b> - this shows all instances associated with the account, some of which may not be currently managed by the Chef server.
92
92
 
93
93
  knife openstack flavor list
94
94
  ---------------------------
95
95
 
96
- 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.
96
+ Provides a list of all available flavors (available "hardware" configurations for a server) available to the currently configured OpenStack account. Each flavor has a unique combination of virtual cpus, disk space and memory capacity. This data may be useful when choosing a flavor to pass to the `knife openstack server create` subcommand.
97
97
 
98
98
  knife openstack image list
99
99
  --------------------------
100
100
 
101
- 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.
101
+ Lists all available images and snapshots available to the currently configured OpenStack 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 to pass to the `knife openstack server create` subcommand.
102
102
 
103
103
  knife openstack group list
104
104
  --------------------
105
105
 
106
- 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.
106
+ Provides a list of the security groups available to the currently configured OpenStack 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.
107
+
108
+ knife openstack network list
109
+ --------------------
110
+
111
+ Lists the networks available to the currently configured OpenStack account. This data may be useful when choosing your networks to pass to the `knife openstack server create` subcommand. This command is only available with OpenStack deployments using the Neutron network service (not nova-network). Please see `knife openstack server delete --help` for all of the supported options.
107
112
 
108
113
  # License #
109
114
 
110
- Author:: Seth Chisamore (<schisamo@opscode.com>)
115
+ Author:: Seth Chisamore (<schisamo@getchef.com>)
111
116
 
112
- Author:: Matt Ray (<matt@opscode.com>)
117
+ Author:: Matt Ray (<matt@getchef.com>)
113
118
 
114
119
  Author:: Chirag Jog (<chirag@clogeny.com>)
115
120
 
116
- Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
121
+ Copyright:: Copyright (c) 2011-2014 Chef Software, Inc.
117
122
 
118
123
  License:: Apache License, Version 2.0
119
124
 
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.has_rdoc = true
10
10
  s.extra_rdoc_files = ["README.md", "LICENSE" ]
11
11
  s.authors = ["Seth Chisamore", "Matt Ray"]
12
- s.email = ["schisamo@opscode.com", "matt@opscode.com"]
12
+ s.email = ["schisamo@getchef.com", "matt@getchef.com"]
13
13
  s.homepage = "https://github.com/opscode/knife-openstack"
14
14
  s.summary = %q{OpenStack Compute Support for Chef's Knife Command}
15
15
  s.description = s.summary
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_dependency "fog", ">= 1.10.0"
23
23
  s.add_dependency "chef", ">= 0.10.10"
24
24
  s.add_dependency "knife-windows"
25
-
25
+
26
26
  %w(rspec-core rspec-expectations rspec-mocks rspec_junit_formatter).each { |gem| s.add_development_dependency gem }
27
27
  s.require_paths = ["lib"]
28
28
  end
@@ -1,7 +1,7 @@
1
1
  #
2
- # Author:: Seth Chisamore (<schisamo@opscode.com>)
3
- # Author:: Matt Ray (<matt@opscode.com>)
4
- # Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
2
+ # Author:: Seth Chisamore (<schisamo@getchef.com>)
3
+ # Author:: Matt Ray (<matt@getchef.com>)
4
+ # Copyright:: Copyright (c) 2011-2014 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -71,6 +71,11 @@ class Chef
71
71
  :default => false,
72
72
  :proc => Proc.new { |key| Chef::Config[:knife][:openstack_insecure] = key }
73
73
 
74
+ option :availability_zone,
75
+ :short => "-Z ZONE_NAME",
76
+ :long => "--availability-zone ZONE_NAME",
77
+ :description => "The availability zone for this server",
78
+ :proc => Proc.new { |z| Chef::Config[:knife][:availability_zone] = z }
74
79
  end
75
80
  end
76
81
 
@@ -102,6 +107,35 @@ class Chef
102
107
  end
103
108
  end
104
109
 
110
+ def network
111
+ Chef::Log.debug("openstack_username #{Chef::Config[:knife][:openstack_username]}")
112
+ Chef::Log.debug("openstack_auth_url #{Chef::Config[:knife][:openstack_auth_url]}")
113
+ Chef::Log.debug("openstack_tenant #{Chef::Config[:knife][:openstack_tenant]}")
114
+ Chef::Log.debug("openstack_insecure #{Chef::Config[:knife][:openstack_insecure].to_s}")
115
+
116
+ @network ||= begin
117
+ network = Fog::Network.new(
118
+ :provider => 'OpenStack',
119
+ :openstack_username => Chef::Config[:knife][:openstack_username],
120
+ :openstack_api_key => Chef::Config[:knife][:openstack_password],
121
+ :openstack_auth_url => Chef::Config[:knife][:openstack_auth_url],
122
+ :openstack_tenant => Chef::Config[:knife][:openstack_tenant],
123
+ :connection_options => {
124
+ :ssl_verify_peer => !Chef::Config[:knife][:openstack_insecure]
125
+ }
126
+ )
127
+ rescue Excon::Errors::Unauthorized => e
128
+ ui.fatal("Connection failure, please check your OpenStack username and password.")
129
+ exit 1
130
+ rescue Excon::Errors::SocketError => e
131
+ ui.fatal("Connection failure, please check your OpenStack authentication URL.")
132
+ exit 1
133
+ rescue Fog::Errors::NotFound => e
134
+ ui.fatal("No OpenStack Network service found. This command is unavailable with nova-network.")
135
+ exit 1
136
+ end
137
+ end
138
+
105
139
  def locate_config_value(key)
106
140
  key = key.to_sym
107
141
  Chef::Config[:knife][key] || config[key]
@@ -1,7 +1,7 @@
1
1
  #
2
- # Author:: Seth Chisamore (<schisamo@opscode.com>)
3
- # Author:: Matt Ray (<matt@opscode.com>)
4
- # Copyright:: Copyright (c) 2011-2012 Opscode, Inc.
2
+ # Author:: Seth Chisamore (<schisamo@getchef.com>)
3
+ # Author:: Matt Ray (<matt@getchef.com>)
4
+ # Copyright:: Copyright (c) 2011-2014 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -32,16 +32,16 @@ class Chef
32
32
  validate!
33
33
 
34
34
  flavor_list = [
35
- ui.color('ID', :bold),
36
35
  ui.color('Name', :bold),
36
+ ui.color('ID', :bold),
37
37
  ui.color('Virtual CPUs', :bold),
38
38
  ui.color('RAM', :bold),
39
39
  ui.color('Disk', :bold),
40
40
  ]
41
41
  begin
42
- connection.flavors.sort_by(&:id).each do |flavor|
43
- flavor_list << flavor.id.to_s
42
+ connection.flavors.sort_by(&:name).each do |flavor|
44
43
  flavor_list << flavor.name
44
+ flavor_list << flavor.id.to_s
45
45
  flavor_list << flavor.vcpus.to_s
46
46
  flavor_list << "#{flavor.ram.to_s} MB"
47
47
  flavor_list << "#{flavor.disk.to_s} GB"
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Matt Ray (<matt@opscode.com>)
3
- # Copyright:: Copyright (c) 2013 Opscode, Inc.
2
+ # Author:: Matt Ray (<matt@getchef.com>)
3
+ # Copyright:: Copyright (c) 2013-2014 Chef Software, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,13 +39,13 @@ class Chef
39
39
  ui.color('Description', :bold),
40
40
  ]
41
41
  connection.security_groups.sort_by(&:name).each do |group|
42
- group.rules.each do |rule|
43
- unless rule['ip_protocol'].nil?
42
+ group.security_group_rules.each do |rule|
43
+ unless rule.ip_protocol.nil?
44
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']
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
49
  group_list << group.description
50
50
  end
51
51
  end
@@ -1,7 +1,7 @@
1
1
  #
2
- # Author:: Seth Chisamore (<schisamo@opscode.com>)
3
- # Author:: Matt Ray (<matt@opscode.com>)
4
- # Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
2
+ # Author:: Seth Chisamore (<schisamo@getchef.com>)
3
+ # Author:: Matt Ray (<matt@getchef.com>)
4
+ # Copyright:: Copyright (c) 2011-2014 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -38,8 +38,8 @@ class Chef
38
38
  validate!
39
39
 
40
40
  image_list = [
41
- ui.color('ID', :bold),
42
41
  ui.color('Name', :bold),
42
+ ui.color('ID', :bold),
43
43
  ui.color('Snapshot', :bold),
44
44
  ]
45
45
  begin
@@ -48,8 +48,8 @@ class Chef
48
48
  end.each do |image|
49
49
  unless ((image.name =~ /initrd$|kernel$|loader$|virtual$|vmlinuz$/) &&
50
50
  !config[:disable_filter])
51
- image_list << image.id
52
51
  image_list << image.name
52
+ image_list << image.id
53
53
  snapshot = 'no'
54
54
  image.metadata.each do |datum|
55
55
  if (datum.key == 'image_type') && (datum.value == 'snapshot')
@@ -0,0 +1,31 @@
1
+ require 'chef/knife/openstack_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class OpenstackNetworkList < Knife
6
+
7
+ include Knife::OpenstackBase
8
+
9
+ banner "knife openstack network list (options)"
10
+
11
+ def run
12
+
13
+ validate!
14
+
15
+ net_list = [
16
+ ui.color('Name', :bold),
17
+ ui.color('ID', :bold),
18
+ ui.color('Tenant', :bold),
19
+ ui.color('Shared', :bold),
20
+ ]
21
+ network.networks.all.sort_by(&:name).each do |network|
22
+ net_list << network.name
23
+ net_list << network.id
24
+ net_list << network.tenant_id
25
+ net_list << network.shared.to_s
26
+ end
27
+ puts ui.list(net_list, :uneven_columns_across, 4)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -40,15 +40,15 @@ class Chef
40
40
  attr_accessor :initial_sleep_delay
41
41
 
42
42
  option :flavor,
43
- :short => "-f FLAVOR_ID",
44
- :long => "--flavor FLAVOR_ID",
45
- :description => "The flavor ID of server (m1.small, m1.medium, etc)",
43
+ :short => "-f FLAVOR",
44
+ :long => "--flavor FLAVOR",
45
+ :description => "The flavor name or ID of server (m1.small, m1.medium, etc)",
46
46
  :proc => Proc.new { |f| Chef::Config[:knife][:flavor] = f }
47
47
 
48
48
  option :image,
49
- :short => "-I IMAGE_ID",
50
- :long => "--image IMAGE_ID",
51
- :description => "The image ID for the server",
49
+ :short => "-I IMAGE",
50
+ :long => "--image IMAGE",
51
+ :description => "A regexp matching an image name or an image ID for the server",
52
52
  :proc => Proc.new { |i| Chef::Config[:knife][:image] = i }
53
53
 
54
54
  option :security_groups,
@@ -58,11 +58,23 @@ class Chef
58
58
  :default => ["default"],
59
59
  :proc => Proc.new { |groups| groups.split(',') }
60
60
 
61
+ md = {}
62
+ option :metadata,
63
+ :short => "-M X=1",
64
+ :long => "--metadata X=1",
65
+ :description => "Metadata information for this server (may pass multiple times)",
66
+ :proc => Proc.new { |data| md.merge!({data.split('=')[0]=>data.split('=')[1]}) }
67
+
61
68
  option :chef_node_name,
62
69
  :short => "-N NAME",
63
70
  :long => "--node-name NAME",
64
71
  :description => "The Chef node name for your new node"
65
72
 
73
+ option :network_ids,
74
+ :long => "--network-ids NETWORK_ID_1,NETWORK_ID_2,NETWORK_ID_3",
75
+ :description => "Comma separated list of the UUID(s) of the network(s) for the server to attach",
76
+ :proc => Proc.new { |networks| networks.split(',') }
77
+
66
78
  option :floating_ip,
67
79
  :short => "-a [IP]",
68
80
  :long => "--floating-ip [IP]",
@@ -265,32 +277,33 @@ class Chef
265
277
  # servers require a name, generate one if not passed
266
278
  node_name = get_node_name(config[:chef_node_name])
267
279
 
268
- # this really should be caught in Fog
269
- if locate_config_value(:user_data).nil?
270
- server_def = {
271
- :name => node_name,
272
- :image_ref => locate_config_value(:image),
273
- :flavor_ref => locate_config_value(:flavor),
274
- :security_groups => locate_config_value(:security_groups),
275
- :key_name => locate_config_value(:openstack_ssh_key_id)
276
- }
277
- else
278
- server_def = {
279
- :name => node_name,
280
- :image_ref => locate_config_value(:image),
281
- :flavor_ref => locate_config_value(:flavor),
282
- :security_groups => locate_config_value(:security_groups),
283
- :key_name => locate_config_value(:openstack_ssh_key_id),
284
- :user_data => locate_config_value(:user_data)
285
- }
280
+ # define the server to be created
281
+ server_def = {
282
+ :name => node_name,
283
+ :image_ref => image.id,
284
+ :flavor_ref => flavor.id,
285
+ :security_groups => locate_config_value(:security_groups),
286
+ :availability_zone => locate_config_value(:availability_zone),
287
+ :metadata => locate_config_value(:metadata),
288
+ :key_name => locate_config_value(:openstack_ssh_key_id)
289
+ }
290
+ server_def[:user_data] = locate_config_value(:user_data) unless locate_config_value(:user_data).nil?
291
+ unless locate_config_value(:network_ids).nil?
292
+ server_def[:nics] = locate_config_value(:network_ids).map do |nic|
293
+ nic_id = { 'net_id' => nic }
294
+ nic_id
295
+ end
286
296
  end
297
+ Chef::Log.debug("server_def is: #{server_def}")
287
298
 
288
299
  Chef::Log.debug("Name #{node_name}")
300
+ Chef::Log.debug("Availability Zone #{locate_config_value(:availability_zone)}")
289
301
  Chef::Log.debug("Image #{locate_config_value(:image)}")
290
302
  Chef::Log.debug("Flavor #{locate_config_value(:flavor)}")
291
303
  Chef::Log.debug("Requested Floating IP #{locate_config_value(:floating_ip)}")
292
304
  Chef::Log.debug("Security Groups #{locate_config_value(:security_groups)}")
293
305
  Chef::Log.debug("User Data #{locate_config_value(:user_data)}")
306
+ Chef::Log.debug("Metadata #{locate_config_value(:metadata)}")
294
307
  Chef::Log.debug("Creating server #{server_def}")
295
308
 
296
309
  begin
@@ -313,6 +326,7 @@ class Chef
313
326
 
314
327
  msg_pair("Instance Name", server.name)
315
328
  msg_pair("Instance ID", server.id)
329
+ msg_pair("Availability zone", server.availability_zone)
316
330
 
317
331
  print "\n#{ui.color("Waiting for server", :magenta)}"
318
332
 
@@ -326,8 +340,8 @@ class Chef
326
340
  msg_pair("SSH Identity File", config[:identity_file])
327
341
  msg_pair("SSH Keypair", server.key_name) if server.key_name
328
342
  msg_pair("SSH Password", server.password) if (server.password && !server.key_name)
329
- Chef::Log.debug("Addresses #{server.addresses}")
330
343
 
344
+ Chef::Log.debug("Addresses #{server.addresses}")
331
345
  msg_pair("Public IP Address", primary_public_ip_address(server.addresses)) if primary_public_ip_address(server.addresses)
332
346
  msg_pair("Private IP Address", primary_private_ip_address(server.addresses)) if primary_private_ip_address(server.addresses)
333
347
 
@@ -360,7 +374,7 @@ class Chef
360
374
  unless config[:network] # --no-network
361
375
  bootstrap_ip_address = primary_public_ip_address(server.addresses) ||
362
376
  primary_private_ip_address(server.addresses) ||
363
- server.addresses.first
377
+ server.addresses[1][0]['addr']
364
378
  Chef::Log.debug("No Bootstrap Network: #{config[:bootstrap_network]}")
365
379
  else
366
380
  bootstrap_ip_address = primary_network_ip_address(server.addresses, config[:bootstrap_network])
@@ -414,6 +428,7 @@ class Chef
414
428
  def bootstrap_common_params(bootstrap, server_name)
415
429
  bootstrap.config[:chef_node_name] = config[:chef_node_name] || server_name
416
430
  bootstrap.config[:run_list] = config[:run_list]
431
+ bootstrap.config[:first_boot_attributes] = config[:first_boot_attributes]
417
432
  bootstrap.config[:prerelease] = config[:prerelease]
418
433
  bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
419
434
  bootstrap.config[:distro] = locate_config_value(:distro)
@@ -432,6 +447,7 @@ class Chef
432
447
  bootstrap = Chef::Knife::Bootstrap.new
433
448
  bootstrap.name_args = [bootstrap_ip_address]
434
449
  bootstrap.config[:ssh_user] = config[:ssh_user]
450
+ bootstrap.config[:ssh_password] = config[:ssh_password] || server.password unless config[:ssh_key_name]
435
451
  bootstrap.config[:ssh_port] = config[:ssh_port]
436
452
  bootstrap.config[:identity_file] = config[:identity_file]
437
453
  bootstrap.config[:host_key_verify] = config[:host_key_verify]
@@ -440,11 +456,11 @@ class Chef
440
456
  end
441
457
 
442
458
  def flavor
443
- @flavor ||= connection.flavors.get(locate_config_value(:flavor))
459
+ @flavor ||= connection.flavors.find{|f| f.name == locate_config_value(:flavor) || f.id == locate_config_value(:flavor) }
444
460
  end
445
461
 
446
462
  def image
447
- @image ||= connection.images.get(locate_config_value(:image))
463
+ @image ||= connection.images.find{|img| img.name =~ /#{locate_config_value(:image)}/ || img.id == locate_config_value(:image) }
448
464
  end
449
465
 
450
466
  def is_floating_ip_valid
@@ -461,12 +477,13 @@ class Chef
461
477
  else
462
478
  return false # no floating IPs available
463
479
  end
464
- end
465
- # floating requested with value
466
- if addresses.find_index { |a| a.ip == address }
467
- return true
468
480
  else
469
- return false # requested floating IP does not exist
481
+ # floating requested with value
482
+ if addresses.find_index { |a| a.ip == address }
483
+ return true
484
+ else
485
+ return false # requested floating IP does not exist
486
+ end
470
487
  end
471
488
  end
472
489
 
@@ -1,7 +1,7 @@
1
1
  #
2
- # Author:: Seth Chisamore (<schisamo@opscode.com>)
3
- # Author:: Matt Ray (<matt@opscode.com>)
4
- # Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
2
+ # Author:: Seth Chisamore (<schisamo@getchef.com>)
3
+ # Author:: Matt Ray (<matt@getchef.com>)
4
+ # Copyright:: Copyright (c) 2011-2014 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -64,7 +64,7 @@ class Chef
64
64
 
65
65
  @name_args.each do |instance_id|
66
66
  begin
67
- server = connection.servers.get(instance_id)
67
+ server = connection.servers.find{|s| s.name == instance_id || s.id == instance_id }
68
68
 
69
69
  msg_pair("Instance Name", server.name)
70
70
  msg_pair("Instance ID", server.id)
@@ -74,6 +74,7 @@ class Chef
74
74
  msg_pair("Network", name)
75
75
  msg_pair(" IP Address", addr[0]['addr'])
76
76
  end
77
+ msg_pair("Availability Zone", server.availability_zone)
77
78
 
78
79
  puts "\n"
79
80
  confirm("Do you really want to delete this server")
@@ -1,7 +1,7 @@
1
1
  #
2
- # Author:: Seth Chisamore (<schisamo@opscode.com>)
3
- # Author:: Matt Ray (<matt@opscode.com>)
4
- # Copyright:: Copyright (c) 2011-2013 Opscode, Inc.
2
+ # Author:: Seth Chisamore (<schisamo@getchef.com>)
3
+ # Author:: Matt Ray (<matt@getchef.com>)
4
+ # Copyright:: Copyright (c) 2011-2014 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,8 +33,9 @@ class Chef
33
33
  validate!
34
34
 
35
35
  server_list = [
36
- ui.color('Instance ID', :bold),
37
36
  ui.color('Name', :bold),
37
+ ui.color('Instance ID', :bold),
38
+ ui.color('Zone', :bold),
38
39
  ui.color('Public IP', :bold),
39
40
  ui.color('Private IP', :bold),
40
41
  ui.color('Flavor', :bold),
@@ -44,9 +45,10 @@ class Chef
44
45
  ]
45
46
 
46
47
  begin
47
- connection.servers.all.sort_by(&:id).each do |server|
48
- server_list << server.id.to_s
48
+ connection.servers.all.sort_by(&:name).each do |server|
49
49
  server_list << server.name
50
+ server_list << server.id.to_s
51
+ server_list << server.availability_zone
50
52
  if primary_public_ip_address(server.addresses)
51
53
  server_list << primary_public_ip_address(server.addresses)
52
54
  else
@@ -81,7 +83,7 @@ class Chef
81
83
  ui.fatal("Unknown server error (#{response['badRequest']['code']}): #{response['badRequest']['message']}")
82
84
  raise e
83
85
  end
84
- puts ui.list(server_list, :uneven_columns_across, 8)
86
+ puts ui.list(server_list, :uneven_columns_across, 9)
85
87
 
86
88
  end
87
89
  end
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module OpenStack
3
- VERSION = '0.9.1'
3
+ VERSION = '0.10.0'
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Mukta Aphale (<mukta.aphale@clogeny.com>)
3
- # Copyright:: Copyright (c) 2013 Opscode, Inc.
3
+ # Copyright:: Copyright (c) 2013-2014 Chef Software, Inc.
4
4
 
5
5
  require File.expand_path('../../spec_helper', __FILE__)
6
6
  require 'fog'
@@ -11,8 +11,8 @@ describe Chef::Knife::OpenstackServerCreate do
11
11
  before do
12
12
 
13
13
  @openstack_connection = double(Fog::Compute::OpenStack)
14
- @openstack_connection.stub_chain(:flavors, :get).and_return ('flavor_id')
15
- @openstack_connection.stub_chain(:images, :get).and_return double('image_id')
14
+ @openstack_connection.stub_chain(:flavors, :find).and_return double('flavor', {:id => 'flavor_id'})
15
+ @openstack_connection.stub_chain(:images, :find).and_return double('image', {:id => 'image_id'})
16
16
  @openstack_connection.stub_chain(:addresses).and_return [double('addresses', {
17
17
  :instance_id => nil,
18
18
  :ip => '111.111.111.111',
@@ -38,7 +38,6 @@ describe Chef::Knife::OpenstackServerCreate do
38
38
  @knife_openstack_create.stub(:puts)
39
39
  @knife_openstack_create.stub(:print)
40
40
 
41
-
42
41
  @openstack_servers = double()
43
42
  @new_openstack_server = double()
44
43
 
@@ -47,14 +46,15 @@ describe Chef::Knife::OpenstackServerCreate do
47
46
  :key_name => 'key_name',
48
47
  :flavor => 'flavor_id',
49
48
  :image => 'image_id',
49
+ :availability_zone => 'zone1',
50
50
  :addresses => {
51
+ 'foo' => [{'addr' => '34.56.78.90'}],
51
52
  'public' => [{'addr' => '75.101.253.10'}],
52
53
  'private' => [{'addr' => '10.251.75.20'}]
53
54
  },
54
55
  :password => 'password'
55
56
  }
56
57
 
57
-
58
58
  @openstack_server_attribs.each_pair do |attrib, value|
59
59
  @new_openstack_server.stub(attrib).and_return(value)
60
60
  end
@@ -68,6 +68,8 @@ describe Chef::Knife::OpenstackServerCreate do
68
68
  it "ensures default options" do
69
69
  @options[:bootstrap_protocol][:default].should == nil
70
70
  @options[:distro][:default].should == 'chef-full'
71
+ @options[:availability_zone][:default].should == nil
72
+ @options[:metadata][:default].should == nil
71
73
  @options[:floating_ip][:default].should == '-1'
72
74
  @options[:host_key_verify][:default].should == true
73
75
  @options[:private_network][:default].should == false
@@ -78,6 +80,7 @@ describe Chef::Knife::OpenstackServerCreate do
78
80
  @options[:server_create_timeout][:default].should == 600
79
81
  @options[:ssh_port][:default].should == '22'
80
82
  @options[:ssh_user][:default].should == 'root'
83
+ @options[:first_boot_attributes][:default].should == {}
81
84
  end
82
85
 
83
86
  it "doesn't set an OpenStack endpoint type by default" do
@@ -130,6 +133,7 @@ describe Chef::Knife::OpenstackServerCreate do
130
133
  @knife_openstack_create.config[:chef_node_name] = "blarf"
131
134
  @knife_openstack_create.config[:template_file] = '~/.chef/templates/my-bootstrap.sh.erb'
132
135
  @knife_openstack_create.config[:distro] = 'ubuntu-10.04-magic-sparkles'
136
+ @knife_openstack_create.config[:first_boot_attributes] = {'some_var' => true}
133
137
  @knife_openstack_create.config[:run_list] = ['role[base]']
134
138
 
135
139
  @bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server,
@@ -160,6 +164,19 @@ describe Chef::Knife::OpenstackServerCreate do
160
164
  @bootstrap.config[:chef_node_name].should == 'blarf'
161
165
  end
162
166
 
167
+ it "configures the bootstrap to use the server password" do
168
+ @bootstrap.config[:ssh_password].should == 'password'
169
+ end
170
+
171
+ it "configures the bootstrap to use the config ssh password" do
172
+ @knife_openstack_create.config[:ssh_password] = 'testing123'
173
+
174
+ bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server,
175
+ @new_openstack_server.addresses['public'].last['addr'])
176
+
177
+ bootstrap.config[:ssh_password].should == 'testing123'
178
+ end
179
+
163
180
  it "configures the bootstrap to use the OpenStack server id if no explicit node name is set" do
164
181
  @knife_openstack_create.config[:chef_node_name] = nil
165
182
 
@@ -186,6 +203,10 @@ describe Chef::Knife::OpenstackServerCreate do
186
203
  @bootstrap.config[:use_sudo].should be_true
187
204
  end
188
205
 
206
+ it "configures the bootstrap with json attributes" do
207
+ @bootstrap.config[:first_boot_attributes]['some_var'].should be_true
208
+ end
209
+
189
210
  it "configured the bootstrap to use the desired template" do
190
211
  @bootstrap.config[:template_file].should == '~/.chef/templates/my-bootstrap.sh.erb'
191
212
  end
@@ -195,4 +216,42 @@ describe Chef::Knife::OpenstackServerCreate do
195
216
  end
196
217
  end
197
218
 
219
+ describe "when configuring the bootstrap process with private networks" do
220
+ before do
221
+ @knife_openstack_create.config[:private_network] = true
222
+
223
+ @bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server,
224
+ @new_openstack_server.addresses['private'].last['addr'])
225
+ end
226
+
227
+ it "configures the bootstrap to use private network" do
228
+ @bootstrap.name_args.should == ['10.251.75.20']
229
+ end
230
+ end
231
+
232
+ describe "when configuring the bootstrap process with alternate networks" do
233
+ before do
234
+ @knife_openstack_create.config[:bootstrap_network] = 'foo'
235
+
236
+ @bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server,
237
+ @new_openstack_server.addresses['foo'].last['addr'])
238
+ end
239
+
240
+ it "configures the bootstrap to use alternate network" do
241
+ @bootstrap.name_args.should == ['34.56.78.90']
242
+ end
243
+ end
244
+
245
+ describe "when configuring the bootstrap process with no networks" do
246
+ before do
247
+ @knife_openstack_create.config[:network] = false
248
+
249
+ @bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server,
250
+ @new_openstack_server.addresses['public'].last['addr'])
251
+ end
252
+
253
+ it "configures the bootstrap to use public network since none specified" do
254
+ @bootstrap.name_args.should == ['75.101.253.10']
255
+ end
256
+ end
198
257
  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.9.1
4
+ version: 0.10.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: 2014-03-12 00:00:00.000000000 Z
13
+ date: 2014-05-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: fog
@@ -126,8 +126,8 @@ dependencies:
126
126
  version: '0'
127
127
  description: OpenStack Compute Support for Chef's Knife Command
128
128
  email:
129
- - schisamo@opscode.com
130
- - matt@opscode.com
129
+ - schisamo@getchef.com
130
+ - matt@getchef.com
131
131
  executables: []
132
132
  extensions: []
133
133
  extra_rdoc_files:
@@ -145,6 +145,7 @@ files:
145
145
  - lib/chef/knife/openstack_flavor_list.rb
146
146
  - lib/chef/knife/openstack_group_list.rb
147
147
  - lib/chef/knife/openstack_image_list.rb
148
+ - lib/chef/knife/openstack_network_list.rb
148
149
  - lib/chef/knife/openstack_server_create.rb
149
150
  - lib/chef/knife/openstack_server_delete.rb
150
151
  - lib/chef/knife/openstack_server_list.rb