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,74 +0,0 @@
1
- module LeapCli; module Commands
2
-
3
- desc 'Run tests.'
4
- command [:test, :t] do |test|
5
- test.desc 'Run the test suit on FILTER nodes.'
6
- test.arg_name 'FILTER', :optional => true
7
- test.command :run do |run|
8
- run.switch 'continue', :desc => 'Continue over errors and failures (default is --no-continue).', :negatable => true
9
- run.action do |global_options,options,args|
10
- test_order = File.join(Path.platform, 'tests/order.rb')
11
- if File.exists?(test_order)
12
- require test_order
13
- end
14
- manager.filter!(args).names_in_test_dependency_order.each do |node_name|
15
- node = manager.nodes[node_name]
16
- begin
17
- ssh_connect(node) do |ssh|
18
- ssh.run(test_cmd(options))
19
- end
20
- rescue Capistrano::CommandError => exc
21
- if options[:continue]
22
- exit_status(1)
23
- else
24
- bail!
25
- end
26
- end
27
- end
28
- end
29
- end
30
-
31
- test.desc 'Creates files needed to run tests.'
32
- test.command :init do |init|
33
- init.action do |global_options,options,args|
34
- generate_test_client_openvpn_configs
35
- end
36
- end
37
-
38
- test.default_command :run
39
- end
40
-
41
- private
42
-
43
- def test_cmd(options)
44
- if options[:continue]
45
- "#{Leap::Platform.leap_dir}/bin/run_tests --continue"
46
- else
47
- "#{Leap::Platform.leap_dir}/bin/run_tests"
48
- end
49
- end
50
-
51
- #
52
- # generates a whole bunch of openvpn configs that can be used to connect to different openvpn gateways
53
- #
54
- def generate_test_client_openvpn_configs
55
- assert_config! 'provider.ca.client_certificates.unlimited_prefix'
56
- assert_config! 'provider.ca.client_certificates.limited_prefix'
57
- template = read_file! Path.find_file(:test_client_openvpn_template)
58
- manager.environment_names.each do |env|
59
- vpn_nodes = manager.nodes[:environment => env][:services => 'openvpn']['openvpn.allow_limited' => true]
60
- if vpn_nodes.any?
61
- generate_test_client_cert(provider.ca.client_certificates.limited_prefix) do |key, cert|
62
- write_file! [:test_openvpn_config, [env, 'limited'].compact.join('_')], Util.erb_eval(template, binding)
63
- end
64
- end
65
- vpn_nodes = manager.nodes[:environment => env][:services => 'openvpn']['openvpn.allow_unlimited' => true]
66
- if vpn_nodes.any?
67
- generate_test_client_cert(provider.ca.client_certificates.unlimited_prefix) do |key, cert|
68
- write_file! [:test_openvpn_config, [env, 'unlimited'].compact.join('_')], Util.erb_eval(template, binding)
69
- end
70
- end
71
- end
72
- end
73
-
74
- end; end
@@ -1,136 +0,0 @@
1
-
2
- #
3
- # perhaps we want to verify that the key files are actually the key files we expect.
4
- # we could use 'file' for this:
5
- #
6
- # > file ~/.gnupg/00440025.asc
7
- # ~/.gnupg/00440025.asc: PGP public key block
8
- #
9
- # > file ~/.ssh/id_rsa.pub
10
- # ~/.ssh/id_rsa.pub: OpenSSH RSA public key
11
- #
12
-
13
- module LeapCli
14
- module Commands
15
-
16
- desc 'Adds a new trusted sysadmin by adding public keys to the "users" directory.'
17
- arg_name 'USERNAME' #, :optional => false, :multiple => false
18
- command :'add-user' do |c|
19
-
20
- c.switch 'self', :desc => 'Add yourself as a trusted sysadin by choosing among the public keys available for the current user.', :negatable => false
21
- c.flag 'ssh-pub-key', :desc => 'SSH public key file for this new user'
22
- c.flag 'pgp-pub-key', :desc => 'OpenPGP public key file for this new user'
23
-
24
- c.action do |global_options,options,args|
25
- username = args.first
26
- if !username.any?
27
- if options[:self]
28
- username ||= `whoami`.strip
29
- else
30
- help! "Either USERNAME argument or --self flag is required."
31
- end
32
- end
33
- if Leap::Platform.reserved_usernames.include? username
34
- bail! %(The username "#{username}" is reserved. Sorry, pick another.)
35
- end
36
-
37
- ssh_pub_key = nil
38
- pgp_pub_key = nil
39
-
40
- if options['ssh-pub-key']
41
- ssh_pub_key = read_file!(options['ssh-pub-key'])
42
- end
43
- if options['pgp-pub-key']
44
- pgp_pub_key = read_file!(options['pgp-pub-key'])
45
- end
46
-
47
- if options[:self]
48
- ssh_pub_key ||= pick_ssh_key.to_s
49
- pgp_pub_key ||= pick_pgp_key
50
- end
51
-
52
- assert!(ssh_pub_key, 'Sorry, could not find SSH public key.')
53
-
54
- if ssh_pub_key
55
- write_file!([:user_ssh, username], ssh_pub_key)
56
- end
57
- if pgp_pub_key
58
- write_file!([:user_pgp, username], pgp_pub_key)
59
- end
60
-
61
- update_authorized_keys
62
- end
63
- end
64
-
65
- #
66
- # let the the user choose among the ssh public keys that we encounter, or just pick the key if there is only one.
67
- #
68
- def pick_ssh_key
69
- ssh_keys = []
70
- Dir.glob("#{ENV['HOME']}/.ssh/*.pub").each do |keyfile|
71
- ssh_keys << SshKey.load(keyfile)
72
- end
73
-
74
- if `which ssh-add`.strip.any?
75
- `ssh-add -L 2> /dev/null`.split("\n").compact.each do |line|
76
- key = SshKey.load(line)
77
- if key
78
- key.comment = 'ssh-agent'
79
- ssh_keys << key unless ssh_keys.include?(key)
80
- end
81
- end
82
- end
83
- ssh_keys.compact!
84
-
85
- assert! ssh_keys.any?, 'Sorry, could not find any SSH public key for you. Have you run ssh-keygen?'
86
-
87
- if ssh_keys.length > 1
88
- key_index = numbered_choice_menu('Choose your SSH public key', ssh_keys.collect(&:summary)) do |line, i|
89
- say("#{i+1}. #{line}")
90
- end
91
- else
92
- key_index = 0
93
- end
94
-
95
- return ssh_keys[key_index]
96
- end
97
-
98
- #
99
- # let the the user choose among the gpg public keys that we encounter, or just pick the key if there is only one.
100
- #
101
- def pick_pgp_key
102
- begin
103
- require 'gpgme'
104
- rescue LoadError
105
- log "Skipping OpenPGP setup because gpgme is not installed."
106
- return
107
- end
108
-
109
- secret_keys = GPGME::Key.find(:secret)
110
- if secret_keys.empty?
111
- log "Skipping OpenPGP setup because I could not find any OpenPGP keys for you"
112
- return nil
113
- end
114
-
115
- secret_keys.select!{|key| !key.expired}
116
-
117
- if secret_keys.length > 1
118
- key_index = numbered_choice_menu('Choose your OpenPGP public key', secret_keys) do |key, i|
119
- key_info = key.to_s.split("\n")[0..1].map{|line| line.sub(/^\s*(sec|uid)\s*/,'')}.join(' -- ')
120
- say("#{i+1}. #{key_info}")
121
- end
122
- else
123
- key_index = 0
124
- end
125
-
126
- key_id = secret_keys[key_index].sha
127
-
128
- # can't use this, it includes signatures:
129
- #puts GPGME::Key.export(key_id, :armor => true, :export_options => :export_minimal)
130
-
131
- # export with signatures removed:
132
- return `gpg --armor --export-options export-minimal --export #{key_id}`.strip
133
- end
134
-
135
- end
136
- end
@@ -1,50 +0,0 @@
1
- module LeapCli; module Commands
2
-
3
- extend self
4
- extend LeapCli::Util
5
- extend LeapCli::Util::RemoteCommand
6
-
7
- def path(name)
8
- Path.named_path(name)
9
- end
10
-
11
- #
12
- # keeps prompting the user for a numbered choice, until they pick a good one or bail out.
13
- #
14
- # block is yielded and is responsible for rendering the choices.
15
- #
16
- def numbered_choice_menu(msg, items, &block)
17
- while true
18
- say("\n" + msg + ':')
19
- items.each_with_index &block
20
- say("q. quit")
21
- index = ask("number 1-#{items.length}> ")
22
- if index.empty?
23
- next
24
- elsif index =~ /q/
25
- bail!
26
- else
27
- i = index.to_i - 1
28
- if i < 0 || i >= items.length
29
- bail!
30
- else
31
- return i
32
- end
33
- end
34
- end
35
- end
36
-
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
- end; end
@@ -1,197 +0,0 @@
1
- autoload :IPAddr, 'ipaddr'
2
- require 'fileutils'
3
-
4
- module LeapCli; module Commands
5
-
6
- desc "Manage local virtual machines."
7
- long_desc "This command provides a convient way to manage Vagrant-based virtual machines. If FILTER argument is missing, the command runs on all local virtual machines. The Vagrantfile is automatically generated in 'test/Vagrantfile'. If you want to run vagrant commands manually, cd to 'test'."
8
- command [:local, :l] do |local|
9
- local.desc 'Starts up the virtual machine(s)'
10
- local.arg_name 'FILTER', :optional => true #, :multiple => false
11
- local.command :start do |start|
12
- start.flag(:basebox,
13
- :desc => "The basebox to use. This value is passed to vagrant as the "+
14
- "`config.vm.box` option. The value here should be the name of an installed box or a "+
15
- "shorthand name of a box in HashiCorp's Atlas.",
16
- :arg_name => 'BASEBOX',
17
- :default_value => 'LEAP/wheezy'
18
- )
19
- start.action do |global_options,options,args|
20
- vagrant_command(["up", "sandbox on"], args, options)
21
- end
22
- end
23
-
24
- local.desc 'Shuts down the virtual machine(s)'
25
- local.arg_name 'FILTER', :optional => true #, :multiple => false
26
- local.command :stop do |stop|
27
- stop.action do |global_options,options,args|
28
- if global_options[:yes]
29
- vagrant_command("halt --force", args)
30
- else
31
- vagrant_command("halt", args)
32
- end
33
- end
34
- end
35
-
36
- local.desc 'Destroys the virtual machine(s), reclaiming the disk space'
37
- local.arg_name 'FILTER', :optional => true #, :multiple => false
38
- local.command :destroy do |destroy|
39
- destroy.action do |global_options,options,args|
40
- if global_options[:yes]
41
- vagrant_command("destroy --force", args)
42
- else
43
- vagrant_command("destroy", args)
44
- end
45
- end
46
- end
47
-
48
- local.desc 'Print the status of local virtual machine(s)'
49
- local.arg_name 'FILTER', :optional => true #, :multiple => false
50
- local.command :status do |status|
51
- status.action do |global_options,options,args|
52
- vagrant_command("status", args)
53
- end
54
- end
55
-
56
- local.desc 'Saves the current state of the virtual machine as a new snapshot'
57
- local.arg_name 'FILTER', :optional => true #, :multiple => false
58
- local.command :save do |status|
59
- status.action do |global_options,options,args|
60
- vagrant_command("sandbox commit", args)
61
- end
62
- end
63
-
64
- local.desc 'Resets virtual machine(s) to the last saved snapshot'
65
- local.arg_name 'FILTER', :optional => true #, :multiple => false
66
- local.command :reset do |reset|
67
- reset.action do |global_options,options,args|
68
- vagrant_command("sandbox rollback", args)
69
- end
70
- end
71
- end
72
-
73
- public
74
-
75
- #
76
- # returns the path to a vagrant ssh key file.
77
- #
78
- # if the vagrant.key file is owned by root or ourselves, then
79
- # we need to make sure that it owned by us and not world readable.
80
- #
81
- def vagrant_ssh_key_file
82
- file_path = File.expand_path('../../../vendor/vagrant_ssh_keys/vagrant.key', File.dirname(__FILE__))
83
- Util.assert_files_exist! file_path
84
- uid = File.new(file_path).stat.uid
85
- if uid == 0 || uid == Process.euid
86
- FileUtils.install file_path, '/tmp/vagrant.key', :mode => 0600
87
- file_path = '/tmp/vagrant.key'
88
- end
89
- return file_path
90
- end
91
-
92
- protected
93
-
94
- def vagrant_command(cmds, args, options={})
95
- vagrant_setup(options)
96
- cmds = cmds.to_a
97
- if args.empty?
98
- nodes = [""]
99
- else
100
- nodes = manager.filter(args)[:environment => "local"].field(:name)
101
- end
102
- if nodes.any?
103
- vagrant_dir = File.dirname(Path.named_path(:vagrantfile))
104
- exec = ["cd #{vagrant_dir}"]
105
- cmds.each do |cmd|
106
- nodes.each do |node|
107
- exec << "vagrant #{cmd} #{node}"
108
- end
109
- end
110
- execute exec.join('; ')
111
- else
112
- bail! "No nodes found. This command only works on nodes with ip_address in the network #{LeapCli.leapfile.vagrant_network}"
113
- end
114
- end
115
-
116
- private
117
-
118
- def vagrant_setup(options)
119
- assert_bin! 'vagrant', 'Vagrant is required for running local virtual machines. Run "sudo apt-get install vagrant".'
120
-
121
- if vagrant_version <= Gem::Version.new('1.0.0')
122
- gem_path = assert_run!('vagrant gem which sahara')
123
- if gem_path.nil? || gem_path.empty? || gem_path =~ /^ERROR/
124
- log :installing, "vagrant plugin 'sahara'"
125
- assert_run! 'vagrant gem install sahara -v 0.0.13'
126
- end
127
- else
128
- unless assert_run!('vagrant plugin list | grep sahara | cat').chars.any?
129
- log :installing, "vagrant plugin 'sahara'"
130
- assert_run! 'vagrant plugin install sahara'
131
- end
132
- end
133
- create_vagrant_file(options)
134
- end
135
-
136
- def vagrant_version
137
- @vagrant_version ||= Gem::Version.new(assert_run!('vagrant --version').split(' ')[1])
138
- end
139
-
140
- def execute(cmd)
141
- log 2, :run, cmd
142
- exec cmd
143
- end
144
-
145
- def create_vagrant_file(options)
146
- lines = []
147
- netmask = IPAddr.new('255.255.255.255').mask(LeapCli.leapfile.vagrant_network.split('/').last).to_s
148
-
149
- basebox = options[:basebox] || 'LEAP/wheezy'
150
-
151
- if vagrant_version <= Gem::Version.new('1.1.0')
152
- lines << %[Vagrant::Config.run do |config|]
153
- manager.each_node do |node|
154
- if node.vagrant?
155
- lines << %[ config.vm.define :#{node.name} do |config|]
156
- lines << %[ config.vm.box = "#{basebox}"]
157
- lines << %[ config.vm.network :hostonly, "#{node.ip_address}", :netmask => "#{netmask}"]
158
- lines << %[ config.vm.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]]
159
- lines << %[ config.vm.customize ["modifyvm", :id, "--name", "#{node.name}"]]
160
- lines << %[ #{leapfile.custom_vagrant_vm_line}] if leapfile.custom_vagrant_vm_line
161
- lines << %[ end]
162
- end
163
- end
164
- else
165
- lines << %[Vagrant.configure("2") do |config|]
166
- manager.each_node do |node|
167
- if node.vagrant?
168
- lines << %[ config.vm.define :#{node.name} do |config|]
169
- lines << %[ config.vm.box = "#{basebox}"]
170
- lines << %[ config.vm.network :private_network, ip: "#{node.ip_address}"]
171
- lines << %[ config.vm.provider "virtualbox" do |v|]
172
- lines << %[ v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]]
173
- lines << %[ v.name = "#{node.name}"]
174
- lines << %[ end]
175
- lines << %[ #{leapfile.custom_vagrant_vm_line}] if leapfile.custom_vagrant_vm_line
176
- lines << %[ end]
177
- end
178
- end
179
- end
180
-
181
- lines << %[end]
182
- lines << ""
183
- write_file! :vagrantfile, lines.join("\n")
184
- end
185
-
186
- def pick_next_vagrant_ip_address
187
- taken_ips = manager.nodes[:environment => "local"].field(:ip_address)
188
- if taken_ips.any?
189
- highest_ip = taken_ips.map{|ip| IPAddr.new(ip)}.max
190
- new_ip = highest_ip.succ
191
- else
192
- new_ip = IPAddr.new(LeapCli.leapfile.vagrant_network).succ.succ
193
- end
194
- return new_ip.to_s
195
- end
196
-
197
- end; end