conjur-cli 2.1.3 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -16,3 +16,5 @@ spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
+ .kateproject.d
20
+ .idea
data/.kateproject ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "Conjur CLI"
3
+ , "files": [ { "git": 1 } ]
4
+ }
5
+
data/conjur.gemspec CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |gem|
5
5
  gem.authors = ["Rafa\305\202 Rzepecki", "Kevin Gilpin"]
6
6
  gem.email = ["divided.mind@gmail.com", "kevin.gilpin@inscitiv.com",]
7
7
  gem.summary = %q{Conjur command line interface}
8
- gem.homepage = ""
8
+ gem.homepage = "https://github.com/inscitiv/cli-ruby"
9
9
 
10
10
  gem.files = `git ls-files`.split($\) + Dir['build_number']
11
11
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
data/lib/conjur/authn.rb CHANGED
@@ -43,8 +43,11 @@ module Conjur::Authn
43
43
 
44
44
  def ask_for_credentials(options = {})
45
45
  raise "No credentials provided or found" if options[:noask]
46
-
47
- hl = HighLine.new
46
+
47
+ # also use stderr here, because we might be prompting for a password as part
48
+ # of a command like user:create that we'd want to send to a file.
49
+ hl = HighLine.new $stdin, $stderr
50
+
48
51
  user = options[:username] || hl.ask("Enter your username to log into Conjur: ")
49
52
  pass = options[:password] || hl.ask("Please enter your password (it will not be echoed): "){ |q| q.echo = false }
50
53
  api_key = if cas_server = options[:"cas-server"]
data/lib/conjur/cli.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'gli'
2
2
  require 'conjur/config'
3
+ require 'conjur/log'
3
4
 
4
5
  module Conjur
5
6
  class CLI
@@ -9,7 +10,9 @@ module Conjur
9
10
  def load_config
10
11
  [ File.join("/etc", "conjur.conf"), ( ENV['CONJURRC'] || File.join(ENV['HOME'], ".conjurrc") ) ].each do |f|
11
12
  if File.exists?(f)
12
- $stderr.puts "Loading #{f}"
13
+ if Conjur.log
14
+ Conjur.log << "Loading #{f}\n"
15
+ end
13
16
  Conjur::Config.merge YAML.load(IO.read(f))
14
17
  end
15
18
  end
@@ -21,7 +24,7 @@ module Conjur
21
24
  ENV['CONJUR_ENV'] = Config[:env] || "production"
22
25
  ENV['CONJUR_STACK'] = Config[:stack] if Config[:stack]
23
26
  ENV['CONJUR_STACK'] ||= 'v3' if ENV['CONJUR_ENV'] == 'production'
24
- ENV['CONJUR_ACCOUNT'] = Config[:account] or raise "Missing configuration setting: account"
27
+ ENV['CONJUR_ACCOUNT'] = Config[:account] or raise "Missing configuration setting: account. Please set it in ~/.conjurrc"
25
28
 
26
29
  Conjur::Config.plugins.each do |plugin|
27
30
  require "conjur-asset-#{plugin}"
@@ -29,8 +32,10 @@ module Conjur
29
32
 
30
33
  commands_from 'conjur/command'
31
34
 
32
- $stderr.puts "Using host #{Conjur::Authn::API.host}"
33
-
35
+ if Conjur.log
36
+ Conjur.log << "Using host #{Conjur::Authn::API.host}\n"
37
+ end
38
+
34
39
  pre do |global,command,options,args|
35
40
  require 'active_support/core_ext'
36
41
  options.delete_if{|k,v| v.blank?}
@@ -10,7 +10,7 @@ class Conjur::Command::Assets < Conjur::Command
10
10
  acting_as_option(c)
11
11
 
12
12
  c.action do |global_options, options, args|
13
- kind = require_arg(args, 'kind')
13
+ kind = require_arg(args, 'kind').gsub('-', '_')
14
14
 
15
15
  m = "create_#{kind}"
16
16
  record = if api.method(m).arity == 1
@@ -31,7 +31,7 @@ class Conjur::Command::Assets < Conjur::Command
31
31
  arg_name "kind id"
32
32
  command :show do |c|
33
33
  c.action do |global_options,options,args|
34
- kind = require_arg(args, "kind")
34
+ kind = require_arg(args, "kind").gsub('-', '_')
35
35
  id = require_arg(args, "resource-id")
36
36
  display api.send(kind, id).attributes
37
37
  end
@@ -41,7 +41,7 @@ class Conjur::Command::Assets < Conjur::Command
41
41
  arg_name "kind id"
42
42
  command :exists do |c|
43
43
  c.action do |global_options,options,args|
44
- kind = require_arg(args, "kind")
44
+ kind = require_arg(args, "kind").gsub('-', '_')
45
45
  id = require_arg(args, "id")
46
46
  puts api.send(kind, id).exists?
