conjur-cli 4.9.3 → 4.10.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5d219c046cb6b4a44c0b1754f925b0ea77882eb2
4
+ data.tar.gz: 2986ef662a9d837d49e30e66b3d465d82b541099
5
+ SHA512:
6
+ metadata.gz: 4ef2f8845165add6f0e3c0988f5b919bc241194738f2561190bf2c7b159394f0b3db202efa854123dd3e28a6aae0a60add5b618844ab7feae2707f70dc44f598
7
+ data.tar.gz: 88176c1f04a89cc484dc6cfc7c4f32aa7a9938d1818e5e29a44f3d9799642277929c41314234d6259120233ac080d4a93e5130d0820592cdec80a267f16deb06
data/.gitignore CHANGED
@@ -27,3 +27,5 @@ tmp
27
27
  .idea
28
28
  .rvmrc
29
29
  update_ci.sh
30
+ .ruby-version
31
+ .ruby-gemset
data/Gemfile CHANGED
@@ -3,8 +3,9 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in conjur.gemspec
4
4
  gemspec
5
5
 
6
- gem 'conjur-api', '>=4.8', git: 'https://github.com/conjurinc/api-ruby.git', branch: 'master'
6
+ gem 'conjur-api', git: 'https://github.com/conjurinc/api-ruby.git', branch: 'master'
7
7
 
8
8
  group :test, :development do
9
9
  gem 'pry'
10
+ gem 'ruby-prof'
10
11
  end
data/Rakefile CHANGED
@@ -16,4 +16,35 @@ task :jenkins => ['ci:setup:rspec', :spec, 'ci:setup:cucumber_report_cleanup'] d
16
16
  File.write('build_number', ENV['BUILD_NUMBER']) if ENV['BUILD_NUMBER']
17
17
  end
18
18
 
