summaryrefslogtreecommitdiff
path: root/lib/leap_cli/commands/node.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/leap_cli/commands/node.rb')
-rw-r--r--lib/leap_cli/commands/node.rb177
1 files changed, 59 insertions, 118 deletions
diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb
index a23661b3..60540de9 100644
--- a/lib/leap_cli/commands/node.rb
+++ b/lib/leap_cli/commands/node.rb
@@ -3,8 +3,6 @@
# but all other `node x` commands live here.
#
-autoload :IPAddr, 'ipaddr'
-
module LeapCli; module Commands
##
@@ -18,33 +16,16 @@ module LeapCli; module Commands
"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")
+ "Separate 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.switch :local, :desc => 'Make a local testing node (by assigning the next available local IP address). Local nodes are run as virtual machines on your computer.', :negatable => false
+ add.switch :vm, :desc => 'Make a remote virtual machine for this node. Requires a valid cloud.json configuration.', :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.env)
- if options[:local]
- node['ip_address'] = pick_next_vagrant_ip_address
- end
- seed_node_data_from_cmd_line(node, args[1..-1])
- seed_node_data_from_template(node)
- validate_ip_address(node)
- begin
- 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
- rescue LeapCli::ConfigError => exc
- remove_node_files(name)
+ if options[:vm]
+ do_vm_add(global_options, options, args)
+ else
+ do_node_add(global_options, options, args)
end
end
end
@@ -53,15 +34,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, include_disabled: true)
- 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)
+ do_node_move(global_options, options, args)
end
end
@@ -69,12 +42,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, include_disabled: true)
- remove_node_files(node.name)
- if node.vagrant?
- vagrant_command("destroy --force", [node.name])
- end
- remove_node_facts(node.name)
+ do_node_rm(global_options, options, args)
end
end
end
@@ -93,96 +61,69 @@ module LeapCli; module Commands
node
end
- def seed_node_data_from_cmd_line(node, args)
- args.each do |seed|
- key, value = seed.split(':', 2)
- 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
+ protected
#
- # load "new node template" information into the `node`, modifying `node`.
- # values in the template will not override existing node values.
+ # additionally called by `leap vm add`
#
- def seed_node_data_from_template(node)
- 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
+ def do_node_add(global, options, args)
+ name = args.first
+ unless global[:force]
+ assert_files_missing! [:node_config, name]
end
- end
-
- def remove_node_files(node_name)
- (Leap::Platform.node_files + [:node_files_dir]).each do |path|
- remove_file! [path, node_name]
+ node = Config::Node.new(manager.env)
+ node['name'] = name
+ if options[:ip_address]
+ node['ip_address'] = options[:ip_address]
+ elsif options[:local]
+ node['ip_address'] = pick_next_vagrant_ip_address
end
+ node.seed_from_args(args[1..-1])
+ node.seed_from_template
+ node.validate!
+ node.write_configs
+ # reapply inheritance, since tags/services might have changed:
+ node = manager.reload_node!(node)
+ node.generate_cert
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
+ private
- 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
+ def do_node_move(global, options, args)
+ node = get_node_from_args(args, include_disabled: true)
+ new_name = args.last
+ Config::Node.validate_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
- 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
+ remove_directory! [:node_files_dir, node.name]
+ rename_node_facts(node.name, new_name)
+ if node.vm_id?
+ node['name'] = new_name
+ bind_server_to_node(node.vm.id, node, options)
end
end
- def assert_valid_node_name!(name, local=false)
- assert! name, 'No <node-name> 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)"
+ def do_node_rm(global, options, args)
+ node = get_node_from_args(args, include_disabled: true)
+ if node.vm?
+ if !node.vm_id?
+ log :warning, "The node #{node.name} is missing a 'vm.id' property. "+
+ "You may have a virtual machine instance that is left "+
+ "running. Check `leap vm status`"
+ else
+ msg = "The node #{node.name} appears to be associated with a virtual machine. " +
+ "Do you want to also destroy this virtual machine? "
+ if global[:yes] || agree(msg)
+ do_vm_rm(global, options, args)
+ end
+ end
+ elsif node.vagrant?
+ vagrant_command("destroy --force", [node.name])
end
+ node.remove_files
+ remove_node_facts(node.name)
end
end; end