leap_cli 1.5.6 → 1.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/leap +29 -6
- data/lib/leap/platform.rb +36 -1
- data/lib/leap_cli/commands/ca.rb +97 -20
- data/lib/leap_cli/commands/compile.rb +49 -8
- data/lib/leap_cli/commands/db.rb +13 -4
- data/lib/leap_cli/commands/deploy.rb +138 -29
- data/lib/leap_cli/commands/env.rb +76 -0
- data/lib/leap_cli/commands/facts.rb +10 -3
- data/lib/leap_cli/commands/inspect.rb +2 -2
- data/lib/leap_cli/commands/list.rb +10 -10
- data/lib/leap_cli/commands/node.rb +7 -132
- data/lib/leap_cli/commands/node_init.rb +169 -0
- data/lib/leap_cli/commands/pre.rb +4 -27
- data/lib/leap_cli/commands/ssh.rb +152 -0
- data/lib/leap_cli/commands/test.rb +22 -13
- data/lib/leap_cli/commands/user.rb +12 -4
- data/lib/leap_cli/commands/vagrant.rb +4 -4
- data/lib/leap_cli/config/filter.rb +175 -0
- data/lib/leap_cli/config/manager.rb +130 -61
- data/lib/leap_cli/config/node.rb +32 -0
- data/lib/leap_cli/config/object.rb +69 -44
- data/lib/leap_cli/config/object_list.rb +44 -39
- data/lib/leap_cli/config/secrets.rb +24 -12
- data/lib/leap_cli/config/tag.rb +7 -0
- data/lib/{core_ext → leap_cli/core_ext}/boolean.rb +0 -0
- data/lib/{core_ext → leap_cli/core_ext}/hash.rb +0 -0
- data/lib/{core_ext → leap_cli/core_ext}/json.rb +0 -0
- data/lib/{core_ext → leap_cli/core_ext}/nil.rb +0 -0
- data/lib/{core_ext → leap_cli/core_ext}/string.rb +0 -0
- data/lib/leap_cli/core_ext/yaml.rb +29 -0
- data/lib/leap_cli/exceptions.rb +24 -0
- data/lib/leap_cli/leapfile.rb +60 -10
- data/lib/{lib_ext → leap_cli/lib_ext}/capistrano_connections.rb +0 -0
- data/lib/{lib_ext → leap_cli/lib_ext}/gli.rb +0 -0
- data/lib/leap_cli/log.rb +1 -1
- data/lib/leap_cli/logger.rb +18 -1
- data/lib/leap_cli/markdown_document_listener.rb +1 -1
- data/lib/leap_cli/override/json.rb +11 -0
- data/lib/leap_cli/path.rb +20 -6
- data/lib/leap_cli/remote/leap_plugin.rb +2 -2
- data/lib/leap_cli/remote/puppet_plugin.rb +1 -1
- data/lib/leap_cli/remote/rsync_plugin.rb +1 -1
- data/lib/leap_cli/remote/tasks.rb +1 -1
- data/lib/leap_cli/ssh_key.rb +63 -1
- data/lib/leap_cli/util/remote_command.rb +19 -2
- data/lib/leap_cli/util/secret.rb +1 -1
- data/lib/leap_cli/util/x509.rb +3 -2
- data/lib/leap_cli/util.rb +11 -3
- data/lib/leap_cli/version.rb +2 -2
- data/lib/leap_cli.rb +24 -14
- data/vendor/certificate_authority/lib/certificate_authority/certificate.rb +85 -29
- data/vendor/certificate_authority/lib/certificate_authority/distinguished_name.rb +5 -0
- data/vendor/certificate_authority/lib/certificate_authority/extensions.rb +406 -41
- data/vendor/certificate_authority/lib/certificate_authority/key_material.rb +0 -34
- data/vendor/certificate_authority/lib/certificate_authority/serial_number.rb +6 -0
- data/vendor/certificate_authority/lib/certificate_authority/signing_request.rb +36 -1
- metadata +25 -24
- data/lib/leap_cli/commands/shell.rb +0 -89
- data/lib/leap_cli/config/macros.rb +0 -430
- data/lib/leap_cli/constants.rb +0 -7
- data/lib/leap_cli/requirements.rb +0 -19
- data/lib/lib_ext/markdown_document_listener.rb +0 -122
data/bin/leap
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
if ARGV.include?('--debug')
|
4
|
-
|
3
|
+
if ARGV.include?('--debug') || ARGV.include?('-d')
|
4
|
+
DEBUG=true
|
5
|
+
begin
|
6
|
+
require 'debugger'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
else
|
10
|
+
DEBUG=false
|
5
11
|
end
|
6
12
|
|
7
13
|
begin
|
@@ -18,7 +24,6 @@ rescue LoadError
|
|
18
24
|
# This allows you to run the command directly while developing the gem, and also lets you
|
19
25
|
# run from anywhere (I like to link 'bin/leap' to /usr/local/bin/leap).
|
20
26
|
#
|
21
|
-
require 'rubygems'
|
22
27
|
base_dir = File.expand_path('..', File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__))
|
23
28
|
require File.join(base_dir, 'lib','leap_cli','load_paths')
|
24
29
|
require 'leap_cli'
|
@@ -27,7 +32,7 @@ end
|
|
27
32
|
require 'gli'
|
28
33
|
require 'highline'
|
29
34
|
require 'forwardable'
|
30
|
-
require 'lib_ext/gli' # our custom extensions to gli
|
35
|
+
require 'leap_cli/lib_ext/gli' # our custom extensions to gli
|
31
36
|
|
32
37
|
#
|
33
38
|
# Typically, GLI and Highline methods are loaded into the global namespace.
|
@@ -78,9 +83,27 @@ module LeapCli::Commands
|
|
78
83
|
exit(0)
|
79
84
|
end
|
80
85
|
|
86
|
+
# disable GLI error catching
|
87
|
+
ENV['GLI_DEBUG'] = "true"
|
88
|
+
def error_message(msg)
|
89
|
+
end
|
90
|
+
|
81
91
|
# load commands and run
|
82
92
|
commands_from('leap_cli/commands')
|
83
93
|
ORIGINAL_ARGV = ARGV.dup
|
84
|
-
|
85
|
-
|
94
|
+
begin
|
95
|
+
exit_status = run(ARGV)
|
96
|
+
exit(LeapCli::Util.exit_status || exit_status)
|
97
|
+
rescue StandardError => exc
|
98
|
+
if exc.respond_to? :log
|
99
|
+
exc.log
|
100
|
+
else
|
101
|
+
puts
|
102
|
+
LeapCli.log :error, "%s: %s" % [exc.class, exc.message]
|
103
|
+
puts
|
104
|
+
end
|
105
|
+
if DEBUG
|
106
|
+
raise exc
|
107
|
+
end
|
108
|
+
end
|
86
109
|
end
|
data/lib/leap/platform.rb
CHANGED
@@ -16,10 +16,25 @@ module Leap
|
|
16
16
|
attr_accessor :monitor_username
|
17
17
|
attr_accessor :reserved_usernames
|
18
18
|
|
19
|
+
attr_accessor :hiera_path
|
20
|
+
attr_accessor :files_dir
|
21
|
+
attr_accessor :leap_dir
|
22
|
+
attr_accessor :init_path
|
23
|
+
|
24
|
+
attr_accessor :default_puppet_tags
|
25
|
+
|
19
26
|
def define(&block)
|
20
|
-
# some
|
27
|
+
# some defaults:
|
21
28
|
@reserved_usernames = []
|
29
|
+
@hiera_path = '/etc/leap/hiera.yaml'
|
30
|
+
@leap_dir = '/srv/leap'
|
31
|
+
@files_dir = '/srv/leap/files'
|
32
|
+
@init_path = '/srv/leap/initialized'
|
33
|
+
@default_puppet_tags = []
|
34
|
+
|
22
35
|
self.instance_eval(&block)
|
36
|
+
|
37
|
+
@version ||= Versionomy.parse("0.0")
|
23
38
|
end
|
24
39
|
|
25
40
|
def version=(version)
|
@@ -44,10 +59,30 @@ module Leap
|
|
44
59
|
# return true if the platform version is within the specified range.
|
45
60
|
#
|
46
61
|
def version_in_range?(range)
|
62
|
+
if range.is_a? String
|
63
|
+
range = range.split('..')
|
64
|
+
end
|
47
65
|
minimum_platform_version = Versionomy.parse(range.first)
|
48
66
|
maximum_platform_version = Versionomy.parse(range.last)
|
49
67
|
@version >= minimum_platform_version && @version <= maximum_platform_version
|
50
68
|
end
|
69
|
+
|
70
|
+
def major_version
|
71
|
+
if @version.major == 0
|
72
|
+
"#{@version.major}.#{@version.minor}"
|
73
|
+
else
|
74
|
+
@version.major
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def method_missing(method, *args)
|
79
|
+
puts
|
80
|
+
puts "WARNING:"
|
81
|
+
puts " leap_cli is out of date and does not understand `#{method}`."
|
82
|
+
puts " called from: #{caller.first}"
|
83
|
+
puts " please upgrade to a newer leap_cli"
|
84
|
+
end
|
85
|
+
|
51
86
|
end
|
52
87
|
|
53
88
|
end
|
data/lib/leap_cli/commands/ca.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
autoload :OpenSSL, 'openssl'
|
2
|
+
autoload :CertificateAuthority, 'certificate_authority'
|
3
|
+
autoload :Date, 'date'
|
4
4
|
require 'digest/md5'
|
5
5
|
|
6
6
|
module LeapCli; module Commands
|
@@ -36,6 +36,7 @@ module LeapCli; module Commands
|
|
36
36
|
|
37
37
|
nodes = manager.filter!(args)
|
38
38
|
nodes.each_node do |node|
|
39
|
+
warn_if_commercial_cert_will_soon_expire(node)
|
39
40
|
if !node.x509.use
|
40
41
|
remove_file!([:node_x509_key, node.name])
|
41
42
|
remove_file!([:node_x509_cert, node.name])
|
@@ -81,9 +82,19 @@ module LeapCli; module Commands
|
|
81
82
|
# http://www.redkestrel.co.uk/Articles/CSR.html
|
82
83
|
#
|
83
84
|
cert.desc "Creates a CSR for use in buying a commercial X.509 certificate."
|
84
|
-
cert.long_desc "Unless specified, the CSR is created for the provider's primary domain.
|
85
|
+
cert.long_desc "Unless specified, the CSR is created for the provider's primary domain. "+
|
86
|
+
"The properties used for this CSR come from `provider.ca.server_certificates`, "+
|
87
|
+
"but may be overridden here."
|
85
88
|
cert.command :csr do |csr|
|
86
89
|
csr.flag 'domain', :arg_name => 'DOMAIN', :desc => 'Specify what domain to create the CSR for.'
|
90
|
+
csr.flag ['organization', 'O'], :arg_name => 'ORGANIZATION', :desc => "Override default O in distinguished name."
|
91
|
+
csr.flag ['unit', 'OU'], :arg_name => 'UNIT', :desc => "Set OU in distinguished name."
|
92
|
+
csr.flag 'email', :arg_name => 'EMAIL', :desc => "Set emailAddress in distinguished name."
|
93
|
+
csr.flag ['locality', 'L'], :arg_name => 'LOCALITY', :desc => "Set L in distinguished name."
|
94
|
+
csr.flag ['state', 'ST'], :arg_name => 'STATE', :desc => "Set ST in distinguished name."
|
95
|
+
csr.flag ['country', 'C'], :arg_name => 'COUNTRY', :desc => "Set C in distinguished name."
|
96
|
+
csr.flag :bits, :arg_name => 'BITS', :desc => "Override default certificate bit length"
|
97
|
+
csr.flag :digest, :arg_name => 'DIGEST', :desc => "Override default signature digest"
|
87
98
|
csr.action do |global_options,options,args|
|
88
99
|
assert_config! 'provider.domain'
|
89
100
|
assert_config! 'provider.name'
|
@@ -97,24 +108,25 @@ module LeapCli; module Commands
|
|
97
108
|
|
98
109
|
# RSA key
|
99
110
|
keypair = CertificateAuthority::MemoryKeyMaterial.new
|
100
|
-
|
101
|
-
|
111
|
+
bit_size = (options[:bits] || server_certificates.bit_size).to_i
|
112
|
+
log :generating, "%s bit RSA key" % bit_size do
|
113
|
+
keypair.generate_key(bit_size)
|
102
114
|
write_file! [:commercial_key, domain], keypair.private_key.to_pem
|
103
115
|
end
|
104
116
|
|
105
117
|
# CSR
|
106
118
|
dn = CertificateAuthority::DistinguishedName.new
|
107
|
-
|
108
|
-
dn.
|
109
|
-
dn.
|
110
|
-
dn.
|
111
|
-
dn.
|
112
|
-
dn.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
csr
|
119
|
+
dn.common_name = domain
|
120
|
+
dn.organization = options[:organization] || provider.name[provider.default_language]
|
121
|
+
dn.ou = options[:organizational_unit] # optional
|
122
|
+
dn.email_address = options[:email] # optional
|
123
|
+
dn.country = options[:country] || server_certificates['country'] # optional
|
124
|
+
dn.state = options[:state] || server_certificates['state'] # optional
|
125
|
+
dn.locality = options[:locality] || server_certificates['locality'] # optional
|
126
|
+
|
127
|
+
digest = options[:digest] || server_certificates.digest
|
128
|
+
log :generating, "CSR with #{digest} digest and #{print_dn(dn)}" do
|
129
|
+
csr = create_csr(dn, keypair, digest)
|
118
130
|
request = csr.to_x509_csr
|
119
131
|
write_file! [:commercial_csr, domain], csr.to_pem
|
120
132
|
end
|
@@ -191,7 +203,7 @@ module LeapCli; module Commands
|
|
191
203
|
return true
|
192
204
|
else
|
193
205
|
cert = load_certificate_file([:node_x509_cert, node.name])
|
194
|
-
if cert.not_after < months_from_yesterday(
|
206
|
+
if cert.not_after < months_from_yesterday(2)
|
195
207
|
log :updating, "cert for node '#{node.name}' because it will expire soon"
|
196
208
|
return true
|
197
209
|
end
|
@@ -208,11 +220,12 @@ module LeapCli; module Commands
|
|
208
220
|
ips << $1 if value =~ /^IP Address:(.*)$/
|
209
221
|
dns_names << $1 if value =~ /^DNS:(.*)$/
|
210
222
|
end
|
223
|
+
dns_names.sort!
|
211
224
|
if ips.first != node.ip_address
|
212
225
|
log :updating, "cert for node '#{node.name}' because ip_address has changed (from #{ips.first} to #{node.ip_address})"
|
213
226
|
return true
|
214
227
|
elsif dns_names != dns_names_for_node(node)
|
215
|
-
log :updating, "cert for node '#{node.name}' because domain name aliases have changed
|
228
|
+
log :updating, "cert for node '#{node.name}' because domain name aliases have changed\n from: #{dns_names.inspect}\n to: #{dns_names_for_node(node).inspect})"
|
216
229
|
return true
|
217
230
|
end
|
218
231
|
end
|
@@ -221,6 +234,22 @@ module LeapCli; module Commands
|
|
221
234
|
return false
|
222
235
|
end
|
223
236
|
|
237
|
+
def warn_if_commercial_cert_will_soon_expire(node)
|
238
|
+
dns_names_for_node(node).each do |domain|
|
239
|
+
if file_exists?([:commercial_cert, domain])
|
240
|
+
cert = load_certificate_file([:commercial_cert, domain])
|
241
|
+
path = Path.relative_path([:commercial_cert, domain])
|
242
|
+
if cert.not_after < Time.now.utc
|
243
|
+
log :error, "the commercial certificate '#{path}' has EXPIRED! " +
|
244
|
+
"You should renew it with `leap cert csr --domain #{domain}`."
|
245
|
+
elsif cert.not_after < months_from_yesterday(2)
|
246
|
+
log :warning, "the commercial certificate '#{path}' will expire soon. "+
|
247
|
+
"You should renew it with `leap cert csr --domain #{domain}`."
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
224
253
|
def generate_cert_for_node(node)
|
225
254
|
return if node.x509.use == false
|
226
255
|
|
@@ -261,6 +290,43 @@ module LeapCli; module Commands
|
|
261
290
|
yield cert.key_material.private_key.to_pem, cert.to_pem
|
262
291
|
end
|
263
292
|
|
293
|
+
#
|
294
|
+
# creates a CSR and returns it.
|
295
|
+
# with the correct extReq attribute so that the CA
|
296
|
+
# doens't generate certs with extensions we don't want.
|
297
|
+
#
|
298
|
+
def create_csr(dn, keypair, digest)
|
299
|
+
csr = CertificateAuthority::SigningRequest.new
|
300
|
+
csr.distinguished_name = dn
|
301
|
+
csr.key_material = keypair
|
302
|
+
csr.digest = digest
|
303
|
+
|
304
|
+
# define extensions manually (library doesn't support setting these on CSRs)
|
305
|
+
extensions = []
|
306
|
+
extensions << CertificateAuthority::Extensions::BasicConstraints.new.tap {|basic|
|
307
|
+
basic.ca = false
|
308
|
+
}
|
309
|
+
extensions << CertificateAuthority::Extensions::KeyUsage.new.tap {|keyusage|
|
310
|
+
keyusage.usage = ["digitalSignature", "keyEncipherment"]
|
311
|
+
}
|
312
|
+
extensions << CertificateAuthority::Extensions::ExtendedKeyUsage.new.tap {|extkeyusage|
|
313
|
+
extkeyusage.usage = [ "serverAuth"]
|
314
|
+
}
|
315
|
+
|
316
|
+
# convert extensions to attribute 'extReq'
|
317
|
+
# aka "Requested Extensions"
|
318
|
+
factory = OpenSSL::X509::ExtensionFactory.new
|
319
|
+
attrval = OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence(
|
320
|
+
extensions.map{|e| factory.create_ext(e.openssl_identifier, e.to_s, e.critical)}
|
321
|
+
)])
|
322
|
+
attrs = [
|
323
|
+
OpenSSL::X509::Attribute.new("extReq", attrval),
|
324
|
+
]
|
325
|
+
csr.attributes = attrs
|
326
|
+
|
327
|
+
return csr
|
328
|
+
end
|
329
|
+
|
264
330
|
def ca_root
|
265
331
|
@ca_root ||= begin
|
266
332
|
load_certificate_file(:ca_cert, :ca_key)
|
@@ -381,8 +447,10 @@ module LeapCli; module Commands
|
|
381
447
|
names = [node.domain.internal, node.domain.full]
|
382
448
|
if node['dns'] && node.dns['aliases'] && node.dns.aliases.any?
|
383
449
|
names += node.dns.aliases
|
384
|
-
names.compact!
|
385
450
|
end
|
451
|
+
names.compact!
|
452
|
+
names.sort!
|
453
|
+
names.uniq!
|
386
454
|
return names
|
387
455
|
end
|
388
456
|
|
@@ -403,6 +471,15 @@ module LeapCli; module Commands
|
|
403
471
|
cert_serial_number(domain_name).to_s(36)
|
404
472
|
end
|
405
473
|
|
474
|
+
# prints CertificateAuthority::DistinguishedName fields
|
475
|
+
def print_dn(dn)
|
476
|
+
fields = {}
|
477
|
+
[:common_name, :locality, :state, :country, :organization, :organizational_unit, :email_address].each do |attr|
|
478
|
+
fields[attr] = dn.send(attr) if dn.send(attr)
|
479
|
+
end
|
480
|
+
fields.inspect
|
481
|
+
end
|
482
|
+
|
406
483
|
##
|
407
484
|
## TIME HELPERS
|
408
485
|
##
|
@@ -3,11 +3,20 @@ module LeapCli
|
|
3
3
|
module Commands
|
4
4
|
|
5
5
|
desc "Compile generated files."
|
6
|
-
command :compile do |c|
|
6
|
+
command [:compile, :c] do |c|
|
7
7
|
c.desc 'Compiles node configuration files into hiera files used for deployment.'
|
8
|
+
c.arg_name 'ENVIRONMENT', :optional => true
|
8
9
|
c.command :all do |all|
|
9
10
|
all.action do |global_options,options,args|
|
10
|
-
|
11
|
+
environment = args.first
|
12
|
+
if !LeapCli.leapfile.environment.nil? && !environment.nil? && environment != LeapCli.leapfile.environment
|
13
|
+
bail! "You cannot specify an ENVIRONMENT argument while the environment is pinned."
|
14
|
+
end
|
15
|
+
if environment && manager.environment_names.include?(environment)
|
16
|
+
compile_hiera_files(manager.filter([environment]))
|
17
|
+
else
|
18
|
+
compile_hiera_files(manager.filter)
|
19
|
+
end
|
11
20
|
end
|
12
21
|
end
|
13
22
|
|
@@ -29,7 +38,10 @@ module LeapCli
|
|
29
38
|
|
30
39
|
# export generated files
|
31
40
|
manager.export_nodes(nodes)
|
32
|
-
|
41
|
+
# a "clean" export of secrets will also remove keys that are no longer used,
|
42
|
+
# but this should not be done if we are not examining all possible nodes.
|
43
|
+
clean_export = nodes.nil?
|
44
|
+
manager.export_secrets(clean_export)
|
33
45
|
end
|
34
46
|
|
35
47
|
def update_compiled_ssh_configs
|
@@ -50,14 +62,16 @@ module LeapCli
|
|
50
62
|
# keys, and every monitor node has a copy of the private monitor key.
|
51
63
|
#
|
52
64
|
def generate_monitor_ssh_keys
|
53
|
-
priv_key_file = :monitor_priv_key
|
54
|
-
pub_key_file = :monitor_pub_key
|
65
|
+
priv_key_file = path(:monitor_priv_key)
|
66
|
+
pub_key_file = path(:monitor_pub_key)
|
55
67
|
unless file_exists?(priv_key_file, pub_key_file)
|
56
|
-
|
68
|
+
ensure_dir(File.dirname(priv_key_file))
|
69
|
+
ensure_dir(File.dirname(pub_key_file))
|
70
|
+
cmd = %(ssh-keygen -N '' -C 'monitor' -t rsa -b 4096 -f '%s') % priv_key_file
|
57
71
|
assert_run! cmd
|
58
72
|
if file_exists?(priv_key_file, pub_key_file)
|
59
|
-
log :created,
|
60
|
-
log :created,
|
73
|
+
log :created, priv_key_file
|
74
|
+
log :created, pub_key_file
|
61
75
|
else
|
62
76
|
log :failed, 'to create monitor ssh keys'
|
63
77
|
end
|
@@ -75,6 +89,9 @@ module LeapCli
|
|
75
89
|
if keys.empty?
|
76
90
|
bail! "You must have at least one public SSH user key configured in order to proceed. See `leap help add-user`."
|
77
91
|
end
|
92
|
+
if file_exists?(path(:monitor_pub_key))
|
93
|
+
keys << path(:monitor_pub_key)
|
94
|
+
end
|
78
95
|
keys.sort.each do |keyfile|
|
79
96
|
ssh_type, ssh_key = File.read(keyfile).strip.split(" ")
|
80
97
|
buffer << ssh_type
|
@@ -87,6 +104,30 @@ module LeapCli
|
|
87
104
|
write_file!(:authorized_keys, buffer.string)
|
88
105
|
end
|
89
106
|
|
107
|
+
#
|
108
|
+
# generates the known_hosts file.
|
109
|
+
#
|
110
|
+
# we do a 'late' binding on the hostnames and ip part of the ssh pub key record in order to allow
|
111
|
+
# for the possibility that the hostnames or ip has changed in the node configuration.
|
112
|
+
#
|
113
|
+
def update_known_hosts
|
114
|
+
buffer = StringIO.new
|
115
|
+
buffer << "#\n"
|
116
|
+
buffer << "# This file is automatically generated by the command `leap`. You should NOT modify this file.\n"
|
117
|
+
buffer << "# Instead, rerun `leap node init` on whatever node is causing SSH problems.\n"
|
118
|
+
buffer << "#\n"
|
119
|
+
manager.nodes.keys.sort.each do |node_name|
|
120
|
+
node = manager.nodes[node_name]
|
121
|
+
hostnames = [node.name, node.domain.internal, node.domain.full, node.ip_address].join(',')
|
122
|
+
pub_key = read_file([:node_ssh_pub_key,node.name])
|
123
|
+
if pub_key
|
124
|
+
buffer << [hostnames, pub_key].join(' ')
|
125
|
+
buffer << "\n"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
write_file!(:known_hosts, buffer.string)
|
129
|
+
end
|
130
|
+
|
90
131
|
##
|
91
132
|
## ZONE FILE
|
92
133
|
##
|
data/lib/leap_cli/commands/db.rb
CHANGED
@@ -2,14 +2,23 @@ module LeapCli; module Commands
|
|
2
2
|
|
3
3
|
desc 'Database commands.'
|
4
4
|
command :db do |db|
|
5
|
-
db.desc 'Destroy all the databases.'
|
5
|
+
db.desc 'Destroy all the databases. If present, limit to FILTER nodes.'
|
6
|
+
db.arg_name 'FILTER', :optional => true
|
6
7
|
db.command :destroy do |destroy|
|
7
8
|
destroy.action do |global_options,options,args|
|
8
9
|
say 'You are about to permanently destroy all database data.'
|
9
10
|
return unless agree("Continue? ")
|
10
|
-
nodes = manager.
|
11
|
-
|
12
|
-
|
11
|
+
nodes = manager.filter(args)
|
12
|
+
if nodes.any?
|
13
|
+
nodes = nodes[:services => 'couchdb']
|
14
|
+
end
|
15
|
+
if nodes.any?
|
16
|
+
ssh_connect(nodes, connect_options(options)) do |ssh|
|
17
|
+
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"')
|
18
|
+
ssh.run('grep ^seq_file /etc/leap/tapicero.yaml | cut -f2 -d\" | xargs rm -v')
|
19
|
+
end
|
20
|
+
else
|
21
|
+
say 'No nodes'
|
13
22
|
end
|
14
23
|
end
|
15
24
|
end
|