From 64787942086b6fbfdf432cd6250f0937c785de1a Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 12 Aug 2015 14:37:21 -0700 Subject: mv commands and macros to lib/leap_cli --- lib/leap_cli/commands/node.rb | 165 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 lib/leap_cli/commands/node.rb (limited to 'lib/leap_cli/commands/node.rb') diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb new file mode 100644 index 00000000..12d6b49d --- /dev/null +++ b/lib/leap_cli/commands/node.rb @@ -0,0 +1,165 @@ +# +# fyi: the `node init` command lives in node_init.rb, +# but all other `node x` commands live here. +# + +autoload :IPAddr, 'ipaddr' + +module LeapCli; module Commands + + ## + ## COMMANDS + ## + + desc 'Node management' + command [:node, :n] do |node| + node.desc 'Create a new configuration file for a node named NAME.' + node.long_desc ["If specified, the optional argument SEED can be used to seed values in the node configuration file.", + "The format is property_name:value.", + "For example: `leap node add web1 ip_address:1.2.3.4 services:webapp`.", + "To set nested properties, property name can contain '.', like so: `leap node add web1 ssh.port:44`", + "Separeate multiple values for a single property with a comma, like so: `leap node add mynode services:webapp,dns`"].join("\n\n") + node.arg_name 'NAME [SEED]' # , :optional => false, :multiple => false + node.command :add do |add| + add.switch :local, :desc => 'Make a local testing node (by automatically assigning the next available local IP address). Local nodes are run as virtual machines on your computer.', :negatable => false + add.action do |global_options,options,args| + # argument sanity checks + name = args.first + assert_valid_node_name!(name, options[:local]) + assert_files_missing! [:node_config, name] + + # create and seed new node + node = Config::Node.new(manager) + if options[:local] + node['ip_address'] = pick_next_vagrant_ip_address + end + seed_node_data(node, args[1..-1]) + validate_ip_address(node) + begin + write_file! [:node_config, name], node.dump_json + "\n" + node['name'] = name + if file_exists? :ca_cert, :ca_key + generate_cert_for_node(manager.reload_node!(node)) + end + rescue LeapCli::ConfigError => exc + remove_node_files(name) + end + end + end + + node.desc 'Renames a node file, and all its related files.' + node.arg_name 'OLD_NAME NEW_NAME' + node.command :mv do |mv| + mv.action do |global_options,options,args| + node = get_node_from_args(args) + new_name = args.last + assert_valid_node_name!(new_name, node.vagrant?) + ensure_dir [:node_files_dir, new_name] + Leap::Platform.node_files.each do |path| + rename_file! [path, node.name], [path, new_name] + end + remove_directory! [:node_files_dir, node.name] + rename_node_facts(node.name, new_name) + end + end + + node.desc 'Removes all the files related to the node named NAME.' + node.arg_name 'NAME' #:optional => false #, :multiple => false + node.command :rm do |rm| + rm.action do |global_options,options,args| + node = get_node_from_args(args) + remove_node_files(node.name) + if node.vagrant? + vagrant_command("destroy --force", [node.name]) + end + remove_node_facts(node.name) + end + end + end + + ## + ## PUBLIC HELPERS + ## + + def get_node_from_args(args, options={}) + node_name = args.first + node = manager.node(node_name) + if node.nil? && options[:include_disabled] + node = manager.disabled_node(node_name) + end + assert!(node, "Node '#{node_name}' not found.") + node + end + + def seed_node_data(node, args) + args.each do |seed| + key, value = seed.split(':') + value = format_seed_value(value) + assert! key =~ /^[0-9a-z\._]+$/, "illegal characters used in property '#{key}'" + if key =~ /\./ + key_parts = key.split('.') + final_key = key_parts.pop + current_object = node + key_parts.each do |key_part| + current_object[key_part] ||= Config::Object.new + current_object = current_object[key_part] + end + current_object[final_key] = value + else + node[key] = value + end + end + end + + def remove_node_files(node_name) + (Leap::Platform.node_files + [:node_files_dir]).each do |path| + remove_file! [path, node_name] + end + end + + # + # conversions: + # + # "x,y,z" => ["x","y","z"] + # + # "22" => 22 + # + # "5.1" => 5.1 + # + def format_seed_value(v) + if v =~ /,/ + v = v.split(',') + v.map! do |i| + i = i.to_i if i.to_i.to_s == i + i = i.to_f if i.to_f.to_s == i + i + end + else + v = v.to_i if v.to_i.to_s == v + v = v.to_f if v.to_f.to_s == v + end + return v + end + + def validate_ip_address(node) + IPAddr.new(node['ip_address']) + rescue ArgumentError + bail! do + if node['ip_address'] + log :invalid, "ip_address #{node['ip_address'].inspect}" + else + log :missing, "ip_address" + end + end + end + + def assert_valid_node_name!(name, local=false) + assert! name, 'No specified.' + if local + assert! name =~ /^[0-9a-z]+$/, "illegal characters used in node name '#{name}' (note: Vagrant does not allow hyphens or underscores)" + else + assert! name =~ /^[0-9a-z-]+$/, "illegal characters used in node name '#{name}' (note: Linux does not allow underscores)" + end + end + +end; end \ No newline at end of file -- cgit v1.2.3 From 8d4e3610ce836e4fe95c347920b9da5c32037dbb Mon Sep 17 00:00:00 2001 From: Christoph Kluenter Date: Wed, 16 Dec 2015 11:19:10 +0100 Subject: ensure that the key/value are only split on the first colon --- lib/leap_cli/commands/node.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/leap_cli/commands/node.rb') diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb index 12d6b49d..ecd11f5e 100644 --- a/lib/leap_cli/commands/node.rb +++ b/lib/leap_cli/commands/node.rb @@ -93,7 +93,7 @@ module LeapCli; module Commands def seed_node_data(node, args) args.each do |seed| - key, value = seed.split(':') + key, value = seed.split(':', 2) value = format_seed_value(value) assert! key =~ /^[0-9a-z\._]+$/, "illegal characters used in property '#{key}'" if key =~ /\./ @@ -162,4 +162,4 @@ module LeapCli; module Commands end end -end; end \ No newline at end of file +end; end -- cgit v1.2.3 From 8eec2d89983934868c9be07d55825cbe3bdcdaaf Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Feb 2016 17:58:44 -0800 Subject: added templates for `leap node add`, so that new nodes can get default values set in their initial .json file. --- lib/leap_cli/commands/node.rb | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'lib/leap_cli/commands/node.rb') diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb index ecd11f5e..cc352762 100644 --- a/lib/leap_cli/commands/node.rb +++ b/lib/leap_cli/commands/node.rb @@ -33,11 +33,13 @@ module LeapCli; module Commands if options[:local] node['ip_address'] = pick_next_vagrant_ip_address end - seed_node_data(node, args[1..-1]) + seed_node_data_from_cmd_line(node, args[1..-1]) + seed_node_data_from_template(node) validate_ip_address(node) begin - write_file! [:node_config, name], node.dump_json + "\n" node['name'] = name + json = node.dump_json(:exclude => ['name']) + write_file!([:node_config, name], json + "\n") if file_exists? :ca_cert, :ca_key generate_cert_for_node(manager.reload_node!(node)) end @@ -91,7 +93,7 @@ module LeapCli; module Commands node end - def seed_node_data(node, args) + def seed_node_data_from_cmd_line(node, args) args.each do |seed| key, value = seed.split(':', 2) value = format_seed_value(value) @@ -111,6 +113,23 @@ module LeapCli; module Commands end end + # + # load "new node template" information into the `node`, modifying `node`. + # values in the template will not override existing node values. + # + def seed_node_data_from_template(node) + return unless manager.respond_to?(:template) + node.inherit_from!(manager.template('common')) + [node['services']].flatten.each do |service| + if service + template = manager.template(service) + if template + node.inherit_from!(template) + end + end + end + end + def remove_node_files(node_name) (Leap::Platform.node_files + [:node_files_dir]).each do |path| remove_file! [path, node_name] @@ -142,6 +161,11 @@ module LeapCli; module Commands end def validate_ip_address(node) + if node['ip_address'] == "REQUIRED" + bail! do + log :error, "ip_address is not set. Specify with `leap node add NAME ip_address:ADDRESS`." + end + end IPAddr.new(node['ip_address']) rescue ArgumentError bail! do -- cgit v1.2.3 From 55ede82e2127095d613f062dc452e33c87f7b424 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 17 Mar 2016 14:41:54 -0700 Subject: allow 'node rm' on disabled nodes --- lib/leap_cli/commands/node.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/leap_cli/commands/node.rb') diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb index cc352762..142c0766 100644 --- a/lib/leap_cli/commands/node.rb +++ b/lib/leap_cli/commands/node.rb @@ -53,7 +53,7 @@ module LeapCli; module Commands node.arg_name 'OLD_NAME NEW_NAME' node.command :mv do |mv| mv.action do |global_options,options,args| - node = get_node_from_args(args) + node = get_node_from_args(args, include_disabled: true) new_name = args.last assert_valid_node_name!(new_name, node.vagrant?) ensure_dir [:node_files_dir, new_name] @@ -69,7 +69,7 @@ module LeapCli; module Commands node.arg_name 'NAME' #:optional => false #, :multiple => false node.command :rm do |rm| rm.action do |global_options,options,args| - node = get_node_from_args(args) + node = get_node_from_args(args, include_disabled: true) remove_node_files(node.name) if node.vagrant? vagrant_command("destroy --force", [node.name]) -- cgit v1.2.3 From 53fdac31bce3a66b37811dbe81e3d3f71c533a0c Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 12 Apr 2016 10:39:06 -0700 Subject: fix node seeding (closes #8026) --- lib/leap_cli/commands/node.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/leap_cli/commands/node.rb') diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb index 142c0766..a23661b3 100644 --- a/lib/leap_cli/commands/node.rb +++ b/lib/leap_cli/commands/node.rb @@ -29,7 +29,7 @@ module LeapCli; module Commands assert_files_missing! [:node_config, name] # create and seed new node - node = Config::Node.new(manager) + node = Config::Node.new(manager.env) if options[:local] node['ip_address'] = pick_next_vagrant_ip_address end @@ -118,7 +118,6 @@ module LeapCli; module Commands # values in the template will not override existing node values. # def seed_node_data_from_template(node) - return unless manager.respond_to?(:template) node.inherit_from!(manager.template('common')) [node['services']].flatten.each do |service| if service -- cgit v1.2.3