conjur-cli 5.2.5 → 5.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3e4d7900d35da02505f1bfb843f9f79414fc49b5
4
- data.tar.gz: 4c382758571b68d6de8c2e501c81726179cc987c
3
+ metadata.gz: 45db6cca737f188f732a2684c54952df012e4da0
4
+ data.tar.gz: c39fc7be243e1508a4a71459e77c1248efff5ba4
5
5
  SHA512:
6
- metadata.gz: 48fa15fa3e402e2d72bfffb14b8e895f5078ca2de8840abad219a76d65e07e64fd0e4c30dc7f78a16e24717738c0dc1dd31718d95ec9dd96e7c5655788df4512
7
- data.tar.gz: 27f5ef9102d531e69a8d8821d71678914632ab4a398ff00ce934b968916709194bbb0d2b2467d6723087f61220132d6af2c059ca7c1fa9f548c8663f37495c56
6
+ metadata.gz: 3c2db8ea4d3cef7dbb0c099e89fe02416dc2247a3463c9796d46ad572a591e4c7d796d17bee5f3b7eb479ebf047469491459116a654205575d2932cb36c019ea
7
+ data.tar.gz: 302e5e260a4169265c2b2cae9e7f23fcfb37197ef51532662cc71dac1fe2abd463e831c15db8b043d2e690c3bb3d9e3c16f513b21cd60d809b79e3beb3fbb438
@@ -1,3 +1,9 @@
1
+ # 5.3.0
2
+
3
+ * Add `jobs` subcommands for `ldap-sync`.
4
+ * Add `--detach` switch to `now` subcommand.
5
+ * Relax dependency gem versions.
6
+
1
7
  # 5.2.5
2
8
 
3
9
  * Fix behavior of `conjur env` when [policy plugin](https://github.com/conjurinc/conjur-asset-policy) is installed.
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ source 'https://rubygems.org'
6
6
  # Specify your gem's dependencies in conjur.gemspec
7
7
  gemspec
8
8
 
9
- gem 'conjur-api', '>= 4.26', git: 'https://github.com/conjurinc/api-ruby.git', branch: 'master'
9
+ gem 'conjur-api', '>= 4.26.2', git: 'https://github.com/conjurinc/api-ruby.git', branch: 'master'
10
10
  gem 'semantic', '>= 1.4.1', git: 'https://github.com/jlindsey/semantic.git'
11
11
 
12
12
  group :test, :development do
@@ -1,3 +1,23 @@
1
+ Transform /\$ns/ do |s|
2
+ s.gsub('$ns', namespace)
3
+ end
4
+
5
+ Transform /\$user_role/ do |s|
6
+ s.gsub('$user_role', test_user.role_id)
7
+ end
8
+
9
+ Transform /^table:/ do |table|
10
+ table.tap do |t|
11
+ t.hashes.each do |row|
12
+ row.each do |_,v|
13
+ v.gsub!('$ns', namespace)
14
+ v.gsub!('$user_role', test_user.role_id)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+
1
21
  Then /^I reset the command list/ do
2
22
  aruba.command_monitor.clear
3
23
  end
@@ -9,7 +29,6 @@ When /^the command completes successfully/ do
9
29
  end
10
30
 
11
31
  Then /^I send the audit event:/ do |event|
12
- event = event.gsub('$ns',@namespace)
13
32
  step "I run `env RESTCLIENT_LOG=stderr conjur audit send` interactively"
14
33
  last_command_started.write event
15
34
  last_command_started.close_io :stdin
@@ -19,12 +38,11 @@ end
19
38
  # this is step copypasted from https://github.com/cucumber/aruba/blob/master/lib/aruba/cucumber.rb#L24
20
39
  # original has typo in regexp, which is fixed here
21
40
  Given(/^a file named "([^"]*?)" with: '(.*?)'$/) do |file_name, file_content|
22
- file_content.gsub!('$ns',@namespace)
23
41
  write_file(file_name, file_content)
24
42
  end
25
43
 
26
44
  Given(/^a file named "([^"]*?)" with namespace substitution:$/) do |file_name, file_content|
27
- step "a file named \"#{file_name}\" with:", file_content.gsub('$ns',@namespace)
45
+ step "a file named \"#{file_name}\" with:", file_content
28
46
  end
29
47
 
30
48
  Then /^it prints the path to temporary file which contains: '(.*)'$/ do |content|