19
- task default: [:spec, :features]
19
+ task :completions do
20
+ # having 'lib' in the load path, which happens to be the case when running rake,
21
+ # messes up GLIs commands_from
22
+ $:.delete('lib')
23
+ require 'conjur/cli'
24
+ require 'yaml'
25
+
26
+ Conjur::CLI.init!
27
+ def ignore? name
28
+ name = name.to_s
29
+ # Ignore GLIs internal commands and one of our deprecated ones
30
+ name.start_with?('_') or name.include?(':')
31
+ end
32
+
33
+ def visit cmd
34
+ child = {}
35
+ cmd.commands.each do |name, ccmd|
36
+ next if ignore?(name)
37
+ child[name] = visit(ccmd)
38
+ child[name] = true if child[name].empty?
39
+ end
40
+ child
41
+ end
42
+
43
+ commands = visit Conjur::CLI
44
+
45
+ File.open("#{File.dirname(__FILE__)}/bin/_conjur_completions.yaml", "w") do |io|
46
+ YAML.dump(commands, io)
47
+ end
48
+ end
49
+
50
+ task default: [:completions, :spec, :features]
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (C) 2013 Conjur Inc
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ # this software and associated documentation files (the "Software"), to deal in
7
+ # the Software without restriction, including without limitation the rights to
8
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ # the Software, and to permit persons to whom the Software is furnished to do so,
10
+ # subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+ #
22
+
23
+ # You can use this file by adding the following to something that gets sourced (like .bashrc)
24
+ #
25
+ # _conjur()
26
+ # {
27
+ # COMPREPLY=($(_conjur_completions $COMP_CWORD ${COMP_WORDS[@]}))
28
+ # }
29
+ # complete -F _conjur conjur
30
+
31
+ require 'yaml'
32
+ completions = File.open("#{File.dirname(__FILE__)}/_conjur_completions.yaml"){ |_| YAML.load(_) }
33
+ # ARGV[0] is the index into ARGV[1...] of the current word
34
+ index = ARGV[0].to_i - 1
35
+ words = ARGV[2..-1]
36
+ parents = words[0...index]
37
+ word = words[index] || ""
38
+
39
+ current = completions
40
+ previous = current
41
+ until parents.empty? or current.nil? or not current.kind_of?(Hash) # make sure to stop if we hit a 'true' entry
42
+ previous = current
43
+ current = current[parents.shift.to_sym]
44
+ end
45
+
46
+ if current.kind_of?(Hash)
47
+ puts current.keys.map(&:to_s).select{|k| k.start_with?(word)}.sort.join("\n")
48
+ end
@@ -0,0 +1,96 @@
1
+ ---
2
+ :help: true
3
+ :asset:
4
+ :create: true
5
+ :show: true
6
+ :exists: true
7
+ :list: true
8
+ :members:
9
+ :add: true
10
+ :remove: true
11
+ :audit:
12
+ :all: true
13
+ :role: true
14
+ :resource: true
15
+ :authn:
16
+ :login: true
17
+ :authenticate: true
18
+ :logout: true
19
+ :whoami: true
20
+ :env:
21
+ :run: true
22
+ :check: true
23
+ :template: true
24
+ :help: true
25
+ :group:
26
+ :create: true
27
+ :list: true
28
+ :show: true
29
+ :members:
30
+ :list: true
31
+ :add: true
32
+ :remove: true
33
+ :host:
34
+ :create: true
35
+ :show: true
36
+ :list: true
37
+ :enroll: true
38
+ :layers: true
39
+ :id:
40
+ :create: true
41
+ :init: true
42
+ :layer:
43
+ :create: true
44
+ :list: true
45
+ :show: true
46
+ :provision: true
47
+ :hosts:
48
+ :permit: true
49
+ :deny: true
50
+ :permitted_roles: true
51
+ :add: true
52
+ :remove: true
53
+ :policy:
54
+ :load: true
55
+ :pubkeys:
56
+ :show: true
57
+ :names: true
58
+ :add: true
59
+ :delete: true
60
+ :resource:
61
+ :create: true
62
+ :show: true
63
+ :exists: true
64
+ :permit: true
65
+ :deny: true
66
+ :check: true
67
+ :give: true
68
+ :permitted_roles: true
69
+ :annotate: true
70
+ :annotation: true
71
+ :annotations: true
72
+ :list: true
73
+ :role:
74
+ :create: true
75
+ :exists: true
76
+ :memberships: true
77
+ :members: true
78
+ :grant_to: true
79
+ :revoke_from: true
80
+ :script:
81
+ :execute: true
82
+ :secret:
83
+ :create: true
84
+ :value: true
85
+ :user:
86
+ :create: true
87
+ :show: true
88
+ :list: true
89
+ :update_password: true
90
+ :variable:
91
+ :create: true
92
+ :show: true
93
+ :list: true
94
+ :values:
95
+ :add: true
96
+ :value: true
data/conjur.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
 
18
18
 
19
19
  gem.add_dependency 'activesupport'
20
- gem.add_dependency 'conjur-api', '>=4.8'
20
+ gem.add_dependency 'conjur-api', '>=4.9.0'
21
21
  gem.add_dependency 'gli', '>=2.8.0'
22
22
  gem.add_dependency 'highline'
23
23
  gem.add_dependency 'netrc'
@@ -26,7 +26,7 @@ Gem::Specification.new do |gem|
26
26
 
27
27
  gem.add_runtime_dependency 'cas_rest_client'
28
28
 
29
- gem.add_development_dependency 'rspec'
29
+ gem.add_development_dependency 'rspec', '>= 2.14', '< 3.0'
30
30
  gem.add_development_dependency 'simplecov'
31
31
  gem.add_development_dependency 'aruba'
32
32
  gem.add_development_dependency 'ci_reporter', '~> 1.8'
data/lib/conjur/authn.rb CHANGED
@@ -18,13 +18,12 @@
18
18
  # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
- require 'highline'
22
- require 'active_support'
23
21
  require 'active_support/deprecation'
24
22
  require 'conjur/api'
25
23
  require 'netrc'
26
24
 
27
25
  module Conjur::Authn
26
+ autoload :API, 'conjur/authn-api'
28
27
  class << self
29
28
  def login(options = {})
30
29
  delete_credentials
@@ -32,6 +31,7 @@ module Conjur::Authn
32
31
  end
33
32
 
34
33
  def authenticate(options = {})
34
+ require 'conjur/api'
35
35
  Conjur::API.authenticate(*get_credentials(options))
36
36
  end
37
37
 
@@ -74,12 +74,17 @@ module Conjur::Authn
74
74
  def ask_for_credentials(options = {})
