knife-hp 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,14 +1,14 @@
1
- # TODO #
2
- This is a list of features currently lacking and (eventually) under development:
3
- * should we sort the image list like the HP console does? segmented by Public/Partner/Private? "knife hp image list partner"?
4
- * should the node.name and node.id be the same (might have to fix this in the ohai plugin since this appears unavailable for setting)
5
- * take either the flavor ID or the flavor name for server create
6
- * take either the image ID or the image name for server create
7
- * Show the flavor and image names in `hp server list`
8
- * Validate ohai cloud support (waiting on OHAI-425)
1
+ ## v0.4.0
2
+ * Upgrade to support 13.5 HP Helion Public Cloud Services. For more information check https://docs.hpcloud.com/migration-overview/
3
+ * KNIFE-444 knife-hp incompatible with hpcloud v13.5
4
+ * Added support for HP's regions (US East and US West) and the availability zones within those regions
5
+ * Added 'knife hp network list'
6
+ * Added floating IP address support
7
+ * Added --networks to specify networks to attach to
8
+ * Replaced --private-network with --bootstrap-network
9
9
 
10
10
  ## v0.3.1
11
- * KNIFE-309 knife hp server list fails with nil image
11
+ * KNIFE-309 knife hp server list fails with nil image from boot from volume
12
12
 
13
13
  ## v0.3.0
14
14
  * update dependency on to Fog 1.10.0
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  Knife HP
2
2
  ========
3
3
 
4
- This is the official Opscode Knife plugin for HP Cloud Compute. This plugin gives knife the ability to create, bootstrap and manage instances in the HP Cloud.
4
+ This is the official Opscode Knife plugin for HP Helion Public Cloud Compute. This plugin gives knife the ability to create, bootstrap and manage instances in the HP Public Cloud 13.5 and later. You may need to go to https://horizon.hpcloud.com and enable Compute under "Activate Services" for the Availability Zones you wish to use. To properly configure your networks (include a router for external access), please refer to https://docs.hpcloud.com/hpcloudconsole.
5
+
6
+ If you are still using the older version of the API, you may need version 0.3.1 of this plugin, HP's migration and upgrade instructions are here: https://docs.hpcloud.com/migration-overview-reference/.
5
7
 
6
8
  Please refer to the [CHANGELOG](CHANGELOG.md) for version history.
7
9
 
@@ -19,13 +21,13 @@ Depending on your system's configuration, you may need to run this command with
19
21
 
20
22
  # Configuration #
21
23
 
22
- In order to communicate with HP Compute Cloud's API you will need to tell Knife the Access Key ID, the Secret Key and Tenant ID (found on the "API Keys" page). You may also override the auth URI and availability zone. The easiest way to accomplish this is to create these entries in your `knife.rb` file:
24
+ In order to communicate with HP Helion Compute Cloud's API you will need to tell Knife the Access Key ID, the Secret Key and Tenant ID (found on the "API Keys" page). You may also override the auth URI and availability zone. The easiest way to accomplish this is to create these entries in your `knife.rb` file:
23
25
 
24
26
  knife[:hp_access_key] = "Your HP Cloud Access Key ID"
25
27
  knife[:hp_secret_key] = "Your HP Cloud Secret Key"
26
28
  knife[:hp_tenant_id] = "Your HP Cloud Tenant ID"
27
29
  knife[:hp_auth_uri] = "Your HP Cloud Auth URI" (optional, default is 'https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/')
28
- knife[:hp_avl_zone] = "Your HP Cloud Availability Zone" (optional, default is 'az1', choices are 'az1', 'az2' or 'az3')
30
+ knife[:hp_avl_zone] = "Your HP Cloud Availability Zone" (optional, default is 'region-a.geo-1', the other option is 'region-b.geo-1').
29
31
 
30
32
  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
33
 
@@ -41,7 +43,7 @@ You also have the option of passing your HP Cloud API options from the command l
41
43
  `-K` (or `--hp-secret`) your HP Cloud Secret Key
42
44
  `-T` (or `--hp-tenant`) your HP Cloud Tenant ID
43
45
  `--hp-auth` your HP Cloud Auth URI (optional, default is 'https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/')
44
- `-Z` (or `--hp-zone`) your HP Cloud Availability Zone (optional, default is 'az1', choices are 'az1', 'az2' or 'az3')
46
+ `-Z` (or `--hp-zone`) your HP Cloud Availability Zone (optional, default is 'region-a.geo-1', the other option is 'region-b.geo-1')
45
47
 
46
48
  knife hp server create -A 'MyUsername' -K 'MyPassword' -T 'MyTenant' -f 101 -I 120 -S hpkeypair -i ~/.ssh/hpkeypair.pem -r 'role[webserver]'
47
49
 
@@ -59,46 +61,51 @@ This plugin provides the following Knife subcommands. Specific command options c
59
61
  knife hp server create
60
62
  ----------------------
61
63
 
