conjur-cli 4.23.0 → 4.24.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 +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
|