75
75
  raise "No credentials provided or found" if options[:noask]
76
76
 
77
+
77
78
  # also use stderr here, because we might be prompting for a password as part
78
79
  # of a command like user:create that we'd want to send to a file.
80
+ require 'highline'
81
+ require 'conjur/api'
82
+
79
83
  hl = HighLine.new $stdin, $stderr
80
84
 
81
85
  user = options[:username] || hl.ask("Enter your username to log into Conjur: ")
82
86
  pass = options[:password] || hl.ask("Please enter your password (it will not be echoed): "){ |q| q.echo = false }
87
+
83
88
  api_key = if cas_server = options[:"cas-server"]
84
89
  Conjur::API.login_cas(user, pass, cas_server)
85
90
  else
@@ -87,8 +92,13 @@ module Conjur::Authn
87
92
  end
88
93
  @credentials = [user, api_key]
89
94
  end
90
-
91
- def connect(cls = Conjur::API, options = {})
95
+
96
+ def connect(cls = nil, options = {})
97
+ if cls.nil?
98
+ require 'conjur/api'
99
+ require 'conjur/base'
100
+ cls = Conjur::API
101
+ end
92
102
  cls.new_from_key(*get_credentials(options))
93
103
  end
94
104
  end
data/lib/conjur/cli.rb CHANGED
@@ -19,11 +19,24 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  require 'gli'
22
- require 'conjur/config'
23
- require 'conjur/log'
24
- require 'conjur/identifier_manipulation'
22
+ # need this to prevent an active support bug in some versions
23
+ require 'active_support'
24
+ require 'active_support/deprecation'
25
+
25
26
 
26
27
  module Conjur
28
+ autoload :Config, 'conjur/config'
29
+ autoload :Log, 'conjur/log'
30
+ autoload :IdentifierManipulation, 'conjur/identifier_manipulation'
31
+ autoload :Authn, 'conjur/authn'
32
+ autoload :Command, 'conjur/command'
33
+ autoload :DSL, 'conjur/dsl/runner'
34
+ autoload :DSLCommand, 'conjur/command/dsl_command'
35
+
36
+ module Audit
37
+ autoload :Follower, 'conjur/audit/follower'
38
+ end
39
+
27
40
  class CLI
28
41
  extend GLI::App
29
42
 
@@ -31,36 +44,58 @@ module Conjur
31
44
  def load_config
32
45
  Conjur::Config.load
33
46
  end
34
-
47
+
35
48
  def apply_config
36
49
  Conjur::Config.apply
37
50
  end
38
- end
39
-
40
- load_config
41
51
 
42
- Conjur::Config.plugins.each do |plugin|
43
- begin
44
- filename = "conjur-asset-#{plugin}"
45
- require filename
46
- rescue LoadError
47
- warn "Could not load plugin '#{plugin}' specified in your config file.\nMake sure you have the #{filename}-api gem installed."
52
+ # Horible hack!
53
+ # We want to support legacy commands like host:list, but we don't want to
54
+ # do too much effort, and GLIs support for aliasing doesn't work out so well with
55
+ # subcommands.
56
+ def run args
57
+ args = args.shift.split(':') + args unless args.empty?
58
+ super args
59
+ end
60
+
61
+ def load_plugins
62
+ # These used to be plugins but now they are in the core CLI
63
+ plugins = Conjur::Config.plugins - %w(layer pubkeys)
64
+
65
+ plugins.each do |plugin|
66
+ begin
67
+ filename = "conjur-asset-#{plugin}"
68
+ require filename
69
+ rescue LoadError
70
+ warn "Could not load plugin '#{plugin}' specified in your config file.\nMake sure you have the #{filename}-api gem installed."
71
+ end
72
+ end
73
+ end
74
+
75
+ # This makes our generate-commands script a little bit cleaner. We can call this from that script
76
+ # to ensure that commands for all plugins are loaded.
77
+ def init!
78
+ subcommand_option_handling :normal
79
+ load_config
80
+ apply_config
81
+ load_plugins
82
+ commands_from 'conjur/command'
48
83
  end
49
84
  end
50
85
 
51
- commands_from 'conjur/command'
86
+ init!
52
87
 
53
88
  pre do |global,command,options,args|
89
+ require 'conjur/api'
54
90
 