62
- Provisions a new server in the HP 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. This can be overridden using the `-d` or `--template-file` command options. If you do not pass a node name with `-N NAME` (or `--node-name NAME`) a name will be generated for the node.
64
+ Provisions a new server in the HP Helion 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. This can be overridden using the `-d` or `--template-file` command options. If you do not pass a node name with `-N NAME` (or `--node-name NAME`) a name will be generated for the node.
65
+
66
+ knife hp server create -f 101 -I 202e7659-f7c6-444a-8b32-872fe2ed080c -S hpkeypair -i ~/.ssh/hpkeypair.pem
67
+
68
+ ### networking ###
69
+
70
+ If you do not specify any `--network-ids` and do not specify the `--bootstrap-network`, the server will connect to the default network and boot off of it. If you are not bootstrapping from the HP network, you will need to request a floating IP address to be associated with your node with `--floating-ip` (or `-a`) with or without specifying the IP.
63
71
 
64
- knife hp server create -f 101 -I 9883 -S hpkeypair -i ~/.ssh/hpkeypair.pem -Z az2 -x ubuntu
72
+ knife hp server create -a -f 100 -I 202e7659-f7c6-444a-8b32-872fe2ed080c -S hpkeypair -i ~/.ssh/hpkeypair.pem
65
73
 
66
74
  knife hp server delete
67
75
  ----------------------
68
76
 
69
- Deletes an existing server in the currently configured HP Compute Cloud account. <b>PLEASE NOTE</b> - this does not delete the associated node and client objects from the Chef Server without using the `-P` or `--purge` option to purge the client.
77
+ Deletes an existing server in the currently configured HP Helion Compute Cloud account. <b>PLEASE NOTE</b> - this does not delete the associated node and client objects from the Chef Server without using the `-P` or `--purge` option to purge the client.
70
78
 
71
79
  knife hp server list
72
80
  --------------------
73
81
 
74
- Outputs a list of all servers in the currently configured HP 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.
82
+ Outputs a list of all servers in the currently configured HP Helion Compute Cloud account by Region. <b>PLEASE NOTE</b> - this shows all instances associated with the account, some of which may not be currently managed by the Chef Server.
75
83
 
76
84
  knife hp flavor list
77
85
  --------------------
78
86
 
79
- Outputs a list of all flavors (hardware configuration for a server) available to the currently configured HP Compute Cloud account. Each flavor has a unique combination of virtual cores, disk space and memory capacity. This data may be useful when choosing a flavor id to pass to the `knife hp server create` subcommand.
87
+ Outputs a list of all flavors (hardware configuration for a server) available to the currently configured HP Helion 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 hp server create` subcommand.
80
88
 
81
89
  knife hp image list
82
90
  -------------------
83
91
 
84
- Outputs a list of all images available to the currently configured HP Compute Cloud account. An image is a collection of files used to create or rebuild a server. The returned list filtered and does not contain images with "(deprecated)", "(Kernel)" or "(Ramdisk)" in their names (this may be disabled with `--disable-filter`). This data may be useful when choosing an image id to pass to the `knife hp server create` subcommand.
92
+ Outputs a list of all images available to the currently configured HP Helion Compute Cloud account. An image is a collection of files used to create or rebuild a server. The returned list filtered and does not contain images with "(deprecated)", "(Kernel)" or "(Ramdisk)" in their names (this may be disabled with `--disable-filter`). This data may be useful when choosing an image id to pass to the `knife hp server create` subcommand.
85
93
 
86
94
  knife hp group list
87
95
  --------------------
88
96
 
89
- Outputs a list of the security groups available to the currently configured HP 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 hp server create` subcommand.
97
+ Outputs a list of the security groups available to the currently configured HP Helion Compute Cloud account by Region. Each group may have multiple rules. This data may be useful when choosing your security group(s) to pass to the `knife hp server create` subcommand.
90
98
 
91
- KNOWN ISSUES
92
- ============
99
+ knife hp network list
100
+ ---------------------
93
101
 
94
- * There is no support in Ohai yet, but the empty `/etc/chef/ohai/hints/hp.json` is created. http://tickets.opscode.com/browse/OHAI-425
95
- * The [CHANGELOG](CHANGELOG.md) has more missing/incomplete features listed.
102
+ Lists the networks available to the currently configured HP Helion Compute Cloud account by Region. This data may be useful when choosing your networks to pass to the `knife hp server create` subcommand.
96
103
 
97
104
  # License #
98
105
 
99
- Author:: Matt Ray (<matt@opscode.com>)
106
+ Author:: Matt Ray (<matt@getchef.com>)
100
107
 
101
- Copyright:: Copyright (c) 2012-2013 Opscode, Inc.
108
+ Copyright:: Copyright (c) 2012-2014 Chef Software, Inc.
102
109
 
103
110
  License:: Apache License, Version 2.0
104
111
 
@@ -19,7 +19,7 @@ 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", ">= 1.10.0"
23
- s.add_dependency "chef", ">= 0.10.10"
22
+ s.add_dependency "fog", ">= 1.20"
23
+ s.add_dependency "chef", ">= 11.0"
24
24
 
