conjur-cli 4.23.0 → 4.24.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 +4 -0
- data/lib/conjur/command/variables.rb +92 -13
- data/lib/conjur/version.rb +1 -1
- data/spec/command/variables_spec.rb +140 -55
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f4a996c0914a820ab371451e111785dc061c89a7
|
|
4
|
+
data.tar.gz: 3469ca2580a5df324247818f181515e530d4bc03
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c73f490d57c0dbd9cfc0c69aab11d6832442be416c29cc4b147d048669ca7c0914bdeda8ed6f82f8bde7d171ca955680b201af0685f879ba85334de850e0438b
|
|
7
|
+
data.tar.gz: b4a2f624525b425cfbfbb69eb03f2b04fd84cbe02772f47ac4dbe14371860aa764dfaa69151e8cc0a021108388ed7c491420cdd16a6944bf539b673c13f03dee
|
data/CHANGELOG.md
CHANGED
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
19
19
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
class Conjur::Command::Variables < Conjur::Command
|
|
23
22
|
desc "Manage variables"
|
|
24
23
|
command :variable do |var|
|
|
@@ -26,10 +25,10 @@ class Conjur::Command::Variables < Conjur::Command
|
|
|
26
25
|
var.arg_name "id [value]"
|
|
27
26
|
var.command :create do |c|
|
|
28
27
|
c.arg_name "mime_type"
|
|
29
|
-
c.flag [:m, :"mime-type"], default_value:
|
|
28
|
+
c.flag [:m, :"mime-type"], default_value: 'text/plain'
|
|
30
29
|
|
|
31
30
|
c.arg_name "kind"
|
|
32
|
-
c.flag [:k, :"kind"], default_value:
|
|
31
|
+
c.flag [:k, :"kind"], default_value: 'secret'
|
|
33
32
|
|
|
34
33
|
c.arg_name "value"
|
|
35
34
|
c.desc "Initial value, which may also be specified as the second command argument after the variable id"
|
|
@@ -37,26 +36,54 @@ class Conjur::Command::Variables < Conjur::Command
|
|
|
37
36
|
|
|
38
37
|
acting_as_option(c)
|
|
39
38
|
|
|
40
|
-
c.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
c.arg_name 'interactive'
|
|
40
|
+
c.desc 'Create variable interactively'
|
|
41
|
+
c.switch [:i, :'interactive']
|
|
42
|
+
|
|
43
|
+
c.action do |global_options,options, args|
|
|
44
|
+
@default_mime_type = c.flags[:m].default_value
|
|
45
|
+
@default_kind = c.flags[:k].default_value
|
|
46
|
+
|
|
47
|
+
id = args.shift unless args.empty?
|
|
48
|
+
|
|
45
49
|
value = args.shift unless args.empty?
|
|
46
50
|
|
|
47
|
-
raise "Received extra arguments '#{args.join(' ')}'" unless args.empty?
|
|
48
51
|
raise "Received conflicting value arguments" if value && options[:value]
|
|
49
|
-
|
|
50
|
-
options[:id] = id if id
|
|
51
|
-
options[:value] ||= value if value
|
|
52
52
|
|
|
53
|
+
groupid = options[:'ownerid']
|
|
53
54
|
mime_type = options.delete(:m)
|
|
54
55
|
kind = options.delete(:k)
|
|
55
|
-
|
|
56
|
+
value ||= options.delete(:v)
|
|
57
|
+
|
|
58
|
+
options.delete(:'interactive')
|
|
56
59
|
options.delete(:"mime-type")
|
|
57
60
|
options.delete(:"kind")
|
|
61
|
+
options.delete(:'value')
|
|
62
|
+
|
|
63
|
+
annotations = {}
|
|
64
|
+
|
|
65
|
+
# If the user asked for interactive mode, or he didn't specify
|
|
66
|
+
# both an id and a value, prompt for any missing options.
|
|
67
|
+
if options.delete(:i) || !(id && value)
|
|
68
|
+
id ||= prompt_for_id
|
|
58
69
|
|
|
70
|
+
groupid ||= prompt_for_group
|
|
71
|
+
|
|
72
|
+
kind = prompt_for_kind if !kind || kind == @default_kind
|
|
73
|
+
|
|
74
|
+
mime_type = prompt_for_mime_type if !mime_type || mime_type == @default_mime_type
|
|
75
|
+
|
|
76
|
+
annotations = prompt_for_annotations
|
|
77
|
+
|
|
78
|
+
value ||= prompt_for_value
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
options[:id] = id
|
|
82
|
+
options[:value] = value
|
|
83
|
+
options[:'ownerid'] = groupid if groupid
|
|
84
|
+
|
|
59
85
|
var = api.create_variable(mime_type, kind, options)
|
|
86
|
+
api.resource(var).annotations.merge!(annotations) if annotations && !annotations.empty?
|
|
60
87
|
display(var, options)
|
|
61
88
|
end
|
|
62
89
|
end
|
|
@@ -124,4 +151,56 @@ class Conjur::Command::Variables < Conjur::Command
|
|
|
124
151
|
end
|
|
125
152
|
|
|
126
153
|
end
|
|
154
|
+
|
|
155
|
+
def self.prompt_for_id
|
|
156
|
+
highline.ask('Enter the id: ')
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def self.prompt_for_group
|
|
160
|
+
highline.ask('Enter the group: ', ->(name) { @group && @group.roleid } ) do |q|
|
|
161
|
+
q.validate = ->(name) do
|
|
162
|
+
name.empty? || (@group = api.group(name)).exists?
|
|
163
|
+
end
|
|
164
|
+
q.responses[:not_valid] = "Group '<%= @answer %>' doesn't exist, or you don't have permission to use it"
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def self.prompt_for_kind
|
|
169
|
+
highline.ask('Enter the kind: ') {|q| q.default = @default_kind }
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def self.prompt_for_mime_type
|
|
173
|
+
highline.ask('Enter the MIME type: ') {|q| q.default = @default_mime_type }
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def self.prompt_for_annotations
|
|
177
|
+
highline.say('Add annotations (press enter to finish):')
|
|
178
|
+
{}.tap do |annotations|
|
|
179
|
+
until (name = highline.ask('annotation name: ')).empty?
|
|
180
|
+
annotations[name] = read_till_eof('annotation value (^D to finish):')
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def self.prompt_for_value
|
|
186
|
+
read_till_eof('Enter the value (^D on its own line to finish):')
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def self.highline
|
|
190
|
+
require 'highline'
|
|
191
|
+
@highline ||= HighLine.new($stdin,$stderr)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def self.read_till_eof(prompt = nil)
|
|
195
|
+
highline.say(prompt) if prompt
|
|
196
|
+
[].tap do |lines|
|
|
197
|
+
loop do
|
|
198
|
+
begin
|
|
199
|
+
lines << highline.ask('')
|
|
200
|
+
rescue EOFError
|
|
201
|
+
break
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end.join("\n")
|
|
205
|
+
end
|
|
127
206
|
end
|
data/lib/conjur/version.rb
CHANGED
|
@@ -1,72 +1,157 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Conjur::Command::Variables, logged_in: true do
|
|
4
|
-
let(:
|
|
5
|
-
let(:
|
|
4
|
+
let(:host) { 'https://core.example.com' }
|
|
5
|
+
let(:collection_url) { "#{host}/variables" }
|
|
6
|
+
let(:mime_type) { 'text/plain' }
|
|
7
|
+
let(:kind) { 'secret' }
|
|
8
|
+
let(:base_payload) do
|
|
9
|
+
{ id: id, value: value, mime_type: mime_type, kind: kind }.tap do |t|
|
|
10
|
+
group && t.merge(ownerid: group)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
6
13
|
let(:id) { 'the-id' }
|
|
7
14
|
let(:variable) { post_response(id) }
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
expect { invoke }.to write({ id: 'assigned-id' }).to(:stdout)
|
|
15
|
+
let (:group) { nil }
|
|
16
|
+
let (:annotation) { {} }
|
|
17
|
+
let (:value) { 'the-value' }
|
|
18
|
+
let (:full_payload) { base_payload }
|
|
19
|
+
|
|
20
|
+
context 'when there are command-line errors' do
|
|
21
|
+
describe_command "variable:create -v the-value-1 the-id the-value-2" do
|
|
22
|
+
it "complains about conflicting values" do
|
|
23
|
+
expect { invoke }.to raise_error("Received conflicting value arguments")
|
|
24
|
+
end
|
|
20
25
|
end
|
|
21
26
|
end
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
context 'when there are no command-line errors' do
|
|
29
|
+
|
|
30
|
+
before do
|
|
31
|
+
allow(Conjur::Command::Variables).to receive(:prompt_for_id) { id }
|
|
32
|
+
allow(Conjur::Command::Variables).to receive(:prompt_for_group) { group }
|
|
33
|
+
allow(Conjur::Command::Variables).to receive(:prompt_for_kind) { kind }
|
|
34
|
+
allow(Conjur::Command::Variables).to receive(:prompt_for_mime_type) { mime_type }
|
|
35
|
+
allow(Conjur::Command::Variables).to receive(:prompt_for_annotations) { annotation }
|
|
36
|
+
allow(Conjur::Command::Variables).to receive(:prompt_for_value) { value }
|
|
31
37
|
|
|
32
|
-
expect
|
|
38
|
+
expect(RestClient::Request).to receive(:execute).with({
|
|
39
|
+
method: :post,
|
|
40
|
+
url: collection_url,
|
|
41
|
+
headers: {},
|
|
42
|
+
payload: full_payload
|
|
43
|
+
}.merge(cert_store_options)).and_return(variable)
|
|
33
44
|
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
url: collection_url,
|
|
41
|
-
headers: {},
|
|
42
|
-
payload: base_payload.merge({ id: 'the-id', value: 'the-value' })
|
|
43
|
-
}.merge(cert_store_options)).and_return(variable)
|
|
44
|
-
|
|
45
|
-
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
|
45
|
+
|
|
46
|
+
describe_command "variable:create the-different-id" do
|
|
47
|
+
let (:id) { 'the-different-id' }
|
|
48
|
+
it "propagates the user-assigned id" do
|
|
49
|
+
expect { invoke }.to write({ id: 'the-different-id' }).to(:stdout)
|
|
50
|
+
end
|
|
46
51
|
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
|
|
53
|
+
describe_command "variable:create the-id the-different-value" do
|
|
54
|
+
let (:value) { 'the-different-value' }
|
|
55
|
+
it "propagates the user-assigned id" do
|
|
56
|
+
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
|
57
|
+
end
|
|
52
58
|
end
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
|
|
60
|
+
describe_command "variable:create -m application/json" do
|
|
61
|
+
let (:mime_type) { 'application/json' }
|
|
62
|
+
it "propagates the user-assigned MIME type" do
|
|
63
|
+
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
|
64
|
+
end
|
|
58
65
|
end
|
|
59
|
-
|
|
66
|
+
|
|
67
|
+
describe_command "variable:create -k password" do
|
|
68
|
+
let (:kind) { 'password' }
|
|
69
|
+
it "propagates the user-assigned kind" do
|
|
70
|
+
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe "in interactive mode" do
|
|
75
|
+
after do
|
|
76
|
+
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
subject { Conjur::Command::Variables }
|
|
80
|
+
|
|
81
|
+
context "when -i is omitted" do
|
|
82
|
+
describe_command 'variable:create' do
|
|
83
|
+
it { is_expected.to receive(:prompt_for_id) }
|
|
84
|
+
it { is_expected.to receive(:prompt_for_group) }
|
|
85
|
+
it { is_expected.to receive(:prompt_for_kind) }
|
|
86
|
+
it { is_expected.to receive(:prompt_for_mime_type) }
|
|
87
|
+
it { is_expected.to receive(:prompt_for_annotations) }
|
|
88
|
+
it { is_expected.to receive(:prompt_for_value) }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
describe_command 'variable:create the-id' do
|
|
92
|
+
it { is_expected.not_to receive(:prompt_for_id) }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe_command 'variable:create the-id the-value' do
|
|
96
|
+
it { is_expected.not_to receive(:prompt_for_value) }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe_command 'variable:create -m application/json' do
|
|
100
|
+
let (:mime_type) { 'application/json' }
|
|
101
|
+
it { is_expected.not_to receive(:prompt_for_mime_type) }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe_command 'variable:create -k password' do
|
|
105
|
+
let (:kind) { 'password' }
|
|
106
|
+
it { is_expected.not_to receive(:prompt_for_kind) }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe_command 'variable:create -v the-value' do
|
|
110
|
+
it { is_expected.not_to receive(:prompt_for_value) }
|
|
111
|
+
end
|
|
60
112
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
113
|
+
describe_command 'variable:create --as-group the-group' do
|
|
114
|
+
before do
|
|
115
|
+
allow(RestClient::Request).to receive(:execute).with({
|
|
116
|
+
method: :head,
|
|
117
|
+
url: 'https://authz.example.com/the-account/roles/group/the-group',
|
|
118
|
+
headers: {}
|
|
119
|
+
}.merge(cert_store_options)).and_return(OpenStruct.new(headers: {}, body: '{}'))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
let (:full_payload) { base_payload.merge(ownerid: 'the-account:group:the-group') }
|
|
123
|
+
|
|
124
|
+
it { is_expected.not_to receive(:prompt_for_group) }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe_command 'variable:create --as-role the-account:group:the-group' do
|
|
128
|
+
before do
|
|
129
|
+
allow(RestClient::Request).to receive(:execute).with({
|
|
130
|
+
method: :head,
|
|
131
|
+
url: 'https://authz.example.com/the-account/roles/group/the-group',
|
|
132
|
+
headers: {}
|
|
133
|
+
}.merge(cert_store_options)).and_return(OpenStruct.new(headers: {}, body: '{}'))
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
let (:full_payload) { base_payload.merge(ownerid: 'the-account:group:the-group') }
|
|
137
|
+
|
|
138
|
+
it { is_expected.not_to receive(:prompt_for_group) }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context "when -i is provided" do
|
|
144
|
+
describe_command 'variable:create -i the-id the-value' do
|
|
145
|
+
it { is_expected.not_to receive(:prompt_for_id) }
|
|
146
|
+
it { is_expected.not_to receive(:prompt_for_value) }
|
|
147
|
+
it { is_expected.to receive(:prompt_for_group) }
|
|
148
|
+
it { is_expected.to receive(:prompt_for_mime_type) }
|
|
149
|
+
it { is_expected.to receive(:prompt_for_kind) }
|
|
150
|
+
it { is_expected.to receive(:prompt_for_annotations) }
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
70
154
|
end
|
|
155
|
+
|
|
71
156
|
end
|
|
72
157
|
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: 4.
|
|
4
|
+
version: 4.24.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: 2015-05-
|
|
12
|
+
date: 2015-05-06 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activesupport
|