leap_cli 1.8.1 → 1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/bin/leap +6 -12
  3. data/lib/leap_cli.rb +3 -23
  4. data/lib/leap_cli/bootstrap.rb +36 -12
  5. data/lib/leap_cli/commands/common.rb +88 -46
  6. data/lib/leap_cli/commands/new.rb +24 -17
  7. data/lib/leap_cli/commands/pre.rb +3 -1
  8. data/lib/leap_cli/core_ext/hash.rb +19 -0
  9. data/lib/leap_cli/leapfile.rb +47 -32
  10. data/lib/leap_cli/log.rb +196 -88
  11. data/lib/leap_cli/path.rb +5 -5
  12. data/lib/leap_cli/util.rb +28 -18
  13. data/lib/leap_cli/version.rb +8 -3
  14. data/vendor/acme-client/lib/acme-client.rb +1 -0
  15. data/vendor/acme-client/lib/acme/client.rb +122 -0
  16. data/vendor/acme-client/lib/acme/client/certificate.rb +30 -0
  17. data/vendor/acme-client/lib/acme/client/certificate_request.rb +111 -0
  18. data/vendor/acme-client/lib/acme/client/crypto.rb +98 -0
  19. data/vendor/acme-client/lib/acme/client/error.rb +16 -0
  20. data/vendor/acme-client/lib/acme/client/faraday_middleware.rb +123 -0
  21. data/vendor/acme-client/lib/acme/client/resources.rb +5 -0
  22. data/vendor/acme-client/lib/acme/client/resources/authorization.rb +44 -0
  23. data/vendor/acme-client/lib/acme/client/resources/challenges.rb +6 -0
  24. data/vendor/acme-client/lib/acme/client/resources/challenges/base.rb +43 -0
  25. data/vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb +19 -0
  26. data/vendor/acme-client/lib/acme/client/resources/challenges/http01.rb +18 -0
  27. data/vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb +24 -0
  28. data/vendor/acme-client/lib/acme/client/resources/registration.rb +37 -0
  29. data/vendor/acme-client/lib/acme/client/self_sign_certificate.rb +60 -0
  30. data/vendor/acme-client/lib/acme/client/version.rb +7 -0
  31. data/vendor/base32/lib/base32.rb +67 -0
  32. data/vendor/certificate_authority/lib/certificate_authority.rb +2 -1
  33. data/vendor/certificate_authority/lib/certificate_authority/certificate.rb +4 -4
  34. data/vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb +7 -5
  35. data/vendor/certificate_authority/lib/certificate_authority/core_extensions.rb +46 -0
  36. data/vendor/certificate_authority/lib/certificate_authority/distinguished_name.rb +6 -2
  37. data/vendor/certificate_authority/lib/certificate_authority/extensions.rb +10 -3
  38. data/vendor/certificate_authority/lib/certificate_authority/key_material.rb +11 -9
  39. data/vendor/certificate_authority/lib/certificate_authority/ocsp_handler.rb +3 -3
  40. data/vendor/certificate_authority/lib/certificate_authority/pkcs11_key_material.rb +0 -2
  41. data/vendor/certificate_authority/lib/certificate_authority/serial_number.rb +8 -2
  42. data/vendor/certificate_authority/lib/certificate_authority/validations.rb +31 -0
  43. data/vendor/rsync_command/lib/rsync_command.rb +49 -12
  44. metadata +50 -91
  45. data/lib/leap/platform.rb +0 -90
  46. data/lib/leap_cli/config/environment.rb +0 -180
  47. data/lib/leap_cli/config/filter.rb +0 -178
  48. data/lib/leap_cli/config/manager.rb +0 -419
  49. data/lib/leap_cli/config/node.rb +0 -77
  50. data/lib/leap_cli/config/object.rb +0 -428
  51. data/lib/leap_cli/config/object_list.rb +0 -209
  52. data/lib/leap_cli/config/provider.rb +0 -22
  53. data/lib/leap_cli/config/secrets.rb +0 -87
  54. data/lib/leap_cli/config/sources.rb +0 -11
  55. data/lib/leap_cli/config/tag.rb +0 -25
  56. data/lib/leap_cli/lib_ext/capistrano_connections.rb +0 -16
  57. data/lib/leap_cli/logger.rb +0 -237
  58. data/lib/leap_cli/remote/leap_plugin.rb +0 -192
  59. data/lib/leap_cli/remote/puppet_plugin.rb +0 -26
  60. data/lib/leap_cli/remote/rsync_plugin.rb +0 -35
  61. data/lib/leap_cli/remote/tasks.rb +0 -51
  62. data/lib/leap_cli/ssh_key.rb +0 -195
  63. data/lib/leap_cli/util/remote_command.rb +0 -158
  64. data/lib/leap_cli/util/secret.rb +0 -55
  65. data/lib/leap_cli/util/x509.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 32bb57fcbb9e75766687cc73e04998ab9d34154f