25
25
  end
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Matt Ray (<matt@opscode.com>)
3
- # Copyright:: Copyright (c) 2012-2013 Opscode, Inc.
2
+ # Author:: Matt Ray (<matt@getchef.com>)
3
+ # Copyright:: Copyright (c) 2012-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");
@@ -44,7 +44,7 @@ class Chef
44
44
  option :hp_secret_key,
45
45
  :short => "-K SECRET",
46
46
  :long => "--hp-secret SECRET",
47
- :description => "Your HP Cloud Secret Key",
47
+ :description => "Your HP Cloud Access Secret Key",
48
48
  :proc => Proc.new { |key| Chef::Config[:knife][:hp_secret_key] = key }
49
49
 
50
50
  option :hp_tenant_id,
@@ -60,28 +60,47 @@ class Chef
60
60
  :proc => Proc.new { |endpoint| Chef::Config[:knife][:hp_auth_uri] = endpoint }
61
61
 
62
62
  option :hp_avl_zone,
63
- :short => "-Z Zone",
64
- :long => "--hp-zone Zone",
65
- :default => "az1",
66
- :description => "Your HP Cloud Availability Zone (az1/az2/az3)",
67
- :proc => Proc.new { |key| Chef::Config[:knife][:hp_avl_zone] = key }
63
+ :short => "-R region",
64
+ :long => "--hp-region Region",
65
+ :default => "US-EAST",
66
+ :description => "Your HP Cloud Region (US-EAST/US-WEST)",
67
+ :proc => Proc.new { |key| Chef::Config[:knife][:hp_avl_zone] = key.downcase }
68
+
68
69
  end
69
70
  end
70
71
 
71
72
  def connection
72
- Chef::Log.debug("hp_access_key: #{Chef::Config[:knife][:hp_access_key]}")
73
- Chef::Log.debug("hp_secret_key: #{Chef::Config[:knife][:hp_secret_key]}")
74
- Chef::Log.debug("hp_tenant_id: #{Chef::Config[:knife][:hp_tenant_id]}")
75
73
  Chef::Log.debug("hp_auth_uri: #{locate_config_value(:hp_auth_uri)}")
76
- Chef::Log.debug("hp_avl_zone: #{availability_zone()}")
74
+ Chef::Log.debug("hp_access_key: #{locate_config_value(:hp_access_key)}")
75
+ Chef::Log.debug("hp_secret_key: #{locate_config_value(:hp_secret_key)}")
76
+ Chef::Log.debug("hp_tenant_id: #{locate_config_value(:hp_tenant_id)}")
77
+ Chef::Log.debug("hp_avl_zone: #{region()}")
77
78
  @connection ||= begin
78
79
  connection = Fog::Compute.new(
79
80
  :provider => 'HP',
80
- :hp_access_key => Chef::Config[:knife][:hp_access_key],
81
- :hp_secret_key => Chef::Config[:knife][:hp_secret_key],
82
- :hp_tenant_id => Chef::Config[:knife][:hp_tenant_id],
81
+ :version => :v2,
82
+ :hp_auth_uri => locate_config_value(:hp_auth_uri),
83
+ :hp_access_key => locate_config_value(:hp_access_key),
84
+ :hp_secret_key => locate_config_value(:hp_secret_key),
85
+ :hp_tenant_id => locate_config_value(:hp_tenant_id),
86
+ :hp_avl_zone => region()
87
+ )
88
+ end
89
+ end
90
+
91
+ def netconnection
92
+ Chef::Log.debug("hp_auth_uri: #{locate_config_value(:hp_auth_uri)}")
93
+ Chef::Log.debug("hp_access_key: #{locate_config_value(:hp_access_key)}")
94
+ Chef::Log.debug("hp_secret_key: #{locate_config_value(:hp_secret_key)}")
95
+ Chef::Log.debug("hp_tenant_id: #{locate_config_value(:hp_tenant_id)}")
96
+ Chef::Log.debug("hp_avl_zone: #{region()}")
97
+ @connection ||= begin
98
+ connection = Fog::HP::Network.new(
83
99
  :hp_auth_uri => locate_config_value(:hp_auth_uri),
84
- :hp_avl_zone => availability_zone()
100
+ :hp_access_key => locate_config_value(:hp_access_key),
101
+ :hp_secret_key => locate_config_value(:hp_secret_key),
102
+ :hp_tenant_id => locate_config_value(:hp_tenant_id),
103
+ :hp_avl_zone => region()
85
104
  )
86
105
  end
87
106
  end
@@ -103,7 +122,7 @@ class Chef
103
122
  keys.each do |k|
104
123
  pretty_key = k.to_s.gsub(/_/, ' ').gsub(/\w+/){ |w| (w =~ /(ssh)|(hp)/i) ? w.upcase : w.capitalize }
105
124
  if Chef::Config[:knife][k].nil?
106
- errors << "You did not provided a valid '#{pretty_key}' value."
125
+ errors << "You did not provide a valid '#{pretty_key}' value."
107
126
  end
108
127
  end
109
128
 
@@ -112,19 +131,17 @@ class Chef
112
131
  end
113
132
  end
114
133
 
115
- def availability_zone()
134
+ def region()
116
135
  case locate_config_value(:hp_avl_zone)