@@ -0,0 +1,24 @@
1
+ When /^I send a (GET|POST|PATCH|PUT|DELETE) request forwarded from "(.*?)" to "(.*?)"$/ do |method, ip, url|
2
+ headers['X-Forwarded-For'] = ip
3
+ step %Q{I send a #{method} request to "#{url}"}
4
+ end
5
+
6
+ When /^I send a (GET|POST|PATCH|PUT|DELETE) request forwarded from "(.*?)" to "(.*?)" with:$/ do |method, ip, url, params_table|
7
+ headers['X-Forwarded-For'] = ip
8
+ step %Q{I send a #{method} request to "#{url}" with:}, params_table
9
+ end
10
+
11
+
12
+ When /^I set the( JSON)? request body to:$/ do |is_json, body|
13
+ step("I send and accept JSON") if is_json
14
+ @body = body
15
+ end
16
+
17
+ When /^I set the( JSON)? request body to "(.*?)"/ do |is_json, body|
18
+ step("I send and accept JSON") if is_json
19
+ @body = body
20
+ end
21
+
22
+ Then /^the HTTP JSON response at "(.*?)" should be "(.*?)"$/ do |path, value|
23
+ expect(@response.get(path)).to eq(value)
24
+ end
@@ -0,0 +1,44 @@
1
+ When /^I create a hostfactory token for "(.*?)" with CIDR "(.*?)"$/ do |hf, cidr|
2
+ step %Q{I successfully run `conjur hostfactory token create --cidr #{cidr} #{hf}`}
3
+ @hostfactory_token = JSON.parse(last_command_started.stdout)[0]['token']
4
+ end
5
+
6
+ When /^I(?: can)? use the hostfactory token from "(.*?)" to create host "(.*?)"$/ do |ip, host|
7
+ headers['Authorization'] = %Q{Token token="#{@hostfactory_token}"}
8
+ step %Q{I send a POST request forwarded from "#{ip}" to "/api/host_factories/hosts" with:}, table([["id"], [host]])
9
+ step %Q{the response status should be "201"}
10
+ end
11
+
12
+ When /^I get the audit event for the resource "(.*?)" with action "(.*?)"$/ do |resource, action|
13
+ # resource needs to be URL-encoded, but cucumber-api URL-encodes the
14
+ # whole string.
15
+ response = RestClient.get(resolve("/api/audit/resources/#{CGI.escape(resource)}"), @headers)
16
+ @response = CucumberApi::Response.create(response)
17
+ @headers = nil
18
+ @body = nil
19
+ step %Q{the response status should be "200"}
20
+
21
+ json = JSON.parse(@response)
22
+ @audit_event = json.find {|e| e['action'] == action}
23
+ end
24
+
25
+ Then /^the audit event should show the request from "(.*?)"$/ do |ip|
26
+ expect(@audit_event['request']['ip']).to eq(ip)
27
+ end
28
+
29
+ When /^I create a pubkey for "(.*?)" from "(.*?)" with "(.*?)"$/ do |user, ip, key|
30
+ steps %Q{
31
+ Given I send "text/plain" and accept JSON
32
+ And I set the request body to "#{key}"
33
+ When I send a POST request forwarded from "#{ip}" to "/api/pubkeys/#{user}"
34
+ Then the response status should be "200"
35
+ }
36
+ @pubkey_var = @response.get "resource_identifier"
37
+ end
38
+
39
+ When /^I get the audit event for the pubkey variable with action "(.*?)"$/ do |action|
40
+ # Need reveal, test user doesn't have privilege to see resources
41
+ # created by pubkeys.
42
+ headers['X-Conjur-Privilege'] = 'reveal'
43
+ step %Q{I get the audit event for the resource "#{@pubkey_var}" with action "#{action}"}
44
+ end
@@ -8,16 +8,14 @@ Given(/^I login as a new user$/) do
8
8
  end
9
9
 
10
10
  Given(/^I create a new user named "(.*?)"$/) do |username|
11
- username_ns = username.gsub('$ns',@namespace)
12
-
13
- step "I successfully run `conjur user create --as-role user:admin@#{@namespace} #{username_ns}`"
11
+ step "I successfully run `conjur user create --as-role user:admin@#{namespace} #{username}`"
14
12
 
15
13
  user_info = JSON.parse(last_command_started.stdout)
16
- save_password username_ns, user_info['api_key']
14
+ save_password username, user_info['api_key']
17
15
  end
18
16
 
19
17
  Given(/^I create a new host with id "(.*?)"$/) do |hostid|
20
- step "I successfully run `conjur host create #{@namespace}/monitoring/server`"
18
+ step "I successfully run `conjur host create #{namespace}/monitoring/server`"
21
19
  host = JSON.parse(last_json)
22
20
  @host_id = host['id']
23
21
  @host_api_key = host['api_key']
@@ -29,16 +27,14 @@ Given(/^I login as the new host/) do
29
27
  end
30
28
 
31
29
  Given(/^I login as new user "(.*?)"$/) do |username|
32
- username_ns = username.gsub('$ns',@namespace)
33
- step %Q(I create a new user named "#{username_ns}")
34
- step %Q(I login as "#{username_ns}")
30
+ step %Q(I create a new user named "#{username}")
31
+ step %Q(I login as "#{username}")
35
32
  end
36
33
 
37
34
  Given(/^I login as "(.*?)"$/) do |username|
38
- username_ns = username.gsub('$ns',@namespace)
39
- password = find_password(username_ns)
35
+ password = find_password(username)
40
36
 
41
- step %Q(I set the environment variable "CONJUR_AUTHN_LOGIN" to "#{username_ns}")
37
+ step %Q(I set the environment variable "CONJUR_AUTHN_LOGIN" to "#{username}")
42
38
  step %Q(I set the environment variable "CONJUR_AUTHN_API_KEY" to "#{password}")
43
39
  end
44
40
 
@@ -1,4 +1,23 @@
1
1
  require "aruba/cucumber"
2
2
  require "json_spec/cucumber"
3
+ require 'cucumber-api'
4
+ require 'addressable/uri'
3
5
 
4
6
  $LOAD_PATH.unshift File.expand_path('../..', File.dirname(__FILE__))
7
+
8
+ # Overwrite cucumber-api's resolve function so it will use the scheme
9
+ # and host from ENV['CONJUR_APPLIANCE_URL'] if url doesn't already
10
+ # have a host.
11
+ $orig_resolve = self.method(:resolve)
12
+ def resolve url
13
+ # disable cucumber-api's ill-considered cache. Re-authenticate in
14
+ # case it (cucumber-api) wiped out the headers
15
+ $cache = {}
16
+ add_user_auth_header
17
+ url = Addressable::URI.parse(url)
18
+ unless url.host
19
+ conjur_url = Addressable::URI.parse(Conjur.configuration.appliance_url)
20
+ url.merge!(:scheme => conjur_url.scheme, :host => conjur_url.host)
21
+ end
22
+ $orig_resolve.call(url.to_s)
23
+ end
@@ -21,32 +21,35 @@ end
21
21
  Before do
22
22
  step %Q(I set the environment variable "CONJUR_AUTHN_LOGIN" to "#{username}")
23
23
  step %Q(I set the environment variable "CONJUR_AUTHN_API_KEY" to "#{password}")
24
-
25
- @admin_api = conjur_api = Conjur::Authn.connect
26
-
27
- @namespace = conjur_api.create_variable("text/plain", "id").id
28
- user = conjur_api.create_user "admin@#{@namespace}", ownerid: "#{Conjur.configuration.account}:user:#{username}"
29
24
 
30
- conjur_api = Conjur::Authn.connect
31
- @security_admin = conjur_api.create_group [ @namespace, "security_admin" ].join('/')
32
- @security_admin.add_member user, admin_option: true
25
+ @admin_api = Conjur::Authn.connect
26
+ @test_user = admin_api.create_user "admin@#{namespace}", ownerid: "#{Conjur.configuration.account}:user:#{username}"
27
+
28
+ @security_admin = admin_api.create_group [ namespace, "security_admin" ].join('/')
29
+ @security_admin.add_member test_user, admin_option: true
33
30
 
34
- JsonSpec.memorize "MY_ROLEID", %Q("#{user.roleid}")
35
- JsonSpec.memorize "NAMESPACE", @namespace
31
+ JsonSpec.memorize "MY_ROLEID", %Q("#{test_user.roleid}")
32
+ JsonSpec.memorize "NAMESPACE", namespace
36
33
 
37
- @admin_api.group("pubkeys-1.0/key-managers").add_member @security_admin
38
- @admin_api.resource('!:!:conjur').permit 'elevate', user, grant_option: true
39
- @admin_api.resource('!:!:conjur').permit 'reveal', user, grant_option: true
34
+ admin_api.group("pubkeys-1.0/key-managers").add_member @security_admin
35
+ admin_api.resource('!:!:conjur').permit 'elevate', test_user, grant_option: true
36
+ admin_api.resource('!:!:conjur').permit 'reveal', test_user, grant_option: true
40
37
 
41
- conjur_api.create_user "attic@#{@namespace}"
42
-
43
- step %Q(I set the environment variable "CONJUR_AUTHN_LOGIN" to "#{user.login}")
44
- step %Q(I set the environment variable "CONJUR_AUTHN_API_KEY" to "#{user.api_key}")
38
+ admin_api.create_user "attic@#{namespace}"
39
+
40
+ # Set up the environment so the CLI will authenticate
41
+ # correctly. Note that the API caches credentials, so these
42
+ # variables won't have any effect on future calls to
43
+ # Conjur::Authn.connect
44
+ step %Q(I set the environment variable "CONJUR_AUTHN_LOGIN" to "#{test_user.login}")
45
+ step %Q(I set the environment variable "CONJUR_AUTHN_API_KEY" to "#{test_user.api_key}")
45
46
  end
46
47
 
47
48
  After do
48
- if @admin_api
49
- @admin_api.group("pubkeys-1.0/key-managers").remove_member @security_admin
49
+ if admin_api
50
+ admin_api.group("pubkeys-1.0/key-managers").remove_member @security_admin
51
+ admin_api = nil
52
+ namespace = nil
50
53
  end
51
54
  tempfiles.each { |tempfile| File.unlink(tempfile) unless tempfile.nil? }
52
55
  end
@@ -4,6 +4,8 @@ require 'conjur/api'
4
4
  module ConjurCLIWorld
5
5
  include Aruba::Api
6
6
 
7
+ attr_accessor :admin_api, :namespace, :test_user, :headers
8
+
7
9
  def last_json
8
10
  process_cmd last_command_started.stdout
9
11
  end
@@ -28,8 +30,12 @@ module ConjurCLIWorld
28
30
  password
29
31
  end
30
32
 
33
+ def admin_role
34
+ admin_api.current_role.role_id
35
+ end
36
+
31
37
  def namespace
32
- @namespace or raise "@namespace is not initialized"
38
+ @namespace ||= admin_api.create_variable("text/plain", "id").id
33
39
  end
34
40
 
35
41
  # Aruba's method
@@ -51,6 +57,19 @@ module ConjurCLIWorld
51
57
  def tempfiles
52
58
  @tempfiles||=[]
53
59
  end
60
+
61
+ def headers
62
+ @headers ||= {}
63
+ end
64
+
65
+ def add_user_auth_header
66
+ return if headers['Authorization']
67
+
68
+ token = Conjur::API.authenticate(test_user.login, test_user.api_key)
69
+ headers.merge!(
70
+ 'Authorization' => %Q{Token token="#{Base64.strict_encode64(token.to_json)}"}
71
+ )
72
+ end
54
73
 
55
74
  protected
56
75
 
@@ -0,0 +1,82 @@
1
+ Feature: Conjur services support trusted proxies
2
+
3
+ As an administrator of the Conjur Appliance, I want to be able to
4
+ specify CIDRs for machines that should be regarded as trusted
5
+ proxies. IP addresses that match those CIDRs can be regarded as
6
+ coming from localhost. Other addresses should not be remapped (even
7
+ if those addresses are non-routable), and so will appear in audit
8
+ events and be used to validate CIDR restrictions (e.g. on
9
+ hostfactory tokens).
10
+
11
+ Scenario: authn supports trusted proxies for CIDR restrictions
12
+ Given I set the JSON request body to:
13
+ """
14
+ {
15
+ "login": "restricted@$ns",
16
+ "password": "restricted",
17
+ "ownerid": "cucumber:user:admin@$ns",
18
+ "cidr": ["192.168.0.0/24"]
19
+ }
20
+ """
21
+ And I send a POST request to "/api/users"
22
+ And the response status should be "201"
23
+ Given I send "text/plain" and accept JSON
24
+ And I set the request body to "restricted"
25
+ When I send a POST request forwarded from "192.168.0.1" to "/api/authn/users/restricted@$ns/authenticate"
26
+ Then the response status should be "200"
27
+
28
+ Scenario: authz supports trusted proxies
29
+ Given I send a PUT request forwarded from "192.168.0.1" to "/api/authz/cucumber/resources/test/$ns/resource?acting_as=$user_role"
30
+ And the response status should be "204"
31
+ When I successfully run `conjur audit resource test:$ns/resource`
32
+ Then the JSON response at "request/ip" should be "192.168.0.1"
33
+
34
+ Scenario: core supports trusted proxies
35
+ Given I set the JSON request body to:
36
+ """
37
+ {
38
+ "id": "$ns/var",
39
+ "kind": "password",
40
+ "mime_type": "text/plain"
41
+ }
42
+ """
43
+ And I send a POST request forwarded from "192.168.0.1" to "/api/variables"
44
+ And the response status should be "201"
45
+ When I successfully run `conjur audit resource variable:$ns/var`
46
+ Then the JSON response at "request/ip" should be "192.168.0.1"
47
+
48
+ Scenario: expiration supports trusted proxies
49
+ Given I successfully run `conjur variable create $ns_expiration_var value`
50
+ And I send a GET request forwarded from "192.168.0.1" to "/api/variables/$ns_expiration_var/value"
51
+ And the response status should be "200"
52
+ When I get the audit event for the resource "cucumber:variable:$ns_expiration_var" with action "check"
53
+ Then the audit event should show the request from "192.168.0.1"
54
+
55
+ Scenario: host-factory supports trusted proxies when creating hostfactories
56
+ Given I successfully run `conjur layer create --as-role $user_role $ns/layer`
57
+ When I send a POST request forwarded from "192.168.0.1" to "/api/host_factories" with:
58
+ | id | roleid | ownerid | layers[] |
59
+ | $ns/hf | $user_role | $user_role | $ns/layer |
60
+
61
+ And the response status should be "201"
62
+ And I successfully run `conjur audit resource host_factory:$ns/hf`
63
+ Then the JSON response at "request/ip" should be "192.168.0.1"
64
+
65
+ Scenario: hostfactory supports trusted proxies when creating hosts
66
+ Given I successfully run `conjur layer create --as-role $user_role $ns/layer`
67
+ And I successfully run `conjur hostfactory create --as-role $user_role --layer $ns/layer $ns/hf`
68
+ And I create a hostfactory token for "$ns/hf" with CIDR "192.168.0.0/16"
69
+ When I use the hostfactory token from "192.168.0.1" to create host "$ns/host"
70
+ And I get the audit event for the resource "cucumber:host:$ns/host" with action "create"
71
+ Then the audit event should show the request from "192.168.0.1"
72
+
73
+ Scenario: hostfactory supports trusted proxies when validating token CIDR restrictions
74
+ Given I successfully run `conjur layer create --as-role $user_role $ns/layer`
75
+ And I successfully run `conjur hostfactory create --as-role $user_role --layer $ns/layer $ns/hf`
76
+ And I create a hostfactory token for "$ns/hf" with CIDR "192.168.0.0/16"
77
+ Then I can use the hostfactory token from "192.168.0.1" to create host "$ns/host1"
78
+
79
+ Scenario: pubkeys supports trusted proxies
80
+ Given I create a pubkey for "pubkeys_user@$ns" from "192.168.0.1" with "ssh-rsa foobar pubkeys_user@host"
81
+ When I get the audit event for the pubkey variable with action "create"
82
+ Then the audit event should show the request from "192.168.0.1"
@@ -16,23 +16,25 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Conjur::VERSION
17
17
 
18
18
  gem.add_dependency 'activesupport', '~> 4.2'
19
- gem.add_dependency 'bundler', '< 1.12.0'
20
19
  gem.add_dependency 'conjur-api', '~> 4.21'
21
20
  gem.add_dependency 'gli', '>=2.8.0'
22
21
  gem.add_dependency 'highline', '~> 1.7'
23
- gem.add_dependency 'netrc', '~> 0.10.2'
22
+ gem.add_dependency 'netrc', '~> 0.10'
24
23
  gem.add_dependency 'methadone', '~> 1.9'
25
24
  gem.add_dependency 'deep_merge', '~> 1.0'
26
25
  gem.add_dependency 'xdg', '~> 2.2'
26
+ gem.add_dependency 'table_print', '~> 1.5'
27
27
 
28
28
  gem.add_runtime_dependency 'cas_rest_client', '~> 1.3'
29
29
 
30
30
  gem.add_development_dependency 'rspec', '~> 3.0'
31
31
  gem.add_development_dependency 'simplecov'
32
- gem.add_development_dependency 'aruba', '~> 0.12.0'
32
+ gem.add_development_dependency 'aruba', '~> 0.12'
33
33
  gem.add_development_dependency 'ci_reporter_rspec', '~> 1.0'
34
34
  gem.add_development_dependency 'ci_reporter_cucumber', '~> 1.0'
35
35
  gem.add_development_dependency 'rake', '~> 10.0'
36
- gem.add_development_dependency 'io-grab', '~> 0.0.1'
36
+ gem.add_development_dependency 'io-grab', '~> 0.0'
37
37
  gem.add_development_dependency 'json_spec'
38
+ gem.add_development_dependency 'cucumber-api'
39
+ gem.add_development_dependency 'addressable'
38
40
  end
@@ -1,9 +1,74 @@
1
1
  require 'conjur/command'
2
2
 
3
3
  class Conjur::Command::LDAPSync < Conjur::Command
4
+
5
+ LIST_FORMATS = %w(pretty json)
6
+
7
+ def self.find_job_by_id args
8
+ job_id = require_arg args, 'JOB-ID'
9
+
10
+ if (job = api.ldap_sync_jobs.find{|j| j.id == job_id})
11
+ job
12
+ else
13
+ exit_now! "No job found with ID '#{job_id}'"
14
+ end
15
+ end
16
+
4
17
  desc 'LDAP sync management commands'
5
18
  command :'ldap-sync' do |cgrp|
6
19
 
20
+ cgrp.desc 'Manage detached LDAP sync jobs'
21
+ cgrp.command :jobs do |jobs|
22
+
23
+ jobs.desc 'List detached jobs'
24
+ jobs.command :list do |cmd|
25
+
26
+ cmd.desc "Specify output format (#{LIST_FORMATS.join(',')})"
27
+ cmd.flag %w(f format), default_value: 'json', must_match: LIST_FORMATS
28
+
29
+ cmd.desc 'Show only JOB ids'
30
+ cmd.switch %w(i ids-only), default_value: false
31
+
32
+ cmd.action do |_,options,_|
33
+ jobs = api.ldap_sync_jobs.map(&:to_h)
34
+
35
+
36
+ if options[:format] == 'pretty'
37
+ require 'table_print'
38
+ fields = [{id: {width: 38}}]
39
+
40
+ fields.concat([:type, :state, :exclusive]) unless options[:'ids-only']
41
+
42
+ tp jobs, *fields
43
+ else
44
+ jobs = jobs.map{|j| j[:id]} if options[:'ids-only']
45
+
46
+ display(jobs)
47
+ end
48
+
49
+ end
50
+ end
51
+
52
+ jobs.desc 'Delete a detached job'
53
+ jobs.arg_name 'JOB-ID'
54
+ jobs.command :delete do |cmd|
55
+ cmd.action do |_, _, args|
56
+ find_job_by_id(args).delete
57
+ puts "Job deleted"
58
+ end
59
+ end
60
+
61
+ jobs.desc 'Show the output from a detached job'
62
+ jobs.arg_name 'JOB-ID'
63
+ jobs.command :show do |cmd|
64
+ cmd.action do |_,_,args|
65
+ find_job_by_id(args).output do |event|
66
+ display(event)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
7
72
  cgrp.desc 'Trigger a sync of users/groups from LDAP to Conjur'
8
73
  cgrp.command :now do |cmd|
9
74
  cmd.desc 'LDAP Sync profile to use (defined in UI)'
@@ -19,33 +84,45 @@ class Conjur::Command::LDAPSync < Conjur::Command
19
84
  cmd.default_value 'text'
20
85
  cmd.arg_name 'format'
21
86
  cmd.flag ['f', 'format'], :must_match => ['text', 'yaml']
22
-
87
+
88
+ cmd.desc 'Run sync as a detached job'
89
+ cmd.default_value true
90
+ cmd.switch ['detach']
91
+
23
92
  cmd.action do |_ ,options, args|
24
93
  assert_empty args
25
94
 
26
95
  format = options[:format] == 'text' ? 'application/json' : 'text/yaml'
27
96
 
28
- # options[:'dry-run'] is nil when dry_run should be disabled (either --no-dry-run
29
- # or no option given at all). It is true when --dry-run is given.
30
- dry_run = options[:'dry-run']
31
- dry_run = false if dry_run.nil?
97
+ dry_run = !!options[:'dry-run']
98
+
99
+ # Don't ever run dry-run jobs detached
100
+ options[:detach] = false if dry_run
32
101
 
33
102
  $stderr.puts "Performing #{dry_run ? 'dry run ' : ''}LDAP sync"
34
103
 
35
- response = api.ldap_sync_now(options[:profile], format, dry_run)
104
+ response = api.ldap_sync_now(:config_name => options[:profile],
105
+ :format => format,
106
+ :dry_run => dry_run,
107
+ :detach_job => options[:detach]
108
+ )
36
109
 
37
- if options[:format] == 'text'
38
- puts "Messages:"
39
- response['events'].each do |event|
40
- puts [ event['timestamp'], event['severity'], event['message'] ].join("\t")
41
- end
42
- puts
43
- puts "Actions:"
44
- response['result']['actions'].each do |action|
45
- puts action
110
+ if !options[:detach]
111
+ if options[:format] == 'text'
112
+ puts "Messages:"
113
+ response['events'].each do |event|
114
+ puts [ event['timestamp'], event['severity'], event['message'] ].join("\t")
115
+ end
116
+ puts
117
+ puts "Actions:"
118
+ response['result']['actions'].each do |action|
119
+ puts action
120
+ end
121
+ else
122
+ puts response
46
123
  end
47
124
  else
48
- puts response
125
+ display response
49
126
  end
50
127
  end
51
128
  end
@@ -19,6 +19,6 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  module Conjur
22
- VERSION = '5.2.5'
22
+ VERSION = '5.3.0'
23
23
  ::Version=VERSION
24
24
  end
@@ -22,7 +22,78 @@ describe Conjur::Command::LDAPSync, logged_in: true do
22
22
  }
23
23
  ].to_yaml }