4
- data.tar.gz: 36b47fa44ec131b4ef08898c5dc79d65543eedbf
3
+ metadata.gz: c76581ff17beffa03bea2e6447ec048d9282cd43
4
+ data.tar.gz: e1b082558769fad1644c0bf78afa138aa66fcb15
5
5
  SHA512:
6
- metadata.gz: 9f403ad270bc60cf3a6da1851939dc52e6da9b581cd7ee52ff0bd38f033d52827e319c7def7a173769b38114a4672190ed1ed6af537825673b9122d0caed35bd
7
- data.tar.gz: 3ac1c581600222cd3251989f122e33f01b482aaca653da7dbdd8463de98528abfda6bffe5d14dfc215a3eb93ca2eccb9a9e54fa27b97d5b4a5dd65b8869f261b
6
+ metadata.gz: fc24e99df33af964af23fdff085bb2a87808a92138545378c70fd43e0a1c0581394c3d7c9faffa774feffb063c3da491f7a892267beb985672d736c603aff79a
7
+ data.tar.gz: 67c3838bc0eeaf0bd72eaf1d6c843fbfeca25414bec9ccc4120cf2e514cb2f157cad942fd4b7c67b4d9803097e11694ff0360f4eb0cf0b1e312bf0734fce1449
data/bin/leap CHANGED
@@ -14,6 +14,7 @@ else
14
14
  $VERBOSE=nil
15
15
  DEBUG=false
16
16
  end
17
+ TEST = false
17
18
 
18
19
  LEAP_CLI_BASE_DIR = File.expand_path('..', File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__))
19
20
 
@@ -27,8 +28,6 @@ rescue LoadError
27
28
  end
28
29
 
29
30
  require 'gli'
30
- require 'highline'
31
- require 'forwardable'
32
31
  require 'leap_cli/lib_ext/gli' # our custom extensions to gli
33
32
 
34
33
  #
@@ -40,16 +39,6 @@ require 'leap_cli/lib_ext/gli' # our custom extensions to gli
40
39
  #
41
40
  module LeapCli::Commands
42
41
  extend GLI::App
43
- extend Forwardable
44
-
45
- # delegate highline methods to make them available to sub-commands
46
- @terminal = HighLine.new
47
- def_delegator :@terminal, :ask, 'self.ask'
48
- def_delegator :@terminal, :agree, 'self.agree'
49
- def_delegator :@terminal, :choose, 'self.choose'
50
- def_delegator :@terminal, :say, 'self.say'
51
- def_delegator :@terminal, :color, 'self.color'
52
- def_delegator :@terminal, :list, 'self.list'
53
42
 
54
43
  # make config manager available as 'manager'
55
44
  def self.manager
@@ -90,6 +79,9 @@ module LeapCli::Commands
90
79
 
91
80
  # run command
92
81
  begin
82
+ if ARGV.any?
83
+ LeapCli.log_raw(:log, nil, "COMMAND") { 'leap ' + ARGV.join(' ') }
84
+ end
93
85
  exit_status = run(ARGV)
94
86
  exit(LeapCli::Util.exit_status || exit_status)
95
87
  rescue StandardError => exc
@@ -102,6 +94,8 @@ module LeapCli::Commands
102
94
  end
103
95
  if DEBUG
104
96
  raise exc
97
+ else
98
+ exit(1)
105
99
  end
106
100
  end
107
101
  end
data/lib/leap_cli.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module LeapCli
2
- module Commands; end # for commands in leap_cli/commands
3
- module Macro; end # for macros in leap_platform/provider_base/lib/macros
2
+ module Commands; end # for commands in leap_platform/lib/leap_cli/commands
3
+ module Macro; end # for macros in leap_platform/lib/leap_cli/macros
4
4
  end
5
5
 
6
6
  $ruby_version = RUBY_VERSION.split('.').collect{ |i| i.to_i }.extend(Comparable)
@@ -11,11 +11,8 @@ $:.unshift(File.expand_path('../leap_cli/override',__FILE__))
11
11
  # for a few gems, things will break if using earlier versions.
12
12
  # enforce the compatible versions here:
13
13
  require 'rubygems'
14
- gem 'net-ssh', '~> 2.7'
15
14
  gem 'gli', '~> 2.12', '>= 2.12.0'
16
15
 