117
- when 'az3'
118
- return 'az-3.region-a.geo-1'
119
- when 'az2'
120
- return 'az-2.region-a.geo-1'
136
+ when 'us-west'
137
+ Chef::Log.debug("hp_avl_zone: us-west->'region-a.geo-1'")
138
+ return 'region-a.geo-1'
121
139
  else
122
- return 'az-1.region-a.geo-1'
140
+ Chef::Log.debug("hp_avl_zone: us-east->'region-b.geo-1'")
141
+ return 'region-b.geo-1'
123
142
  end
124
143
  end
125
144
 
126
145
  end
127
146
  end
128
147
  end
129
-
130
-
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Matt Ray (<matt@opscode.com>)
3
- # Copyright:: Copyright (c) 2012 Opscode, Inc.
2
+ # Author:: Matt Ray (<matt@getchef.com>)
3
+ # Copyright:: Copyright (c) 2012-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");
@@ -33,16 +33,16 @@ class Chef
33
33
  flavor_list = [
34
34
  ui.color('ID', :bold),
35
35
  ui.color('Name', :bold),
36
- ui.color('Cores', :bold),
36
+ ui.color('VCPUs', :bold),
37
37
  ui.color('RAM', :bold),
38
38
  ui.color('Disk', :bold),
39
39
  ]
40
- connection.flavors.sort_by(&:id).each do |flavor|
41
- flavor_list << flavor.id.to_s
42
- flavor_list << flavor.name
43
- flavor_list << flavor.cores.to_s
44
- flavor_list << "#{flavor.ram.to_s} MB"
45
- flavor_list << "#{flavor.disk.to_s} GB"
40
+ connection.list_flavors_detail.body['flavors'].sort_by { |h| h['name'] }.each do |flavor|
41
+ flavor_list << flavor['id']
42
+ flavor_list << flavor['name']
43
+ flavor_list << flavor['vcpus'].to_s
44
+ flavor_list << "#{flavor['ram'].to_s} MB"
45
+ flavor_list << "#{flavor['disk'].to_s} GB"
46
46
  end
47
47
  puts ui.list(flavor_list, :uneven_columns_across, 5)
48
48
  end
@@ -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");
@@ -32,25 +32,27 @@ class Chef
32
32
 