55
- if command.name_for_help.first == "init" and options.has_key?("account")
91
+ if command.name_for_help.first == "init" and options.has_key?("account")
56
92
  ENV["CONJUR_ACCOUNT"]=options["account"]
57
93
  end
58
94
  apply_config
59
-
60
95
  require 'active_support/core_ext'
61
96
  options.delete_if{|k,v| v.blank?}
62
97
  options.symbolize_keys!
63
-
98
+
64
99
  if as_group = options.delete(:"as-group")
65
100
  group = Conjur::Command.api.group(as_group)
66
101
  role = Conjur::Command.api.role(group.roleid)
@@ -77,6 +112,7 @@ module Conjur
77
112
  end
78
113
 
79
114
  on_error do |exception|
115
+ require 'rest-client'
80
116
  if exception.is_a?(RestClient::Exception)
81
117
  begin
82
118
  body = JSON.parse(exception.response.body)
@@ -85,7 +121,7 @@ module Conjur
85
121
  $stderr.puts exception.response.body if exception.response
86
122
  end
87
123
  end
88
-
124
+ require 'conjur/log'
89
125
  if Conjur.log
90
126
  Conjur.log << "error: #{exception}\n#{exception.backtrace.join("\n") rescue 'NO BACKTRACE?'}"
91
127
  end
@@ -20,21 +20,21 @@
20
20
  #
21
21
  module Conjur
22
22
  class Command
23
- extend IdentifierManipulation
23
+ extend Conjur::IdentifierManipulation
24
24
 
25
25
  @@api = nil
26
26
 
27
27
  class << self
28
28
  attr_accessor :prefix
29
-
30
- def method_missing *a
31
- Conjur::CLI.send *a
29
+ def method_missing *a, &b
30
+ Conjur::CLI.send *a, &b
32
31
  end
33
-
32
+
34
33
  def command name, *a, &block
35
- Conjur::CLI.command "#{prefix}:#{name}", *a, &block
34
+ name = "#{prefix}:#{name}" if prefix
35
+ Conjur::CLI.command(name, *a, &block)
36
36
  end
37
-
37
+
38
38
  def require_arg(args, name)
39
39
  args.shift or raise "Missing parameter: #{name}"
40
40
  end
@@ -42,8 +42,14 @@ module Conjur
42
42
  def api
43
43
  @@api ||= Conjur::Authn.connect
44
44
  end
45
-
45
+
46
+ # Prevent a deprecated command from being displayed in the help output
47
+ def hide_docs(command)
48
+ def command.nodoc; true end
49
+ end
50
+
46
51
  def acting_as_option(command)
52
+ return if command.flags.member?(:"as-group") # avoid duplicate flags
47
53
  command.arg_name 'Perform all actions as the specified Group'
48
54
  command.flag [:"as-group"]
49
55
 
@@ -52,6 +58,7 @@ module Conjur
52
58
  end
53
59
 
54
60
  def command_options_for_list(c)
61
+ return if c.flags.member?(:role) # avoid duplicate flags
55
62
  c.desc "Role to act as. By default, the current logged-in role is used."
56
63
  c.flag [:role]
57
64
 
@@ -74,9 +81,10 @@ module Conjur
74
81
  def command_impl_for_list(global_options, options, args)
75
82
  opts = options.slice(:search, :limit, :options, :kind)
76
83
  opts[:acting_as] = options[:role] if options[:role]
84
+ opts[:search]=opts[:search].gsub('-',' ') if opts[:search]
77
85
  resources = api.resources(opts)
78
86
  if options[:ids]
79
- puts resources.map(&:resourceid)
87
+ puts JSON.pretty_generate(resources.map(&:resourceid))
80
88
  else
81
89
  resources = resources.map &:attributes
82
90
  unless options[:'raw-annotations']
@@ -114,10 +122,14 @@ module Conjur
114
122
  elsif obj.respond_to?(:id)
115
123
  obj.id
116
124
  else
117
- JSON.pretty_generate obj
125
+ begin
126
+ JSON.pretty_generate(obj)
127
+ rescue JSON::GeneratorError
128
+ obj.to_json
129
+ end
118
130
  end
119
131
  puts str
120
132
  end
121
133
  end
122
134
  end
123
- end
135
+ end