17
- require 'leap/platform'
18
-
19
16
  require 'leap_cli/version'
20
17
  require 'leap_cli/exceptions'
21
18
 
@@ -32,30 +29,13 @@ require 'leap_cli/core_ext/yaml'
32
29
  require 'leap_cli/log'
33
30
  require 'leap_cli/path'
34
31
  require 'leap_cli/util'
35
- require 'leap_cli/util/secret'
36
- require 'leap_cli/util/remote_command'
37
- require 'leap_cli/util/x509'
38
- require 'leap_cli/logger'
39
32
  require 'leap_cli/bootstrap'
40
33
 
41
- require 'leap_cli/ssh_key'
42
- require 'leap_cli/config/object'
43
- require 'leap_cli/config/node'
44
- require 'leap_cli/config/tag'
45
- require 'leap_cli/config/provider'
46
- require 'leap_cli/config/secrets'
47
- require 'leap_cli/config/object_list'
48
- require 'leap_cli/config/filter'
49
- require 'leap_cli/config/environment'
50
- require 'leap_cli/config/manager'
51
-
52
34
  require 'leap_cli/markdown_document_listener'
53
35
 
54
36
  #
55
37
  # allow everyone easy access to log() command.
56
38
  #
57
39
  module LeapCli
58
- Util.send(:extend, LeapCli::Log)
59
- Config::Manager.send(:include, LeapCli::Log)
60
- extend LeapCli::Log
40
+ extend LeapCli::LogCommand
61
41
  end
@@ -5,8 +5,8 @@
5
5
 
6
6
  module LeapCli
7
7
  module Bootstrap
8
- extend LeapCli::Log
9
8
  extend self
9
+ extend LeapCli::LogCommand
10
10
 
11
11
  #
12
12
  # the argument leapfile_path is only used for tests
@@ -36,9 +36,11 @@ module LeapCli
36
36
  # called from leap executable.
37
37
  #
38
38
  def load_libraries(app)
39
- if LeapCli.log_level >= 2
39
+ if LeapCli.logger.log_level >= 2
40
40
  log_version
41
41
  end
42
+ add_platform_lib_to_path
43
+ load_platform_libraries
42
44
  load_commands(app)
43
45
  load_macros
44
46
  end
@@ -72,14 +74,14 @@ module LeapCli
72
74
  options = parse_logging_options(argv)
73
75
  verbose = (options[:verbose] || 1).to_i
74
76
  if verbose
75
- LeapCli.set_log_level(verbose)
77
+ LeapCli.logger.log_level = verbose
76
78
  end
77
79
  if options[:log]
78
- LeapCli.log_file = options[:log]
79
- LeapCli::Util.log_raw(:log) { $0 + ' ' + argv.join(' ')}
80
+ LeapCli.logger.log_file = options[:log]
81
+ LeapCli.logger.log_raw(:log) { $0 + ' ' + argv.join(' ')}
80
82
  end
81
83
  unless options[:color].nil?
82
- LeapCli.log_in_color = options[:color]
84
+ LeapCli.logger.log_in_color = options[:color]
83
85
  end
84
86
  end
85
87
 
@@ -97,17 +99,16 @@ module LeapCli
97
99
  if !Path.platform || !File.directory?(Path.platform)
98
100
  bail! { log :missing, "platform directory '#{Path.platform}'" }
99
101
  end
100
- if LeapCli.log_file.nil? && LeapCli.leapfile.log
101
- LeapCli.log_file = LeapCli.leapfile.log
102
+ if LeapCli.logger.log_file.nil? && LeapCli.leapfile.log
103
+ LeapCli.logger.log_file = LeapCli.leapfile.log
102
104
  end
103
105
  elsif !leapfile_optional?(argv)
104
106
  puts
105
107
  puts " ="
106
- log :note, "There is no `Leapfile` in this directory, or any parent directory.\n"+
107
- " = "+
108
+ log :NOTE, "There is no `Leapfile` in this directory, or any parent directory.\n"+
109
+ " = "+
108
110
  "Without this file, most commands will not be available."
109
111
  puts " ="
110
- puts
111
112
  end
112
113
  end
113
114
 
@@ -158,7 +159,9 @@ module LeapCli
158
159
  # Yes, hacky.
159
160
  #
160
161
  def leapfile_optional?(argv)
161
- if argv.include?('--version')
162
+ if TEST
163
+ return true
164
+ elsif argv.include?('--version')
162
165
  return true
163
166
  else
164
167
  without_flags = argv.select {|i| i !~ /^-/}
@@ -193,5 +196,26 @@ module LeapCli
193
196
  end
194
197
  end
195
198
 