47
47
  end
@@ -51,7 +51,7 @@ class Conjur::Command::Assets < Conjur::Command
51
51
  arg_name "kind"
52
52
  command :list do |c|
53
53
  c.action do |global_options,options,args|
54
- kind = require_arg(args, "kind")
54
+ kind = require_arg(args, "kind").gsub('-', '_')
55
55
  api.send(kind.pluralize).each do |e|
56
56
  display(e, options)
57
57
  end
@@ -35,4 +35,15 @@ DESC
35
35
  Conjur::Authn.delete_credentials
36
36
  end
37
37
  end
38
+
39
+ desc "Prints out the current logged in username"
40
+ command :whoami do |c|
41
+ c.action do
42
+ if creds = Conjur::Authn.read_credentials
43
+ puts creds[0]
44
+ else
45
+ exit_now! 'Not logged in.', -1
46
+ end
47
+ end
48
+ end
38
49
  end
@@ -0,0 +1,25 @@
1
+ require 'conjur/command'
2
+
3
+ class Conjur::Command::Field < Conjur::Command
4
+ self.prefix = :field
5
+
6
+ desc "Selects a field from structured input"
7
+ arg_name "pattern (value | STDIN)"
8
+ command :select do |c|
9
+ c.action do |global_options,options,args|
10
+ pattern = require_arg(args, 'pattern')
11
+ value = args.shift || STDIN.read
12
+
13
+ require 'json'
14
+ json = JSON.parse(value)
15
+ class << json
16
+ def get_binding
17
+ record = self
18
+
19
+ binding
20
+ end
21
+ end
22
+ puts json.get_binding.eval(pattern)
23
+ end
24
+ end
25
+ end
@@ -29,6 +29,22 @@ class Conjur::Command::Groups < Conjur::Command
29
29
 
30
30
  group = api.group(group)
31
31
  api.role(group.roleid).grant_to member, !!options[:admin]
32
+
33
+ puts "Membership granted"
34
+ end
35
+ end
36
+
37
+ desc "Remove a group member"
38
+ arg_name "group member"
39
+ command :"members:remove" do |c|
40
+ c.action do |global_options,options,args|
41
+ group = require_arg(args, 'group')
42
+ member = require_arg(args, 'member')
43
+
44
+ group = api.group(group)
45
+ api.role(group.roleid).revoke_from member
46
+
47
+ puts "Membership revoked"
32
48
  end
33
49
  end
34
50
  end
@@ -17,7 +17,11 @@ class Conjur::Command::Users < Conjur::Command
17
17
 
18
18
  opts = options.slice(:ownerid)
19
19
  if options[:p]
20
- hl = HighLine.new
20
+
21
+ # use stderr to allow output redirection, e.g.
22
+ # conjur user:create -p username > user.json
23
+ hl = HighLine.new($stdin, $stderr)
24
+
21
25
  password = hl.ask("Enter the password (it will not be echoed): "){ |q| q.echo = false }
22
26
  confirmation = hl.ask("Confirm the password: "){ |q| q.echo = false }
23
27
 
@@ -48,7 +48,7 @@ class Conjur::Command::Variables < Conjur::Command
48
48
 
49
49
  c.action do |global_options,options,args|
50
50
  id = require_arg(args, 'variable')
51
- puts api.variable(id).value(options[:version])
51
+ $stdout.write api.variable(id).value(options[:version])
52
52
  end
53
53
  end
54
54
  end
@@ -1,3 +1,3 @@
1
1
  module Conjur
2
- VERSION = "2.1.3"
2
+ VERSION = "2.1.4"
3
3
  end
@@ -1,15 +1,40 @@
1
1
  require 'spec_helper'
2
2
  require 'tempfile'
3
+ require 'write_expectation'
3
4
 
4
5
  describe Conjur::Command::Authn do
5
6
  let(:netrcfile) { Tempfile.new 'authtest' }
7
+ let(:netrc) { Netrc.read(netrcfile.path) }
8
+ let(:host) { 'https://authn.example.com' }
9
+
6
10
  before do
7
- Conjur::Auth.stub netrc: Netrc.read(netrcfile.path)
11
+ Conjur::Authn.stub netrc: netrc, host: host
12
+ end
13
+
14
+ context "when not logged in" do
15
+ describe_command 'authn:whoami' do
16
+ it "errors out" do
17
+ expect{ invoke }.to write(/not logged in/i).to :stderr
18
+ end
19
+ end
8
20
  end
9
- describe_command 'auth:logout' do
10
- it "deletes credentials" do
11
- Conjur::Auth.should_receive :delete_credentials
12
- invoke
21
+
22
+ context "when logged in" do
23
+ let(:username) { 'dknuth' }
24
+ let(:api_key) { 'sekrit' }
25
+ before { netrc[host] = [username, api_key] }
26
+
27
+ describe_command 'authn:logout' do
28
+ it "deletes credentials" do
29
+ invoke
30
+ netrc[host].should_not be
31
+ end
32
+ end
33
+
34
+ describe_command 'authn:whoami' do
35
+ it "prints the current username to stdout" do
36
+ expect { invoke }.to write username
37
+ end
13
38
  end
