From 40f8ae5bcf91872a4e3214a713d31753681415f5 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 17 Apr 2013 11:28:54 -0700 Subject: [PATCH 1/8] Add option to enable extra networks --- lib/chef/knife/rackspace_server_create.rb | 45 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/chef/knife/rackspace_server_create.rb b/lib/chef/knife/rackspace_server_create.rb index 198cb4d..daca89b 100644 --- a/lib/chef/knife/rackspace_server_create.rb +++ b/lib/chef/knife/rackspace_server_create.rb @@ -143,6 +143,14 @@ class RackspaceServerCreate < Knife :description => "Verify host key, enabled by default", :boolean => true, :default => true + + option :network, + :long => '--network [LABEL_OR_ID]', + :description => "Add private network. Use multiple --network options to specify multiple networks.", + :proc => Proc.new{|name| + Chef::Config[:knife][:rackspace_networks] ||= [] + (Chef::Config[:knife][:rackspace_networks] << name).uniq! + } option :bootstrap_protocol, :long => "--bootstrap-protocol protocol", @@ -159,7 +167,8 @@ class RackspaceServerCreate < Knife :long => "--bootstrap-proxy PROXY_URL", :description => "The proxy server for the node being bootstrapped", :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_proxy] = v } - + + def load_winrm_deps require 'winrm' require 'em-winrm' @@ -265,14 +274,18 @@ def run end node_name = get_node_name(config[:chef_node_name] || config[:server_name]) + networks = get_networks(Chef::Config[:knife][:rackspace_networks]) - server = connection.servers.create( + server = connection.servers.new( :name => node_name, :image_id => Chef::Config[:knife][:image], :flavor_id => locate_config_value(:flavor), :metadata => Chef::Config[:knife][:rackspace_metadata], :personality => files ) + server.save( + :networks => networks + ) msg_pair("Instance ID", server.id) msg_pair("Host ID", server.host_id) @@ -280,6 +293,7 @@ def run msg_pair("Flavor", server.flavor.name) msg_pair("Image", server.image.name) msg_pair("Metadata", server.metadata) + msg_pair("Networks", Chef::Config[:knife][:rackspace_networks].sort.join(', ')) if networks print "\n#{ui.color("Waiting server", :magenta)}" @@ -381,5 +395,32 @@ def get_node_name(chef_node_name) #lazy uuids chef_node_name = "rs-"+rand.to_s.split('.')[1] unless version_one? end + + def get_networks(names) + if(Chef::Config[:knife][:rackspace_version] == 'v2') + # Always include public net and service net + nets = [ + '00000000-0000-0000-0000-000000000000', + '11111111-1111-1111-1111-111111111111' + ] + found_nets = connection.networks.find_all do |n| + names.include?(n.label) || names.include?(n.id) + end + + names.each do |name| + net = found_nets.detect{|n| n.label == name || n.id == name} + if(net) + nets << net.id + else + ui.error("Failed to locate network: #{name}") + exit 1 + end + end + nets + elsif(names && !names.empty?) + ui.error("Custom networks are only available in v2 API") + exit 1 + end + end end end From bd4df4d10f20140a7826c43eeef5108631252e42 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Thu, 18 Apr 2013 18:43:40 -0700 Subject: [PATCH 2/8] Add tooling for creating, listing, deleting networks --- lib/chef/knife/rackspace_network_create.rb | 46 ++++++++++++++++++++++ lib/chef/knife/rackspace_network_delete.rb | 37 +++++++++++++++++ lib/chef/knife/rackspace_network_list.rb | 32 +++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 lib/chef/knife/rackspace_network_create.rb create mode 100644 lib/chef/knife/rackspace_network_delete.rb create mode 100644 lib/chef/knife/rackspace_network_list.rb diff --git a/lib/chef/knife/rackspace_network_create.rb b/lib/chef/knife/rackspace_network_create.rb new file mode 100644 index 0000000..0534528 --- /dev/null +++ b/lib/chef/knife/rackspace_network_create.rb @@ -0,0 +1,46 @@ +require 'chef/knife/rackspace_base' + +class Chef + class Knife + class RackspaceNetworkCreate < Knife + + include Knife::RackspaceBase + + banner "knife rackspace network create (options)" + + option :label, + :short => "-L LABEL", + :long => "--label LABEL", + :description => "Label for the network", + :required => true + + option :cidr, + :short => "-C CIDR", + :long => "--cidr CIDR", + :description => "CIDR for the network", + :required => true + + def run + if version_one? + ui.error "Networks are not supported in v1" + exit 1 + else + networks_list = [ + ui.color('Label', :bold), + ui.color('CIDR', :bold), + ui.color('ID', :bold) + ] + end + options = {} + [:cidr, :label].each do |key| + options[key] = config[key] + end + net = connection.networks.create(options) + + msg_pair("Network ID", net.id) + msg_pair("Label", net.label) + msg_pair("CIDR", net.cidr) + end + end + end +end diff --git a/lib/chef/knife/rackspace_network_delete.rb b/lib/chef/knife/rackspace_network_delete.rb new file mode 100644 index 0000000..8c9cb70 --- /dev/null +++ b/lib/chef/knife/rackspace_network_delete.rb @@ -0,0 +1,37 @@ +require 'chef/knife/rackspace_base' + +class Chef + class Knife + class RackspaceNetworkDelete < Knife + + include Knife::RackspaceBase + + banner "knife rackspace network delete NETWORK_ID [NETWORK_ID] (options)" + + def run + if version_one? + ui.error "Networks are not supported in v1" + exit 1 + else + @name_args.each do |net_id| + network = connection.networks.get(net_id) + unless(network) + ui.error "Could not locate network: #{net_id}" + exit 1 + end + msg_pair("Network ID", network.id) + msg_pair("Label", network.label) + msg_pair("CIDR", network.cidr) + + puts "\n" + confirm("Do you really want to delete this network") + + network.destroy + + ui.warn("Deleted network #{network.id}") + end + end + end + end + end +end diff --git a/lib/chef/knife/rackspace_network_list.rb b/lib/chef/knife/rackspace_network_list.rb new file mode 100644 index 0000000..6839d08 --- /dev/null +++ b/lib/chef/knife/rackspace_network_list.rb @@ -0,0 +1,32 @@ +require 'chef/knife/rackspace_base' + +class Chef + class Knife + class RackspaceNetworkList < Knife + + include Knife::RackspaceBase + + banner "knife rackspace network list (options)" + + def run + if version_one? + ui.error "Networks are not supported in v1" + exit 1 + else + networks_list = [ + ui.color('Label', :bold), + ui.color('CIDR', :bold), + ui.color('ID', :bold) + ] + end + connection.networks.sort_by(&:id).each do |network| + next if network.id.match(%r{^([0-]+|[1-]+)$}) # skip builtins + networks_list << network.label + networks_list << network.cidr + networks_list << network.id.to_s + end + puts ui.list(networks_list, :uneven_columns_across, 3) + end + end + end +end From ba2e7fabdd0be8f82cf2358b997688cf42d5a74c Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Mon, 22 Apr 2013 12:33:20 -0700 Subject: [PATCH 3/8] Ensure proper Array type before processing --- lib/chef/knife/rackspace_server_create.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/chef/knife/rackspace_server_create.rb b/lib/chef/knife/rackspace_server_create.rb index daca89b..663a499 100644 --- a/lib/chef/knife/rackspace_server_create.rb +++ b/lib/chef/knife/rackspace_server_create.rb @@ -397,6 +397,7 @@ def get_node_name(chef_node_name) end def get_networks(names) + names = Array(names) unless names.is_a?(Array) if(Chef::Config[:knife][:rackspace_version] == 'v2') # Always include public net and service net nets = [ From 1a645da740de2289a31e6753609769f7c07c2e5a Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Mon, 22 Apr 2013 12:36:14 -0700 Subject: [PATCH 4/8] Only output network information if custom networks requested --- lib/chef/knife/rackspace_server_create.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/chef/knife/rackspace_server_create.rb b/lib/chef/knife/rackspace_server_create.rb index 663a499..3cc993c 100644 --- a/lib/chef/knife/rackspace_server_create.rb +++ b/lib/chef/knife/rackspace_server_create.rb @@ -293,7 +293,9 @@ def run msg_pair("Flavor", server.flavor.name) msg_pair("Image", server.image.name) msg_pair("Metadata", server.metadata) - msg_pair("Networks", Chef::Config[:knife][:rackspace_networks].sort.join(', ')) if networks + if(networks && Chef::Config[:knife][:rackspace_networks]) + msg_pair("Networks", Chef::Config[:knife][:rackspace_networks].sort.join(', ')) + end print "\n#{ui.color("Waiting server", :magenta)}" From add93bf170637fb22faba69119d8a6f585e3edc2 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Tue, 30 Apr 2013 16:21:15 -0700 Subject: [PATCH 5/8] Do not filter public and service networks out of list --- lib/chef/knife/rackspace_network_list.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/chef/knife/rackspace_network_list.rb b/lib/chef/knife/rackspace_network_list.rb index 6839d08..97b9ec3 100644 --- a/lib/chef/knife/rackspace_network_list.rb +++ b/lib/chef/knife/rackspace_network_list.rb @@ -20,7 +20,6 @@ def run ] end connection.networks.sort_by(&:id).each do |network| - next if network.id.match(%r{^([0-]+|[1-]+)$}) # skip builtins networks_list << network.label networks_list << network.cidr networks_list << network.id.to_s From ed7c954843b8cf6e7d8455a8afd3a6e8cd7d26c3 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Tue, 30 Apr 2013 16:21:32 -0700 Subject: [PATCH 6/8] Provide option to enable or disable default networks --- lib/chef/knife/rackspace_server_create.rb | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/chef/knife/rackspace_server_create.rb b/lib/chef/knife/rackspace_server_create.rb index 3cc993c..ad0ca60 100644 --- a/lib/chef/knife/rackspace_server_create.rb +++ b/lib/chef/knife/rackspace_server_create.rb @@ -144,10 +144,16 @@ class RackspaceServerCreate < Knife :boolean => true, :default => true + option :default_networks, + :long => "--[no-]-default-networks", + :description => "Include public and service networks, enabled by default", + :boolean => true, + :default => true + option :network, :long => '--network [LABEL_OR_ID]', :description => "Add private network. Use multiple --network options to specify multiple networks.", - :proc => Proc.new{|name| + :proc => Proc.new{ |name| Chef::Config[:knife][:rackspace_networks] ||= [] (Chef::Config[:knife][:rackspace_networks] << name).uniq! } @@ -401,11 +407,14 @@ def get_node_name(chef_node_name) def get_networks(names) names = Array(names) unless names.is_a?(Array) if(Chef::Config[:knife][:rackspace_version] == 'v2') - # Always include public net and service net - nets = [ - '00000000-0000-0000-0000-000000000000', - '11111111-1111-1111-1111-111111111111' - ] + if(config[:default_networks]) + nets = [ + '00000000-0000-0000-0000-000000000000', + '11111111-1111-1111-1111-111111111111' + ] + else + nets = [] + end found_nets = connection.networks.find_all do |n| names.include?(n.label) || names.include?(n.id) end From 20d7b29c37719e5315674180d5030c90bf9bfb33 Mon Sep 17 00:00:00 2001 From: Adam DePue Date: Tue, 4 Jun 2013 03:48:55 +0000 Subject: [PATCH 7/8] Code review feedback and documentation cleanup --- lib/chef/knife/rackspace_base.rb | 2 +- lib/chef/knife/rackspace_server_create.rb | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/chef/knife/rackspace_base.rb b/lib/chef/knife/rackspace_base.rb index d6214f5..ece340e 100644 --- a/lib/chef/knife/rackspace_base.rb +++ b/lib/chef/knife/rackspace_base.rb @@ -157,7 +157,7 @@ def public_dns_name(server) @public_dns_name ||= begin Resolv.getname(ip_address) rescue - "#{ip_address.gsub('.','-')}.static.cloud-ips.com" + "#{ip_address.gsub('.','-')}.static.cloud-ips.com" unless ip_address == nil end end diff --git a/lib/chef/knife/rackspace_server_create.rb b/lib/chef/knife/rackspace_server_create.rb index ad0ca60..9d79bde 100644 --- a/lib/chef/knife/rackspace_server_create.rb +++ b/lib/chef/knife/rackspace_server_create.rb @@ -145,7 +145,7 @@ class RackspaceServerCreate < Knife :default => true option :default_networks, - :long => "--[no-]-default-networks", + :long => "--[no-]default-networks", :description => "Include public and service networks, enabled by default", :boolean => true, :default => true @@ -405,7 +405,7 @@ def get_node_name(chef_node_name) end def get_networks(names) - names = Array(names) unless names.is_a?(Array) + names = Array(names) if(Chef::Config[:knife][:rackspace_version] == 'v2') if(config[:default_networks]) nets = [ @@ -415,12 +415,10 @@ def get_networks(names) else nets = [] end - found_nets = connection.networks.find_all do |n| - names.include?(n.label) || names.include?(n.id) - end + available_networks = connection.networks.all names.each do |name| - net = found_nets.detect{|n| n.label == name || n.id == name} + net = available_networks.detect{|n| n.label == name || n.id == name} if(net) nets << net.id else From faea0b6fe83297ad27d5cc129fefc9de11927192 Mon Sep 17 00:00:00 2001 From: Adam DePue Date: Tue, 4 Jun 2013 17:36:01 +0000 Subject: [PATCH 8/8] Better condition handling on nil ip address --- lib/chef/knife/rackspace_base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chef/knife/rackspace_base.rb b/lib/chef/knife/rackspace_base.rb index ece340e..b3448db 100644 --- a/lib/chef/knife/rackspace_base.rb +++ b/lib/chef/knife/rackspace_base.rb @@ -157,7 +157,7 @@ def public_dns_name(server) @public_dns_name ||= begin Resolv.getname(ip_address) rescue - "#{ip_address.gsub('.','-')}.static.cloud-ips.com" unless ip_address == nil + "#{ip_address.gsub('.','-')}.static.cloud-ips.com" if ip_address end end