33
33
  group_list = [
34
34
  ui.color('Name', :bold),
35
+ ui.color('Direction', :bold),
36
+ ui.color('Type', :bold),
35
37
  ui.color('Protocol', :bold),
36
- ui.color('From', :bold),
37
- ui.color('To', :bold),
38
- ui.color('CIDR', :bold),
38
+ ui.color('Port Range', :bold),
39
+ ui.color('Remote', :bold),
39
40
  ui.color('Description', :bold),
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
+ netconnection.security_groups.sort_by(&:name).each do |group|
43
+ group.security_group_rules.each do |rule|
44
+ unless rule['protocol'].nil?
44
45
  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']
46
+ group_list << rule['direction']
47
+ group_list << rule['ethertype']
48
+ group_list << rule['protocol']
49
+ group_list << "#{rule['port_range_min']}-#{rule['port_range_max']}"
50
+ group_list << rule['remote_ip_prefix']
49
51
  group_list << group.description
50
52
  end
51
53
  end
52
54
  end
53
- puts ui.list(group_list, :uneven_columns_across, 6)
55
+ puts ui.list(group_list, :uneven_columns_across, 7)
54
56
  end
55
57
  end
56
58
  end
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Matt Ray (<matt@opscode.com>)
3
- # Copyright:: Copyright (c) 2012 Opscode, Inc.
2
+ # Author:: Matt Ray (<matt@getchef.com>)
3
+ # Copyright:: Copyright (c) 2012-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");
@@ -0,0 +1,53 @@
1
+ #
2
+ # Author:: Matt Ray (<matt@getchef.com>)
3
+ # Copyright:: Copyright (c) 2014 Chef Software, 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
+ class Chef
20
+ class Knife
21
+ class HpNetworkList < Knife
22
+
23
+ include Knife::HpBase
24
+
25
+ banner "knife hp group list (options)"
26
+
27
+ require 'chef/knife/hp_base'
28
+
29
+ banner "knife hp network list (options)"
30
+
31
+ def run
32
+
33
+ validate!
34
+
35
+ net_list = [
36
+ ui.color('Name', :bold),
37
+ ui.color('ID', :bold),
38
+ ui.color('Tenant', :bold),
39
+ ui.color('External', :bold),
40
+ ui.color('Shared', :bold),
41
+ ]
42
+ netconnection.list_networks.body['networks'].sort_by { |h| h['name'] }.each do |network|
43
+ net_list << network['name']
44
+ net_list << network['id']
45
+ net_list << network['tenant_id']
46
+ net_list << network['router:external'].to_s
47
+ net_list << network['shared'].to_s
48
+ end
49
+ puts ui.list(net_list, :uneven_columns_across, 5)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Matt Ray (<matt@opscode.com>)
3
- # Copyright:: Copyright (c) 2012-2013 Opscode, Inc.
2
+ # Author:: Matt Ray (<matt@getchef.com>)
3
+ # Copyright:: Copyright (c) 2012-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");
@@ -56,6 +56,13 @@ class Chef
56
56
  :description => "The HP Cloud Key Pair ID",
57
57
  :proc => Proc.new { |key| Chef::Config[:knife][:hp_ssh_key_id] = key }
58
58
 
59
+ option :availability_zone,
60
+ :short => "-Z Zone",
61
+ :long => "--hp-zone Zone",
62
+ :default => "az1",
63
+ :description => "Your HP Cloud Availability Zone within your Region (az1/az2/az3)",
64
+ :proc => Proc.new { |key| Chef::Config[:knife][:hp_avl_zone] = key }
65
+
59
66
  option :chef_node_name,
60
67
  :short => "-N NAME",
61
68
  :long => "--node-name NAME",
@@ -117,11 +124,20 @@ class Chef
117
124
  :boolean => true,
118
125
  :default => true
119
126
 
120
- option :private_network,
121
- :long => '--private-network',
122
- :description => 'Use the private IP for bootstrapping rather than the public IP',
123
- :boolean => true,
124
- :default => false
127
+ option :networks,
128
+ :long => "--networks NETWORK_1,NETWORK_2,NETWORK_3",
129
+ :description => "Comma separated list of the name(s) of the network(s) for the server to attach",
130
+ :proc => Proc.new { |networks| networks.split(',') }
131
+
132
+ option :floating_ip,
133
+ :short => "-a [IP]",
134
+ :long => "--floating-ip [IP]",
135
+ :default => "-1",
136
+ :description => "Request to associate a floating IP address to server. Assumes IPs have been allocated to the project. Specifying IP is optional."
137
+
138
+ option :bootstrap_network,
139
+ :long => '--bootstrap-network NAME',
140
+ :description => "Specify network for bootstrapping."
125
141
 
126
142
  def tcp_test_ssh(hostname)
127
143
  tcp_socket = TCPSocket.new(hostname, 22)
@@ -159,120 +175,158 @@ class Chef
159
175
  Chef::Log.debug("Flavor #{locate_config_value(:flavor)}")
160
176
  Chef::Log.debug("Image #{locate_config_value(:image)}")
161
177
  Chef::Log.debug("Group(s) #{config[:security_groups]}")
178
+ Chef::Log.debug("Availability Zone #{locate_config_value(:availability_zone)}")
179
+ Chef::Log.debug("Requested Floating IP #{locate_config_value(:floating_ip)}")
162
180
  Chef::Log.debug("Key Pair #{Chef::Config[:knife][:hp_ssh_key_id]}")
163
181
 
164
182
  server_def = {
165
- :name => node_name,
166
- :flavor_id => locate_config_value(:flavor),
167
- :image_id => locate_config_value(:image),
168
- :security_groups => config[:security_groups],
169
- :key_name => Chef::Config[:knife][:hp_ssh_key_id],
170
- :personality => [{
171
- "path" => "/etc/chef/ohai/hints/hp.json",
172
- "contents" => ''
173
- }]
174
- }
175
-
176
- server = connection.servers.create(server_def)
177
-
178
- msg_pair("Instance ID", server.id)
179
- msg_pair("Instance Name", server.name)
180
- msg_pair("Flavor", server.flavor['id'])
181
- msg_pair("Image", server.image['id'])
182
- msg_pair("Security Group(s)", server.security_groups.collect {|x| x['name']}.join(", "))
183
- msg_pair("SSH Key Pair", server.key_name)
184
-
185
- print "\n#{ui.color("Waiting for server", :magenta)}"
186
-
187
- # wait for it to be ready to do stuff
188
- server.wait_for { print "."; ready? }
189
-
190
- puts("\n")
191
-
192
- msg_pair("Public IP Address", server.public_ip_address)
193
- msg_pair("Private IP Address", server.private_ip_address)
194
-
195
- # bootstrap using private network.
196
- if config[:private_network]
197
- bootstrap_ip_address = server.private_ip_address
198
- else
199
- bootstrap_ip_address = server.public_ip_address
183
+ :name => node_name,
184
+ :flavor_id => locate_config_value(:flavor),
185
+ :image_id => locate_config_value(:image),
186
+ :security_groups => config[:security_groups],
187
+ :availability_zone => locate_config_value(:availability_zone),
188
+ :key_name => Chef::Config[:knife][:hp_ssh_key_id]
189
+ }
190
+ unless locate_config_value(:networks).nil?
191
+ server_def[:nics] = locate_config_value(:networks).map do |nic|
192
+ nic_id = { 'net_id' => nic }
193
+ nic_id
194
+ end
195
+ end
196
+ Chef::Log.debug("server_def is: #{server_def}")
197
+
198
+ server = connection.servers.create(server_def)
199
+
200
+ msg_pair("Instance Name", server.name)
201
+ msg_pair("Instance ID", server.id)
202
+ msg_pair("Availability zone", server.availability_zone)
203
+
204
+ print "\n#{ui.color("Waiting for server", :magenta)}"
205
+
206
+ # wait for it to be ready to do stuff
207
+ server.wait_for { print "."; ready? }
208
+
209
+ puts("\n")
210
+
211
+ msg_pair("Flavor", server.flavor.name)
212
+ msg_pair("Image", server.image.name)
213
+ msg_pair("Security Group(s)", server.security_groups.collect {|x| x['name']}.join(", "))
214
+ msg_pair("SSH Key Pair", server.key_name)
215
+
216
+ Chef::Log.debug("Addresses #{server.addresses}")
217
+
218
+ floating_address = locate_config_value(:floating_ip)
219
+ Chef::Log.debug("Floating IP Address requested #{floating_address}")
220
+ unless (floating_address == '-1') # no floating IP requested
221
+ addresses = connection.addresses
222
+ # floating requested without value
223
+ if floating_address.nil?
224
+ free_floating = addresses.find_index { |a| a.fixed_ip.nil? }
225
+ if free_floating.nil? # no free floating IP found
226
+ ui.error("Unable to assign a Floating IP from allocated IPs.")
227
+ exit 1
228
+ else
229
+ floating_address = addresses[free_floating].ip
230
+ end
231
+ end
232
+ connection.associate_address(server.id, floating_address)
233
+ msg_pair("Floating IP Address", floating_address)
234
+ end
235
+
236
+ bootstrap_network = locate_config_value(:bootstrap_network)
237
+
238
+ unless bootstrap_network.nil?
239
+ Chef::Log.debug("Bootstrap specified network: #{bootstrap_network}")
240
+ bootstrap_ip_address = primary_network_ip_address(server.addresses, bootstrap_network)
241
+ else
242
+ if (floating_address == '-1') # no float requested
243
+ Chef::Log.debug("Bootstrap first network: #{server.addresses.first[0]}")
244
+ bootstrap_ip_address = server.addresses.first[1][0]['addr']
245
+ else
246
+ Chef::Log.debug("Bootstrap floating IP address: #{floating_address}")
247
+ bootstrap_ip_address = floating_address
248
+ end
249
+ end
250
+
251
+ print "\n#{ui.color("Waiting for sshd on #{bootstrap_ip_address}", :magenta)}"
252
+
253
+ # hack to ensure the nodes have had time to spin up
254
+ print(".")
255
+ sleep 30
256
+ print(".")
257
+
258
+ print(".") until tcp_test_ssh(bootstrap_ip_address) {
259
+ sleep @initial_sleep_delay ||= 10
260
+ puts("done")
261
+ }
262
+
263
+ bootstrap_for_node(server, bootstrap_ip_address).run
264
+
265
+ puts "\n"
266
+ msg_pair("Instance ID", server.id)
267
+ msg_pair("Instance Name", server.name)
268
+ msg_pair("Flavor", server.flavor.name)
269
+ msg_pair("Image", server.image.name)
270
+ msg_pair("Security Group(s)", server.security_groups.collect {|x| x['name']}.join(", "))
271
+ msg_pair("SSH Key Pair", server.key_name)
272
+ server.addresses.each do |name,addr|
273
+ msg_pair("Network", name)
274
+ msg_pair(" IP Address", addr[0]['addr'])
275
+ end
276
+ msg_pair("Environment", config[:environment] || '_default')
277
+ msg_pair("Run List", config[:run_list].join(', '))
200
278
  end