24
24
 
25
- describe_command 'ldap-sync now -f text' do
25
+
26
+
27
+ context 'when testing ldap-sync jobs commands' do
28
+ let(:jobs){
29
+ [
30
+ Conjur::LdapSyncJob.new(api, :id => 'job-1', :type => 'sync', :state => 'running', :exclusive => true),
31
+ Conjur::LdapSyncJob.new(api, :id => 'job-2', :type => 'connect', :state => 'success', :exclusive => false)
32
+ ]
33
+ }
34
+
35
+ before do
36
+ expect_any_instance_of(Conjur::API).to receive(:ldap_sync_jobs).and_return jobs
37
+ end
38
+
39
+ describe_command 'ldap-sync jobs list' do
40
+ it 'prints the jobs as json' do
41
+ expect { invoke }.to write(JSON.pretty_generate jobs.map(&:as_json))
42
+ end
43
+ end
44
+
45
+ describe_command 'ldap-sync jobs list -i' do
46
+ it 'prints the job ids only' do
47
+ expect { invoke }.to write(JSON.pretty_generate jobs.map(&:id))
48
+ end
49
+ end
50
+
51
+ describe_command 'ldap-sync jobs list -f pretty' do
52
+
53
+ it 'prints the jobs in a fancy table' do
54
+ expect{ invoke }.to write /ID\s*|\s*TYPE\s*|\s*STATE\s*|\s*EXCLUSIVE.*?
55
+ job-1\s*|\s*sync\s*|\s*running\s*|\s*true
56
+ job-2\s*|\s*connect\s*|\s*success\s*|\s*false/x
57
+ end
58
+ end
59
+
60
+
61
+ describe_command 'ldap-sync jobs delete job-2' do
62
+ let(:victim){ jobs[1] }
63
+ it 'deletes the job' do
64
+ expect(victim).to receive(:delete)
65
+ invoke
66
+ end
67
+ end
68
+
69
+ describe_command 'ldap-sync jobs delete no-such-job' do
70
+ it 'fails with a sensible error message' do
71
+ expect{ invoke }.to raise_exception(/No job found with ID 'no-such-job'/)
72
+ end
73
+ end
74
+
75
+ describe_command 'ldap-sync jobs show job-1' do
76
+ let(:victim){ jobs[0] }
77
+ it 'prints the values passed to output' do
78
+ expect(victim).to receive(:output) do |&block|
79
+ block.call({foo: 'bar'})
80
+ block.call({spam: 'eggs'})
81
+ end
82
+
83
+ expect{invoke}.to write(<<EOS)
84
+ {
85
+ "foo": "bar"
86
+ }
87
+ {
88
+ "spam": "eggs"
89
+ }
90
+ EOS
91
+
92
+ end
93
+ end
94
+ end
95
+
96
+ describe_command 'ldap-sync now --no-detach -f text' do
26
97
  before {
27
98
  expect_any_instance_of(Conjur::API).to receive(:ldap_sync_now).and_return json_response
28
99
  }