199
+ #
200
+ # makes all the ruby libraries in the leap_platform/lib directory
201
+ # available for inclusion.
202
+ #
203
+ def add_platform_lib_to_path
204
+ if Path.platform
205
+ path = File.join(Path.platform, 'lib')
206
+ $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
207
+ end
208
+ end
209
+
210
+ #
211
+ # loads libraries that live in the platform and should
212
+ # always be available.
213
+ #
214
+ def load_platform_libraries
215
+ if Path.platform
216
+ require 'leap_cli/load_libraries'
217
+ end
218
+ end
219
+
196
220
  end
197
221
  end
@@ -1,61 +1,103 @@
1
- #
2
- # Some common helpers available to all LeapCli::Commands
3
- #
4
- # This also includes utility methods, and makes all instance
5
- # methods available as class methods.
6
- #
1
+ require 'readline'
7
2
 
8
- module LeapCli
9
- module Commands
3
+ module LeapCli; module Commands
10
4
 
11
- extend self
12
- extend LeapCli::Log
13
- extend LeapCli::Util
14
- extend LeapCli::Util::RemoteCommand
5
+ extend LeapCli::LogCommand
6
+ extend LeapCli::Util
15
7
 
16
- protected
17
-
18
- def path(name)
19
- Path.named_path(name)
20
- end
8
+ def path(name)
9
+ Path.named_path(name)
10
+ end
21
11
 
22
- #
23
- # keeps prompting the user for a numbered choice, until they pick a good one or bail out.
24
- #
25
- # block is yielded and is responsible for rendering the choices.
26
- #
27
- def numbered_choice_menu(msg, items, &block)
28
- while true
29
- say("\n" + msg + ':')
30
- items.each_with_index &block
31
- say("q. quit")
32
- index = ask("number 1-#{items.length}> ")
33
- if index.empty?
34
- next
35
- elsif index =~ /q/
12
+ #
13
+ # keeps prompting the user for a numbered choice, until they pick a good one or bail out.
14
+ #
15
+ # block is yielded and is responsible for rendering the choices.
16
+ #
17
+ def numbered_choice_menu(msg, items, &block)
18
+ while true
19
+ say("\n" + msg + ':')
20
+ items.each_with_index(&block)
21
+ say("q. quit")
22
+ index = ask("number 1-#{items.length}> ")
23
+ if index.nil? || index.empty?
24
+ next
25
+ elsif index =~ /q/
26
+ bail!
27
+ else
28
+ i = index.to_i - 1
29
+ if i < 0 || i >= items.length
36
30
  bail!
37
31
  else
38
- i = index.to_i - 1
39
- if i < 0 || i >= items.length
40
- bail!
41
- else
42
- return i
43
- end
32
+ return i
44
33
  end
45
34
  end
46
35
  end
36
+ end
37
+
38
+ def parse_node_list(nodes)
39
+ if nodes.is_a? Config::Object
40
+ Config::ObjectList.new(nodes)
41
+ elsif nodes.is_a? Config::ObjectList
42
+ nodes
43
+ elsif nodes.is_a? String
44
+ manager.filter!(nodes)
45
+ else
46
+ bail! "argument error"
47
+ end
48
+ end
49
+
50
+ def say(statement)
51
+ if ends_in_whitespace?(statement)
52
+ $stdout.print(statement)
53
+ $stdout.flush
54
+ else
55
+ $stdout.puts(statement)
56
+ end
57
+ end
58
+
59
+ def ask(question, options={})
60
+ default = options[:default]
61
+ if default
62
+ if ends_in_whitespace?(question)
63
+ question = question + "|" + default + "| "
64
+ else
65
+ question = question + "|" + default + "|"
66
+ end
67
+ end
68
+ response = Readline.readline(question, true) # set to false if ever reading passwords.
69
+ if response
70
+ response = response.strip
71
+ if response.empty?
72
+ return default
73
+ else
74
+ return response
75
+ end
76
+ else
77
+ return default
78
+ end
79
+ end
47
80
 
48
- def parse_node_list(nodes)
49
- if nodes.is_a? Config::Object
50
- Config::ObjectList.new(nodes)
51
- elsif nodes.is_a? Config::ObjectList
52
- nodes
53
- elsif nodes.is_a? String
54
- manager.filter!(nodes)
81
+ def agree(question, options={})
82
+ while true
83
+ response = ask(question, options)
84
+ if response.nil?
85
+ say('Please enter "yes" or "no".')
86
+ elsif ["y","yes", "ye"].include?(response.downcase)
87
+ return true
88
+ elsif ["n", "no"].include?(response.downcase)
89
+ return false
55
90
  else