201
279
 
202
- print "\n#{ui.color("Waiting for sshd", :magenta)}"
203
-
204
- # hack to ensure the nodes have had time to spin up
205
- print(".")
206
- sleep 30
207
- print(".")
208
-
209
- print(".") until tcp_test_ssh(bootstrap_ip_address) {
210
- sleep @initial_sleep_delay ||= 10
211
- puts("done")
212
- }
213
-
214
- bootstrap_for_node(server, bootstrap_ip_address).run
215
-
216
- puts "\n"
217
- msg_pair("Instance ID", server.id)
218
- msg_pair("Instance Name", server.name)
219
- msg_pair("Flavor", server.flavor['id'])
220
- msg_pair("Image", server.image['id'])
221
- msg_pair("Security Group(s)", server.security_groups.collect {|x| x['name']}.join(", "))
222
- msg_pair("SSH Key Pair", server.key_name)
223
- msg_pair("Public IP Address", server.public_ip_address)
224
- msg_pair("Private IP Address", server.private_ip_address)
225
- msg_pair("Environment", config[:environment] || '_default')
226
- msg_pair("Run List", config[:run_list].join(', '))
227
- end
280
+ def bootstrap_for_node(server, bootstrap_ip_address)
281
+ bootstrap = Chef::Knife::Bootstrap.new
282
+ bootstrap.name_args = bootstrap_ip_address
283
+ bootstrap.config[:run_list] = config[:run_list]
284
+ bootstrap.config[:ssh_user] = config[:ssh_user]
285
+ bootstrap.config[:identity_file] = config[:identity_file]
286
+ bootstrap.config[:host_key_verify] = config[:host_key_verify]
287
+ bootstrap.config[:chef_node_name] = server.name
288
+ bootstrap.config[:prerelease] = config[:prerelease]
289
+ bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
290
+ bootstrap.config[:bootstrap_proxy] = locate_config_value(:bootstrap_proxy)
291
+ bootstrap.config[:distro] = locate_config_value(:distro)
292
+ bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
293
+ bootstrap.config[:template_file] = locate_config_value(:template_file)
294
+ bootstrap.config[:environment] = config[:environment]
295
+ # let ohai know we're using OpenStack
296
+ Chef::Config[:knife][:hints] ||= {}
297
+ Chef::Config[:knife][:hints]['hp'] ||= {}
298
+ bootstrap
299
+ end
228
300
 
