summaryrefslogtreecommitdiff
path: root/lib/leap_cli/commands/inspect.rb
blob: fbd577e5770d85714ad6a4acaa1ea8b84969824c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
96
97
98
99
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
module LeapCli; module Commands

  desc 'Prints details about a file. Alternately, the argument FILE can be the name of a node, service or tag.'
  arg_name 'FILE'
  command [:inspect, :i] do |c|
    c.switch 'base', :desc => 'Inspect the FILE from the provider_base (i.e. without local inheritance).', :negatable => false
    c.action do |global_options,options,args|
      object = args.first
      assert! object, 'A file path or node/service/tag name is required'
      method = inspection_method(object)
      if method && defined?(method)
        self.send(method, object, options)
      else
        log "Sorry, I don't know how to inspect that."
      end
    end
  end

  private

  FTYPE_MAP = {
    "PEM certificate"         => :inspect_x509_cert,
    "PEM RSA private key"     => :inspect_x509_key,
    "OpenSSH RSA public key"  => :inspect_ssh_pub_key,
    "PEM certificate request" => :inspect_x509_csr
  }

  def inspection_method(object)
    if File.exist?(object)
      ftype = `file #{object}`.split(':').last.strip
      log 2, "file is of type '#{ftype}'"
      if FTYPE_MAP[ftype]
        FTYPE_MAP[ftype]
      elsif File.extname(object) == ".json"
        full_path = File.expand_path(object, Dir.pwd)
        if path_match?(:node_config, full_path)
          :inspect_node
        elsif path_match?(:service_config, full_path)
          :inspect_service
        elsif path_match?(:tag_config, full_path)
          :inspect_tag
        elsif path_match?(:provider_config, full_path) || path_match?(:provider_env_config, full_path)
          :inspect_provider
        elsif path_match?(:common_config, full_path)
          :inspect_common
        else
          nil
        end
      end
    elsif manager.nodes[object]
      :inspect_node
    elsif manager.services[object]
      :inspect_service
    elsif manager.tags[object]
      :inspect_tag
    elsif object == "common"
      :inspect_common
    elsif object == "provider"
      :inspect_provider
    else
      nil
    end
  end

  #
  # inspectors
  #

  def inspect_x509_key(file_path, options)
    assert_bin! 'openssl'
    puts assert_run! 'openssl rsa -in %s -text -check' % file_path
  end

  def inspect_x509_cert(file_path, options)
    assert_bin! 'openssl'
    puts assert_run! 'openssl x509 -in %s -text -noout' % file_path
    log 0, :"SHA1 fingerprint", X509.fingerprint("SHA1", file_path)
    log 0, :"SHA256 fingerprint", X509.fingerprint("SHA256", file_path)
  end

  def inspect_x509_csr(file_path, options)
    assert_bin! 'openssl'
    puts assert_run! 'openssl req -text -noout -verify -in %s' % file_path
  end

  #def inspect_ssh_pub_key(file_path)
  #end

  def inspect_node(arg, options)
    inspect_json manager.nodes[name(arg)]
  end

  def inspect_service(arg, options)
    if options[:base]
      inspect_json manager.base_services[name(arg)]
    else
      inspect_json manager.services[name(arg)]
    end
  end

  def inspect_tag(arg, options)
    if options[:base]
      inspect_json manager.base_tags[name(arg)]
    else
      inspect_json manager.tags[name(arg)]
    end
  end

  def inspect_provider(arg, options)
    if options[:base]
      inspect_json manager.base_provider
    elsif arg =~ /provider\.(.*)\.json/
      inspect_json manager.env($1).provider
    else
      inspect_json manager.provider
    end
  end

  def inspect_common(arg, options)
    if options[:base]
      inspect_json manager.base_common
    else
      inspect_json manager.common
    end
  end

  #
  # helpers
  #

  def name(arg)
    File.basename(arg).sub(/\.json$/, '')
  end

  def inspect_json(config)
    if config
      puts JSON.sorted_generate(config)
    end
  end

  def path_match?(path_symbol, path)
    Dir.glob(Path.named_path([path_symbol, '*'])).include?(path)
  end

end; end