conjur-cli 5.1.2 → 5.2.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 +4 -4
- data/CHANGELOG.md +8 -1
- data/Dockerfile +1 -1
- data/Gemfile +1 -1
- data/acceptance-features/directory/hostfactory/create.feature +0 -1
- data/ci/publish.sh +1 -1
- data/features/conjurize.feature +3 -3
- data/lib/conjur/authn.rb +13 -1
- data/lib/conjur/command/ldapsync.rb +49 -0
- data/lib/conjur/conjurize/script.rb +21 -4
- data/lib/conjur/version.rb +1 -1
- data/spec/authn_spec.rb +38 -8
- data/spec/command/ldapsync_spec.rb +43 -0
- data/spec/conjurize/script_spec.rb +62 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4737c65684b90ddd2b62d5fb186573b7099e496b
|
4
|
+
data.tar.gz: c6ff97b50c512c96568e0361991af49309b868ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bcb80c73f81df2f96f1d18780c2d94f69c1fe3d8ec9153e6276b529ecd21429836a8ec08a058c2975471d751e9f6cc5bf3332a1f0e9640fbc67ca48ac1a3ca1
|
7
|
+
data.tar.gz: 3a355ec8286f3b4d198777b5f34666c4cfaf6dbf9db3a9f558c47ee54166439e259a3aabd3a5ae3bcc12086137a434bba2d415ac8c2c4e47c27bd279ff1392a7
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
+
# 5.2.0
|
2
|
+
|
3
|
+
* Add `ldap-sync` management commands (requires Conjur 4.7 or later).
|
4
|
+
* Use `CONJUR_AUTHN_TOKEN` as the Conjur access token, if it's available in the environment.
|
5
|
+
* `conjurize` will ignore `conjur` cookbook releases that don't have an associated tarball.
|
6
|
+
* Pass `--recipe-url` argument to Chef, which is now required.
|
7
|
+
|
1
8
|
# 5.1.2
|
2
9
|
|
3
|
-
* Fix problem finding config files for plugin installation
|
10
|
+
* Fix problem finding config files for plugin installation.
|
4
11
|
|
5
12
|
# 5.1.1
|
6
13
|
|
data/Dockerfile
CHANGED
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', git: 'https://github.com/conjurinc/api-ruby.git', branch: 'master'
|
9
|
+
gem 'conjur-api', '>= 4.24', 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
|
@@ -5,7 +5,6 @@ Feature: Create a Host Factory
|
|
5
5
|
Scenario: Create a host factory successfully
|
6
6
|
Given I successfully run `conjur layer create --as-group $ns/security_admin $ns/layer`
|
7
7
|
Then I successfully run `conjur hostfactory create --as-group $ns/security_admin --layer $ns/layer $ns/hostfactory`
|
8
|
-
And the JSON should have "deputy_api_key"
|
9
8
|
|
10
9
|
Scenario: The client role can use itself as the hostfactory role
|
11
10
|
Given I successfully run `conjur user create unprivileged@$ns`
|
data/ci/publish.sh
CHANGED
data/features/conjurize.feature
CHANGED
@@ -112,16 +112,16 @@ curl -L https://www.opscode.com/chef/install.sh | bash
|
|
112
112
|
"""
|
113
113
|
And the output should match:
|
114
114
|
"""
|
115
|
-
chef-solo -
|
115
|
+
chef-solo --recipe-url https:\/\/github.com\/conjur-cookbooks\/conjur\/releases\/download/v\d\.\d\.\d/conjur-v\d\.\d\.\d.tar.gz -o conjur
|
116
116
|
"""
|
117
117
|
|
118
118
|
Scenario: conjurize with arbitrary cookbook
|
119
119
|
When I conjurize "--conjur-cookbook-url https://example.com --conjur-run-list fry"
|
120
|
-
Then the stdout should contain "chef-solo -
|
120
|
+
Then the stdout should contain "chef-solo --recipe-url https://example.com -o fry"
|
121
121
|
|
122
122
|
Scenario: conjurize with path to chef-solo
|
123
123
|
When I conjurize "--chef-executable /path/to/chef-solo --conjur-cookbook-url https://example.com --conjur-run-list fry"
|
124
|
-
Then the stdout should contain "/path/to/chef-solo -
|
124
|
+
Then the stdout should contain "/path/to/chef-solo --recipe-url https://example.com -o fry"
|
125
125
|
And the stdout should not contain "curl -L https://www.opscode.com/chef/install.sh"
|
126
126
|
|
127
127
|
Scenario: conjurize with sudo-ized commands
|
data/lib/conjur/authn.rb
CHANGED
@@ -126,7 +126,11 @@ module Conjur::Authn
|
|
126
126
|
require 'conjur/base'
|
127
127
|
cls = Conjur::API
|
128
128
|
end
|
129
|
-
|
129
|
+
if token = token_from_environment
|
130
|
+
cls.new_from_token token
|
131
|
+
else
|
132
|
+
cls.new_from_key(*get_credentials(options))
|
133
|
+
end
|
130
134
|
end
|
131
135
|
|
132
136
|
protected
|
@@ -141,5 +145,13 @@ module Conjur::Authn
|
|
141
145
|
def windows?
|
142
146
|
RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
|
143
147
|
end
|
148
|
+
|
149
|
+
def token_from_environment
|
150
|
+
return nil unless token = ENV['CONJUR_AUTHN_TOKEN']
|
151
|
+
|
152
|
+
require 'json'
|
153
|
+
require 'base64'
|
154
|
+
JSON.parse(Base64.decode64(token))
|
155
|
+
end
|
144
156
|
end
|
145
157
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'conjur/command'
|
2
|
+
|
3
|
+
class Conjur::Command::LDAPSync < Conjur::Command
|
4
|
+
desc 'LDAP sync management commands'
|
5
|
+
command :'ldap-sync' do |cgrp|
|
6
|
+
|
7
|
+
cgrp.desc 'Trigger a sync of users/groups from LDAP to Conjur'
|
8
|
+
cgrp.command :now do |cmd|
|
9
|
+
cmd.desc 'LDAP Sync profile to use (defined in UI)'
|
10
|
+
cmd.default_value 'default'
|
11
|
+
cmd.arg_name 'profile'
|
12
|
+
cmd.flag ['p', 'profile']
|
13
|
+
|
14
|
+
cmd.desc 'Print the actions that would be performed'
|
15
|
+
cmd.default_value false
|
16
|
+
cmd.switch ['dry-run']
|
17
|
+
|
18
|
+
cmd.desc 'Output format of sync operation (text, yaml)'
|
19
|
+
cmd.default_value 'text'
|
20
|
+
cmd.arg_name 'format'
|
21
|
+
cmd.flag ['f', 'format'], :must_match => ['text', 'yaml']
|
22
|
+
|
23
|
+
cmd.action do |_ ,options, args|
|
24
|
+
assert_empty args
|
25
|
+
|
26
|
+
format = options[:format] == 'text' ? 'application/json' : 'text/yaml'
|
27
|
+
dry_run = options[:'dry-run']
|
28
|
+
|
29
|
+
$stderr.puts "Performing #{dry_run ? 'dry run ' : ''}LDAP sync"
|
30
|
+
|
31
|
+
response = api.ldap_sync_now(options[:profile], format, dry_run)
|
32
|
+
|
33
|
+
if options[:format] == 'text'
|
34
|
+
puts "Messages:"
|
35
|
+
response['events'].each do |event|
|
36
|
+
puts [ event['timestamp'], event['severity'], event['message'] ].join("\t")
|
37
|
+
end
|
38
|
+
puts
|
39
|
+
puts "Actions:"
|
40
|
+
response['result']['actions'].each do |action|
|
41
|
+
puts action
|
42
|
+
end
|
43
|
+
else
|
44
|
+
puts response
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -7,12 +7,29 @@ class Conjur::Conjurize
|
|
7
7
|
COOKBOOK_RELEASES_URL =
|
8
8
|
"https://api.github.com/repos/conjur-cookbooks/conjur/releases".freeze
|
9
9
|
|
10
|
+
def self.tarballs_of_releases releases
|
11
|
+
releases.map do |release|
|
12
|
+
assets = release["assets"].select do |asset|
|
13
|
+
asset["name"] =~ /conjur-v\d.\d.\d.tar.gz/
|
14
|
+
end
|
15
|
+
|
16
|
+
[release["name"], assets.map { |asset| asset["browser_download_url"] }]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
10
20
|
def self.latest_conjur_cookbook_release
|
11
21
|
json = JSON.parse open(COOKBOOK_RELEASES_URL).read
|
12
|
-
tarballs = json
|
13
|
-
|
22
|
+
tarballs = tarballs_of_releases json
|
23
|
+
|
24
|
+
latest = tarballs.first
|
25
|
+
selected = tarballs.find { |release| !release[1].empty? }
|
26
|
+
|
27
|
+
if selected != latest
|
28
|
+
warn "WARNING: Latest cookbook release (#{latest.first}) does not "\
|
29
|
+
"contain a valid package. Falling back to #{selected.first}."
|
14
30
|
end
|
15
|
-
|
31
|
+
|
32
|
+
selected[1].first
|
16
33
|
end
|
17
34
|
|
18
35
|
HEADER = <<-HEADER.freeze
|
@@ -81,7 +98,7 @@ set -e
|
|
81
98
|
@chef_script ||= [
|
82
99
|
("curl -L https://www.opscode.com/chef/install.sh | " + sudo["bash"] \
|
83
100
|
if install_chef?),
|
84
|
-
(sudo["#{chef_executable} -
|
101
|
+
(sudo["#{chef_executable} --recipe-url #{conjur_cookbook_url} " \
|
85
102
|
"-o #{conjur_run_list}"] if run_chef?)
|
86
103
|
].join "\n"
|
87
104
|
end
|
data/lib/conjur/version.rb
CHANGED
data/spec/authn_spec.rb
CHANGED
@@ -8,23 +8,53 @@ describe Conjur::Authn do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "credentials from environment" do
|
11
|
+
shared_examples_for "is_not_written_to_netrc" do
|
12
|
+
it "are not written to netrc" do
|
13
|
+
expect(Conjur::Authn).not_to receive(:write_credentials)
|
14
|
+
Conjur::Authn.get_credentials
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:api) { Conjur::Authn.connect }
|
19
|
+
|
11
20
|
before do
|
12
21
|
Conjur::Authn.instance_variable_set("@credentials", nil)
|
13
|
-
expect(ENV).to receive(:[]).with("CONJUR_AUTHN_LOGIN").and_return "the-login"
|
14
|
-
expect(ENV).to receive(:[]).with("CONJUR_AUTHN_API_KEY").and_return "the-api-key"
|
15
22
|
end
|
16
23
|
|
17
24
|
after do
|
18
25
|
Conjur::Authn.instance_variable_set("@credentials", nil)
|
19
26
|
end
|
20
27
|
|
21
|
-
|
22
|
-
expect(Conjur::Authn.get_credentials).to eq([ "the-login", "the-api-key" ])
|
23
|
-
end
|
28
|
+
let(:encoded_token) { nil }
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
30
|
+
before do
|
31
|
+
allow(ENV).to receive(:[]).and_call_original
|
32
|
+
allow(ENV).to receive(:[]).with("CONJUR_AUTHN_TOKEN").and_return encoded_token
|
33
|
+
allow(ENV).to receive(:[]).with("CONJUR_AUTHN_LOGIN").and_return "the-login"
|
34
|
+
allow(ENV).to receive(:[]).with("CONJUR_AUTHN_API_KEY").and_return "the-api-key"
|
35
|
+
end
|
36
|
+
|
37
|
+
context "login and API key" do
|
38
|
+
it "are used to authn" do
|
39
|
+
expect(Conjur::Authn.get_credentials).to eq([ "the-login", "the-api-key" ])
|
40
|
+
|
41
|
+
expect(api.username).to eq('the-login')
|
42
|
+
expect(api.api_key).to eq('the-api-key')
|
43
|
+
end
|
44
|
+
it_should_behave_like "is_not_written_to_netrc"
|
45
|
+
end
|
46
|
+
context "token" do
|
47
|
+
let(:token) { { "data" => "the-token-login" } }
|
48
|
+
let(:encoded_token) { Base64.strict_encode64(token.to_json) }
|
49
|
+
before {
|
50
|
+
allow_any_instance_of(Conjur::API).to receive(:validate_token)
|
51
|
+
}
|
52
|
+
it "is used to authn" do
|
53
|
+
expect(api.username).to eq('the-token-login')
|
54
|
+
expect(api.api_key).to_not be
|
55
|
+
expect(api.token).to eq(token)
|
56
|
+
end
|
57
|
+
it_should_behave_like "is_not_written_to_netrc"
|
28
58
|
end
|
29
59
|
end
|
30
60
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Conjur::Command::LDAPSync, logged_in: true do
|
4
|
+
let(:timestamp) { Time.now.to_s }
|
5
|
+
let(:json_response) { {
|
6
|
+
'events' => [
|
7
|
+
{ "timestamp" => timestamp,
|
8
|
+
"severity" => "info",
|
9
|
+
"message" => "Performing sync"
|
10
|
+
}
|
11
|
+
],
|
12
|
+
'result' => {
|
13
|
+
'actions' => [
|
14
|
+
"user 'Guest'", "group 'Domain Computers'"
|
15
|
+
]
|
16
|
+
}
|
17
|
+
} }
|
18
|
+
let(:yaml_response) { [
|
19
|
+
'annotations' => {
|
20
|
+
'ldap-sync/source' => '192.168.99.100:389',
|
21
|
+
'ldap-sync/upstream-dn' => 'cn=Guest,dc=example,dc=org',
|
22
|
+
}
|
23
|
+
].to_yaml }
|
24
|
+
|
25
|
+
describe_command 'ldap-sync now -f text' do
|
26
|
+
before {
|
27
|
+
expect_any_instance_of(Conjur::API).to receive(:ldap_sync_now).and_return json_response
|
28
|
+
}
|
29
|
+
it 'prints out diagnostic events' do
|
30
|
+
expect { invoke }.to write([ timestamp, "info", "Performing sync" ].join("\t"))
|
31
|
+
end
|
32
|
+
it 'prints out actions as text' do
|
33
|
+
expect { invoke }.to write("user 'Guest'\ngroup 'Domain Computers'")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe_command 'ldap-sync now -f yaml' do
|
38
|
+
it 'prints out actions as unparsed yaml' do
|
39
|
+
expect_any_instance_of(Conjur::API).to receive(:ldap_sync_now).and_return yaml_response
|
40
|
+
expect { invoke }.to write(yaml_response)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "conjur/conjurize/script"
|
3
|
+
|
4
|
+
describe Conjur::Conjurize::Script do
|
5
|
+
describe ".latest_conjur_cookbook_release" do
|
6
|
+
let(:releases_json) do
|
7
|
+
%([
|
8
|
+
{
|
9
|
+
"name": "v0.4.0",
|
10
|
+
"assets": [{
|
11
|
+
"name": "conjur-v0.4.0.tar.gz",
|
12
|
+
"browser_download_url": "http://example.com/conjur-v0.4.0.tar.gz"
|
13
|
+
}]
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"name": "v0.3.0",
|
17
|
+
"assets": [{
|
18
|
+
"name": "conjur-v0.3.0.tar.gz",
|
19
|
+
"browser_download_url": "http://example.com/conjur-v0.3.0.tar.gz"
|
20
|
+
}]
|
21
|
+
}
|
22
|
+
])
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
allow(Conjur::Conjurize::Script).to receive(:open)\
|
27
|
+
.with("https://api.github.com/repos/conjur-cookbooks/conjur/releases")\
|
28
|
+
.and_return double(read: releases_json)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "looks up the latest release download url" do
|
32
|
+
expect(Conjur::Conjurize::Script.latest_conjur_cookbook_release).to \
|
33
|
+
eq "http://example.com/conjur-v0.4.0.tar.gz"
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with latest release is without any tarballs" do
|
37
|
+
let(:releases_json) do
|
38
|
+
%([
|
39
|
+
{
|
40
|
+
"name": "v0.4.0",
|
41
|
+
"assets": []
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"name": "v0.3.0",
|
45
|
+
"assets": [{
|
46
|
+
"name": "conjur-v0.3.0.tar.gz",
|
47
|
+
"browser_download_url": "http://example.com/conjur-v0.3.0.tar.gz"
|
48
|
+
}]
|
49
|
+
}
|
50
|
+
])
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns the previous one and warns" do
|
54
|
+
err = $stderr.grab do
|
55
|
+
expect(Conjur::Conjurize::Script.latest_conjur_cookbook_release).to \
|
56
|
+
eq "http://example.com/conjur-v0.3.0.tar.gz"
|
57
|
+
end
|
58
|
+
expect(err).to include "WARNING"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
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.
|
4
|
+
version: 5.2.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-
|
12
|
+
date: 2016-05-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -389,6 +389,7 @@ files:
|
|
389
389
|
- lib/conjur/command/ids.rb
|
390
390
|
- lib/conjur/command/init.rb
|
391
391
|
- lib/conjur/command/layers.rb
|
392
|
+
- lib/conjur/command/ldapsync.rb
|
392
393
|
- lib/conjur/command/plugin.rb
|
393
394
|
- lib/conjur/command/pubkeys.rb
|
394
395
|
- lib/conjur/command/resources.rb
|
@@ -427,6 +428,7 @@ files:
|
|
427
428
|
- spec/command/hosts_spec.rb
|
428
429
|
- spec/command/init_spec.rb
|
429
430
|
- spec/command/layers_spec.rb
|
431
|
+
- spec/command/ldapsync_spec.rb
|
430
432
|
- spec/command/pubkeys_spec.rb
|
431
433
|
- spec/command/resources_spec.rb
|
432
434
|
- spec/command/roles_spec.rb
|
@@ -437,6 +439,7 @@ files:
|
|
437
439
|
- spec/command_spec.rb
|
438
440
|
- spec/complete_spec.rb
|
439
441
|
- spec/config_spec.rb
|
442
|
+
- spec/conjurize/script_spec.rb
|
440
443
|
- spec/conjurize_spec.rb
|
441
444
|
- spec/conjurrc
|
442
445
|
- spec/dsl/runner_spec.rb
|
@@ -497,6 +500,7 @@ test_files:
|
|
497
500
|
- spec/command/hosts_spec.rb
|
498
501
|
- spec/command/init_spec.rb
|
499
502
|
- spec/command/layers_spec.rb
|
503
|
+
- spec/command/ldapsync_spec.rb
|
500
504
|
- spec/command/pubkeys_spec.rb
|
501
505
|
- spec/command/resources_spec.rb
|
502
506
|
- spec/command/roles_spec.rb
|
@@ -507,6 +511,7 @@ test_files:
|
|
507
511
|
- spec/command_spec.rb
|
508
512
|
- spec/complete_spec.rb
|
509
513
|
- spec/config_spec.rb
|
514
|
+
- spec/conjurize/script_spec.rb
|
510
515
|
- spec/conjurize_spec.rb
|
511
516
|
- spec/conjurrc
|
512
517
|
- spec/dsl/runner_spec.rb
|