conjur-cli 5.3.0 → 5.4.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 +6 -0
- data/Gemfile +4 -2
- data/bin/conjur +2 -0
- data/conjur.gemspec +2 -2
- data/deprecations.sh +38 -0
- data/lib/conjur/command.rb +5 -1
- data/lib/conjur/command/groups.rb +15 -6
- data/lib/conjur/command/host_factories.rb +3 -1
- data/lib/conjur/command/hosts.rb +10 -4
- data/lib/conjur/command/layers.rb +18 -6
- data/lib/conjur/command/ldapsync.rb +87 -99
- data/lib/conjur/command/resources.rb +15 -5
- data/lib/conjur/command/roles.rb +9 -3
- data/lib/conjur/command/rubydsl.rb +1 -1
- data/lib/conjur/command/users.rb +9 -3
- data/lib/conjur/command/variables.rb +6 -2
- data/lib/conjur/version.rb +1 -1
- data/lib/patches/gli.rb +31 -0
- data/spec/command/ldapsync_spec.rb +16 -133
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2bb2f6423b56a36f979bdd3d26be85172e986a9
|
4
|
+
data.tar.gz: 8a35bfcafee51a86fe6fd28112049bace77ebf98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8253351f69a787a362e355d45e13a8249a9500c0a3693ae1e902ee3c6413d0667ff202c21165ed574fb6448fbb9381367c3ad1103f37d6fbe0cb73bf299a7729
|
7
|
+
data.tar.gz: 3b6a5f2ddc3c965ed51302132f6bf9fe365c2e139643ce47a72031c324a0f250c6d72bbdfb58939fa5b6ae79b11945f630fd10c1e62caf40f40f2a165470cc6c
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -6,11 +6,13 @@ source 'https://rubygems.org'
|
|
6
6
|
# Specify your gem's dependencies in conjur.gemspec
|
7
7
|
gemspec
|
8
8
|
|
9
|
-
gem '
|
9
|
+
gem 'activesupport', '~> 4.2'
|
10
|
+
|
11
|
+
gem 'conjur-api', '>= 4.28.1', git: 'https://github.com/conjurinc/api-ruby.git', branch: 'master'
|
10
12
|
gem 'semantic', '>= 1.4.1', git: 'https://github.com/jlindsey/semantic.git'
|
11
13
|
|
12
14
|
group :test, :development do
|
13
|
-
gem 'pry'
|
15
|
+
gem 'pry' # Don't be tempted to change this to pry-byebug until we drop support for 1.9
|
14
16
|
gem 'pry-doc'
|
15
17
|
gem 'ruby-prof'
|
16
18
|
gem 'conjur-debify', '~> 1.0'
|
data/bin/conjur
CHANGED
data/conjur.gemspec
CHANGED
@@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Conjur::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency 'activesupport', '
|
19
|
-
gem.add_dependency 'conjur-api', '
|
18
|
+
gem.add_dependency 'activesupport', '>= 4.2'
|
19
|
+
gem.add_dependency 'conjur-api', '>= 4.28.1'
|
20
20
|
gem.add_dependency 'gli', '>=2.8.0'
|
21
21
|
gem.add_dependency 'highline', '~> 1.7'
|
22
22
|
gem.add_dependency 'netrc', '~> 0.10'
|
data/deprecations.sh
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
searchstring='DEPRECATED'
|
4
|
+
|
5
|
+
function bundleexec {
|
6
|
+
bundle exec "$@" 2> /dev/null
|
7
|
+
}
|
8
|
+
|
9
|
+
echo "Planned deprecations for Conjur CLI"
|
10
|
+
echo "-----"
|
11
|
+
|
12
|
+
echo "group"
|
13
|
+
bundleexec conjur group | grep "$searchstring"
|
14
|
+
echo "group members"
|
15
|
+
bundleexec conjur group members | grep "$searchstring"
|
16
|
+
|
17
|
+
echo "hostfactory"
|
18
|
+
bundleexec conjur hostfactory | grep "$searchstring"
|
19
|
+
|
20
|
+
echo "host"
|
21
|
+
bundleexec conjur host | grep "$searchstring"
|
22
|
+
|
23
|
+
echo "layer"
|
24
|
+
bundleexec conjur layer | grep "$searchstring"
|
25
|
+
echo "layer hosts"
|
26
|
+
bundleexec conjur layer hosts | grep "$searchstring"
|
27
|
+
|
28
|
+
echo "resource"
|
29
|
+
bundleexec conjur resource | grep "$searchstring"
|
30
|
+
|
31
|
+
echo "role"
|
32
|
+
bundleexec conjur role | grep "$searchstring"
|
33
|
+
|
34
|
+
echo "user"
|
35
|
+
bundleexec conjur user | grep "$searchstring"
|
36
|
+
|
37
|
+
echo "variable"
|
38
|
+
bundleexec conjur variable | grep "$searchstring"
|
data/lib/conjur/command.rb
CHANGED
@@ -29,7 +29,7 @@ module Conjur
|
|
29
29
|
|
30
30
|
class << self
|
31
31
|
attr_accessor :prefix
|
32
|
-
|
32
|
+
|
33
33
|
def method_missing *a, &b
|
34
34
|
Conjur::CLI.send *a, &b
|
35
35
|
end
|
@@ -466,6 +466,10 @@ an alternative destination role.)
|
|
466
466
|
false
|
467
467
|
end
|
468
468
|
|
469
|
+
def notify_deprecated
|
470
|
+
STDERR.puts 'WARNING! This command is deprecated and will be removed. Use policy instead.'
|
471
|
+
end
|
472
|
+
|
469
473
|
end
|
470
474
|
end
|
471
475
|
end
|
@@ -29,16 +29,17 @@ class Conjur::Command::Groups < Conjur::Command
|
|
29
29
|
|
30
30
|
desc "Manage groups"
|
31
31
|
command :group do |group|
|
32
|
-
group.desc "Create a new group"
|
32
|
+
group.desc "Create a new group [DEPRECATED]"
|
33
33
|
group.command :create do |c|
|
34
34
|
c.desc "GID number to be associated with the group (optional)"
|
35
35
|
c.flag [:gidnumber]
|
36
36
|
|
37
37
|
acting_as_option(c)
|
38
|
-
|
39
38
|
interactive_option c
|
40
39
|
|
41
40
|
c.action do |global_options,options,args|
|
41
|
+
notify_deprecated
|
42
|
+
|
42
43
|
id = args.shift
|
43
44
|
|
44
45
|
interactive = options[:interactive] || id.blank?
|
@@ -86,12 +87,14 @@ class Conjur::Command::Groups < Conjur::Command
|
|
86
87
|
end
|
87
88
|
end
|
88
89
|
|
89
|
-
group.desc "Update group's attributes (eg. gidnumber)"
|
90
|
+
group.desc "Update group's attributes (eg. gidnumber) [DEPRECATED]"
|
90
91
|
group.arg_name "GROUP"
|
91
92
|
group.command :update do |c|
|
92
93
|
c.desc "GID number to be associated with the group"
|
93
94
|
c.flag [:gidnumber]
|
94
95
|
c.action do |global_options, options, args|
|
96
|
+
notify_deprecated
|
97
|
+
|
95
98
|
id = require_arg(args, 'GROUP')
|
96
99
|
|
97
100
|
options[:gidnumber] = Integer(options[:gidnumber])
|
@@ -110,12 +113,14 @@ class Conjur::Command::Groups < Conjur::Command
|
|
110
113
|
end
|
111
114
|
end
|
112
115
|
|
113
|
-
group.desc "Decommission a group"
|
116
|
+
group.desc "Decommission a group [DEPRECATED]"
|
114
117
|
group.arg_name "GROUP"
|
115
118
|
group.command :retire do |c|
|
116
119
|
retire_options c
|
117
120
|
|
118
121
|
c.action do |global_options,options,args|
|
122
|
+
notify_deprecated
|
123
|
+
|
119
124
|
id = require_arg(args, 'GROUP')
|
120
125
|
|
121
126
|
group = api.group(id)
|
@@ -144,7 +149,7 @@ class Conjur::Command::Groups < Conjur::Command
|
|
144
149
|
end
|
145
150
|
end
|
146
151
|
|
147
|
-
members.desc "Add a new group member"
|
152
|
+
members.desc "Add a new group member [DEPRECATED]"
|
148
153
|
members.arg_name "GROUP USER"
|
149
154
|
members.command :add do |c|
|
150
155
|
c.desc "Also grant the admin option"
|
@@ -157,6 +162,8 @@ class Conjur::Command::Groups < Conjur::Command
|
|
157
162
|
c.switch [:r, :'revoke-admin']
|
158
163
|
|
159
164
|
c.action do |global_options,options,args|
|
165
|
+
notify_deprecated
|
166
|
+
|
160
167
|
group = require_arg(args, 'GROUP')
|
161
168
|
member = require_arg(args, 'USER')
|
162
169
|
member = assume_user_kind(member)
|
@@ -177,10 +184,12 @@ class Conjur::Command::Groups < Conjur::Command
|
|
177
184
|
end
|
178
185
|
end
|
179
186
|
|
180
|
-
members.desc "Remove a group member"
|
187
|
+
members.desc "Remove a group member [DEPRECATED]"
|
181
188
|
members.arg_name "GROUP USER"
|
182
189
|
members.command :remove do |c|
|
183
190
|
c.action do |global_options,options,args|
|
191
|
+
notify_deprecated
|
192
|
+
|
184
193
|
group = require_arg(args, 'GROUP')
|
185
194
|
member = require_arg(args, 'USER')
|
186
195
|
member = assume_user_kind(member)
|
@@ -23,7 +23,7 @@ class Conjur::Command::HostFactories < Conjur::Command
|
|
23
23
|
desc "Manage host factories"
|
24
24
|
|
25
25
|
command :hostfactory do |hf|
|
26
|
-
hf.desc "Create a new host factory"
|
26
|
+
hf.desc "Create a new host factory [DEPRECATED]"
|
27
27
|
hf.arg_name "id"
|
28
28
|
hf.command :create do |c|
|
29
29
|
acting_as_option(c)
|
@@ -33,6 +33,8 @@ class Conjur::Command::HostFactories < Conjur::Command
|
|
33
33
|
c.flag [:l, :layer]
|
34
34
|
|
35
35
|
c.action do |global_options,options,args|
|
36
|
+
notify_deprecated
|
37
|
+
|
36
38
|
id = require_arg(args, 'hostfactory')
|
37
39
|
|
38
40
|
unless options[:ownerid]
|
data/lib/conjur/command/hosts.rb
CHANGED
@@ -26,7 +26,7 @@ class Conjur::Command::Hosts < Conjur::Command
|
|
26
26
|
|
27
27
|
desc "Manage hosts"
|
28
28
|
command :host do |hosts|
|
29
|
-
hosts.desc "Create a new host"
|
29
|
+
hosts.desc "Create a new host [DEPRECATED]"
|
30
30
|
hosts.arg_name "NAME"
|
31
31
|
hosts.command :create do |c|
|
32
32
|
c.arg_name "password"
|
@@ -38,6 +38,8 @@ class Conjur::Command::Hosts < Conjur::Command
|
|
38
38
|
acting_as_option(c)
|
39
39
|
|
40
40
|
c.action do |global_options,options,args|
|
41
|
+
notify_deprecated
|
42
|
+
|
41
43
|
id = args.shift
|
42
44
|
|
43
45
|
unless id
|
@@ -61,12 +63,14 @@ class Conjur::Command::Hosts < Conjur::Command
|
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
64
|
-
hosts.desc "Decommission a host"
|
66
|
+
hosts.desc "Decommission a host [DEPRECATED]"
|
65
67
|
hosts.arg_name "HOST"
|
66
68
|
hosts.command :retire do |c|
|
67
69
|
retire_options c
|
68
70
|
|
69
71
|
c.action do |global_options,options,args|
|
72
|
+
notify_deprecated
|
73
|
+
|
70
74
|
id = require_arg(args, 'HOST')
|
71
75
|
|
72
76
|
host = api.host(id)
|
@@ -132,13 +136,15 @@ class Conjur::Command::Hosts < Conjur::Command
|
|
132
136
|
end
|
133
137
|
end
|
134
138
|
|
135
|
-
hosts.desc "Update a hosts's attributes"
|
139
|
+
hosts.desc "Update a hosts's attributes [DEPRECATED]"
|
136
140
|
hosts.arg_name "HOST"
|
137
141
|
hosts.command :update do |c|
|
138
142
|
c.desc "A comma-delimited list of CIDR addresses to restrict host to (optional). Use 'all' to reset"
|
139
143
|
c.flag [:cidr]
|
140
144
|
|
141
145
|
c.action do |global_options, options, args|
|
146
|
+
notify_deprecated
|
147
|
+
|
142
148
|
id = require_arg(args, 'HOST')
|
143
149
|
|
144
150
|
host = api.host(id)
|
@@ -153,7 +159,7 @@ class Conjur::Command::Hosts < Conjur::Command
|
|
153
159
|
end
|
154
160
|
end
|
155
161
|
|
156
|
-
hosts.desc "
|
162
|
+
hosts.desc "Enroll a new host into conjur [DEPRECATED]"
|
157
163
|
hosts.arg_name "HOST"
|
158
164
|
hosts.command :enroll do |c|
|
159
165
|
hide_docs(c)
|
@@ -35,12 +35,14 @@ class Conjur::Command::Layers < Conjur::Command
|
|
35
35
|
desc "Operations on layers"
|
36
36
|
command :layer do |layer|
|
37
37
|
|
38
|
-
layer.desc "Create a new layer"
|
38
|
+
layer.desc "Create a new layer [DEPRECATED]"
|
39
39
|
layer.arg_name "LAYER"
|
40
40
|
layer.command :create do |c|
|
41
41
|
acting_as_option(c)
|
42
42
|
|
43
43
|
c.action do |global_options,options,args|
|
44
|
+
notify_deprecated
|
45
|
+
|
44
46
|
id = require_arg(args, 'LAYER')
|
45
47
|
|
46
48
|
layer = api.create_layer(id, options)
|
@@ -104,12 +106,14 @@ class Conjur::Command::Layers < Conjur::Command
|
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
107
|
-
layer.desc "Decommission a layer"
|
109
|
+
layer.desc "Decommission a layer [DEPRECATED]"
|
108
110
|
layer.arg_name "LAYER"
|
109
111
|
layer.command :retire do |c|
|
110
112
|
retire_options c
|
111
113
|
|
112
114
|
c.action do |global_options,options,args|
|
115
|
+
notify_deprecated
|
116
|
+
|
113
117
|
id = require_arg(args, 'LAYER')
|
114
118
|
|
115
119
|
layer = api.layer(id)
|
@@ -134,23 +138,27 @@ class Conjur::Command::Layers < Conjur::Command
|
|
134
138
|
|
135
139
|
layer.desc "Operations on hosts"
|
136
140
|
layer.command :hosts do |hosts|
|
137
|
-
hosts.desc "Permit a privilege on hosts in the layer"
|
141
|
+
hosts.desc "Permit a privilege on hosts in the layer [DEPRECATED]"
|
138
142
|
hosts.long_desc <<-DESC
|
139
143
|
Privilege may be : execute, update
|
140
144
|
DESC
|
141
145
|
hosts.arg_name "LAYER ROLE PRIVILEGE"
|
142
146
|
hosts.command :permit do |c|
|
143
147
|
c.action do |global_options,options,args|
|
148
|
+
notify_deprecated
|
149
|
+
|
144
150
|
id, role_name, role = parse_layer_permission_args(global_options, options, args)
|
145
151
|
api.layer(id).add_member role_name, role
|
146
152
|
puts "Permission granted"
|
147
153
|
end
|
148
154
|
end
|
149
155
|
|
150
|
-
hosts.desc "Remove a privilege on hosts in the layer"
|
156
|
+
hosts.desc "Remove a privilege on hosts in the layer [DEPRECATED]"
|
151
157
|
hosts.arg_name "LAYER ROLE PRIVILEGE"
|
152
158
|
hosts.command :deny do |c|
|
153
159
|
c.action do |global_options,options,args|
|
160
|
+
notify_deprecated
|
161
|
+
|
154
162
|
id, role_name, role = parse_layer_permission_args(global_options, options, args)
|
155
163
|
api.layer(id).remove_member role_name, role
|
156
164
|
puts "Permission removed"
|
@@ -171,10 +179,12 @@ Privilege may be : execute, update
|
|
171
179
|
end
|
172
180
|
end
|
173
181
|
|
174
|
-
hosts.desc "Add a host to an layer"
|
182
|
+
hosts.desc "Add a host to an layer [DEPRECATED]"
|
175
183
|
hosts.arg_name "LAYER HOST"
|
176
184
|
hosts.command :add do |c|
|
177
185
|
c.action do |global_options, options, args|
|
186
|
+
notify_deprecated
|
187
|
+
|
178
188
|
id = require_arg(args, 'LAYER')
|
179
189
|
hostid = require_hostid_arg(args)
|
180
190
|
|
@@ -183,10 +193,12 @@ Privilege may be : execute, update
|
|
183
193
|
end
|
184
194
|
end
|
185
195
|
|
186
|
-
hosts.desc "Remove a host from an layer"
|
196
|
+
hosts.desc "Remove a host from an layer [DEPRECATED]"
|
187
197
|
hosts.arg_name "LAYER HOST"
|
188
198
|
hosts.command :remove do |c|
|
189
199
|
c.action do |global_options, options, args|
|
200
|
+
notify_deprecated
|
201
|
+
|
190
202
|
id = require_arg(args, 'LAYER')
|
191
203
|
hostid = require_hostid_arg(args)
|
192
204
|
|
@@ -4,127 +4,115 @@ class Conjur::Command::LDAPSync < Conjur::Command
|
|
4
4
|
|
5
5
|
LIST_FORMATS = %w(pretty json)
|
6
6
|
|
7
|
-
def self.
|
8
|
-
|
7
|
+
def self.error_messages(resp)
|
8
|
+
resp['events'].collect {|e| e['message'] if e['severity'] == 'error'}.compact
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def self.show_messages(resp)
|
12
|
+
msgs = resp['events'].each_with_object([]) do |e, arr|
|
13
|
+
if e['severity'] == 'warn' || e['severity'] == 'error'
|
14
|
+
arr << "\n#{e['severity'].upcase}: #{e['message']}"
|
15
|
+
end
|
14
16
|
end
|
17
|
+
$stderr.puts(msgs.join("\n") + "\n\n") unless msgs.empty?
|
15
18
|
end
|
16
19
|
|
17
20
|
desc 'LDAP sync management commands'
|
18
21
|
command :'ldap-sync' do |cgrp|
|
19
22
|
|
20
|
-
cgrp.desc 'Manage
|
21
|
-
cgrp.command :
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
23
|
+
cgrp.desc 'Manage the policy used to sync Conjur and the LDAP server'
|
24
|
+
cgrp.command :policy do |policy|
|
25
|
+
min_version policy, '4.8.0'
|
26
|
+
|
27
|
+
policy.desc 'Show the current policy'
|
28
|
+
policy.command :show do |show|
|
29
|
+
min_version show, '4.8.0'
|
30
|
+
show.desc 'LDAP Sync profile to use (defined in UI)'
|
31
|
+
show.arg_name 'profile'
|
32
|
+
show.flag ['p', 'profile']
|
33
|
+
|
34
|
+
show.action do |_,options,_|
|
35
|
+
|
36
|
+
config_name = options[:profile] || 'default'
|
37
|
+
resp = api.ldap_sync_policy(config_name)
|
38
|
+
|
39
|
+
show_messages(resp)
|
40
|
+
|
41
|
+
if (policy = resp['policy'])
|
42
|
+
if resp['ok']
|
43
|
+
puts(resp['policy'])
|
44
|
+
else
|
45
|
+
exit_now! "Failed creating the policy."
|
46
|
+
end
|
43
47
|
else
|
44
|
-
|
45
|
-
|
46
|
-
display(jobs)
|
48
|
+
exit_now! resp['error']['message']
|
47
49
|
end
|
48
|
-
|
49
50
|
end
|
50
51
|
end
|
52
|
+
end
|
51
53
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
# Currently hidden. It's easier to use the CLI than cURL, though,
|
55
|
+
# so we might want to expose the profile subcommands.
|
56
|
+
cgrp.desc 'Manage profiles for LDAP sync'
|
57
|
+
cgrp.command :profile do |profile|
|
58
|
+
hide_docs(profile)
|
59
|
+
min_version profile, '4.8.0'
|
60
|
+
|
61
|
+
profile.desc 'Show the profile'
|
62
|
+
profile.command :show do |show|
|
63
|
+
min_version show, '4.8.0'
|
64
|
+
|
65
|
+
show.arg_name 'profile'
|
66
|
+
show.flag ['p', 'profile']
|
67
|
+
show.action do |_,options,_|
|
68
|
+
display(api.ldap_sync_show_profile(options[:profile]))
|
58
69
|
end
|
59
70
|
end
|
60
71
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
72
|
+
profile.desc 'Create or update a profile'
|
73
|
+
profile.arg_name 'PROFILE_JSON'
|
74
|
+
profile.long_desc %Q{Create or update the given profile.
|
75
|
+
The profile JSON may be provided in two ways:
|
76
|
+
|
77
|
+
1. As a literal (quoted) JSON string.
|
78
|
+
|
79
|
+
2. In a file, by prepending an '@' to the path to the file
|
80
|
+
}
|
81
|
+
profile.command :update do |update|
|
82
|
+
min_version update, '4.8.0'
|
83
|
+
|
84
|
+
update.arg_name 'profile'
|
85
|
+
update.flag ['p', 'profile']
|
86
|
+
update.action do |_, options, args|
|
87
|
+
config = require_arg(args, 'PROFILE_JSON')
|
88
|
+
config = File.read(config[1..-1]) if config[0] == '@'
|
89
|
+
display(api.ldap_sync_update_profile(options[:profile], JSON.parse(config)))
|
68
90
|
end
|
69
91
|
end
|
92
|
+
|
70
93
|
end
|
71
94
|
|
72
|
-
cgrp.desc '
|
73
|
-
cgrp.command :
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
cmd.desc 'Run sync as a detached job'
|
89
|
-
cmd.default_value true
|
90
|
-
cmd.switch ['detach']
|
91
|
-
|
92
|
-
cmd.action do |_ ,options, args|
|
93
|
-
assert_empty args
|
94
|
-
|
95
|
-
format = options[:format] == 'text' ? 'application/json' : 'text/yaml'
|
96
|
-
|
97
|
-
dry_run = !!options[:'dry-run']
|
98
|
-
|
99
|
-
# Don't ever run dry-run jobs detached
|
100
|
-
options[:detach] = false if dry_run
|
101
|
-
|
102
|
-
$stderr.puts "Performing #{dry_run ? 'dry run ' : ''}LDAP sync"
|
103
|
-
|
104
|
-
response = api.ldap_sync_now(:config_name => options[:profile],
|
105
|
-
:format => format,
|
106
|
-
:dry_run => dry_run,
|
107
|
-
:detach_job => options[:detach]
|
108
|
-
)
|
109
|
-
|
110
|
-
if !options[:detach]
|
111
|
-
if options[:format] == 'text'
|
112
|
-
puts "Messages:"
|
113
|
-
response['events'].each do |event|
|
114
|
-
puts [ event['timestamp'], event['severity'], event['message'] ].join("\t")
|
115
|
-
end
|
116
|
-
puts
|
117
|
-
puts "Actions:"
|
118
|
-
response['result']['actions'].each do |action|
|
119
|
-
puts action
|
120
|
-
end
|
121
|
-
else
|
122
|
-
puts response
|
123
|
-
end
|
95
|
+
cgrp.desc 'Search using an LDAP sync profile'
|
96
|
+
cgrp.command :search do |search|
|
97
|
+
hide_docs(search)
|
98
|
+
min_version search, '4.8.0'
|
99
|
+
|
100
|
+
search.desc 'LDAP Sync profile to use (defined in UI)'
|
101
|
+
search.arg_name 'profile'
|
102
|
+
search.flag ['p', 'profile']
|
103
|
+
search.action do |_,options,_|
|
104
|
+
resp = api.ldap_sync_search(options[:profile] || 'default')
|
105
|
+
|
106
|
+
show_messages(resp)
|
107
|
+
|
108
|
+
if resp['ok']
|
109
|
+
display resp
|
124
110
|
else
|
125
|
-
|
111
|
+
exit_now! "Search failed."
|
126
112
|
end
|
113
|
+
|
127
114
|
end
|
128
115
|
end
|
116
|
+
|
129
117
|
end
|
130
118
|
end
|
@@ -23,12 +23,14 @@ class Conjur::Command::Resources < Conjur::Command
|
|
23
23
|
desc "Manage resources"
|
24
24
|
command :resource do |resource|
|
25
25
|
|
26
|
-
resource.desc "Create a new resource"
|
26
|
+
resource.desc "Create a new resource [DEPRECATED]"
|
27
27
|
resource.arg_name "RESOURCE"
|
28
28
|
resource.command :create do |c|
|
29
29
|
acting_as_option(c)
|
30
30
|
|
31
31
|
c.action do |global_options,options,args|
|
32
|
+
notify_deprecated
|
33
|
+
|
32
34
|
id = full_resource_id( require_arg(args, "RESOURCE") )
|
33
35
|
resource = api.resource(id)
|
34
36
|
|
@@ -59,12 +61,14 @@ class Conjur::Command::Resources < Conjur::Command
|
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
62
|
-
resource.desc "Give a privilege on a resource"
|
64
|
+
resource.desc "Give a privilege on a resource [DEPRECATED]"
|
63
65
|
resource.arg_name "RESOURCE ROLE PRIVILEGE"
|
64
66
|
resource.command :permit do |c|
|
65
67
|
c.desc "allow transfer to other roles"
|
66
68
|
c.switch [:g, :grantable]
|
67
69
|
c.action do |global_options,options,args|
|
70
|
+
notify_deprecated
|
71
|
+
|
68
72
|
id = full_resource_id( require_arg(args, "RESOURCE") )
|
69
73
|
role = require_arg(args, "ROLE")
|
70
74
|
privilege = require_arg(args, "PRIVILEGE")
|
@@ -79,10 +83,12 @@ class Conjur::Command::Resources < Conjur::Command
|
|
79
83
|
end
|
80
84
|
end
|
81
85
|
|
82
|
-
resource.desc "Deny a privilege on a resource"
|
86
|
+
resource.desc "Deny a privilege on a resource [DEPRECATED]"
|
83
87
|
resource.arg_name "RESOURCE ROLE PRIVILEGE"
|
84
88
|
resource.command :deny do |c|
|
85
89
|
c.action do |global_options,options,args|
|
90
|
+
notify_deprecated
|
91
|
+
|
86
92
|
id = full_resource_id( require_arg(args, "RESOURCE") )
|
87
93
|
role = require_arg(args, "ROLE")
|
88
94
|
privilege = require_arg(args, "PRIVILEGE")
|
@@ -115,10 +121,12 @@ class Conjur::Command::Resources < Conjur::Command
|
|
115
121
|
end
|
116
122
|
end
|
117
123
|
|
118
|
-
resource.desc "Grant ownership on a resource to a new owner"
|
124
|
+
resource.desc "Grant ownership on a resource to a new owner [DEPRECATED]"
|
119
125
|
resource.arg_name "RESOURCE USER"
|
120
126
|
resource.command :give do |c|
|
121
127
|
c.action do |global_options,options,args|
|
128
|
+
notify_deprecated
|
129
|
+
|
122
130
|
id = full_resource_id( require_arg(args, "RESOURCE") )
|
123
131
|
owner = require_arg(args, "USER")
|
124
132
|
api.resource(id).give_to owner
|
@@ -136,12 +144,14 @@ class Conjur::Command::Resources < Conjur::Command
|
|
136
144
|
end
|
137
145
|
end
|
138
146
|
|
139
|
-
resource.desc "Set an annotation on a resource"
|
147
|
+
resource.desc "Set an annotation on a resource [DEPRECATED]"
|
140
148
|
resource.arg_name "RESOURCE ANNOTATION value"
|
141
149
|
resource.command :annotate do |c|
|
142
150
|
interactive_option c
|
143
151
|
|
144
152
|
c.action do |global_options, options, args|
|
153
|
+
notify_deprecated
|
154
|
+
|
145
155
|
id = full_resource_id require_arg(args, 'RESOURCE')
|
146
156
|
|
147
157
|
annotations = if options[:interactive]
|
data/lib/conjur/command/roles.rb
CHANGED
@@ -26,7 +26,7 @@ class Conjur::Command::Roles < Conjur::Command
|
|
26
26
|
desc "Manage roles"
|
27
27
|
command :role do |role|
|
28
28
|
|
29
|
-
role.desc "Create a new role"
|
29
|
+
role.desc "Create a new role [DEPRECATED]"
|
30
30
|
role.arg_name "ROLE"
|
31
31
|
role.command :create do |c|
|
32
32
|
acting_as_option(c)
|
@@ -35,6 +35,8 @@ class Conjur::Command::Roles < Conjur::Command
|
|
35
35
|
c.switch "json"
|
36
36
|
|
37
37
|
c.action do |global_options,options,args|
|
38
|
+
notify_deprecated
|
39
|
+
|
38
40
|
id = require_arg(args, 'ROLE')
|
39
41
|
role = api.role(id)
|
40
42
|
|
@@ -102,13 +104,15 @@ class Conjur::Command::Roles < Conjur::Command
|
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
105
|
-
role.desc "Grant a role to another role. You must have admin permission on the granting role."
|
107
|
+
role.desc "Grant a role to another role. You must have admin permission on the granting role. [DEPRECATED]"
|
106
108
|
role.arg_name "ROLE-1 ROLE-2"
|
107
109
|
role.command :grant_to do |c|
|
108
110
|
c.desc "Whether to grant with admin option"
|
109
111
|
c.switch [:a,:admin]
|
110
112
|
|
111
113
|
c.action do |global_options,options,args|
|
114
|
+
notify_deprecated
|
115
|
+
|
112
116
|
id = require_arg(args, 'ROLE-1')
|
113
117
|
member = require_arg(args, 'ROLE-2')
|
114
118
|
role = api.role(id)
|
@@ -120,10 +124,12 @@ class Conjur::Command::Roles < Conjur::Command
|
|
120
124
|
end
|
121
125
|
|
122
126
|
|
123
|
-
role.desc "Revoke a role from another role. You must have admin permission on the revoking role."
|
127
|
+
role.desc "Revoke a role from another role. You must have admin permission on the revoking role. [DEPRECATED]"
|
124
128
|
role.arg_name "ROLE-1 ROLE-2"
|
125
129
|
role.command :revoke_from do |c|
|
126
130
|
c.action do |global_options,options,args|
|
131
|
+
notify_deprecated
|
132
|
+
|
127
133
|
id = require_arg(args, 'ROLE-1')
|
128
134
|
member = require_arg(args, 'ROLE-2')
|
129
135
|
role = api.role(id)
|
@@ -21,7 +21,7 @@
|
|
21
21
|
require 'conjur/command/dsl_command'
|
22
22
|
|
23
23
|
class Conjur::Command::RubyDSL < Conjur::DSLCommand
|
24
|
-
desc "Manage Ruby DSL policies
|
24
|
+
desc "Manage Ruby DSL policies [DEPRECATED]"
|
25
25
|
long_desc 'DEPRECATED. Declarative YML policy supercedes Ruby policy DSL.'
|
26
26
|
command :rubydsl do |rubydsl|
|
27
27
|
rubydsl.desc "Load a policy from Conjur DSL"
|
data/lib/conjur/command/users.rb
CHANGED
@@ -24,7 +24,7 @@ class Conjur::Command::Users < Conjur::Command
|
|
24
24
|
desc "Manage users"
|
25
25
|
command :user do |user|
|
26
26
|
|
27
|
-
user.desc "Create a new user"
|
27
|
+
user.desc "Create a new user [DEPRECATED]"
|
28
28
|
user.arg_name "NAME"
|
29
29
|
user.command :create do |c|
|
30
30
|
c.desc "Prompt for a password for the user (default: --no-password)"
|
@@ -41,6 +41,8 @@ class Conjur::Command::Users < Conjur::Command
|
|
41
41
|
interactive_option c
|
42
42
|
|
43
43
|
c.action do |global_options,options,args|
|
44
|
+
notify_deprecated
|
45
|
+
|
44
46
|
login = args.shift
|
45
47
|
|
46
48
|
interactive = options[:interactive] || login.blank?
|
@@ -101,12 +103,14 @@ class Conjur::Command::Users < Conjur::Command
|
|
101
103
|
end
|
102
104
|
end
|
103
105
|
|
104
|
-
user.desc "Decommission a user"
|
106
|
+
user.desc "Decommission a user [DEPRECATED]"
|
105
107
|
user.arg_name "USER"
|
106
108
|
user.command :retire do |c|
|
107
109
|
retire_options c
|
108
110
|
|
109
111
|
c.action do |global_options,options,args|
|
112
|
+
notify_deprecated
|
113
|
+
|
110
114
|
id = require_arg(args, 'USER')
|
111
115
|
|
112
116
|
user = api.user(id)
|
@@ -164,7 +168,7 @@ class Conjur::Command::Users < Conjur::Command
|
|
164
168
|
end
|
165
169
|
end
|
166
170
|
|
167
|
-
user.desc "Update a user's attributes"
|
171
|
+
user.desc "Update a user's attributes [DEPRECATED]"
|
168
172
|
user.arg_name "USER"
|
169
173
|
user.command :update do |c|
|
170
174
|
c.desc "UID number to be associated with user (optional)"
|
@@ -174,6 +178,8 @@ class Conjur::Command::Users < Conjur::Command
|
|
174
178
|
c.flag [:cidr]
|
175
179
|
|
176
180
|
c.action do |global_options, options, args|
|
181
|
+
notify_deprecated
|
182
|
+
|
177
183
|
login=require_arg(args,'USER')
|
178
184
|
|
179
185
|
uidnumber = options[:uidnumber]
|
@@ -21,7 +21,7 @@
|
|
21
21
|
class Conjur::Command::Variables < Conjur::Command
|
22
22
|
desc "Manage variables"
|
23
23
|
command :variable do |var|
|
24
|
-
var.desc "Create and store a variable"
|
24
|
+
var.desc "Create and store a variable [DEPRECATED]"
|
25
25
|
var.arg_name "NAME VALUE"
|
26
26
|
var.command :create do |c|
|
27
27
|
c.arg_name "MIME-TYPE"
|
@@ -41,6 +41,8 @@ class Conjur::Command::Variables < Conjur::Command
|
|
41
41
|
interactive_option c
|
42
42
|
|
43
43
|
c.action do |global_options,options, args|
|
44
|
+
notify_deprecated
|
45
|
+
|
44
46
|
@default_mime_type = c.flags[:m].default_value
|
45
47
|
@default_kind = c.flags[:k].default_value
|
46
48
|
|
@@ -99,12 +101,14 @@ class Conjur::Command::Variables < Conjur::Command
|
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|
102
|
-
var.desc "Decommission a variable"
|
104
|
+
var.desc "Decommission a variable [DEPRECATED]"
|
103
105
|
var.arg_name "VARIABLE"
|
104
106
|
var.command :retire do |c|
|
105
107
|
retire_options c
|
106
108
|
|
107
109
|
c.action do |global_options,options,args|
|
110
|
+
notify_deprecated
|
111
|
+
|
108
112
|
id = require_arg(args, 'VARIABLE')
|
109
113
|
|
110
114
|
variable = api.variable(id)
|
data/lib/conjur/version.rb
CHANGED
data/lib/patches/gli.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Patch GLI's help formatters so they don't show subcommands that are
|
2
|
+
# supposed to be hidden.
|
3
|
+
module CommandHelpFormatPatch
|
4
|
+
def format
|
5
|
+
@command.commands.reject! {|k,c| c.nodoc}
|
6
|
+
@command.commands_declaration_order.reject! {|c| c.nodoc}
|
7
|
+
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module HelpCompletionFormatPatch
|
13
|
+
def format
|
14
|
+
name = @args.shift
|
15
|
+
|
16
|
+
base = @command_finder.find_command(name)
|
17
|
+
base = @command_finder.last_found_command if base.nil?
|
18
|
+
base = @app if base.nil?
|
19
|
+
|
20
|
+
prefix_to_match = @command_finder.last_unknown_command
|
21
|
+
|
22
|
+
base.commands.reject {|_,c| c.nodoc}.values.map { |command|
|
23
|
+
[command.name,command.aliases]
|
24
|
+
}.flatten.compact.map(&:to_s).sort.select { |command_name|
|
25
|
+
prefix_to_match.nil? || command_name =~ /^#{prefix_to_match}/
|
26
|
+
}.join("\n")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
GLI::Commands::HelpModules::CommandHelpFormat.send(:prepend, CommandHelpFormatPatch)
|
31
|
+
GLI::Commands::HelpModules::HelpCompletionFormat.send(:prepend, HelpCompletionFormatPatch)
|
@@ -1,145 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
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
4
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
before do
|
36
|
-
expect_any_instance_of(Conjur::API).to receive(:ldap_sync_jobs).and_return jobs
|
37
|
-
end
|
38
|
-
|
39
|
-
describe_command 'ldap-sync jobs list' do
|
40
|
-
it 'prints the jobs as json' do
|
41
|
-
expect { invoke }.to write(JSON.pretty_generate jobs.map(&:as_json))
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe_command 'ldap-sync jobs list -i' do
|
46
|
-
it 'prints the job ids only' do
|
47
|
-
expect { invoke }.to write(JSON.pretty_generate jobs.map(&:id))
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe_command 'ldap-sync jobs list -f pretty' do
|
52
|
-
|
53
|
-
it 'prints the jobs in a fancy table' do
|
54
|
-
expect{ invoke }.to write /ID\s*|\s*TYPE\s*|\s*STATE\s*|\s*EXCLUSIVE.*?
|
55
|
-
job-1\s*|\s*sync\s*|\s*running\s*|\s*true
|
56
|
-
job-2\s*|\s*connect\s*|\s*success\s*|\s*false/x
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
describe_command 'ldap-sync jobs delete job-2' do
|
62
|
-
let(:victim){ jobs[1] }
|
63
|
-
it 'deletes the job' do
|
64
|
-
expect(victim).to receive(:delete)
|
65
|
-
invoke
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe_command 'ldap-sync jobs delete no-such-job' do
|
70
|
-
it 'fails with a sensible error message' do
|
71
|
-
expect{ invoke }.to raise_exception(/No job found with ID 'no-such-job'/)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe_command 'ldap-sync jobs show job-1' do
|
76
|
-
let(:victim){ jobs[0] }
|
77
|
-
it 'prints the values passed to output' do
|
78
|
-
expect(victim).to receive(:output) do |&block|
|
79
|
-
block.call({foo: 'bar'})
|
80
|
-
block.call({spam: 'eggs'})
|
81
|
-
end
|
82
|
-
|
83
|
-
expect{invoke}.to write(<<EOS)
|
84
|
-
{
|
85
|
-
"foo": "bar"
|
5
|
+
let (:policy_response) { { 'ok' => true, 'events' => [], 'policy' => <<eop
|
6
|
+
"---
|
7
|
+
- !user
|
8
|
+
annotations:
|
9
|
+
ldap-sync/source: ldap-server:389
|
10
|
+
ldap-sync/upstream-dn: CN=Administrator,OU=functest,OU=testdata,OU=dev-ci,DC=dev-ci,DC=conjur
|
11
|
+
id: Administrator
|
12
|
+
uidnumber:"}
|
13
|
+
eop
|
14
|
+
}
|
86
15
|
}
|
87
|
-
{
|
88
|
-
"spam": "eggs"
|
89
|
-
}
|
90
|
-
EOS
|
91
|
-
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
16
|
|
96
|
-
describe_command
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
it 'prints out diagnostic events' do
|
101
|
-
expect { invoke }.to write([ timestamp, "info", "Performing sync" ].join("\t"))
|
17
|
+
describe_command "ldap-sync policy show" do
|
18
|
+
|
19
|
+
before do
|
20
|
+
expect_any_instance_of(Conjur::API).to receive(:ldap_sync_policy).with('default').and_return policy_response
|
102
21
|
end
|
103
|
-
it 'prints out actions as text' do
|
104
|
-
expect { invoke }.to write("user 'Guest'\ngroup 'Domain Computers'")
|
105
|
-
end
|
106
|
-
end
|
107
22
|
|
108
|
-
|
109
|
-
|
110
|
-
expect_any_instance_of(Conjur::API).to receive(:ldap_sync_now).and_return yaml_response
|
111
|
-
expect { invoke }.to write(yaml_response)
|
23
|
+
it "shows the policy" do
|
24
|
+
expect { invoke }.to write policy_response['policy']
|
112
25
|
end
|
113
26
|
end
|
114
27
|
|
115
|
-
context 'when testing dry-run' do
|
116
|
-
let (:detach) { true }
|
117
|
-
before do
|
118
|
-
expect_any_instance_of(Conjur::API).to receive(:ldap_sync_now)
|
119
|
-
.with(:config_name => 'default', :format => 'application/json', :dry_run => dry_run, :detach_job => detach)
|
120
|
-
.and_return json_response
|
121
|
-
end
|
122
|
-
|
123
|
-
describe_command 'ldap-sync now' do
|
124
|
-
let(:dry_run) { false }
|
125
|
-
it 'passes falsey dry-run value' do
|
126
|
-
invoke
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
describe_command 'ldap-sync now --no-dry-run' do
|
131
|
-
let(:dry_run) { false }
|
132
|
-
it 'passes falsey dry-run value' do
|
133
|
-
invoke
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
describe_command 'ldap-sync now --dry-run' do
|
138
|
-
let(:dry_run) { true }
|
139
|
-
let(:detach) { false }
|
140
|
-
it 'passes truthy dry-run value' do
|
141
|
-
invoke
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
28
|
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.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafal Rzepecki
|
@@ -9,36 +9,36 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-12-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - '>='
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '4.2'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - '>='
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '4.2'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: conjur-api
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - '>='
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: 4.28.1
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - '>='
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: 4.28.1
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: gli
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -394,6 +394,7 @@ files:
|
|
394
394
|
- ci/test.sh
|
395
395
|
- conjur.gemspec
|
396
396
|
- debify.sh
|
397
|
+
- deprecations.sh
|
397
398
|
- features/conjurize.feature
|
398
399
|
- features/dsl_context.feature
|
399
400
|
- features/dsl_host_create.feature
|
@@ -460,6 +461,7 @@ files:
|
|
460
461
|
- lib/conjur/identifier_manipulation.rb
|
461
462
|
- lib/conjur/version.rb
|
462
463
|
- lib/patches/conjur/error.rb
|
464
|
+
- lib/patches/gli.rb
|
463
465
|
- profile.rb
|
464
466
|
- publish.sh
|
465
467
|
- spec/authn_spec.rb
|