conjur-cli 4.28.2 → 4.29.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/.dockerignore +8 -0
- data/.gitignore +2 -0
- data/.overcommit.yml +10 -0
- data/.rubocop.yml +14 -0
- data/CHANGELOG.md +16 -0
- data/Dockerfile +10 -0
- data/Gemfile +2 -0
- data/Rakefile +1 -1
- data/acceptance-features/audit/audit_event_send.feature +46 -43
- data/acceptance-features/audit/send.feature +0 -19
- data/acceptance-features/authentication/login.feature +0 -2
- data/acceptance-features/authentication/logout.feature +0 -3
- data/acceptance-features/authorization/resource/check.feature +6 -4
- data/acceptance-features/authorization/resource/create.feature +4 -2
- data/acceptance-features/authorization/resource/exists.feature +8 -6
- data/acceptance-features/authorization/resource/give.feature +3 -1
- data/acceptance-features/authorization/resource/show.feature +3 -1
- data/acceptance-features/authorization/role/graph.feature +0 -1
- data/acceptance-features/conjurenv/check.feature +3 -10
- data/acceptance-features/conjurenv/run.feature +3 -3
- data/acceptance-features/conjurenv/template.feature +1 -1
- data/acceptance-features/directory/hostfactory/create.feature +13 -0
- data/acceptance-features/directory/hostfactory/tokens.feature +16 -0
- data/acceptance-features/directory/layer/retire.feature +43 -0
- data/acceptance-features/directory/user/update_password.feature +0 -1
- data/acceptance-features/directory/variable/value.feature +3 -2
- data/acceptance-features/dsl/policy_owner.feature +21 -7
- data/acceptance-features/dsl/resource_owner.feature +4 -4
- data/acceptance-features/pubkeys/add.feature +4 -2
- data/acceptance-features/pubkeys/names.feature +6 -3
- data/acceptance-features/pubkeys/show.feature +4 -2
- data/acceptance-features/step_definitions/{cli.rb → cli_steps.rb} +18 -4
- data/acceptance-features/step_definitions/user_steps.rb +13 -12
- data/acceptance-features/support/env.rb +0 -1
- data/acceptance-features/support/hooks.rb +11 -14
- data/acceptance-features/support/world.rb +16 -18
- data/build-deb.sh +19 -0
- data/ci/test.sh +19 -0
- data/conjur.gemspec +9 -12
- data/debify.sh +4 -0
- data/distrib/bin/_conjur +3 -0
- data/distrib/bin/conjur +3 -0
- data/distrib/bin/conjurize +3 -0
- data/distrib/bin/jsonfield +3 -0
- data/features/conjurize.feature +25 -25
- data/features/support/env.rb +5 -1
- data/features/support/hooks.rb +0 -1
- data/jenkins.sh +29 -1
- data/lib/conjur/cli.rb +27 -4
- data/lib/conjur/command.rb +36 -0
- data/lib/conjur/command/audit.rb +12 -0
- data/lib/conjur/command/bootstrap.rb +5 -9
- data/lib/conjur/command/host_factories.rb +187 -0
- data/lib/conjur/command/hosts.rb +82 -2
- data/lib/conjur/command/layers.rb +28 -0
- data/lib/conjur/command/resources.rb +1 -0
- data/lib/conjur/command/rspec/mock_services.rb +1 -1
- data/lib/conjur/command/server.rb +67 -0
- data/lib/conjur/command/users.rb +67 -12
- data/lib/conjur/command/variables.rb +101 -14
- data/lib/conjur/conjurize.rb +25 -69
- data/lib/conjur/conjurize/script.rb +133 -0
- data/lib/conjur/version.rb +1 -1
- data/publish.sh +6 -0
- data/spec/command/elevate_spec.rb +1 -1
- data/spec/command/host_factories_spec.rb +38 -0
- data/spec/command/hosts_spec.rb +86 -22
- data/spec/command/users_spec.rb +51 -3
- data/spec/command/variable_expiration_spec.rb +174 -0
- data/spec/command/variables_spec.rb +1 -1
- data/spec/conjurize_spec.rb +70 -0
- metadata +61 -64
data/lib/conjur/conjurize.rb
CHANGED
|
@@ -2,14 +2,7 @@ require 'methadone'
|
|
|
2
2
|
require 'json'
|
|
3
3
|
require 'open-uri'
|
|
4
4
|
require 'conjur/version.rb'
|
|
5
|
-
|
|
6
|
-
def latest_conjur_release
|
|
7
|
-
url = 'https://api.github.com/repos/conjur-cookbooks/conjur/releases'
|
|
8
|
-
resp = open(url)
|
|
9
|
-
json = JSON.parse(resp.read)
|
|
10
|
-
latest = json[0]['assets'].select {|asset| asset['name'] =~ /conjur-v\d.\d.\d.tar.gz/}[0]
|
|
11
|
-
latest['browser_download_url']
|
|
12
|
-
end
|
|
5
|
+
require "conjur/conjurize/script"
|
|
13
6
|
|
|
14
7
|
module Conjur
|
|
15
8
|
class Conjurize
|
|
@@ -31,77 +24,37 @@ DESC
|
|
|
31
24
|
else
|
|
32
25
|
STDIN.read
|
|
33
26
|
end
|
|
34
|
-
host = JSON.parse input
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
puts generate JSON.parse input
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.generate host
|
|
32
|
+
config = configuration host
|
|
38
33
|
|
|
39
|
-
|
|
34
|
+
if options[:json]
|
|
35
|
+
JSON.dump config
|
|
36
|
+
else
|
|
37
|
+
Script.generate config, options
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.apply_client_config
|
|
42
|
+
require "conjur/cli"
|
|
40
43
|
if conjur_config = options[:c]
|
|
41
44
|
Conjur::Config.load [ conjur_config ]
|
|
42
45
|
else
|
|
43
46
|
Conjur::Config.load
|
|
44
47
|
end
|
|
45
48
|
Conjur::Config.apply
|
|
49
|
+
end
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
conjur_run_list = options[:"conjur-run-list"]
|
|
50
|
-
conjur_cookbook_url = options[:"conjur-cookbook-url"]
|
|
51
|
-
chef_executable = options[:"chef-executable"]
|
|
52
|
-
|
|
53
|
-
if options[:ssh]
|
|
54
|
-
conjur_run_list ||= "conjur"
|
|
55
|
-
conjur_cookbook_url ||= latest_conjur_release()
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
sudo = lambda{|str|
|
|
59
|
-
[ options[:sudo] ? "sudo -n" : nil, str ].compact.join(" ")
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
header = <<-HEADER
|
|
63
|
-
#!/bin/sh
|
|
64
|
-
set -e
|
|
65
|
-
|
|
66
|
-
# Implementation note: 'tee' is used as a sudo-friendly 'cat' to populate a file with the contents provided below.
|
|
67
|
-
HEADER
|
|
68
|
-
|
|
69
|
-
configure_conjur = <<-CONFIGURE
|
|
70
|
-
#{sudo.call 'tee'} /etc/conjur.conf > /dev/null << CONJUR_CONF
|
|
71
|
-
account: #{Conjur.configuration.account}
|
|
72
|
-
appliance_url: #{Conjur.configuration.appliance_url}
|
|
73
|
-
cert_file: /etc/conjur-#{Conjur.configuration.account}.pem
|
|
74
|
-
netrc_path: /etc/conjur.identity
|
|
75
|
-
plugins: []
|
|
76
|
-
CONJUR_CONF
|
|
77
|
-
|
|
78
|
-
#{sudo.call 'tee'} /etc/conjur-#{Conjur.configuration.account}.pem > /dev/null << CONJUR_CERT
|
|
79
|
-
#{File.read(Conjur.configuration.cert_file).strip}
|
|
80
|
-
CONJUR_CERT
|
|
81
|
-
|
|
82
|
-
#{sudo.call 'tee'} /etc/conjur.identity > /dev/null << CONJUR_IDENTITY
|
|
83
|
-
machine #{Conjur.configuration.appliance_url}/authn
|
|
84
|
-
login host/#{login}
|
|
85
|
-
password #{api_key}
|
|
86
|
-
CONJUR_IDENTITY
|
|
87
|
-
#{sudo.call 'chmod'} 0600 /etc/conjur.identity
|
|
88
|
-
CONFIGURE
|
|
89
|
-
|
|
90
|
-
install_chef = if conjur_cookbook_url && !chef_executable
|
|
91
|
-
%Q(curl -L https://www.opscode.com/chef/install.sh | #{sudo.call 'bash'})
|
|
92
|
-
else
|
|
93
|
-
nil
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
chef_executable ||= "chef-solo"
|
|
97
|
-
|
|
98
|
-
run_chef = if conjur_cookbook_url
|
|
99
|
-
%Q(#{sudo.call "#{chef_executable} -r #{conjur_cookbook_url} -o #{conjur_run_list}"})
|
|
100
|
-
else
|
|
101
|
-
nil
|
|
102
|
-
end
|
|
51
|
+
def self.configuration host
|
|
52
|
+
apply_client_config
|
|
103
53
|
|
|
104
|
-
|
|
54
|
+
host.merge \
|
|
55
|
+
"account" => Conjur.configuration.account,
|
|
56
|
+
"appliance_url" => Conjur.configuration.appliance_url,
|
|
57
|
+
"certificate" => File.read(Conjur.configuration.cert_file).strip
|
|
105
58
|
end
|
|
106
59
|
|
|
107
60
|
on("-c CONJUR_CONFIG_FILE", "Overrides defaults (CONJURRC env var, ~/.conjurrc, /etc/conjur.conf).")
|
|
@@ -111,5 +64,8 @@ CONJUR_IDENTITY
|
|
|
111
64
|
on("--sudo", "Indicates that all commands should be run via 'sudo'.")
|
|
112
65
|
on("--conjur-cookbook-url NAME", "Overrides the default Chef cookbook URL for Conjur SSH.")
|
|
113
66
|
on("--conjur-run-list RUNLIST", "Overrides the default Chef run list for Conjur SSH.")
|
|
67
|
+
on \
|
|
68
|
+
"--json",
|
|
69
|
+
"Don't generate the script, instead just dump the configuration as JSON"
|
|
114
70
|
end
|
|
115
71
|
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "open-uri"
|
|
3
|
+
|
|
4
|
+
class Conjur::Conjurize
|
|
5
|
+
# generates a shell script to conjurize a host
|
|
6
|
+
class Script
|
|
7
|
+
COOKBOOK_RELEASES_URL =
|
|
8
|
+
"https://api.github.com/repos/conjur-cookbooks/conjur/releases".freeze
|
|
9
|
+
|
|
10
|
+
def self.latest_conjur_cookbook_release
|
|
11
|
+
json = JSON.parse open(COOKBOOK_RELEASES_URL).read
|
|
12
|
+
tarballs = json[0]["assets"].select do |asset|
|
|
13
|
+
asset["name"] =~ /conjur-v\d.\d.\d.tar.gz/
|
|
14
|
+
end
|
|
15
|
+
tarballs.first["browser_download_url"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
HEADER = <<-HEADER.freeze
|
|
19
|
+
#!/bin/sh
|
|
20
|
+
set -e
|
|
21
|
+
|
|
22
|
+
# Implementation note: 'tee' is used as a sudo-friendly 'cat' to populate a file with the contents provided below.
|
|
23
|
+
HEADER
|
|
24
|
+
|
|
25
|
+
def initialize options
|
|
26
|
+
@options = options
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
attr_reader :options
|
|
30
|
+
|
|
31
|
+
def sudo
|
|
32
|
+
@sudo ||= options["sudo"] ? ->(x) { "sudo -n #{x}" } : ->(x) { x }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Generate a piece of shell to write to a file
|
|
36
|
+
# @param path [String] absolute path to write to
|
|
37
|
+
# @param content [String] contents to write
|
|
38
|
+
# @option options [String, Fixnum] :mode mode to apply to the file
|
|
39
|
+
def write_file path, content, options = {}
|
|
40
|
+
[
|
|
41
|
+
((mode = options[:mode]) && set_mode(path, mode)),
|
|
42
|
+
[sudo["tee"], path, "> /dev/null << EOF"].join(" "),
|
|
43
|
+
content.strip,
|
|
44
|
+
"EOF\n"
|
|
45
|
+
].compact.join("\n")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def set_mode path, mode
|
|
49
|
+
mode = mode.to_s(8) if mode.respond_to? :to_int
|
|
50
|
+
[
|
|
51
|
+
[sudo["touch"], path].join(" "),
|
|
52
|
+
[sudo["chmod"], mode, path].join(" ")
|
|
53
|
+
].join("\n")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.generate configuration, options
|
|
57
|
+
new(options).generate configuration
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def install_chef?
|
|
61
|
+
run_chef? && !options[:"chef-executable"]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def run_chef?
|
|
65
|
+
options.values_at(:ssh, :"conjur-run-list").any?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def chef_executable
|
|
69
|
+
options[:"chef-executable"] || "chef-solo"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def conjur_cookbook_url
|
|
73
|
+
options[:"conjur-cookbook-url"] || Script.latest_conjur_cookbook_release
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def conjur_run_list
|
|
77
|
+
options[:"conjur-run-list"] || "conjur"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def chef_script
|
|
81
|
+
@chef_script ||= [
|
|
82
|
+
("curl -L https://www.opscode.com/chef/install.sh | " + sudo["bash"] \
|
|
83
|
+
if install_chef?),
|
|
84
|
+
(sudo["#{chef_executable} -r #{conjur_cookbook_url} " \
|
|
85
|
+
"-o #{conjur_run_list}"] if run_chef?)
|
|
86
|
+
].join "\n"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def self.rc configuration
|
|
90
|
+
[
|
|
91
|
+
"account: #{configuration['account']}",
|
|
92
|
+
"appliance_url: #{configuration['appliance_url']}",
|
|
93
|
+
"cert_file: /etc/conjur-#{configuration['account']}.pem",
|
|
94
|
+
"netrc_path: /etc/conjur.identity",
|
|
95
|
+
"plugins: []"
|
|
96
|
+
].join "\n"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def self.identity configuration
|
|
100
|
+
"""
|
|
101
|
+
machine #{configuration['appliance_url']}/authn
|
|
102
|
+
login host/#{configuration['id']}
|
|
103
|
+
password #{configuration['api_key']}
|
|
104
|
+
"""
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def configure_conjur configuration
|
|
108
|
+
[
|
|
109
|
+
write_file("/etc/conjur.conf", Script.rc(configuration)),
|
|
110
|
+
write_file(
|
|
111
|
+
"/etc/conjur-#{configuration['account']}.pem",
|
|
112
|
+
configuration["certificate"]
|
|
113
|
+
),
|
|
114
|
+
write_file(
|
|
115
|
+
"/etc/conjur.identity",
|
|
116
|
+
Script.identity(configuration),
|
|
117
|
+
mode: 0600
|
|
118
|
+
)
|
|
119
|
+
].join "\n"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def generate configuration
|
|
123
|
+
fail "No 'id' field in host JSON" unless configuration["id"]
|
|
124
|
+
fail "No 'api_key' field in host JSON" unless configuration["api_key"]
|
|
125
|
+
|
|
126
|
+
[
|
|
127
|
+
HEADER,
|
|
128
|
+
configure_conjur(configuration),
|
|
129
|
+
chef_script
|
|
130
|
+
].join("\n")
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
data/lib/conjur/version.rb
CHANGED
data/publish.sh
ADDED
|
@@ -17,7 +17,7 @@ describe Conjur::Command::Elevate do
|
|
|
17
17
|
|
|
18
18
|
expect(RestClient::Request).to receive(:execute).with({
|
|
19
19
|
method: :get,
|
|
20
|
-
url: "https://core.example.com/users/alice",
|
|
20
|
+
url: "https://core.example.com/api/users/alice",
|
|
21
21
|
username: "dknuth",
|
|
22
22
|
headers: {:authorization=>"Token token=\"eyJsb2dpbiI6ImRrbnV0aCJ9\"", x_conjur_privilege: "elevate"}
|
|
23
23
|
}).and_return(double(:response, body: "[]"))
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'conjur/command/host_factories'
|
|
3
|
+
|
|
4
|
+
describe Conjur::Command::HostFactories, :logged_in => true do
|
|
5
|
+
let (:group_memberships) { double(:group_memberships, :roleid => 'the-account:group:security_admin') }
|
|
6
|
+
let (:group) { double(:group, :exists? => true, :memberships => [group_memberships]) }
|
|
7
|
+
let (:layer_members) { double(:layer_members, :member => double(:member, :roleid => 'the-account:group:security_admin'), :admin_option => true ) }
|
|
8
|
+
let (:layer_role) { double(:layer_role, :members => [layer_members]) }
|
|
9
|
+
let (:layer) { double(:layer, :exists? => true, :role => layer_role) }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
allow(Conjur::Command.api).to receive(:role).with("the-account:group:the-group").and_return group
|
|
13
|
+
allow(Conjur::Command.api).to receive(:layer).with("layer1").and_return layer
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe_command 'hostfactory:create --as-group the-group --layer layer1 hf1 ' do
|
|
17
|
+
|
|
18
|
+
it 'calls api.create_host_factory and prints the results' do
|
|
19
|
+
expect_any_instance_of(Conjur::API).to receive(:create_host_factory).and_return '{}'
|
|
20
|
+
expect { invoke }.to write('{}')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'command-line errors' do
|
|
25
|
+
describe_command 'hostfactory:create hf1' do
|
|
26
|
+
it "fails without owner" do
|
|
27
|
+
expect {invoke}.to raise_error('Use --as-group or --as-role to indicate the host factory role')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
describe_command 'hostfactory:create --as-group the-group hf' do
|
|
31
|
+
it "fails without layer" do
|
|
32
|
+
expect {invoke}.to raise_error('Provide at least one layer')
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
data/spec/command/hosts_spec.rb
CHANGED
|
@@ -1,30 +1,94 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Conjur::Command::Hosts, logged_in: true do
|
|
4
|
-
let(:collection_url) { "https://core.example.com/hosts" }
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
let(:collection_url) { "https://core.example.com/api/hosts" }
|
|
5
|
+
|
|
6
|
+
context "creating a host" do
|
|
7
|
+
let(:new_host) { double("new-host") }
|
|
8
|
+
|
|
9
|
+
describe_command "host:create" do
|
|
10
|
+
it "lets the server assign the id" do
|
|
11
|
+
expect(RestClient::Request).to receive(:execute).with({
|
|
12
|
+
method: :post,
|
|
13
|
+
url: collection_url,
|
|
14
|
+
headers: {},
|
|
15
|
+
payload: {}
|
|
16
|
+
}).and_return(post_response('assigned-id'))
|
|
17
|
+
|
|
18
|
+
expect { invoke }.to write({ id: 'assigned-id' }).to(:stdout)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
describe_command "host:create the-id" do
|
|
22
|
+
it "propagates the user-assigned id" do
|
|
23
|
+
expect(RestClient::Request).to receive(:execute).with({
|
|
24
|
+
method: :post,
|
|
25
|
+
url: collection_url,
|
|
26
|
+
headers: {},
|
|
27
|
+
payload: { id: 'the-id' }
|
|
28
|
+
}).and_return(post_response('the-id'))
|
|
29
|
+
|
|
30
|
+
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
describe_command "host:create --cidr 192.168.1.1,127.0.0.0/32" do
|
|
34
|
+
it "Creates a host with specified CIDR" do
|
|
35
|
+
expect_any_instance_of(Conjur::API).to receive(:create_host).with(
|
|
36
|
+
{ cidr: ['192.168.1.1', '127.0.0.0/32'] }
|
|
37
|
+
).and_return new_host
|
|
38
|
+
invoke
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
describe_command "host:create --as-group security_admin --cidr 192.168.1.1,127.0.0.0/32" do
|
|
42
|
+
it "Creates a host with specified CIDR" do
|
|
43
|
+
expect(api).to receive(:group).with("security_admin").and_return(double(:group, roleid: "the-account:group:security_admin"))
|
|
44
|
+
expect(api).to receive(:role).with("the-account:group:security_admin").and_return(double(:group_role, exists?: true))
|
|
45
|
+
expect_any_instance_of(Conjur::API).to receive(:create_host).with(
|
|
46
|
+
{ ownerid: "the-account:group:security_admin", cidr: ['192.168.1.1', '127.0.0.0/32'] }
|
|
47
|
+
).and_return new_host
|
|
48
|
+
invoke
|
|
49
|
+
end
|
|
16
50
|
end
|
|
17
51
|
end
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
52
|
+
|
|
53
|
+
context "updating host attributes" do
|
|
54
|
+
describe_command "host update --cidr 127.0.0.0/32 the-user" do
|
|
55
|
+
it "updates the CIDR" do
|
|
56
|
+
stub_host = double()
|
|
57
|
+
expect_any_instance_of(Conjur::API).to receive(:host).with("the-user").and_return stub_host
|
|
58
|
+
expect(stub_host).to receive(:update).with(cidr: ['127.0.0.0/32']).and_return ""
|
|
59
|
+
expect { invoke }.to write "Host updated"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe_command "host update --cidr all the-user" do
|
|
64
|
+
it "resets the CIDR restrictions" do
|
|
65
|
+
stub_host = double()
|
|
66
|
+
expect_any_instance_of(Conjur::API).to receive(:host).with("the-user").and_return stub_host
|
|
67
|
+
expect(stub_host).to receive(:update).with(cidr: []).and_return ""
|
|
68
|
+
expect { invoke }.to write "Host updated"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context 'rotating api key' do
|
|
74
|
+
describe_command 'host rotate_api_key --host redis001' do
|
|
75
|
+
before do
|
|
76
|
+
expect(RestClient::Request).to receive(:execute).with({
|
|
77
|
+
method: :head,
|
|
78
|
+
url: 'https://core.example.com/api/hosts/redis001',
|
|
79
|
+
headers: {}
|
|
80
|
+
}).and_return true
|
|
81
|
+
expect(RestClient::Request).to receive(:execute).with({
|
|
82
|
+
method: :put,
|
|
83
|
+
url: 'https://authn.example.com/users/api_key?id=host%2Fredis001',
|
|
84
|
+
headers: {},
|
|
85
|
+
payload: ''
|
|
86
|
+
}).and_return double(:response, body: 'new api key')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'puts with basic auth' do
|
|
90
|
+
invoke
|
|
91
|
+
end
|
|
28
92
|
end
|
|
29
93
|
end
|
|
30
94
|
end
|
data/spec/command/users_spec.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Conjur::Command::Users, logged_in: true do
|
|
4
|
-
let(:create_user_url) { "https://core.example.com/users" }
|
|
4
|
+
let(:create_user_url) { "https://core.example.com/api/users" }
|
|
5
5
|
let(:update_password_url) { "https://authn.example.com/users/password" }
|
|
6
6
|
|
|
7
7
|
context "creating a user" do
|
|
@@ -31,16 +31,41 @@ describe Conjur::Command::Users, logged_in: true do
|
|
|
31
31
|
invoke
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
+
describe_command "#{cmd} --cidr 192.168.1.1,127.0.0.0/32 the-user" do
|
|
35
|
+
it "Creates a user with specified CIDR" do
|
|
36
|
+
expect_any_instance_of(Conjur::API).to receive(:create_user).with(
|
|
37
|
+
"the-user", { cidr: ['192.168.1.1', '127.0.0.0/32'] }
|
|
38
|
+
).and_return new_user
|
|
39
|
+
invoke
|
|
40
|
+
end
|
|
41
|
+
end
|
|
34
42
|
end
|
|
35
43
|
end
|
|
36
44
|
|
|
37
|
-
context "updating
|
|
45
|
+
context "updating user attributes" do
|
|
38
46
|
describe_command "user update --uidnumber 12345 the-user" do
|
|
39
47
|
it "updates the uidnumber" do
|
|
40
48
|
stub_user = double()
|
|
41
49
|
expect_any_instance_of(Conjur::API).to receive(:user).with("the-user").and_return stub_user
|
|
42
50
|
expect(stub_user).to receive(:update).with(uidnumber: 12345).and_return ""
|
|
43
|
-
expect { invoke }.to write "
|
|
51
|
+
expect { invoke }.to write "User updated"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
describe_command "user update --cidr 127.0.0.0/32 the-user" do
|
|
55
|
+
it "updates the CIDR" do
|
|
56
|
+
stub_user = double()
|
|
57
|
+
expect_any_instance_of(Conjur::API).to receive(:user).with("the-user").and_return stub_user
|
|
58
|
+
expect(stub_user).to receive(:update).with(cidr: ['127.0.0.0/32']).and_return ""
|
|
59
|
+
expect { invoke }.to write "User updated"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe_command "user update --cidr all the-user" do
|
|
64
|
+
it "resets the CIDR restrictions" do
|
|
65
|
+
stub_user = double()
|
|
66
|
+
expect_any_instance_of(Conjur::API).to receive(:user).with("the-user").and_return stub_user
|
|
67
|
+
expect(stub_user).to receive(:update).with(cidr: []).and_return ""
|
|
68
|
+
expect { invoke }.to write "User updated"
|
|
44
69
|
end
|
|
45
70
|
end
|
|
46
71
|
end
|
|
@@ -81,4 +106,27 @@ describe Conjur::Command::Users, logged_in: true do
|
|
|
81
106
|
end
|
|
82
107
|
end
|
|
83
108
|
end
|
|
109
|
+
|
|
110
|
+
context 'rotating api key' do
|
|
111
|
+
describe_command 'user rotate_api_key' do
|
|
112
|
+
before do
|
|
113
|
+
expect(RestClient::Request).to receive(:execute).with({
|
|
114
|
+
method: :put,
|
|
115
|
+
url: 'https://authn.example.com/users/api_key',
|
|
116
|
+
user: username,
|
|
117
|
+
password: api_key,
|
|
118
|
+
headers: {},
|
|
119
|
+
payload: ''
|
|
120
|
+
}).and_return double(:response, body: 'new api key')
|
|
121
|
+
expect(Conjur::Authn).to receive(:save_credentials).with({
|
|
122
|
+
username: username,
|
|
123
|
+
password: 'new api key'
|
|
124
|
+
})
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'puts with basic auth' do
|
|
128
|
+
invoke
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
84
132
|
end
|