@@ -34,7 +105,7 @@ describe Conjur::Command::LDAPSync, logged_in: true do
34
105
  end
35
106
  end
36
107
 
37
- describe_command 'ldap-sync now -f yaml' do
108
+ describe_command 'ldap-sync now --no-detach -f yaml' do
38
109
  it 'prints out actions as unparsed yaml' do
39
110
  expect_any_instance_of(Conjur::API).to receive(:ldap_sync_now).and_return yaml_response
40
111
  expect { invoke }.to write(yaml_response)
@@ -42,9 +113,10 @@ describe Conjur::Command::LDAPSync, logged_in: true do
42
113
  end
43
114
 
44
115
  context 'when testing dry-run' do
116
+ let (:detach) { true }
45
117
  before do
46
118
  expect_any_instance_of(Conjur::API).to receive(:ldap_sync_now)
47
- .with('default', 'application/json', dry_run)
119
+ .with(:config_name => 'default', :format => 'application/json', :dry_run => dry_run, :detach_job => detach)
48
120
  .and_return json_response
49
121
  end
50
122
 
@@ -64,6 +136,7 @@ describe Conjur::Command::LDAPSync, logged_in: true do
64
136
 
65
137
  describe_command 'ldap-sync now --dry-run' do
66
138
  let(:dry_run) { true }
