diff --git a/lib/chef/knife/rackspace_base.rb b/lib/chef/knife/rackspace_base.rb index d6214f5..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" + "#{ip_address.gsub('.','-')}.static.cloud-ips.com" if ip_address end end 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..97b9ec3 --- /dev/null +++ b/lib/chef/knife/rackspace_network_list.rb @@ -0,0 +1,31 @@ +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| + 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 diff --git a/lib/chef/knife/rackspace_server_create.rb b/lib/chef/knife/rackspace_server_create.rb index 198cb4d..9d79bde 100644 --- a/lib/chef/knife/rackspace_server_create.rb +++ b/lib/chef/knife/rackspace_server_create.rb @@ -143,6 +143,20 @@ class RackspaceServerCreate < Knife :description => "Verify host key, enabled by default", :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| + Chef::Config[:knife][:rackspace_networks] ||= [] + (Chef::Config[:knife][:rackspace_networks] << name).uniq! + } option :bootstrap_protocol, :long => "--bootstrap-protocol protocol", @@ -159,7 +173,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 +280,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 +299,9 @@ def run msg_pair("Flavor", server.flavor.name) msg_pair("Image", server.image.name) msg_pair("Metadata", server.metadata) + 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)}" @@ -381,5 +403,34 @@ 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) + names = Array(names) + if(Chef::Config[:knife][:rackspace_version] == 'v2') + if(config[:default_networks]) + nets = [ + '00000000-0000-0000-0000-000000000000', + '11111111-1111-1111-1111-111111111111' + ] + else + nets = [] + end + available_networks = connection.networks.all + + names.each do |name| + net = available_networks.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