229
- def bootstrap_for_node(server, bootstrap_ip_address)
230
- bootstrap = Chef::Knife::Bootstrap.new
231
- bootstrap.name_args = bootstrap_ip_address
232
- bootstrap.config[:run_list] = config[:run_list]
233
- bootstrap.config[:ssh_user] = config[:ssh_user]
234
- bootstrap.config[:identity_file] = config[:identity_file]
235
- bootstrap.config[:host_key_verify] = config[:host_key_verify]
236
- bootstrap.config[:chef_node_name] = server.name
237
- bootstrap.config[:prerelease] = config[:prerelease]
238
- bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
239
- bootstrap.config[:bootstrap_proxy] = locate_config_value(:bootstrap_proxy)
240
- bootstrap.config[:distro] = locate_config_value(:distro)
241
- bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
242
- bootstrap.config[:template_file] = locate_config_value(:template_file)
243
- bootstrap.config[:environment] = config[:environment]
244
- bootstrap
245
- end
301
+ def flavor
302
+ @flavor ||= connection.flavors.get(locate_config_value(:flavor))
303
+ end
246
304
 
247
- def flavor
248
- @flavor ||= connection.flavors.get(locate_config_value(:flavor))
249
- end
305
+ def image
306
+ @image ||= connection.images.get(locate_config_value(:image))
307
+ end
250
308
 
251
- def image
252
- @image ||= connection.images.get(locate_config_value(:image))
253
- end
309
+ def validate!
254
310
 
255
- def validate!
311
+ super([:image, :flavor, :hp_access_key, :hp_secret_key, :hp_tenant_id])
256
312
 
257
- super([:image, :flavor, :hp_access_key, :hp_secret_key, :hp_tenant_id])
313
+ if flavor.nil?
314
+ ui.error("You have not provided a valid flavor ID. Please note the options for this value are -f or --flavor.")
315
+ exit 1
316
+ end
258
317
 
259
- if flavor.nil?
260
- ui.error("You have not provided a valid flavor ID. Please note the options for this value are -f or --flavor.")
261
- exit 1
318
+ if image.nil?
319
+ ui.error("You have not provided a valid image ID. Please note the options for this value are -I or --image.")
320
+ exit 1
321
+ end
262
322
  end
263
323
 
264
- if image.nil?
265
- ui.error("You have not provided a valid image ID. Please note the options for this value are -I or --image.")
266
- exit 1
324
+ #generate a random name if chef_node_name is empty
325
+ def get_node_name(chef_node_name)
326
+ return chef_node_name unless chef_node_name.nil?
327
+ #lazy uuids
328
+ chef_node_name = "hp-"+rand.to_s.split('.')[1]
267
329
  end
268
330
  end
269
-
270
- #generate a random name if chef_node_name is empty
271
- def get_node_name(chef_node_name)
272
- return chef_node_name unless chef_node_name.nil?
273
- #lazy uuids
274
- chef_node_name = "hp-"+rand.to_s.split('.')[1]
275
- end
276
331
  end
277
332
  end
278
- end
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Matt Ray (<matt@opscode.com>)
3
- # Copyright:: Copyright (c) 2012 Opscode, Inc.
2
+ # Author:: Matt Ray (<matt@getchef.com>)
3
+ # Copyright:: Copyright (c) 2012-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");
@@ -64,31 +64,22 @@ class Chef
64
64
  @name_args.each do |instance_id|
65
65
  begin
66
66
  server = connection.servers.get(instance_id)
67
- addresses = connection.addresses
68
67
 
69
68
  msg_pair("Instance ID", server.id)
70
69
  msg_pair("Instance Name", server.name)
71
- msg_pair("Flavor", server.flavor['id'])
72
- msg_pair("Image", server.image['id'])
73
- msg_pair("Public IP Address", server.public_ip_address)
74
- msg_pair("Private IP Address", server.private_ip_address)
70
+ msg_pair("Flavor", server.flavor.name)
71
+ msg_pair("Image", server.image.name)
72
+ msg_pair("Availability Zone", server.availability_zone)
73
+ server.addresses.each do |name,addr|
74
+ msg_pair("Network", name)
75
+ msg_pair(" IP Address", addr[0]['addr'])
76
+ end
75
77
 
76
78
  puts "\n"
77
79
  confirm("Do you really want to delete this server")
78
80
 
79
81
  server.destroy
80
82
 
