Module: LeapCli::Commands

Extended by:
Commands, Util, Util::RemoteCommand
Included in:
Commands
Defined in:
lib/leap_cli.rb,
lib/leap_cli/commands/ca.rb,
lib/leap_cli/commands/new.rb,
lib/leap_cli/commands/pre.rb,
lib/leap_cli/commands/list.rb,
lib/leap_cli/commands/node.rb,
lib/leap_cli/commands/test.rb,
lib/leap_cli/commands/user.rb,
lib/leap_cli/commands/util.rb,
lib/leap_cli/commands/clean.rb,
lib/leap_cli/commands/facts.rb,
lib/leap_cli/commands/shell.rb,
lib/leap_cli/commands/deploy.rb,
lib/leap_cli/commands/compile.rb,
lib/leap_cli/commands/inspect.rb,
lib/leap_cli/commands/vagrant.rb

Defined Under Namespace

Classes: NodeTable, TagTable

Instance Method Summary collapse

Methods included from Util

assert!, assert_bin!, assert_config!, assert_files_exist!, assert_files_missing!, assert_run!, bail!, cmd_exists?, current_git_branch, current_git_commit, ensure_dir, erb_eval, exit_status, file_content_equals?, file_exists?, help!, is_git_directory?, long_running, pty_run, quit!, read_file, read_file!, relative_symlink, remove_directory!, remove_file!, rename_file!, replace_file!, write_file!

Methods included from Util::RemoteCommand

ssh_connect

Instance Method Details

#get_node_from_args(args, options = {}) ⇒ Object



145
146
147
148
149
150
151
152
153
# File 'lib/leap_cli/commands/node.rb', line 145

def get_node_from_args(args, options={})
  node_name = args.first
  node = manager.node(node_name)
  if node.nil? && options[:include_disabled]
    node = manager.disabled_node(node_name)
  end
  assert!(node, "Node '#{node_name}' not found.")
  node
end

#numbered_choice_menu(msg, items, &block) ⇒ Object

keeps prompting the user for a numbered choice, until they pick a good one or bail out.

block is yielded and is responsible for rendering the choices.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/leap_cli/commands/util.rb', line 16

def numbered_choice_menu(msg, items, &block)
  while true
    say("\n" + msg + ':')
    items.each_with_index &block
    say("q. quit")
    index = ask("number 1-#{items.length}> ")
    if index.empty?
      next
    elsif index =~ /q/
      bail!
    else
      i = index.to_i - 1
      if i < 0 || i >= items.length
        bail!
      else
        return i
      end
    end
  end
end

#parse_node_list(nodes) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/leap_cli/commands/util.rb', line 38

def parse_node_list(nodes)
  if nodes.is_a? Config::Object
    Config::ObjectList.new(nodes)
  elsif nodes.is_a? Config::ObjectList
    nodes
  elsif nodes.is_a? String
    manager.filter!(nodes)
  else
    bail! "argument error"
  end
end

#path(name) ⇒ Object



7
8
9
# File 'lib/leap_cli/commands/util.rb', line 7

def path(name)
  Path.named_path(name)
end

#pick_pgp_keyObject

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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/leap_cli/commands/user.rb', line 100

def pick_pgp_key
  secret_keys = GPGME::Key.find(:secret)
  if secret_keys.empty?
    log "Skipping OpenPGP setup because I could not find any OpenPGP keys for you"
    return nil
  end

  assert_bin! 'gpg'

  if secret_keys.length > 1
    key_index = numbered_choice_menu('Choose your OpenPGP public key', secret_keys) do |key, i|
      key_info = key.to_s.split("\n")[0..1].map{|line| line.sub(/^\s*(sec|uid)\s*/,'')}.join(' -- ')
      say("#{i+1}. #{key_info}")
    end
  else
    key_index = 0
  end

  key_id = secret_keys[key_index].sha

  # can't use this, it includes signatures:
  #puts GPGME::Key.export(key_id, :armor => true, :export_options => :export_minimal)

  # export with signatures removed:
  return `gpg --armor --export-options export-minimal --export #{key_id}`.strip
end

#pick_ssh_keyObject

let the the user choose among the ssh public keys that we encounter, or just pick the key if there is only one.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/leap_cli/commands/user.rb', line 69

def pick_ssh_key
  ssh_keys = []
  Dir.glob("#{ENV['HOME']}/.ssh/*.pub").each do |keyfile|
    ssh_keys << SshKey.load(keyfile)
  end

  if `which ssh-add`.strip.any?
    `ssh-add -L 2> /dev/null`.split("\n").compact.each do |line|
      key = SshKey.load(line)
      key.comment = 'ssh-agent'
      ssh_keys << key unless ssh_keys.include?(key)
    end
  end
  ssh_keys.compact!

  assert! ssh_keys.any?, 'Sorry, could not find any SSH public key for you. Have you run ssh-keygen?'

  if ssh_keys.length > 1
    key_index = numbered_choice_menu('Choose your SSH public key', ssh_keys.collect(&:summary)) do |line, i|
      say("#{i+1}. #{line}")
    end
  else
    key_index = 0
  end

  return ssh_keys[key_index]
end

#update_known_hostsObject

generates the known_hosts file.

we do a ‘late’ binding on the hostnames and ip part of the ssh pub key record in order to allow for the possibility that the hostnames or ip has changed in the node configuration.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/leap_cli/commands/node.rb', line 127

def update_known_hosts
  buffer = StringIO.new
  buffer << "#\n"
  buffer << "# This file is automatically generated by the command `leap`. You should NOT modify this file.\n"
  buffer << "# Instead, rerun `leap node init` on whatever node is causing SSH problems.\n"
  buffer << "#\n"
  manager.nodes.keys.sort.each do |node_name|
    node = manager.nodes[node_name]
    hostnames = [node.name, node.domain.internal, node.domain.full, node.ip_address].join(',')
    pub_key = read_file([:node_ssh_pub_key,node.name])
    if pub_key
      buffer << [hostnames, pub_key].join(' ')
      buffer << "\n"
    end
  end
  write_file!(:known_hosts, buffer.string)
end

#vagrant_ssh_key_fileObject

returns the path to a vagrant ssh key file.

if the vagrant.key file is owned by root or ourselves, then we need to make sure that it owned by us and not world readable.



74
75
76
77
78
79
80
81
82
83
# File 'lib/leap_cli/commands/vagrant.rb', line 74

def vagrant_ssh_key_file
  file_path = File.expand_path('../../../vendor/vagrant_ssh_keys/vagrant.key', File.dirname(__FILE__))
  Util.assert_files_exist! file_path
  uid = File.new(file_path).stat.uid
  if uid == 0 || uid == Process.euid
    FileUtils.install file_path, '/tmp/vagrant.key', :mode => 0600
    file_path = '/tmp/vagrant.key'
  end
  return file_path
end