56
- bail! "argument error"
91
+ say('Please enter "yes" or "no".')
57
92
  end
58
93
  end
94
+ end
59
95
 
96
+ private
97
+
98
+ # true if str ends in whitespace before a color escape code.
99
+ def ends_in_whitespace?(str)
100
+ /[ \t](\e\[\d+(;\d+)*m)?\Z/ =~ str
60
101
  end
61
- end
102
+
103
+ end; end
@@ -4,7 +4,6 @@ module LeapCli; module Commands
4
4
 
5
5
  desc 'Creates a new provider instance in the specified directory, creating it if necessary.'
6
6
  arg_name 'DIRECTORY'
7
- #skips_pre
8
7
  command :new do |c|
9
8
  c.flag 'name', :desc => "The name of the provider." #, :default_value => 'Example'
10
9
  c.flag 'domain', :desc => "The primary domain of the provider." #, :default_value => 'example.org'
@@ -12,19 +11,7 @@ module LeapCli; module Commands
12
11
  c.flag 'contacts', :desc => "Default email address contacts." #, :default_value => 'root'
13
12
 
14
13
  c.action do |global, options, args|
15
- unless args.first
16
- # this should not be needed, but GLI is not making it required.
17
- bail! "Argument DIRECTORY is required."
18
- end
19
- directory = File.expand_path(args.first)
20
- create_provider_directory(global, directory)
21
- options[:domain] ||= ask_string("The primary domain of the provider: ") {|q| q.default = 'example.org'}
22
- options[:name] ||= ask_string("The name of the provider: ") {|q| q.default = 'Example'}
23
- options[:platform] ||= ask_string("File path of the leap_platform directory: ") {|q| q.default = File.expand_path('../leap_platform', directory)}
24
- options[:platform] = "./" + options[:platform] unless options[:platform] =~ /^\//
25
- options[:contacts] ||= ask_string("Default email address contacts: ") {|q| q.default = 'root@' + options[:domain]}
26
- options[:platform] = relative_path(options[:platform])
27
- create_initial_provider_files(directory, global, options)
14
+ new_provider_action(global, options, args)
28
15
  end
29
16
  end
30
17
 
@@ -32,13 +19,33 @@ module LeapCli; module Commands
32
19
 
33
20
  DEFAULT_REPO = 'https://leap.se/git/leap_platform.git'
34
21
 
22
+ def new_provider_action(global, options, args)
23
+ unless args.first
24
+ # this should not be needed, but GLI is not making it required.
25
+ bail! "Argument DIRECTORY is required."
26
+ end
27
+ directory = File.expand_path(args.first)
28
+ create_provider_directory(global, directory)
29
+ options[:domain] ||= ask_string("The primary domain of the provider: ",
30
+ default: 'example.org')
31
+ options[:name] ||= ask_string("The name of the provider: ",
32
+ default: 'Example')
33
+ options[:platform] ||= ask_string("File path of the leap_platform directory: ",
34
+ default: File.expand_path('../leap_platform', directory))
35
+ options[:platform] = "./" + options[:platform] unless options[:platform] =~ /^\//
36
+ options[:contacts] ||= ask_string("Default email address contacts: ",
37
+ default: 'root@' + options[:domain])
38
+ options[:platform] = relative_path(options[:platform])
39
+ create_initial_provider_files(directory, global, options)
40
+ end
41
+
35
42
  #
36
43
  # don't let the user specify any of the following: y, yes, n, no
37
44
  # they must actually input a real string
38
45
  #
39
- def ask_string(str, &block)
46
+ def ask_string(str, options={})
40
47
  while true
41
- value = ask(str, &block)
48
+ value = ask(str, options)
42
49
  if value =~ /^(y|yes|n|no)$/i
43
50
  say "`#{value}` is not a valid value. Try again"
44
51
  else
@@ -54,7 +61,7 @@ module LeapCli; module Commands
54
61
  unless directory && directory.any?
55
62
  help! "Directory name is required."
56
63
  end
57
- unless File.exists?(directory)
64
+ unless File.exist?(directory)
58
65
  if global[:yes] || agree("Create directory #{directory}? ")
59
66
  ensure_dir directory
60
67
  else
@@ -1,9 +1,11 @@
1
-
2
1
  #
3
2
  # check to make sure we can find the root directory of the platform
4
3
  #
5
4
  module LeapCli; module Commands
6
5
 
6
+ extend self # this is a trick to make all instance methods
7
+ # available as class methods.
8
+
7
9
  desc 'Verbosity level 0..5'
8
10
  arg_name 'LEVEL'
9
11
  default_value '1'