leap_cli 1.7.4 → 1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/bin/leap +6 -13
  3. data/lib/leap/platform.rb +2 -0
  4. data/lib/leap_cli.rb +2 -1
  5. data/lib/leap_cli/bootstrap.rb +197 -0
  6. data/lib/leap_cli/commands/common.rb +61 -0
  7. data/lib/leap_cli/commands/new.rb +5 -1
  8. data/lib/leap_cli/commands/pre.rb +1 -66
  9. data/lib/leap_cli/config/environment.rb +180 -0
  10. data/lib/leap_cli/config/manager.rb +100 -197
  11. data/lib/leap_cli/config/node.rb +2 -2
  12. data/lib/leap_cli/config/object.rb +56 -43
  13. data/lib/leap_cli/config/object_list.rb +6 -3
  14. data/lib/leap_cli/config/provider.rb +11 -0
  15. data/lib/leap_cli/config/secrets.rb +14 -1
  16. data/lib/leap_cli/config/tag.rb +2 -2
  17. data/lib/leap_cli/leapfile.rb +1 -0
  18. data/lib/leap_cli/log.rb +1 -0
  19. data/lib/leap_cli/logger.rb +16 -12
  20. data/lib/leap_cli/markdown_document_listener.rb +3 -1
  21. data/lib/leap_cli/path.rb +12 -0
  22. data/lib/leap_cli/remote/leap_plugin.rb +9 -34
  23. data/lib/leap_cli/remote/puppet_plugin.rb +0 -40
  24. data/lib/leap_cli/remote/tasks.rb +9 -34
  25. data/lib/leap_cli/ssh_key.rb +5 -2
  26. data/lib/leap_cli/version.rb +2 -2
  27. metadata +5 -18
  28. data/lib/leap_cli/commands/ca.rb +0 -518
  29. data/lib/leap_cli/commands/clean.rb +0 -16
  30. data/lib/leap_cli/commands/compile.rb +0 -340
  31. data/lib/leap_cli/commands/db.rb +0 -65
  32. data/lib/leap_cli/commands/deploy.rb +0 -368
  33. data/lib/leap_cli/commands/env.rb +0 -76
  34. data/lib/leap_cli/commands/facts.rb +0 -100
  35. data/lib/leap_cli/commands/inspect.rb +0 -144
  36. data/lib/leap_cli/commands/list.rb +0 -132
  37. data/lib/leap_cli/commands/node.rb +0 -165
  38. data/lib/leap_cli/commands/node_init.rb +0 -169
  39. data/lib/leap_cli/commands/ssh.rb +0 -220
  40. data/lib/leap_cli/commands/test.rb +0 -74
  41. data/lib/leap_cli/commands/user.rb +0 -136
  42. data/lib/leap_cli/commands/util.rb +0 -50
  43. data/lib/leap_cli/commands/vagrant.rb +0 -197