139
+ let(:detach) { false }
67
140
  it 'passes truthy dry-run value' do
68
141
  invoke
69
142
  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: 5.2.5
4
+ version: 5.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafal Rzepecki
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-07-14 00:00:00.000000000 Z
12
+ date: 2016-10-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -25,20 +25,6 @@ dependencies:
25
25
  - - ~>
26
26
  - !ruby/object:Gem::Version
27
27
  version: '4.2'
28
- - !ruby/object:Gem::Dependency
29
- name: bundler
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - <
33
- - !ruby/object:Gem::Version
34
- version: 1.12.0
35
- type: :runtime
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - <
40
- - !ruby/object:Gem::Version
41
- version: 1.12.0
42
28
  - !ruby/object:Gem::Dependency
43
29
  name: conjur-api
44
30
  requirement: !ruby/object:Gem::Requirement
@@ -87,14 +73,14 @@ dependencies:
87
73
  requirements:
88
74
  - - ~>
89
75
  - !ruby/object:Gem::Version
90
- version: 0.10.2
76
+ version: '0.10'
91
77
  type: :runtime
92
78
  prerelease: false
93
79
  version_requirements: !ruby/object:Gem::Requirement
94
80
  requirements:
95
81
  - - ~>
96
82
  - !ruby/object:Gem::Version
