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