14
39
  end
15
40
  end
data/spec/spec_helper.rb CHANGED
@@ -5,9 +5,12 @@ require "simplecov"
5
5
  SimpleCov.start
6
6
 
7
7
  module RSpec::Core::DSL
8
- def describe_command name, *a, &block
9
- describe name, *a do
10
- let(:invoke) { Conjur::Cli.run [name] }
8
+ def describe_command *argv, &block
9
+ describe *argv do
10
+ let(:invoke) do
11
+ Conjur::CLI.error_device = $stderr
12
+ Conjur::CLI.run argv
13
+ end
11
14
  instance_eval &block
12
15
  end
13
16
  end
@@ -0,0 +1,74 @@
1
+ # from https://gist.github.com/elgalu/5073871
2
+ require 'rspec'
3
+ require 'stringio'
4
+
5
+ # Custom matcher to test text written to standard output and standard error
6
+ #
7
+ # @example
8
+ # expect { $stderr.puts "Some random error" }.to write(/Some.* error/).to(:stderr)
9
+ #
10
+ # @example
11
+ # expect { $stderr.puts "Some specific error" }.to write('Some specific error').to(:stderr)
12
+ #
13
+ # @note http://greyblake.com/blog/2012/12/14/custom-expectations-with-rspec/
14
+ RSpec::Matchers.define :write do |message|
15
+ chain(:to) do |io|
16
+ @io = io
17
+ end
18
+
19
+ match do |block|
20
+ output =
21
+ case io
22
+ when :stdout then fake_stdout(&block)
23
+ when :stderr then fake_stderr(&block)
24
+ else fail("Allowed values for `to` are :stdout and :stderr, got `#{io.inspect}`")
25
+ end
26
+
27
+ case message
28
+ when String then output.include? message
29
+ when Regexp then output.match message
30
+ else fail("Allowed types for write `message` are String or Regexp, got `#{message.class}`")
31
+ end
32
+ end
33
+
34
+ description do
35
+ %Q[write #{message.inspect} to #{@io}]
36
+ end
37
+
38
+ def failure_message(to = 'to')
39
+ %Q[expected #{to} #{description} but got #{@buffer.inspect}]
40
+ end
41
+
42
+ failure_message_for_should do
43
+ failure_message 'to'
44
+ end
45
+
46
+ failure_message_for_should_not do
47
+ failure_message 'not to'
48
+ end
49
+
50
+ # Fake STDERR and return a string written to it.
51
+ def fake_stderr
52
+ original_stderr = $stderr
53
+ $stderr = StringIO.new
54
+ yield
55
+ @buffer = $stderr.string
56
+ ensure
57
+ $stderr = original_stderr
58
+ end
59
+
60
+ # Fake STDOUT and return a string written to it.
61
+ def fake_stdout
62
+ original_stdout = $stdout
63
+ $stdout = StringIO.new
64
+ yield
65
+ @buffer = $stdout.string
66
+ ensure
67
+ $stdout = original_stdout
68
+ end
69
+
70
+ # default IO is standard output
71
+ def io
72
+ @io ||= :stdout
73
+ end
74
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conjur-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.3
4
+ version: 2.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-04-30 00:00:00.000000000 Z
13
+ date: 2013-05-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: conjur-api
@@ -134,6 +134,7 @@ extensions: []
134
134
  extra_rdoc_files: []
135
135
  files:
136
136
  - .gitignore
137
+ - .kateproject
137
138
  - .project
138
139
  - .rvmrc
139
140
  - Gemfile
@@ -148,6 +149,7 @@ files:
148
149
  - lib/conjur/command.rb
149
150
  - lib/conjur/command/assets.rb
150
151
  - lib/conjur/command/authn.rb
152
+ - lib/conjur/command/field.rb
151
153
  - lib/conjur/command/groups.rb
152
154
  - lib/conjur/command/hosts.rb
153
155
  - lib/conjur/command/permissions.rb
@@ -160,7 +162,8 @@ files:
160
162
  - lib/conjur/version.rb
161
163
  - spec/command/authn_spec.rb
162
164
  - spec/spec_helper.rb
163
- homepage: ''
165
+ - spec/write_expectation.rb
166
+ homepage: https://github.com/inscitiv/cli-ruby
164
167
  licenses: []
165
168
  post_install_message:
166
169
  rdoc_options: []
@@ -187,3 +190,4 @@ summary: Conjur command line interface
187
190
  test_files:
188
191
  - spec/command/authn_spec.rb
189
192
  - spec/spec_helper.rb
193
+ - spec/write_expectation.rb