97
- version: 0.10.2
83
+ version: '0.10'
98
84
  - !ruby/object:Gem::Dependency
99
85
  name: methadone
100
86
  requirement: !ruby/object:Gem::Requirement
@@ -137,6 +123,20 @@ dependencies:
137
123
  - - ~>
138
124
  - !ruby/object:Gem::Version
139
125
  version: '2.2'
126
+ - !ruby/object:Gem::Dependency
127
+ name: table_print
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ~>
131
+ - !ruby/object:Gem::Version
132
+ version: '1.5'
133
+ type: :runtime
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ~>
138
+ - !ruby/object:Gem::Version
139
+ version: '1.5'
140
140
  - !ruby/object:Gem::Dependency
141
141
  name: cas_rest_client
142
142
  requirement: !ruby/object:Gem::Requirement
@@ -185,14 +185,14 @@ dependencies:
185
185
  requirements:
186
186
  - - ~>
187
187
  - !ruby/object:Gem::Version
188
- version: 0.12.0
188
+ version: '0.12'
189
189
  type: :development
190
190
  prerelease: false
191
191
  version_requirements: !ruby/object:Gem::Requirement
192
192
  requirements:
193
193
  - - ~>
194
194
  - !ruby/object:Gem::Version
195
- version: 0.12.0
195
+ version: '0.12'
196
196
  - !ruby/object:Gem::Dependency