81
- #HP doesn't free allocated IPs when servers are deleted
82
- #if the address is a floating, it's the first entry in the private addresses(?)
83
- float = server.addresses['private'][0]['addr']
84
- Chef::Log.debug("hp_server_delete: float:#{float}")
85
- addresses.each do |address|
86
- if !(address.fixed_ip.nil?) && (address.fixed_ip == float)
87
- msg_pair("Deleted Floating IP Address", float)
88
- address.destroy
89
- end
90
- end
91
-
92
83
  ui.warn("Deleted server #{server.id}")
93
84
 
94
85
  if config[:purge]
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Matt Ray (<matt@opscode.com>)
3
- # Copyright:: Copyright (c) 2012 Opscode, Inc.
2
+ # Author:: Matt Ray (<matt@getchef.com>)
3
+ # Copyright:: Copyright (c) 2012-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");
@@ -34,32 +34,25 @@ class Chef
34
34
  server_list = [
35
35
  ui.color('Instance ID', :bold),
36
36
  ui.color('Name', :bold),
37
- ui.color('Public IP', :bold),
38
- ui.color('Private IP', :bold),
39
37
  ui.color('Flavor', :bold),
40
38
  ui.color('Image', :bold),
39
+ ui.color('Zone', :bold),
41
40
  ui.color('Key Pair', :bold),
42
41
  ui.color('State', :bold)
43
42
  ]
44
- connection.servers.all.sort_by(&:id).each do |server|
43
+ connection.list_servers_detail.body['servers'].sort_by { |h| h['name'] }.each do |server|
45
44
  Chef::Log.debug("Server: #{server.to_yaml}")
46
- # require 'pry'
47
- # binding.pry
48
- server_list << server.id.to_s
49
- server_list << server.name
50
- server_list << (server.public_ip_address or "")
51
- server_list << (server.private_ip_address or "")
52
- server_list << server.flavor['id'].to_s
53
- if server.image
54
- server_list << server.image['id']
55
- else
56
- server_list << ""
57
- end
58
- server_list << (server.key_name or "")
45
+
46
+ server_list << server['id']
47
+ server_list << server['name']
48
+ server_list << server['flavor']['id']
49
+ server_list << server['image']['id']
50
+ server_list << server['OS-EXT-AZ:availability_zone']
51
+ server_list << (server['key_name'] or "")
59
52
  server_list << begin
60
- state = server.state.to_s.downcase
53
+ state = server['status'].downcase
61
54
  case state
62
- when 'shutting-down','terminated','stopping','stopped','active(deleting)','build(deleting)'
55
+ when 'shutting-down','terminated','stopping','stopped','active(deleting)','build(deleting)','error'
63
56
  ui.color(state, :red)
64
57
  when 'pending','build(scheduling)','build(spawning)','build(networking)'
65
58
  ui.color(state, :yellow)
@@ -68,11 +61,9 @@ class Chef
68
61
  end
69
62
  end
70
63
  end
71
- puts ui.list(server_list, :uneven_columns_across, 8)
64
+ puts ui.list(server_list, :uneven_columns_across, 7)
72
65
 
73
66
  end
74
67
  end
75
68
  end
76
69
  end
77
-
78
-
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module Hp
3
- VERSION = "0.3.1"
3
+ VERSION = "0.4.0"
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-hp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.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-06-21 00:00:00.000000000 Z
13
+ date: 2014-05-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: fog
@@ -19,7 +19,7 @@ dependencies:
19
19
  requirements:
20
20
  - - ! '>='
21
21
  - !ruby/object:Gem::Version
22
- version: 1.10.0
22
+ version: '1.20'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,7 +27,7 @@ dependencies:
27
27
  requirements:
28
28
  - - ! '>='
29
29
  - !ruby/object:Gem::Version
30
- version: 1.10.0
30
+ version: '1.20'
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: chef
33
33
  requirement: !ruby/object:Gem::Requirement
@@ -35,7 +35,7 @@ dependencies:
35
35
  requirements:
36
36
  - - ! '>='
37
37
  - !ruby/object:Gem::Version
38
- version: 0.10.10
38
+ version: '11.0'
39
39
  type: :runtime
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - ! '>='
45
45
  - !ruby/object:Gem::Version
46
- version: 0.10.10
46
+ version: '11.0'
47
47
  description: HP Cloud Services Cloud support for Chef's Knife command
48
48
  email:
49
49
  - adam@opscode.com
@@ -65,6 +65,7 @@ files:
65
65
  - lib/chef/knife/hp_flavor_list.rb
66
66
  - lib/chef/knife/hp_group_list.rb
67
67
  - lib/chef/knife/hp_image_list.rb
68
+ - lib/chef/knife/hp_network_list.rb
68
69
  - lib/chef/knife/hp_server_create.rb
69
70
  - lib/chef/knife/hp_server_delete.rb
70
71
  - lib/chef/knife/hp_server_list.rb
@@ -89,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
90
  version: '0'
90
91
  requirements: []
91
92
  rubyforge_project:
92
- rubygems_version: 1.8.25
93
+ rubygems_version: 1.8.23.2
93
94
  signing_key:
94
95
  specification_version: 3
95
96
  summary: HP Cloud Services Cloud support for Chef's Knife command