@@ -1,76 +0,0 @@
1
- module LeapCli
2
- module Commands
3
-
4
- desc "Manipulate and query environment information."
5
- long_desc "The 'environment' node property can be used to isolate sets of nodes into entirely separate environments. "+
6
- "A node in one environment will never interact with a node from another environment. "+
7
- "Environment pinning works by modifying your ~/.leaprc file and is dependent on the "+
8
- "absolute file path of your provider directory (pins don't apply if you move the directory)"
9
- command [:env, :e] do |c|
10
- c.desc "List the available environments. The pinned environment, if any, will be marked with '*'. Will also set the pin if run with an environment argument."
11
- c.arg_name 'ENVIRONMENT', :optional => true
12
- c.command :ls do |ls|
13
- ls.action do |global_options, options, args|
14
- environment = get_env_from_args(args)
15
- if environment
16
- pin(environment)
17
- LeapCli.leapfile.load
18
- end
19
- print_envs
20
- end
21
- end
22
-
23
- c.desc 'Pin the environment to ENVIRONMENT. All subsequent commands will only apply to nodes in this environment.'
24
- c.arg_name 'ENVIRONMENT'
25
- c.command :pin do |pin|
26
- pin.action do |global_options,options,args|
27
- environment = get_env_from_args(args)
28
- if environment
29
- pin(environment)
30
- else
31
- bail! "There is no environment `#{environment}`"
32
- end
33
- end
34
- end
35
-
36
- c.desc "Unpin the environment. All subsequent commands will apply to all nodes."
37
- c.command :unpin do |unpin|
38
- unpin.action do |global_options, options, args|
39
- LeapCli.leapfile.unset('environment')
40
- log 0, :saved, "~/.leaprc, removing environment property."
41
- end
42
- end
43
-
44
- c.default_command :ls
45
- end
46
-
47
- protected
48
-
49
- def get_env_from_args(args)
50
- environment = args.first
51
- if environment == 'default' || (environment && manager.environment_names.include?(environment))
52
- return environment
53
- else
54
- return nil
55
- end
56
- end
57
-
58
- def pin(environment)
59
- LeapCli.leapfile.set('environment', environment)
60
- log 0, :saved, "~/.leaprc with environment set to #{environment}."
61
- end
62
-
63
- def print_envs
64
- envs = ["default"] + manager.environment_names.compact.sort
65
- envs.each do |env|
66
- if env
67
- if LeapCli.leapfile.environment == env
68
- puts "* #{env}"
69
- else
70
- puts " #{env}"
71
- end
72
- end
73
- end
74
- end
75
- end
76
- end
@@ -1,100 +0,0 @@
1
- #
2
- # Gather facter facts
3
- #
4
-
5
- module LeapCli; module Commands
6
-
7
- desc 'Gather information on nodes.'
8
- command :facts do |facts|
9
- facts.desc 'Query servers to update facts.json.'
10
- facts.long_desc "Queries every node included in FILTER and saves the important information to facts.json"
11
- facts.arg_name 'FILTER'
12
- facts.command :update do |update|
13
- update.action do |global_options,options,args|
14
- update_facts(global_options, options, args)
15
- end
16
- end
17
- end
18
-
19
- protected
20
-
21
- def facter_cmd
22
- 'facter --json ' + Leap::Platform.facts.join(' ')
23
- end
24
-
25
- def remove_node_facts(name)
26
- if file_exists?(:facts)
27
- update_facts_file({name => nil})
28
- end
29
- end
30
-
31
- def update_node_facts(name, facts)
32
- update_facts_file({name => facts})
33
- end
34
-
35
- def rename_node_facts(old_name, new_name)
36
- if file_exists?(:facts)
37
- facts = JSON.parse(read_file(:facts) || {})
38
- facts[new_name] = facts[old_name]
39
- facts[old_name] = nil
40
- update_facts_file(facts, true)
41
- end
42
- end
43
-
44
- #
45
- # if overwrite = true, then ignore existing facts.json.
46
- #
47
- def update_facts_file(new_facts, overwrite=false)
48
- replace_file!(:facts) do |content|
49
- if overwrite || content.nil? || content.empty?
50
- old_facts = {}
51
- else
52
- old_facts = manager.facts
53
- end
54
- facts = old_facts.merge(new_facts)
55
- facts.each do |name, value|
56
- if value.is_a? String
57
- if value == ""
58
- value = nil
59
- else
60
- value = JSON.parse(value) rescue JSON::ParserError
61
- end
62
- end
63
- if value.is_a? Hash
64
- value.delete_if {|key,v| v.nil?}
65
- end
66
- facts[name] = value
67
- end
68
- facts.delete_if do |name, value|
69
- value.nil? || value.empty?
70
- end
71
- if facts.empty?
72
- "{}\n"
73
- else
74
- JSON.sorted_generate(facts) + "\n"
75
- end
76
- end
77
- end
78
-
79
- private
80
-
81
- def update_facts(global_options, options, args)
82
- nodes = manager.filter(args, :local => false, :disabled => false)
83
- new_facts = {}
84
- ssh_connect(nodes) do |ssh|
85
- ssh.leap.run_with_progress(facter_cmd) do |response|
86
- node = manager.node(response[:host])
87
- if node
88
- new_facts[node.name] = response[:data].strip
89
- else
90
- log :warning, 'Could not find node for hostname %s' % response[:host]
91
- end
92
- end
93
- end
94
- # only overwrite the entire facts file if and only if we are gathering facts
95
- # for all nodes in all environments.
96
- overwrite_existing = args.empty? && LeapCli.leapfile.environment.nil?
97
- update_facts_file(new_facts, overwrite_existing)
98
- end
99
-
100
- end; end
@@ -1,144 +0,0 @@
1
- module LeapCli; module Commands
2
-
3
- desc 'Prints details about a file. Alternately, the argument FILE can be the name of a node, service or tag.'
4
- arg_name 'FILE'
5
- command [:inspect, :i] do |c|
6
- c.switch 'base', :desc => 'Inspect the FILE from the provider_base (i.e. without local inheritance).', :negatable => false
7
- c.action do |global_options,options,args|
8
- object = args.first
9
- assert! object, 'A file path or node/service/tag name is required'
10
- method = inspection_method(object)
11
- if method && defined?(method)
12
- self.send(method, object, options)
13
- else
14
- log "Sorry, I don't know how to inspect that."
15
- end
16
- end
17
- end
18
-
19
- private
20
-
21
- FTYPE_MAP = {
22
- "PEM certificate" => :inspect_x509_cert,
23
- "PEM RSA private key" => :inspect_x509_key,
24
- "OpenSSH RSA public key" => :inspect_ssh_pub_key,
25
- "PEM certificate request" => :inspect_x509_csr
26
- }
27
-
28
- def inspection_method(object)
29
- if File.exists?(object)
30
- ftype = `file #{object}`.split(':').last.strip
31
- log 2, "file is of type '#{ftype}'"
32
- if FTYPE_MAP[ftype]
33
- FTYPE_MAP[ftype]
34
- elsif File.extname(object) == ".json"
35
- full_path = File.expand_path(object, Dir.pwd)
36
- if path_match?(:node_config, full_path)
37
- :inspect_node
38
- elsif path_match?(:service_config, full_path)
39
- :inspect_service
40
- elsif path_match?(:tag_config, full_path)
41
- :inspect_tag
42
- elsif path_match?(:provider_config, full_path) || path_match?(:provider_env_config, full_path)
43
- :inspect_provider
44
- elsif path_match?(:common_config, full_path)
45
- :inspect_common
46
- else
47
- nil
48
- end
49
- end
50
- elsif manager.nodes[object]
51
- :inspect_node
52
- elsif manager.services[object]
53
- :inspect_service
54
- elsif manager.tags[object]
55
- :inspect_tag
56
- elsif object == "common"
57
- :inspect_common
58
- elsif object == "provider"
59
- :inspect_provider
60
- else
61
- nil
62
- end
63
- end
64
-
65
- #
66
- # inspectors
67
- #
68
-
69
- def inspect_x509_key(file_path, options)
70
- assert_bin! 'openssl'
71
- puts assert_run! 'openssl rsa -in %s -text -check' % file_path
72
- end
73
-
74
- def inspect_x509_cert(file_path, options)
75
- assert_bin! 'openssl'
76
- puts assert_run! 'openssl x509 -in %s -text -noout' % file_path
77
- log 0, :"SHA256 fingerprint", X509.fingerprint("SHA256", file_path)
78
- end
79
-
80
- def inspect_x509_csr(file_path, options)
81
- assert_bin! 'openssl'
82
- puts assert_run! 'openssl req -text -noout -verify -in %s' % file_path
83
- end
84
-
85
- #def inspect_ssh_pub_key(file_path)
86
- #end
87
-
88
- def inspect_node(arg, options)
89
- inspect_json manager.nodes[name(arg)]
90
- end
91
-
92
- def inspect_service(arg, options)
93
- if options[:base]
94
- inspect_json manager.base_services[name(arg)]
95
- else
96
- inspect_json manager.services[name(arg)]
97
- end
98
- end
99
-
100
- def inspect_tag(arg, options)
101
- if options[:base]
102
- inspect_json manager.base_tags[name(arg)]
103
- else
104
- inspect_json manager.tags[name(arg)]
105
- end
106
- end
107
-
108
- def inspect_provider(arg, options)
109
- if options[:base]
110
- inspect_json manager.base_provider
111
- elsif arg =~ /provider\.(.*)\.json/
112
- inspect_json manager.env($1).provider
113
- else
114
- inspect_json manager.provider
115
- end
116
- end
117
-
118
- def inspect_common(arg, options)
119
- if options[:base]
120
- inspect_json manager.base_common
121
- else
122
- inspect_json manager.common
123
- end
124
- end
125
-
126
- #
127
- # helpers
128
- #
129
-
130
- def name(arg)
131
- File.basename(arg).sub(/\.json$/, '')
132
- end
133
-
134
- def inspect_json(config)
135
- if config
136
- puts JSON.sorted_generate(config)
137
- end
138
- end
139
-
140
- def path_match?(path_symbol, path)
141
- Dir.glob(Path.named_path([path_symbol, '*'])).include?(path)
142
- end
143
-
144
- end; end
@@ -1,132 +0,0 @@
1
- require 'command_line_reporter'
2
-
3
- module LeapCli; module Commands
4
-
5
- desc 'List nodes and their classifications'
6
- long_desc 'Prints out a listing of nodes, services, or tags. ' +
7
- 'If present, the FILTER can be a list of names of nodes, services, or tags. ' +
8
- 'If the name is prefixed with +, this acts like an AND condition. ' +
9
- "For example:\n\n" +
10
- "`leap list node1 node2` matches all nodes named \"node1\" OR \"node2\"\n\n" +
11
- "`leap list openvpn +local` matches all nodes with service \"openvpn\" AND tag \"local\""
12
-
13
- arg_name 'FILTER', :optional => true
14
- command [:list,:ls] do |c|
15
- c.flag 'print', :desc => 'What attributes to print (optional)'
16
- c.switch 'disabled', :desc => 'Include disabled nodes in the list.', :negatable => false
17
- c.action do |global_options,options,args|
18
- # don't rely on default manager(), because we want to pass custom options to load()
19
- manager = LeapCli::Config::Manager.new
20
- if global_options[:color]
21
- colors = ['cyan', 'white']
22
- else
23
- colors = [nil, nil]
24
- end
25
- puts
26
- manager.load(:include_disabled => options['disabled'], :continue_on_error => true)
27
- if options['print']
28
- print_node_properties(manager.filter(args), options['print'])
29
- else
30
- if args.any?
31
- NodeTable.new(manager.filter(args), colors).run
32
- else
33
- environment = LeapCli.leapfile.environment || '_all_'
34
- TagTable.new('SERVICES', manager.env(environment).services, colors).run
35
- TagTable.new('TAGS', manager.env(environment).tags, colors).run
36
- NodeTable.new(manager.filter(), colors).run
37
- end
38
- end
39
- end
40
- end
41
-
42
- private
43
-
44
- def self.print_node_properties(nodes, properties)
45
- properties = properties.split(',')
46
- max_width = nodes.keys.inject(0) {|max,i| [i.size,max].max}
47
- nodes.each_node do |node|
48
- value = properties.collect{|prop|
49
- prop_value = node[prop]
50
- if prop_value.nil?
51
- "null"
52
- elsif prop_value == ""
53
- "empty"
54
- elsif prop_value.is_a? LeapCli::Config::Object
55
- node[prop].dump_json(:compact) # TODO: add option of getting pre-evaluation values.
56
- else
57
- prop_value.to_s
58
- end
59
- }.join(', ')
60
- printf("%#{max_width}s %s\n", node.name, value)
61
- end
62
- puts
63
- end
64
-
65
- class TagTable
66
- include CommandLineReporter
67
- def initialize(heading, tag_list, colors)
68
- @heading = heading
69
- @tag_list = tag_list
70
- @colors = colors
71
- end
72
- def run
73
- tags = @tag_list.keys.select{|tag| tag !~ /^_/}.sort # sorted list of tags, excluding _partials
74
- max_width = [20, (tags+[@heading]).inject(0) {|max,i| [i.size,max].max}].max
75
- table :border => false do
76
- row :color => @colors[0] do
77
- column @heading, :align => 'right', :width => max_width
78
- column "NODES", :width => HighLine::SystemExtensions.terminal_size.first - max_width - 2, :padding => 2
79
- end
80
- tags.each do |tag|
81
- next if @tag_list[tag].node_list.empty?
82
- row :color => @colors[1] do
83
- column tag
84
- column @tag_list[tag].node_list.keys.sort.join(', ')
85
- end
86
- end
87
- end
88
- vertical_spacing
89
- end
90
- end
91
-
92
- #
93
- # might be handy: HighLine::SystemExtensions.terminal_size.first
94
- #
95
- class NodeTable
96
- include CommandLineReporter
97
- def initialize(node_list, colors)
98
- @node_list = node_list
99
- @colors = colors
100
- end
101
- def run
102
- rows = @node_list.keys.sort.collect do |node_name|
103
- [node_name, @node_list[node_name].services.sort.join(', '), @node_list[node_name].tags.sort.join(', ')]
104
- end
105
- unless rows.any?
106
- puts Paint["no results", :red]
107
- puts
108
- return
109
- end
110
- padding = 2
111
- max_node_width = [20, (rows.map{|i|i[0]} + ["NODES"] ).inject(0) {|max,i| [i.size,max].max}].max
112
- max_service_width = (rows.map{|i|i[1]} + ["SERVICES"]).inject(0) {|max,i| [i.size+padding+padding,max].max}
113
- max_tag_width = (rows.map{|i|i[2]} + ["TAGS"] ).inject(0) {|max,i| [i.size,max].max}
114
- table :border => false do
115
- row :color => @colors[0] do
116
- column "NODES", :align => 'right', :width => max_node_width
117
- column "SERVICES", :width => max_service_width, :padding => 2
118
- column "TAGS", :width => max_tag_width
119
- end
120
- rows.each do |r|
121
- row :color => @colors[1] do
122
- column r[0]
123
- column r[1]
124
- column r[2]
125
- end
126
- end
127
- end
128
- vertical_spacing
129
- end
130
- end
131
-
132
- end; end