conjur-cli 5.2.5 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
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