197
197
  name: ci_reporter_rspec
198
198
  requirement: !ruby/object:Gem::Requirement
@@ -241,14 +241,14 @@ dependencies:
241
241
  requirements:
242
242
  - - ~>
243
243
  - !ruby/object:Gem::Version
244
- version: 0.0.1
244
+ version: '0.0'
245
245
  type: :development
246
246
  prerelease: false
247
247
  version_requirements: !ruby/object:Gem::Requirement
248
248
  requirements:
249
249
  - - ~>
250
250
  - !ruby/object:Gem::Version
251
- version: 0.0.1
251
+ version: '0.0'
252
252
  - !ruby/object:Gem::Dependency
253
253
  name: json_spec
254
254
  requirement: !ruby/object:Gem::Requirement
@@ -263,6 +263,34 @@ dependencies:
263
263
  - - '>='
264
264
  - !ruby/object:Gem::Version
265
265
  version: '0'
266
+ - !ruby/object:Gem::Dependency
267
+ name: cucumber-api
268
+ requirement: !ruby/object:Gem::Requirement
269
+ requirements:
270
+ - - '>='
271
+ - !ruby/object:Gem::Version
272
+ version: '0'
273
+ type: :development
274
+ prerelease: false
275
+ version_requirements: !ruby/object:Gem::Requirement
276
+ requirements:
277
+ - - '>='
278
+ - !ruby/object:Gem::Version
279
+ version: '0'
280
+ - !ruby/object:Gem::Dependency
281
+ name: addressable
282
+ requirement: !ruby/object:Gem::Requirement
283
+ requirements:
284
+ - - '>='
285
+ - !ruby/object:Gem::Version
286
+ version: '0'
287
+ type: :development
288
+ prerelease: false
289
+ version_requirements: !ruby/object:Gem::Requirement
290
+ requirements:
291
+ - - '>='
292
+ - !ruby/object:Gem::Version
293
+ version: '0'
266
294
  description:
267
295
  email:
268
296
  - rafal@conjur.net
@@ -347,10 +375,13 @@ files:
347
375
  - acceptance-features/pubkeys/show.feature
348
376
  - acceptance-features/step_definitions/cli_steps.rb
349
377
  - acceptance-features/step_definitions/graph_steps.rb
378
+ - acceptance-features/step_definitions/http_steps.rb
379
+ - acceptance-features/step_definitions/trusted_proxy_steps.rb
350
380
  - acceptance-features/step_definitions/user_steps.rb
351
381
  - acceptance-features/support/env.rb
352
382
  - acceptance-features/support/hooks.rb
353
383
  - acceptance-features/support/world.rb
384
+ - acceptance-features/trusted_proxies.feature
354
385
  - bin/_conjur
355
386
  - bin/conjur
356
387
  - bin/conjurize