From a27c9e53f46700acb79b33173060e45c97c183c2 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 18 Dec 2014 10:15:08 -0800 Subject: added info note to leap db destroy --- lib/leap_cli/commands/db.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/db.rb b/lib/leap_cli/commands/db.rb index ea83b0c..fd50424 100644 --- a/lib/leap_cli/commands/db.rb +++ b/lib/leap_cli/commands/db.rb @@ -17,6 +17,7 @@ module LeapCli; module Commands ssh.run('/etc/init.d/bigcouch stop && test ! -z "$(ls /opt/bigcouch/var/lib/ 2> /dev/null)" && rm -r /opt/bigcouch/var/lib/* && echo "db destroyed" || echo "db already destroyed"') ssh.run('grep ^seq_file /etc/leap/tapicero.yaml | cut -f2 -d\" | xargs rm -v') end + say 'You must run `leap deploy` in order to create the databases again.' else say 'No nodes' end -- cgit v1.2.3 From 0bb30766e6f6fe1832343132b3433533e7b314a0 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 22 Jan 2015 14:12:14 -0800 Subject: added support for custom tests in files/tests --- lib/leap_cli/commands/deploy.rb | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/deploy.rb b/lib/leap_cli/commands/deploy.rb index e413807..dbbaaba 100644 --- a/lib/leap_cli/commands/deploy.rb +++ b/lib/leap_cli/commands/deploy.rb @@ -177,17 +177,11 @@ module LeapCli # def sync_support_files(ssh) dest_dir = Leap::Platform.files_dir - source_files = [] - if Path.defined?(:custom_puppet_dir) && file_exists?(:custom_puppet_dir) - source_files += [:custom_puppet_dir, :custom_puppet_modules_dir, :custom_puppet_manifests_dir].collect{|path| - Path.relative_path(path, Path.provider) + '/' # rsync needs trailing slash - } - ensure_dir :custom_puppet_modules_dir - end + custom_files = build_custom_file_list ssh.rsync.update do |server| node = manager.node(server.host) files_to_sync = node.file_paths.collect {|path| Path.relative_path(path, Path.provider) } - files_to_sync += source_files + files_to_sync += custom_files if files_to_sync.any? ssh.leap.log(files_to_sync.join(', ') + ' -> ' + node.name + ':' + dest_dir) { @@ -282,5 +276,24 @@ module LeapCli tags.join(',') end + # + # a provider might have various customization files that should be sync'ed to the server. + # this method builds that list of files to sync. + # + def build_custom_file_list + custom_files = [] + Leap::Platform.paths.keys.grep(/^custom_/).each do |path| + if file_exists?(path) + relative_path = Path.relative_path(path, Path.provider) + if dir_exists?(path) + custom_files << relative_path + '/' # rsync needs trailing slash + else + custom_files << relative_path + end + end + end + return custom_files + end + end end -- cgit v1.2.3 From 5676272e90dc69234181eaa5b2e96447f904966e Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 28 Jan 2015 13:41:12 -0800 Subject: honor --yes for 'db destroy'. closes 6649. --- lib/leap_cli/commands/db.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/db.rb b/lib/leap_cli/commands/db.rb index fd50424..3502d7e 100644 --- a/lib/leap_cli/commands/db.rb +++ b/lib/leap_cli/commands/db.rb @@ -6,8 +6,10 @@ module LeapCli; module Commands db.arg_name 'FILTER', :optional => true db.command :destroy do |destroy| destroy.action do |global_options,options,args| - say 'You are about to permanently destroy all database data.' - return unless agree("Continue? ") + unless global_options[:yes] + say 'You are about to permanently destroy all database data.' + bail! unless agree("Continue? ") + end nodes = manager.filter(args) if nodes.any? nodes = nodes[:services => 'couchdb'] -- cgit v1.2.3 From e01bf415d80883c369dfd4247aae401fde421b80 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 28 Jan 2015 22:19:25 -0800 Subject: cert generation: (1) auto generate certs (2) actually support configuring expiration times. REQUIRES platform >= 0.6.1. closes #6387 --- lib/leap_cli/commands/ca.rb | 71 ++++++++++++++++++++++------------------- lib/leap_cli/commands/deploy.rb | 2 ++ 2 files changed, 41 insertions(+), 32 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/ca.rb b/lib/leap_cli/commands/ca.rb index 357792f..785e043 100644 --- a/lib/leap_cli/commands/ca.rb +++ b/lib/leap_cli/commands/ca.rb @@ -28,22 +28,7 @@ module LeapCli; module Commands cert.command :update do |update| update.switch 'force', :desc => 'Always generate new certificates', :negatable => false update.action do |global_options,options,args| - assert_files_exist! :ca_cert, :ca_key, :msg => 'Run `leap cert ca` to create them' - assert_config! 'provider.ca.server_certificates.bit_size' - assert_config! 'provider.ca.server_certificates.digest' - assert_config! 'provider.ca.server_certificates.life_span' - assert_config! 'common.x509.use' - - nodes = manager.filter!(args) - nodes.each_node do |node| - warn_if_commercial_cert_will_soon_expire(node) - if !node.x509.use - remove_file!([:node_x509_key, node.name]) - remove_file!([:node_x509_cert, node.name]) - elsif options[:force] || cert_needs_updating?(node) - generate_cert_for_node(node) - end - end + update_certificates(manager.filter!(args), options) end end @@ -139,7 +124,7 @@ module LeapCli; module Commands cert = csr.to_cert cert.serial_number.number = cert_serial_number(domain) cert.not_before = yesterday - cert.not_after = years_from_yesterday(1) + cert.not_after = yesterday.advance(:years => 1) cert.parent = ca_root cert.sign! domain_test_signing_profile write_file! [:commercial_cert, domain], cert.to_pem @@ -158,6 +143,29 @@ module LeapCli; module Commands end end + protected + + # + # will generate new certificates for the specified nodes, if needed. + # + def update_certificates(nodes, options={}) + assert_files_exist! :ca_cert, :ca_key, :msg => 'Run `leap cert ca` to create them' + assert_config! 'provider.ca.server_certificates.bit_size' + assert_config! 'provider.ca.server_certificates.digest' + assert_config! 'provider.ca.server_certificates.life_span' + assert_config! 'common.x509.use' + + nodes.each_node do |node| + warn_if_commercial_cert_will_soon_expire(node) + if !node.x509.use + remove_file!([:node_x509_key, node.name]) + remove_file!([:node_x509_cert, node.name]) + elsif options[:force] || cert_needs_updating?(node) + generate_cert_for_node(node) + end + end + end + private def generate_new_certificate_authority(key_file, cert_file, common_name) @@ -179,7 +187,7 @@ module LeapCli; module Commands # set expiration root.not_before = yesterday - root.not_after = years_from_yesterday(provider.ca.life_span.to_i) + root.not_after = yesterday_advance(provider.ca.life_span) # generate private key root.serial_number.number = 1 @@ -203,7 +211,7 @@ module LeapCli; module Commands return true else cert = load_certificate_file([:node_x509_cert, node.name]) - if cert.not_after < months_from_yesterday(2) + if cert.not_after < Time.now.advance(:months => 2) log :updating, "cert for node '#{node.name}' because it will expire soon" return true end @@ -242,7 +250,7 @@ module LeapCli; module Commands if cert.not_after < Time.now.utc log :error, "the commercial certificate '#{path}' has EXPIRED! " + "You should renew it with `leap cert csr --domain #{domain}`." - elsif cert.not_after < months_from_yesterday(2) + elsif cert.not_after < Time.now.advance(:months => 2) log :warning, "the commercial certificate '#{path}' will expire soon. "+ "You should renew it with `leap cert csr --domain #{domain}`." end @@ -261,7 +269,7 @@ module LeapCli; module Commands # set expiration cert.not_before = yesterday - cert.not_after = years_from_yesterday(provider.ca.server_certificates.life_span.to_i) + cert.not_after = yesterday_advance(provider.ca.server_certificates.life_span) # generate key cert.key_material.generate_key(provider.ca.server_certificates.bit_size) @@ -283,7 +291,7 @@ module LeapCli; module Commands cert.serial_number.number = cert_serial_number(provider.domain) cert.subject.common_name = [prefix, random_common_name(provider.domain)].join cert.not_before = yesterday - cert.not_after = years_from_yesterday(1) + cert.not_after = yesterday.advance(:years => 1) cert.key_material.generate_key(1024) # just for testing, remember! cert.parent = client_ca_root cert.sign! client_test_signing_profile @@ -492,16 +500,15 @@ module LeapCli; module Commands Time.utc t.year, t.month, t.day end - def years_from_yesterday(num) - t = yesterday - Time.utc t.year + num, t.month, t.day - end - - def months_from_yesterday(num) - t = yesterday - date = Date.new t.year, t.month, t.day - date = date >> num # >> is months in the future operator - Time.utc date.year, date.month, date.day + def yesterday_advance(string) + number, unit = string.split(' ') + unless ['years', 'months', 'days', 'hours', 'minutes'].include? unit + bail("The time property '#{string}' is missing a unit (one of: years, months, days, hours, minutes).") + end + unless number.to_i.to_s == number + bail("The time property '#{string}' is missing a number.") + end + yesterday.advance(unit.to_sym => number.to_i) end end; end diff --git a/lib/leap_cli/commands/deploy.rb b/lib/leap_cli/commands/deploy.rb index dbbaaba..204be5f 100644 --- a/lib/leap_cli/commands/deploy.rb +++ b/lib/leap_cli/commands/deploy.rb @@ -54,6 +54,8 @@ module LeapCli # compile hiera files for all the nodes in every environment that is # being deployed and only those environments. compile_hiera_files(manager.filter(environments)) + # update server certificates if needed + update_certificates(nodes) ssh_connect(nodes, connect_options(options)) do |ssh| ssh.leap.log :checking, 'node' do -- cgit v1.2.3 From 406a5bc18a5e5733d081c785984f06ad730a8dba Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 2 Feb 2015 14:54:35 -0800 Subject: fix bail! typo --- lib/leap_cli/commands/ca.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/ca.rb b/lib/leap_cli/commands/ca.rb index 785e043..9b3409a 100644 --- a/lib/leap_cli/commands/ca.rb +++ b/lib/leap_cli/commands/ca.rb @@ -503,10 +503,10 @@ module LeapCli; module Commands def yesterday_advance(string) number, unit = string.split(' ') unless ['years', 'months', 'days', 'hours', 'minutes'].include? unit - bail("The time property '#{string}' is missing a unit (one of: years, months, days, hours, minutes).") + bail!("The time property '#{string}' is missing a unit (one of: years, months, days, hours, minutes).") end unless number.to_i.to_s == number - bail("The time property '#{string}' is missing a number.") + bail!("The time property '#{string}' is missing a number.") end yesterday.advance(unit.to_sym => number.to_i) end -- cgit v1.2.3 From c7d5c2798f47ed0a06f0ef57908c556580f72f9c Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 2 Feb 2015 16:41:12 -0800 Subject: more verbose --version (closes #4428) --- lib/leap_cli/commands/pre.rb | 69 +++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 30 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/pre.rb b/lib/leap_cli/commands/pre.rb index 055f3a1..74d7e62 100644 --- a/lib/leap_cli/commands/pre.rb +++ b/lib/leap_cli/commands/pre.rb @@ -28,57 +28,66 @@ module LeapCli; module Commands switch 'color', :negatable => true pre do |global,command,options,args| - # + initialize_leap_cli(true, global) + true + end + + protected + + # + # available options: + # :verbose -- integer log verbosity level + # :log -- log file path + # :color -- true or false, to log in color or not. + # + def initialize_leap_cli(require_provider, options={}) # set verbosity - # - LeapCli.set_log_level(global[:verbose].to_i) + options[:verbose] ||= 1 + LeapCli.set_log_level(options[:verbose].to_i) - # # load Leapfile - # - unless LeapCli.leapfile.load + LeapCli.leapfile.load + if LeapCli.leapfile.valid? + Path.set_platform_path(LeapCli.leapfile.platform_directory_path) + Path.set_provider_path(LeapCli.leapfile.provider_directory_path) + if !Path.provider || !File.directory?(Path.provider) + bail! { log :missing, "provider directory '#{Path.provider}'" } + end + if !Path.platform || !File.directory?(Path.platform) + bail! { log :missing, "platform directory '#{Path.platform}'" } + end + elsif require_provider bail! { log :missing, 'Leapfile in directory tree' } end - Path.set_platform_path(LeapCli.leapfile.platform_directory_path) - Path.set_provider_path(LeapCli.leapfile.provider_directory_path) - if !Path.provider || !File.directory?(Path.provider) - bail! { log :missing, "provider directory '#{Path.provider}'" } - end - if !Path.platform || !File.directory?(Path.platform) - bail! { log :missing, "platform directory '#{Path.platform}'" } - end - # # set log file - # - LeapCli.log_file = global[:log] || LeapCli.leapfile.log + LeapCli.log_file = options[:log] || LeapCli.leapfile.log LeapCli::Util.log_raw(:log) { $0 + ' ' + ORIGINAL_ARGV.join(' ')} log_version - LeapCli.log_in_color = global[:color] - - true + LeapCli.log_in_color = options[:color] end - private - # # add a log entry for the leap command and leap platform versions # def log_version if LeapCli.log_level >= 2 str = "leap command v#{LeapCli::VERSION}" - cli_dir = File.dirname(__FILE__) - if Util.is_git_directory?(cli_dir) - str << " (%s %s)" % [Util.current_git_branch(cli_dir), Util.current_git_commit(cli_dir)] + if Util.is_git_directory?(LEAP_CLI_BASE_DIR) + str << " (%s %s)" % [Util.current_git_branch(LEAP_CLI_BASE_DIR), + Util.current_git_commit(LEAP_CLI_BASE_DIR)] + else + str << " (%s)" % LEAP_CLI_BASE_DIR end log 2, str - str = "leap platform v#{Leap::Platform.version}" - if Util.is_git_directory?(Path.platform) - str << " (%s %s)" % [Util.current_git_branch(Path.platform), Util.current_git_commit(Path.platform)] + if LeapCli.leapfile.valid? + str = "leap platform v#{Leap::Platform.version}" + if Util.is_git_directory?(Path.platform) + str << " (%s %s)" % [Util.current_git_branch(Path.platform), Util.current_git_commit(Path.platform)] + end + log 2, str end - log 2, str end end - end; end -- cgit v1.2.3 From a32c332963e3bca8ab4bd40b636d36a77468e219 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 5 Feb 2015 23:25:18 -0800 Subject: vagrant - fix version calculation when vagrant version has three parts (e.g. 1.1.1) --- lib/leap_cli/commands/vagrant.rb | 91 ++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 51 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/vagrant.rb b/lib/leap_cli/commands/vagrant.rb index 31c7878..5ad43d1 100644 --- a/lib/leap_cli/commands/vagrant.rb +++ b/lib/leap_cli/commands/vagrant.rb @@ -111,32 +111,23 @@ module LeapCli; module Commands def vagrant_setup assert_bin! 'vagrant', 'Vagrant is required for running local virtual machines. Run "sudo apt-get install vagrant".' - version = vagrant_version - case version - when 0..1 - gem_path = assert_run!('vagrant gem which sahara') - if gem_path.nil? || gem_path.empty? || gem_path =~ /^ERROR/ - log :installing, "vagrant plugin 'sahara'" - assert_run! 'vagrant gem install sahara -v 0.0.13' - # (sahara versions above 0.0.13 require vagrant > 1.0) - end - when 2 - unless assert_run!('vagrant plugin list | grep sahara | cat').chars.any? - log :installing, "vagrant plugin 'sahara'" - assert_run! 'vagrant plugin install sahara' - end + if vagrant_version <= Gem::Version.new('1.0.0') + gem_path = assert_run!('vagrant gem which sahara') + if gem_path.nil? || gem_path.empty? || gem_path =~ /^ERROR/ + log :installing, "vagrant plugin 'sahara'" + assert_run! 'vagrant gem install sahara -v 0.0.13' + end + else + unless assert_run!('vagrant plugin list | grep sahara | cat').chars.any? + log :installing, "vagrant plugin 'sahara'" + assert_run! 'vagrant plugin install sahara' + end end create_vagrant_file end def vagrant_version - minor_version = `vagrant --version | rev | cut -d'.' -f 2`.to_i - version = case minor_version - when 1..9 then 2 - when 0 then 1 - else 0 - end - return version + @vagrant_version ||= Gem::Version.new(assert_run!('vagrant --version').split(' ')[1]) end def execute(cmd) @@ -148,38 +139,36 @@ module LeapCli; module Commands lines = [] netmask = IPAddr.new('255.255.255.255').mask(LeapCli.leapfile.vagrant_network.split('/').last).to_s - version = vagrant_version - case version - when 0..1 - lines << %[Vagrant::Config.run do |config|] - manager.each_node do |node| - if node.vagrant? - lines << %[ config.vm.define :#{node.name} do |config|] - lines << %[ config.vm.box = "leap-wheezy"] - lines << %[ config.vm.box_url = "https://downloads.leap.se/platform/vagrant/virtualbox/leap-wheezy.box"] - lines << %[ config.vm.network :hostonly, "#{node.ip_address}", :netmask => "#{netmask}"] - lines << %[ config.vm.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]] - lines << %[ config.vm.customize ["modifyvm", :id, "--name", "#{node.name}"]] - lines << %[ #{leapfile.custom_vagrant_vm_line}] if leapfile.custom_vagrant_vm_line - lines << %[ end] - end + if vagrant_version <= Gem::Version.new('1.1.0') + lines << %[Vagrant::Config.run do |config|] + manager.each_node do |node| + if node.vagrant? + lines << %[ config.vm.define :#{node.name} do |config|] + lines << %[ config.vm.box = "leap-wheezy"] + lines << %[ config.vm.box_url = "https://downloads.leap.se/platform/vagrant/virtualbox/leap-wheezy.box"] + lines << %[ config.vm.network :hostonly, "#{node.ip_address}", :netmask => "#{netmask}"] + lines << %[ config.vm.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]] + lines << %[ config.vm.customize ["modifyvm", :id, "--name", "#{node.name}"]] + lines << %[ #{leapfile.custom_vagrant_vm_line}] if leapfile.custom_vagrant_vm_line + lines << %[ end] end - when 2 - lines << %[Vagrant.configure("2") do |config|] - manager.each_node do |node| - if node.vagrant? - lines << %[ config.vm.define :#{node.name} do |config|] - lines << %[ config.vm.box = "leap-wheezy"] - lines << %[ config.vm.box_url = "https://downloads.leap.se/platform/vagrant/virtualbox/leap-wheezy.box"] - lines << %[ config.vm.network :private_network, ip: "#{node.ip_address}"] - lines << %[ config.vm.provider "virtualbox" do |v|] - lines << %[ v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]] - lines << %[ v.name = "#{node.name}"] - lines << %[ end] - lines << %[ #{leapfile.custom_vagrant_vm_line}] if leapfile.custom_vagrant_vm_line - lines << %[ end] - end + end + else + lines << %[Vagrant.configure("2") do |config|] + manager.each_node do |node| + if node.vagrant? + lines << %[ config.vm.define :#{node.name} do |config|] + lines << %[ config.vm.box = "leap-wheezy"] + lines << %[ config.vm.box_url = "https://downloads.leap.se/platform/vagrant/virtualbox/leap-wheezy.box"] + lines << %[ config.vm.network :private_network, ip: "#{node.ip_address}"] + lines << %[ config.vm.provider "virtualbox" do |v|] + lines << %[ v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]] + lines << %[ v.name = "#{node.name}"] + lines << %[ end] + lines << %[ #{leapfile.custom_vagrant_vm_line}] if leapfile.custom_vagrant_vm_line + lines << %[ end] end + end end lines << %[end] -- cgit v1.2.3 From 5130afca6ff1f5ec49b8abeaccfbe17dec129e32 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 8 Feb 2015 13:01:19 -0800 Subject: pass --info to puppet_command (needed to support logging deploy details) --- lib/leap_cli/commands/deploy.rb | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/deploy.rb b/lib/leap_cli/commands/deploy.rb index 204be5f..a0b7c20 100644 --- a/lib/leap_cli/commands/deploy.rb +++ b/lib/leap_cli/commands/deploy.rb @@ -1,3 +1,4 @@ +require 'etc' module LeapCli module Commands @@ -7,20 +8,17 @@ module LeapCli arg_name 'FILTER' command [:deploy, :d] do |c| - # --fast c.switch :fast, :desc => 'Makes the deploy command faster by skipping some slow steps. A "fast" deploy can be used safely if you recently completed a normal deploy.', :negatable => false - # --sync - c.switch :sync, :desc => "Sync files, but don't actually apply recipes." + c.switch :sync, :desc => "Sync files, but don't actually apply recipes.", :negatable => false - # --force c.switch :force, :desc => 'Deploy even if there is a lockfile.', :negatable => false - # --dev + c.switch :downgrade, :desc => 'Allows deploy to run with an older platform version.', :negatable => false + c.switch :dev, :desc => "Development mode: don't run 'git submodule update' before deploy.", :negatable => false - # --tags c.flag :tags, :desc => 'Specify tags to pass through to puppet (overriding the default).', :arg_name => 'TAG[,TAG]' @@ -71,7 +69,12 @@ module LeapCli end unless options[:sync] ssh.leap.log :applying, "puppet" do - ssh.puppet.apply(:verbosity => [LeapCli.log_level,5].min, :tags => tags(options), :force => options[:force]) + ssh.puppet.apply(:verbosity => [LeapCli.log_level,5].min, + :tags => tags(options), + :force => options[:force], + :info => deploy_info, + :downgrade => options[:downgrade] + ) end end end @@ -297,5 +300,28 @@ module LeapCli return custom_files end + def deploy_info + info = [] + info << "user: %s" % Etc.getpwuid(Process.euid).name + if is_git_directory?(Path.platform) && current_git_branch(Path.platform) != 'master' + info << "platform: %s (%s %s)" % [ + Leap::Platform.version, + current_git_branch(Path.platform), + current_git_commit(Path.platform)[0..4] + ] + else + info << "platform: %s" % Leap::Platform.version + end + if is_git_directory?(LEAP_CLI_BASE_DIR) + info << "leap_cli: %s (%s %s)" % [ + LeapCli::VERSION, + current_git_branch(LEAP_CLI_BASE_DIR), + current_git_commit(LEAP_CLI_BASE_DIR)[0..4] + ] + else + info << "leap_cli: %s" % LeapCli::VERSION + end + info.join(', ') + end end end -- cgit v1.2.3 From 39c8a357ec10b9cb4ecf75324561ed82241e27d6 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 9 Feb 2015 22:44:49 -0800 Subject: more verbose `leap cert update` --- lib/leap_cli/commands/ca.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/ca.rb b/lib/leap_cli/commands/ca.rb index 9b3409a..356e616 100644 --- a/lib/leap_cli/commands/ca.rb +++ b/lib/leap_cli/commands/ca.rb @@ -216,7 +216,7 @@ module LeapCli; module Commands return true end if cert.subject.common_name != node.domain.full - log :updating, "cert for node '#{node.name}' because domain.full has changed" + log :updating, "cert for node '#{node.name}' because domain.full has changed (was #{cert.subject.common_name}, now #{node.domain.full})" return true end cert.openssl_body.extensions.each do |ext| -- cgit v1.2.3 From b1d277f5d58bc5aeef3c024ca7e2b45a0e2edb83 Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 27 Feb 2015 22:19:07 -0800 Subject: added ability to select which dbs to delete with `leap db destroy` --- lib/leap_cli/commands/db.rb | 49 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/db.rb b/lib/leap_cli/commands/db.rb index 3502d7e..55134f5 100644 --- a/lib/leap_cli/commands/db.rb +++ b/lib/leap_cli/commands/db.rb @@ -2,22 +2,30 @@ module LeapCli; module Commands desc 'Database commands.' command :db do |db| - db.desc 'Destroy all the databases. If present, limit to FILTER nodes.' + db.desc 'Destroy one or more databases. If present, limit to FILTER nodes. For example `leap db destroy --db sessions,tokens testing`.' db.arg_name 'FILTER', :optional => true db.command :destroy do |destroy| + destroy.flag :db, :arg_name => "DATABASES", :desc => 'Comma separated list of databases to destroy (no space). Use "--db all" to destroy all databases.', :optional => false destroy.action do |global_options,options,args| - unless global_options[:yes] - say 'You are about to permanently destroy all database data.' - bail! unless agree("Continue? ") - end + dbs = (options[:db]||"").split(',') + bail!('No databases specified') if dbs.empty? nodes = manager.filter(args) if nodes.any? nodes = nodes[:services => 'couchdb'] end if nodes.any? - ssh_connect(nodes, connect_options(options)) do |ssh| - ssh.run('/etc/init.d/bigcouch stop && test ! -z "$(ls /opt/bigcouch/var/lib/ 2> /dev/null)" && rm -r /opt/bigcouch/var/lib/* && echo "db destroyed" || echo "db already destroyed"') - ssh.run('grep ^seq_file /etc/leap/tapicero.yaml | cut -f2 -d\" | xargs rm -v') + unless global_options[:yes] + if dbs.include?('all') + say 'You are about to permanently destroy all database data for nodes [%s].' % nodes.keys.join(', ') + else + say 'You are about to permanently destroy databases [%s] for nodes [%s].' % [dbs.join(', '), nodes.keys.join(', ')] + end + bail! unless agree("Continue? ") + end + if dbs.include?('all') + destroy_all_dbs(nodes) + else + destroy_dbs(nodes, dbs) end say 'You must run `leap deploy` in order to create the databases again.' else @@ -29,4 +37,29 @@ module LeapCli; module Commands private + def destroy_all_dbs(nodes) + ssh_connect(nodes) do |ssh| + ssh.run('/etc/init.d/bigcouch stop && test ! -z "$(ls /opt/bigcouch/var/lib/ 2> /dev/null)" && rm -r /opt/bigcouch/var/lib/* && echo "db destroyed" || echo "db already destroyed"') + ssh.run('grep ^seq_file /etc/leap/tapicero.yaml | cut -f2 -d\" | xargs rm -v') + end + end + + def destroy_dbs(nodes, dbs) + nodes.each_node do |node| + ssh_connect(node) do |ssh| + dbs.each do |db| + ssh.run(DESTROY_DB_COMMAND % {:db => db}) + end + end + end + end + + DESTROY_DB_COMMAND = %{ +if [ 200 = `curl -ns -w "%%{http_code}" -X GET "127.0.0.1:5984/%{db}" -o /dev/null` ]; then + echo "Result from DELETE /%{db}:" `curl -ns -X DELETE "127.0.0.1:5984/%{db}"`; +else + echo "Skipping db '%{db}': it does not exist or has already been deleted."; +fi +} + end; end -- cgit v1.2.3 From 585c00840d17347f54941db36921a4bf4a9f397a Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 31 Mar 2015 14:08:33 -0700 Subject: update tapicero config --- lib/leap_cli/commands/db.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/db.rb b/lib/leap_cli/commands/db.rb index 55134f5..e4fd385 100644 --- a/lib/leap_cli/commands/db.rb +++ b/lib/leap_cli/commands/db.rb @@ -40,7 +40,7 @@ module LeapCli; module Commands def destroy_all_dbs(nodes) ssh_connect(nodes) do |ssh| ssh.run('/etc/init.d/bigcouch stop && test ! -z "$(ls /opt/bigcouch/var/lib/ 2> /dev/null)" && rm -r /opt/bigcouch/var/lib/* && echo "db destroyed" || echo "db already destroyed"') - ssh.run('grep ^seq_file /etc/leap/tapicero.yaml | cut -f2 -d\" | xargs rm -v') + ssh.run('grep ^seq_dir /etc/leap/tapicero.yaml | cut -f2 -d\" | xargs rm -rv') end end -- cgit v1.2.3 From b13d362ac1909bfb14846294577b2d52f63b7abd Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 1 Apr 2015 13:47:54 -0700 Subject: added `leap scp` --- lib/leap_cli/commands/ssh.rb | 100 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 16 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/ssh.rb b/lib/leap_cli/commands/ssh.rb index 40d205e..1a81902 100644 --- a/lib/leap_cli/commands/ssh.rb +++ b/lib/leap_cli/commands/ssh.rb @@ -35,6 +35,33 @@ module LeapCli; module Commands end end + desc 'Secure copy from FILE1 to FILE2. Files are specified as NODE_NAME:FILE_PATH. For local paths, omit "NODE_NAME:".' + arg_name 'FILE1 FILE2' + command :scp do |c| + c.switch :r, :desc => 'Copy recursively' + c.action do |global_options, options, args| + if args.size != 2 + bail!('You must specificy both FILE1 and FILE2') + end + from, to = args + if (from !~ /:/ && to !~ /:/) || (from =~ /:/ && to =~ /:/) + bail!('One FILE must be remote and the other local.') + end + src_node_name = src_file_path = src_node = nil + dst_node_name = dst_file_path = dst_node = nil + if from =~ /:/ + src_node_name, src_file_path = from.split(':') + src_node = get_node_from_args([src_node_name], :include_disabled => true) + dst_file_path = to + else + dst_node_name, dst_file_path = to.split(':') + dst_node = get_node_from_args([dst_node_name], :include_disabled => true) + src_file_path = from + end + exec_scp(options, src_node, src_file_path, dst_node, dst_file_path) + end + end + protected # @@ -78,22 +105,7 @@ module LeapCli; module Commands def exec_ssh(cmd, cli_options, args) node = get_node_from_args(args, :include_disabled => true) port = node.ssh.port - options = [ - "-o 'HostName=#{node.ip_address}'", - # "-o 'HostKeyAlias=#{node.name}'", << oddly incompatible with ports in known_hosts file, so we must not use this or non-standard ports break. - "-o 'GlobalKnownHostsFile=#{path(:known_hosts)}'", - "-o 'UserKnownHostsFile=/dev/null'" - ] - if node.vagrant? - options << "-i #{vagrant_ssh_key_file}" # use the universal vagrant insecure key - options << "-o IdentitiesOnly=yes" # force the use of the insecure vagrant key - options << "-o 'StrictHostKeyChecking=no'" # blindly accept host key and don't save it (since userknownhostsfile is /dev/null) - else - options << "-o 'StrictHostKeyChecking=yes'" - end - if !node.supported_ssh_host_key_algorithms.empty? - options << "-o 'HostKeyAlgorithms=#{node.supported_ssh_host_key_algorithms}'" - end + options = ssh_config(node) username = 'root' if LeapCli.log_level >= 3 options << "-vv" @@ -133,6 +145,62 @@ module LeapCli; module Commands end end + def exec_scp(cli_options, src_node, src_file_path, dst_node, dst_file_path) + node = src_node || dst_node + options = ssh_config(node) + port = node.ssh.port + username = 'root' + options << "-r" if cli_options[:r] + scp = "scp -P #{port} #{options.join(' ')}" + if src_node + command = "#{scp} #{username}@#{src_node.domain.full}:#{src_file_path} #{dst_file_path}" + elsif dst_node + command = "#{scp} #{src_file_path} #{username}@#{dst_node.domain.full}:#{dst_file_path}" + end + log 2, command + + # exec the shell command in a subprocess + pid = fork { exec "#{command}" } + + Signal.trap("SIGINT") do + Process.kill("KILL", pid) + Process.wait(pid) + exit(0) + end + + # wait for shell to exit so we can grab the exit status + _, status = Process.waitpid2(pid) + exit(status.exitstatus) + end + + # + # SSH command line -o options. See `man ssh_config` + # + # NOTES: + # + # The option 'HostKeyAlias=#{node.name}' is oddly incompatible with ports in + # known_hosts file, so we must not use this or non-standard ports break. + # + def ssh_config(node) + options = [ + "-o 'HostName=#{node.ip_address}'", + "-o 'GlobalKnownHostsFile=#{path(:known_hosts)}'", + "-o 'UserKnownHostsFile=/dev/null'" + ] + if node.vagrant? + options << "-i #{vagrant_ssh_key_file}" # use the universal vagrant insecure key + options << "-o IdentitiesOnly=yes" # force the use of the insecure vagrant key + options << "-o 'StrictHostKeyChecking=no'" # blindly accept host key and don't save it + # (since userknownhostsfile is /dev/null) + else + options << "-o 'StrictHostKeyChecking=yes'" + end + if !node.supported_ssh_host_key_algorithms.empty? + options << "-o 'HostKeyAlgorithms=#{node.supported_ssh_host_key_algorithms}'" + end + return options + end + def parse_tunnel_arg(arg) if arg.count(':') == 1 node_name, remote = arg.split(':') -- cgit v1.2.3 From 26842662815d1409400d85275b32789156d50db5 Mon Sep 17 00:00:00 2001 From: varac Date: Tue, 7 Apr 2015 11:14:46 +0200 Subject: make clear that dh file is only needed for VPN --- lib/leap_cli/commands/ca.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/ca.rb b/lib/leap_cli/commands/ca.rb index 356e616..cfa18f5 100644 --- a/lib/leap_cli/commands/ca.rb +++ b/lib/leap_cli/commands/ca.rb @@ -32,7 +32,7 @@ module LeapCli; module Commands end end - cert.desc 'Creates a Diffie-Hellman parameter file.' # (needed for server-side of some TLS connections) + cert.desc 'Creates a Diffie-Hellman parameter file, needed for forward secret OpenVPN ciphers.' # (needed for server-side of some TLS connections) cert.command :dh do |dh| dh.action do |global_options,options,args| long_running do -- cgit v1.2.3 From ddd160afb1fd2c729cf806de879add5a15cafe31 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 8 Apr 2015 18:14:09 -0700 Subject: added `leap history` command to dump the recent deploy history to console --- lib/leap_cli/commands/deploy.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/deploy.rb b/lib/leap_cli/commands/deploy.rb index a0b7c20..394ea61 100644 --- a/lib/leap_cli/commands/deploy.rb +++ b/lib/leap_cli/commands/deploy.rb @@ -84,6 +84,22 @@ module LeapCli end end + desc 'Display recent deployment history for a set of nodes.' + long_desc 'The FILTER can be the name of a node, service, or tag.' + arg_name 'FILTER' + command [:history, :h] do |c| + c.flag :port, :desc => 'Override the default SSH port.', + :arg_name => 'PORT' + c.flag :ip, :desc => 'Override the default SSH IP address.', + :arg_name => 'IPADDRESS' + c.action do |global,options,args| + nodes = manager.filter!(args) + ssh_connect(nodes, connect_options(options)) do |ssh| + ssh.leap.history + end + end + end + private # -- cgit v1.2.3 From 1c58dd5905bdad68df4f57aa3323d95d8bd2db0a Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 27 Apr 2015 09:57:35 -0700 Subject: added --force --- lib/leap_cli/commands/deploy.rb | 65 ++++++++++++++++++++++++++++------------- lib/leap_cli/commands/pre.rb | 14 ++++++--- 2 files changed, 55 insertions(+), 24 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/deploy.rb b/lib/leap_cli/commands/deploy.rb index 394ea61..03240ce 100644 --- a/lib/leap_cli/commands/deploy.rb +++ b/lib/leap_cli/commands/deploy.rb @@ -47,7 +47,7 @@ module LeapCli environments = [nil] end environments.each do |env| - check_platform_pinning(env) + check_platform_pinning(env, global) end # compile hiera files for all the nodes in every environment that is # being deployed and only those environments. @@ -102,6 +102,16 @@ module LeapCli private + def forcible_prompt(forced, msg, prompt) + say(msg) + if forced + log :warning, "continuing anyway because of --force" + else + say "hint: use --force to skip this prompt." + quit!("OK. Bye.") unless agree(prompt) + end + end + # # The currently activated provider.json could have loaded some pinning # information for the platform. If this is the case, refuse to deploy @@ -115,7 +125,7 @@ module LeapCli # "commit": "e1d6280e0a8c565b7fb1a4ed3969ea6fea31a5e2..HEAD" # } # - def check_platform_pinning(environment) + def check_platform_pinning(environment, global_options) provider = manager.env(environment).provider return unless provider['platform'] @@ -133,34 +143,46 @@ module LeapCli # check version if provider.platform['version'] if !Leap::Platform.version_in_range?(provider.platform.version) - say("The platform is pinned to a version range of '#{provider.platform.version}' "+ - "by the `platform.version` property in #{provider_json}, but the platform "+ - "(#{Path.platform}) has version #{Leap::Platform.version}.") - quit!("OK. Bye.") unless agree("Do you really want to deploy from the wrong version? ") + forcible_prompt( + global_options[:force], + "The platform is pinned to a version range of '#{provider.platform.version}' "+ + "by the `platform.version` property in #{provider_json}, but the platform "+ + "(#{Path.platform}) has version #{Leap::Platform.version}.", + "Do you really want to deploy from the wrong version? " + ) end end # check branch if provider.platform['branch'] if !is_git_directory?(Path.platform) - say("The platform is pinned to a particular branch by the `platform.branch` property "+ - "in #{provider_json}, but the platform directory (#{Path.platform}) is not a git repository.") - quit!("OK. Bye.") unless agree("Do you really want to deploy anyway? ") + forcible_prompt( + global_options[:force], + "The platform is pinned to a particular branch by the `platform.branch` property "+ + "in #{provider_json}, but the platform directory (#{Path.platform}) is not a git repository.", + "Do you really want to deploy anyway? " + ) end unless provider.platform.branch == current_git_branch(Path.platform) - say("The platform is pinned to branch '#{provider.platform.branch}' by the `platform.branch` property "+ - "in #{provider_json}, but the current branch is '#{current_git_branch(Path.platform)}' " + - "(for directory '#{Path.platform}')") - quit!("OK. Bye.") unless agree("Do you really want to deploy from the wrong branch? ") + forcible_prompt( + global_options[:force], + "The platform is pinned to branch '#{provider.platform.branch}' by the `platform.branch` property "+ + "in #{provider_json}, but the current branch is '#{current_git_branch(Path.platform)}' " + + "(for directory '#{Path.platform}')", + "Do you really want to deploy from the wrong branch? " + ) end end # check commit if provider.platform['commit'] if !is_git_directory?(Path.platform) - say("The platform is pinned to a particular commit range by the `platform.commit` property "+ - "in #{provider_json}, but the platform directory (#{Path.platform}) is not a git repository.") - quit!("OK. Bye.") unless agree("Do you really want to deploy anyway? ") + forcible_prompt( + global_options[:force], + "The platform is pinned to a particular commit range by the `platform.commit` property "+ + "in #{provider_json}, but the platform directory (#{Path.platform}) is not a git repository.", + "Do you really want to deploy anyway? " + ) end current_commit = current_git_commit(Path.platform) Dir.chdir(Path.platform) do @@ -171,10 +193,13 @@ module LeapCli commit_range = commit_range.split("\n") if !commit_range.include?(current_commit) && provider.platform.commit.split('..').first != current_commit - say("The platform is pinned via the `platform.commit` property in #{provider_json} " + - "to a commit in the range #{provider.platform.commit}, but the current HEAD " + - "(#{current_commit}) is not in that range.") - quit!("OK. Bye.") unless agree("Do you really want to deploy from the wrong commit? ") + forcible_prompt( + global_options[:force], + "The platform is pinned via the `platform.commit` property in #{provider_json} " + + "to a commit in the range #{provider.platform.commit}, but the current HEAD " + + "(#{current_commit}) is not in that range.", + "Do you really want to deploy from the wrong commit? " + ) end end end diff --git a/lib/leap_cli/commands/pre.rb b/lib/leap_cli/commands/pre.rb index 74d7e62..3b316a4 100644 --- a/lib/leap_cli/commands/pre.rb +++ b/lib/leap_cli/commands/pre.rb @@ -9,25 +9,31 @@ module LeapCli; module Commands default_value '1' flag [:v, :verbose] - desc 'Override default log file' + desc 'Override default log file.' arg_name 'FILE' default_value nil flag :log - desc 'Display version number and exit' + desc 'Display version number and exit.' switch :version, :negatable => false - desc 'Skip prompts and assume "yes"' + desc 'Skip prompts and assume "yes".' switch :yes, :negatable => false + desc 'Like --yes, but also skip prompts that are potentially dangerous to skip.' + switch :force, :negatable => false + desc 'Print full stack trace for exceptions and load `debugger` gem if installed.' switch [:d, :debug], :negatable => false - desc 'Disable colors in output' + desc 'Disable colors in output.' default_value true switch 'color', :negatable => true pre do |global,command,options,args| + if global[:force] + global[:yes] = true + end initialize_leap_cli(true, global) true end -- cgit v1.2.3 From 9a6b198873823d8deb6d405222a0eca28312ae0a Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 28 Apr 2015 10:04:43 -0700 Subject: fail to compile if you pass it an invalid environment name --- lib/leap_cli/commands/compile.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/compile.rb b/lib/leap_cli/commands/compile.rb index 78d7520..cfafc74 100644 --- a/lib/leap_cli/commands/compile.rb +++ b/lib/leap_cli/commands/compile.rb @@ -12,8 +12,12 @@ module LeapCli if !LeapCli.leapfile.environment.nil? && !environment.nil? && environment != LeapCli.leapfile.environment bail! "You cannot specify an ENVIRONMENT argument while the environment is pinned." end - if environment && manager.environment_names.include?(environment) - compile_hiera_files(manager.filter([environment])) + if environment + if manager.environment_names.include?(environment) + compile_hiera_files(manager.filter([environment])) + else + bail! "There is no environment named `#{environment}`." + end else compile_hiera_files(manager.filter) end -- cgit v1.2.3 From 6b35bbbe1a9909c737c1cd53edcfc47af0ad063c Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 4 May 2015 16:17:01 -0700 Subject: make gpgme optional --- lib/leap_cli/commands/user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/user.rb b/lib/leap_cli/commands/user.rb index 6c33878..480e9a9 100644 --- a/lib/leap_cli/commands/user.rb +++ b/lib/leap_cli/commands/user.rb @@ -100,9 +100,9 @@ module LeapCli # def pick_pgp_key begin - return unless `which gpg`.strip.any? require 'gpgme' rescue LoadError + log "Skipping OpenPGP setup because gpgme is not installed." return end -- cgit v1.2.3 From ab3184ff6dea960e347da299deaabeb23e2cf86e Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 5 May 2015 14:58:03 -0700 Subject: add --force to 'leap cert csr' --- lib/leap_cli/commands/ca.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/ca.rb b/lib/leap_cli/commands/ca.rb index cfa18f5..d5c6240 100644 --- a/lib/leap_cli/commands/ca.rb +++ b/lib/leap_cli/commands/ca.rb @@ -87,7 +87,11 @@ module LeapCli; module Commands assert_config! 'provider.ca.server_certificates.bit_size' assert_config! 'provider.ca.server_certificates.digest' domain = options[:domain] || provider.domain - assert_files_missing! [:commercial_key, domain], [:commercial_csr, domain], :msg => 'If you really want to create a new key and CSR, remove these files first.' + + unless global_options[:force] + assert_files_missing! [:commercial_key, domain], [:commercial_csr, domain], + :msg => 'If you really want to create a new key and CSR, remove these files first or run with --force.' + end server_certificates = provider.ca.server_certificates -- cgit v1.2.3 From 61fdf41087b480db12720df5d5beadd32992475a Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Tue, 5 May 2015 20:47:30 +0200 Subject: Changed location of local nodes basebox to hashicorp. If you already have local nodes, basebox will not be updated, however when adding new local nodes, they will be checking for updates of the basebox. --- lib/leap_cli/commands/vagrant.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/vagrant.rb b/lib/leap_cli/commands/vagrant.rb index 5ad43d1..e652e8b 100644 --- a/lib/leap_cli/commands/vagrant.rb +++ b/lib/leap_cli/commands/vagrant.rb @@ -144,8 +144,7 @@ module LeapCli; module Commands manager.each_node do |node| if node.vagrant? lines << %[ config.vm.define :#{node.name} do |config|] - lines << %[ config.vm.box = "leap-wheezy"] - lines << %[ config.vm.box_url = "https://downloads.leap.se/platform/vagrant/virtualbox/leap-wheezy.box"] + lines << %[ config.vm.box = "LEAP/wheezy"] lines << %[ config.vm.network :hostonly, "#{node.ip_address}", :netmask => "#{netmask}"] lines << %[ config.vm.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]] lines << %[ config.vm.customize ["modifyvm", :id, "--name", "#{node.name}"]] @@ -158,8 +157,7 @@ module LeapCli; module Commands manager.each_node do |node| if node.vagrant? lines << %[ config.vm.define :#{node.name} do |config|] - lines << %[ config.vm.box = "leap-wheezy"] - lines << %[ config.vm.box_url = "https://downloads.leap.se/platform/vagrant/virtualbox/leap-wheezy.box"] + lines << %[ config.vm.box = "LEAP/wheezy"] lines << %[ config.vm.network :private_network, ip: "#{node.ip_address}"] lines << %[ config.vm.provider "virtualbox" do |v|] lines << %[ v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]] -- cgit v1.2.3