rhc 1.22.5 → 1.23.7
Sign up to get free protection for your applications and to get access to all the features.
- data/autocomplete/rhc_bash +38 -14
- data/features/core_feature.rb +2 -0
- data/lib/rhc/commands/domain.rb +2 -1
- data/lib/rhc/commands/member.rb +255 -33
- data/lib/rhc/commands/scp.rb +1 -1
- data/lib/rhc/exceptions.rb +18 -0
- data/lib/rhc/helpers.rb +1 -1
- data/lib/rhc/rest.rb +1 -0
- data/lib/rhc/rest/client.rb +38 -0
- data/lib/rhc/rest/membership.rb +46 -5
- data/lib/rhc/rest/mock.rb +24 -5
- data/lib/rhc/rest/team.rb +20 -0
- data/spec/rhc/commands/domain_spec.rb +1 -1
- data/spec/rhc/commands/member_spec.rb +384 -21
- metadata +5 -4
data/autocomplete/rhc_bash
CHANGED
@@ -10,9 +10,9 @@ _rhc()
|
|
10
10
|
if [[ "$cur" == -* ]]; then
|
11
11
|
opts="--always-prefix --clean --config --debug --insecure --limit --mock --noprompt --password --raw --rhlogin --server --ssl-ca-file --ssl-client-cert-file --ssl-version --timeout --token"
|
12
12
|
elif [ -z $cur ]; then
|
13
|
-
opts="account alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert app app-configure app-create app-delete app-deploy app-force-stop app-reload app-restart app-scale-down app-scale-up app-show app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage deployment deployment-activate deployment-list deployment-show domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show env env-list env-set env-show env-unset git-clone logout member member-add member-list member-remove port-forward scp server setup snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show tail threaddump"
|
13
|
+
opts="account alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert app app-configure app-create app-delete app-deploy app-force-stop app-reload app-restart app-scale-down app-scale-up app-show app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage deployment deployment-activate deployment-list deployment-show domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show env env-list env-set env-show env-unset git-clone logout member member-add member-list member-remove member-update port-forward scp server setup snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show tail threaddump"
|
14
14
|
else
|
15
|
-
opts="account account-logout activate-deployment add-alias add-authorization add-cartridge add-member add-sshkey alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert aliases app app-configure app-create app-delete app-deploy app-env app-force-stop app-reload app-restart app-scale-down app-scale-up app-scp app-show app-snapshot app-ssh app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list authorizations cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage cartridges configure-app configure-domain create-app create-domain delete-all-authorization delete-app delete-authorization delete-cert-alias delete-domain deploy deploy-app deployment deployment-activate deployment-list deployment-show deployments domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show domains env env-add env-list env-remove env-set env-show env-unset force-stop-app git-clone leave-domain list-alias list-authorization list-cartridge list-deployment list-domain list-env list-member list-sshkey logout member member-add member-list member-remove members port-forward reload-app reload-cartridge remove-alias remove-cartridge remove-member remove-sshkey rename-domain restart-app restart-cartridge restore-snapshot save-snapshot scale-cartridge scale-down-app scale-up-app scp server set-env setup show-app show-cartridge show-deployment show-domain show-env show-sshkey snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show start-app start-cartridge status-cartridge stop-app stop-cartridge storage-cartridge tail threaddump tidy-app unset-env update-cert-alias"
|
15
|
+
opts="account account-logout activate-deployment add-alias add-authorization add-cartridge add-member add-sshkey alias alias-add alias-delete-cert alias-list alias-remove alias-update-cert aliases app app-configure app-create app-delete app-deploy app-env app-force-stop app-reload app-restart app-scale-down app-scale-up app-scp app-show app-snapshot app-ssh app-start app-stop app-tidy apps authorization authorization-add authorization-delete authorization-delete-all authorization-list authorizations cartridge cartridge-add cartridge-list cartridge-reload cartridge-remove cartridge-restart cartridge-scale cartridge-show cartridge-start cartridge-status cartridge-stop cartridge-storage cartridges configure-app configure-domain create-app create-domain delete-all-authorization delete-app delete-authorization delete-cert-alias delete-domain deploy deploy-app deployment deployment-activate deployment-list deployment-show deployments domain domain-configure domain-create domain-delete domain-leave domain-list domain-rename domain-show domains env env-add env-list env-remove env-set env-show env-unset force-stop-app git-clone leave-domain list-alias list-authorization list-cartridge list-deployment list-domain list-env list-member list-sshkey logout member member-add member-list member-remove member-update members port-forward reload-app reload-cartridge remove-alias remove-cartridge remove-member remove-sshkey rename-domain restart-app restart-cartridge restore-snapshot save-snapshot scale-cartridge scale-down-app scale-up-app scp server set-env setup show-app show-cartridge show-deployment show-domain show-env show-sshkey snapshot snapshot-restore snapshot-save ssh sshkey sshkey-add sshkey-list sshkey-remove sshkey-show start-app start-cartridge status-cartridge stop-app stop-cartridge storage-cartridge tail threaddump tidy-app unset-env update-cert-alias update-member"
|
16
16
|
fi
|
17
17
|
else
|
18
18
|
prev="${COMP_WORDS[@]:0:COMP_CWORD}"
|
@@ -78,7 +78,7 @@ _rhc()
|
|
78
78
|
|
79
79
|
"rhc add-member")
|
80
80
|
if [[ "$cur" == -* ]]; then
|
81
|
-
opts="--ids --namespace --role"
|
81
|
+
opts="--global --ids --namespace --role --type"
|
82
82
|
else
|
83
83
|
opts=""
|
84
84
|
fi
|
@@ -192,7 +192,7 @@ _rhc()
|
|
192
192
|
if [[ "$cur" == -* ]]; then
|
193
193
|
opts=""
|
194
194
|
else
|
195
|
-
opts="create delete start stop scale-up scale-down force-stop restart reload tidy show deploy configure
|
195
|
+
opts="env snapshot create delete start stop scale-up scale-down force-stop restart reload tidy show deploy configure"
|
196
196
|
fi
|
197
197
|
;;
|
198
198
|
|
@@ -1206,7 +1206,7 @@ _rhc()
|
|
1206
1206
|
|
1207
1207
|
"rhc list-member")
|
1208
1208
|
if [[ "$cur" == -* ]]; then
|
1209
|
-
opts="--app --ids --namespace --target"
|
1209
|
+
opts="--all --app --ids --namespace --target"
|
1210
1210
|
else
|
1211
1211
|
opts=""
|
1212
1212
|
fi
|
@@ -1232,13 +1232,13 @@ _rhc()
|
|
1232
1232
|
if [[ "$cur" == -* ]]; then
|
1233
1233
|
opts=""
|
1234
1234
|
else
|
1235
|
-
opts="list add remove"
|
1235
|
+
opts="list add update remove"
|
1236
1236
|
fi
|
1237
1237
|
;;
|
1238
1238
|
|
1239
1239
|
"rhc member add")
|
1240
1240
|
if [[ "$cur" == -* ]]; then
|
1241
|
-
opts="--ids --namespace --role"
|
1241
|
+
opts="--global --ids --namespace --role --type"
|
1242
1242
|
else
|
1243
1243
|
opts=""
|
1244
1244
|
fi
|
@@ -1246,7 +1246,7 @@ _rhc()
|
|
1246
1246
|
|
1247
1247
|
"rhc member list")
|
1248
1248
|
if [[ "$cur" == -* ]]; then
|
1249
|
-
opts="--app --ids --namespace --target"
|
1249
|
+
opts="--all --app --ids --namespace --target"
|
1250
1250
|
else
|
1251
1251
|
opts=""
|
1252
1252
|
fi
|
@@ -1254,7 +1254,15 @@ _rhc()
|
|
1254
1254
|
|
1255
1255
|
"rhc member remove")
|
1256
1256
|
if [[ "$cur" == -* ]]; then
|
1257
|
-
opts="--all --ids --namespace"
|
1257
|
+
opts="--all --ids --namespace --type"
|
1258
|
+
else
|
1259
|
+
opts=""
|
1260
|
+
fi
|
1261
|
+
;;
|
1262
|
+
|
1263
|
+
"rhc member update")
|
1264
|
+
if [[ "$cur" == -* ]]; then
|
1265
|
+
opts="--ids --namespace --role --type"
|
1258
1266
|
else
|
1259
1267
|
opts=""
|
1260
1268
|
fi
|
@@ -1262,7 +1270,7 @@ _rhc()
|
|
1262
1270
|
|
1263
1271
|
"rhc member-add")
|
1264
1272
|
if [[ "$cur" == -* ]]; then
|
1265
|
-
opts="--ids --namespace --role"
|
1273
|
+
opts="--global --ids --namespace --role --type"
|
1266
1274
|
else
|
1267
1275
|
opts=""
|
1268
1276
|
fi
|
@@ -1270,7 +1278,7 @@ _rhc()
|
|
1270
1278
|
|
1271
1279
|
"rhc member-list")
|
1272
1280
|
if [[ "$cur" == -* ]]; then
|
1273
|
-
opts="--app --ids --namespace --target"
|
1281
|
+
opts="--all --app --ids --namespace --target"
|
1274
1282
|
else
|
1275
1283
|
opts=""
|
1276
1284
|
fi
|
@@ -1278,7 +1286,15 @@ _rhc()
|
|
1278
1286
|
|
1279
1287
|
"rhc member-remove")
|
1280
1288
|
if [[ "$cur" == -* ]]; then
|
1281
|
-
opts="--all --ids --namespace"
|
1289
|
+
opts="--all --ids --namespace --type"
|
1290
|
+
else
|
1291
|
+
opts=""
|
1292
|
+
fi
|
1293
|
+
;;
|
1294
|
+
|
1295
|
+
"rhc member-update")
|
1296
|
+
if [[ "$cur" == -* ]]; then
|
1297
|
+
opts="--ids --namespace --role --type"
|
1282
1298
|
else
|
1283
1299
|
opts=""
|
1284
1300
|
fi
|
@@ -1286,7 +1302,7 @@ _rhc()
|
|
1286
1302
|
|
1287
1303
|
"rhc members")
|
1288
1304
|
if [[ "$cur" == -* ]]; then
|
1289
|
-
opts="--app --ids --namespace --target"
|
1305
|
+
opts="--all --app --ids --namespace --target"
|
1290
1306
|
else
|
1291
1307
|
opts=""
|
1292
1308
|
fi
|
@@ -1334,7 +1350,7 @@ _rhc()
|
|
1334
1350
|
|
1335
1351
|
"rhc remove-member")
|
1336
1352
|
if [[ "$cur" == -* ]]; then
|
1337
|
-
opts="--all --ids --namespace"
|
1353
|
+
opts="--all --ids --namespace --type"
|
1338
1354
|
else
|
1339
1355
|
opts=""
|
1340
1356
|
fi
|
@@ -1700,6 +1716,14 @@ _rhc()
|
|
1700
1716
|
fi
|
1701
1717
|
;;
|
1702
1718
|
|
1719
|
+
"rhc update-member")
|
1720
|
+
if [[ "$cur" == -* ]]; then
|
1721
|
+
opts="--ids --namespace --role --type"
|
1722
|
+
else
|
1723
|
+
opts=""
|
1724
|
+
fi
|
1725
|
+
;;
|
1726
|
+
|
1703
1727
|
esac
|
1704
1728
|
IFS=$SAVE_IFS
|
1705
1729
|
fi
|
data/features/core_feature.rb
CHANGED
@@ -50,6 +50,7 @@ describe "rhc core scenarios" do
|
|
50
50
|
context "when creating an app" do
|
51
51
|
when_running 'create-app', 'test1', a_web_cartridge
|
52
52
|
before{ no_applications }
|
53
|
+
after { no_applications }
|
53
54
|
it "returns the proper info and is in the rest api" do
|
54
55
|
status.should == 0
|
55
56
|
output.should match "Your application 'test1' is now available"
|
@@ -69,6 +70,7 @@ describe "rhc core scenarios" do
|
|
69
70
|
standard_config
|
70
71
|
@app = has_an_application
|
71
72
|
end
|
73
|
+
after(:all){ @app.destroy }
|
72
74
|
|
73
75
|
let(:app){ @app }
|
74
76
|
|
data/lib/rhc/commands/domain.rb
CHANGED
data/lib/rhc/commands/member.rb
CHANGED
@@ -5,7 +5,7 @@ module RHC::Commands
|
|
5
5
|
summary "Manage membership on domains"
|
6
6
|
syntax "<action>"
|
7
7
|
description <<-DESC
|
8
|
-
|
8
|
+
Developers can collaborate on applications by adding people or teams to
|
9
9
|
domains as members: each member has a role (admin, editor, or viewer),
|
10
10
|
and those roles determine what the user can do with the domain and the
|
11
11
|
applications contained within.
|
@@ -32,7 +32,7 @@ module RHC::Commands
|
|
32
32
|
default_action :help
|
33
33
|
|
34
34
|
summary "List members of a domain or application"
|
35
|
-
syntax "<domain_or_app_name> [-n DOMAIN_NAME] [-a APP_NAME]"
|
35
|
+
syntax "<domain_or_app_name> [-n DOMAIN_NAME] [-a APP_NAME] [--all]"
|
36
36
|
description <<-DESC
|
37
37
|
Show the existing members of a domain or application - you can pass the name
|
38
38
|
of your domain with '-n', the name of your application with '-a', or combine
|
@@ -44,33 +44,67 @@ module RHC::Commands
|
|
44
44
|
'--ids'.
|
45
45
|
DESC
|
46
46
|
option ['--ids'], "Display the IDs of each member", :optional => true
|
47
|
+
option ['--all'], "Display all members, including members of teams", :optional => true
|
47
48
|
takes_application_or_domain :argument => true
|
48
49
|
alias_action :members, :root_command => true
|
49
50
|
def list(path)
|
50
51
|
target = find_app_or_domain(path)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
m.owner?
|
58
|
-
|
59
|
-
|
52
|
+
|
53
|
+
members = target.members
|
54
|
+
if options.all
|
55
|
+
show_members = members.sort
|
56
|
+
else
|
57
|
+
show_members = members.select do |m|
|
58
|
+
if m.owner?
|
59
|
+
true
|
60
|
+
elsif m.explicit_role?
|
61
|
+
true
|
62
|
+
elsif m.from.any? {|f| f["type"] != "team" }
|
63
|
+
true
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end.sort
|
68
|
+
end
|
69
|
+
show_name = show_members.any?{ |m| m.name.presence && m.name != m.login }
|
70
|
+
show_login = show_members.any?{ |m| m.login.presence }
|
71
|
+
|
72
|
+
if show_members.present?
|
73
|
+
say table(show_members.map do |member|
|
74
|
+
[
|
75
|
+
((member.name || "") if show_name),
|
76
|
+
((member.login || "") if show_login),
|
77
|
+
role_description(member, member.teams(members)),
|
78
|
+
(member.id if options.ids),
|
79
|
+
member.type
|
80
|
+
].compact
|
81
|
+
end, :header => [
|
82
|
+
('Name' if show_name),
|
83
|
+
('Login' if show_login),
|
84
|
+
'Role',
|
85
|
+
("ID" if options.ids),
|
86
|
+
"Type"
|
87
|
+
].compact)
|
88
|
+
else
|
89
|
+
info "The #{target.class.model_name.downcase} #{target.name} does not have any members."
|
90
|
+
end
|
91
|
+
|
92
|
+
if show_members.count < members.count
|
93
|
+
paragraph do
|
94
|
+
info "Pass --all to display all members, including members of teams."
|
95
|
+
end
|
60
96
|
end
|
61
|
-
say table(members, :header => [('Name' if show_name), 'Login', 'Role', ("ID" if options.ids)].compact)
|
62
97
|
|
63
98
|
0
|
64
99
|
end
|
65
100
|
|
66
|
-
summary "Add
|
67
|
-
syntax "<login
|
101
|
+
summary "Add a member on a domain"
|
102
|
+
syntax "(<login>... | <team name>... | <id>...) [-n DOMAIN_NAME] [--role view|edit|admin] [--ids] [--type user|team] [--global]"
|
68
103
|
description <<-DESC
|
69
|
-
Adds
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
the owner.
|
104
|
+
Adds members on a domain by passing a user login, team name, or ID for each
|
105
|
+
member. The login and ID for each account are displayed in 'rhc account'.
|
106
|
+
To change the role for an existing domain member, use the 'rhc member update'
|
107
|
+
command.
|
74
108
|
|
75
109
|
Roles
|
76
110
|
view - able to see information about the domain and its apps,
|
@@ -89,26 +123,89 @@ module RHC::Commands
|
|
89
123
|
rhc add-member bob@example.com --role admin -n mydomain
|
90
124
|
Gives the account with login 'bob@example.com' admin access on mydomain
|
91
125
|
|
126
|
+
rhc add-member team1 --type team --role admin -n mydomain
|
127
|
+
Gives your team named 'team1' admin access on mydomain
|
128
|
+
|
92
129
|
DESC
|
93
130
|
takes_domain
|
94
131
|
option ['--ids'], "Treat the arguments as a list of IDs", :optional => true
|
95
|
-
option ['-r', '--role ROLE'], "The role to give to each member - view, edit, or admin (default 'edit')", :type => Role, :optional => true
|
96
|
-
|
132
|
+
option ['-r', '--role ROLE'], "The role to give to each member - view, edit, or admin (default is 'edit')", :type => Role, :optional => true
|
133
|
+
option ['--type TYPE'], "Type of argument(s) being passed. Accepted values are either 'team' or 'user' (default is 'user').", :optional => true
|
134
|
+
option ['--global'], "Use global-scoped teams. Must be used with '--type team'.", :optional => true
|
135
|
+
argument :members, "A list of members (user logins, team names, or IDs) to add. Pass --ids to treat this as a list of IDs.", [], :type => :list
|
97
136
|
def add(members)
|
98
137
|
target = find_domain
|
99
|
-
role = options
|
100
|
-
|
138
|
+
role = get_role_option(options)
|
139
|
+
type = get_type_option(options)
|
140
|
+
global = !!options.global
|
141
|
+
|
142
|
+
raise ArgumentError, 'You must pass at least one user login, team name, or ID to this command.' unless members.present?
|
143
|
+
raise ArgumentError, "The --global option can only be used with '--type team'." if global && !team?(type)
|
144
|
+
|
101
145
|
say "Adding #{pluralize(members.length, role_name(role))} to #{target.class.model_name.downcase} ... "
|
102
|
-
|
146
|
+
|
147
|
+
members = search_teams(members, global).map{|member| member.id} if team?(type) && !options.ids
|
148
|
+
target.update_members(changes_for(members, role, type))
|
149
|
+
|
150
|
+
success "done"
|
151
|
+
|
152
|
+
0
|
153
|
+
end
|
154
|
+
|
155
|
+
summary "Update a member on a domain"
|
156
|
+
syntax "(<login>... | <team name>... | <id>...) --role view|edit|admin [-n DOMAIN_NAME] [--ids] [--type user|team]"
|
157
|
+
description <<-DESC
|
158
|
+
Updates members on a domain by passing a user login, team name, or ID for
|
159
|
+
each member. You can use the 'rhc members' command to list the existing
|
160
|
+
members of your domain. You cannot change the role of the owner.
|
161
|
+
|
162
|
+
Roles
|
163
|
+
view - able to see information about the domain and its apps,
|
164
|
+
but not make any changes
|
165
|
+
edit - create, update, and delete applications, and has Git
|
166
|
+
and SSH access
|
167
|
+
admin - can update membership of a domain
|
168
|
+
|
169
|
+
The default role granted to members when added is 'edit' - use the '--role'
|
170
|
+
argument for 'view' or 'admin'.
|
171
|
+
|
172
|
+
Examples
|
173
|
+
rhc update-member bob@example.com --role view -n mydomain
|
174
|
+
Adds or updates the member with login 'bob@example.com' to 'admin' role on mydomain
|
175
|
+
|
176
|
+
rhc update-member team1 --type team --role admin -n mydomain
|
177
|
+
Updates the team member with name 'team1' to the 'admin' role on mydomain
|
178
|
+
|
179
|
+
rhc update-member team1_id --type team --role admin -n mydomain --ids
|
180
|
+
Adds or updates the team with ID 'team1_id' to the 'admin' role on mydomain
|
181
|
+
|
182
|
+
DESC
|
183
|
+
takes_domain
|
184
|
+
option ['--ids'], "Treat the arguments as a list of IDs", :optional => true
|
185
|
+
option ['-r', '--role ROLE'], "The role to give to each member - view, edit, or admin (default is 'edit')", :type => Role, :optional => true
|
186
|
+
option ['--type TYPE'], "Type of argument(s) being passed. Accepted values are either 'team' or 'user' (default is 'user').", :optional => true
|
187
|
+
argument :members, "A list of members (user logins, team names, or IDs) to update. Pass --ids to treat this as a list of IDs.", [], :type => :list
|
188
|
+
def update(members)
|
189
|
+
target = find_domain
|
190
|
+
role = get_role_option(options)
|
191
|
+
type = get_type_option(options)
|
192
|
+
|
193
|
+
raise ArgumentError, 'You must pass at least one user login, team name, or ID to this command.' unless members.present?
|
194
|
+
|
195
|
+
say "Updating #{pluralize(members.length, role_name(role))} to #{target.class.model_name.downcase} ... "
|
196
|
+
|
197
|
+
members = search_team_members(target.members, members).map{|member| member.id} if team?(type) && !options.ids
|
198
|
+
target.update_members(changes_for(members, role, type))
|
199
|
+
|
103
200
|
success "done"
|
104
201
|
|
105
202
|
0
|
106
203
|
end
|
107
204
|
|
108
205
|
summary "Remove a member from a domain"
|
109
|
-
syntax "<login
|
206
|
+
syntax "(<login>... | <team name>... | <id>...) [-n DOMAIN_NAME] [--ids] [--type user|team]"
|
110
207
|
description <<-DESC
|
111
|
-
Remove members
|
208
|
+
Remove members from a domain by passing a user login, team name, or ID for each
|
112
209
|
member you wish to remove. View the list of existing members with
|
113
210
|
'rhc members <domain_name>'.
|
114
211
|
|
@@ -117,9 +214,11 @@ module RHC::Commands
|
|
117
214
|
takes_domain
|
118
215
|
option ['--ids'], "Treat the arguments as a list of IDs"
|
119
216
|
option ['--all'], "Remove all members from this domain."
|
120
|
-
|
217
|
+
option ['--type TYPE'], "Type of argument(s) being passed. Accepted values are either 'team' or 'user' (default is 'user').", :optional => true
|
218
|
+
argument :members, "A list of members (user logins, team names, or IDs) to remove from the domain. Pass --ids to treat this as a list of IDs.", [], :type => :list
|
121
219
|
def remove(members)
|
122
220
|
target = find_domain
|
221
|
+
type = get_type_option(options)
|
123
222
|
|
124
223
|
if options.all
|
125
224
|
say "Removing all members from #{target.class.model_name.downcase} ... "
|
@@ -127,9 +226,13 @@ module RHC::Commands
|
|
127
226
|
success "done"
|
128
227
|
|
129
228
|
else
|
130
|
-
raise ArgumentError, 'You must pass one
|
229
|
+
raise ArgumentError, 'You must pass at least one user login, team name, or ID to this command.' unless members.present?
|
230
|
+
|
131
231
|
say "Removing #{pluralize(members.length, 'member')} from #{target.class.model_name.downcase} ... "
|
132
|
-
|
232
|
+
|
233
|
+
members = search_team_members(target.members, members).map{|member| member.id} if team?(type) && !options.ids
|
234
|
+
target.update_members(changes_for(members, 'none', type))
|
235
|
+
|
133
236
|
success "done"
|
134
237
|
end
|
135
238
|
|
@@ -137,12 +240,131 @@ module RHC::Commands
|
|
137
240
|
end
|
138
241
|
|
139
242
|
protected
|
140
|
-
def
|
243
|
+
def get_role_option(options, default_value='edit')
|
244
|
+
options.role || default_value
|
245
|
+
end
|
246
|
+
|
247
|
+
def get_type_option(options, default_value='user')
|
248
|
+
type = options.__hash__[:type]
|
249
|
+
case type
|
250
|
+
when 'team'
|
251
|
+
type
|
252
|
+
when 'user'
|
253
|
+
type
|
254
|
+
when nil
|
255
|
+
default_value
|
256
|
+
else
|
257
|
+
raise ArgumentError, "The type '#{type}' is not valid. Type must be 'user' or 'team'."
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def changes_for(members, role, type)
|
141
262
|
members.map do |m|
|
142
|
-
h = {:role => role}
|
143
|
-
h[options.ids ? :id : :login] = m
|
263
|
+
h = {:role => role, :type => type}
|
264
|
+
h[options.ids || team?(type) ? :id : :login] = m
|
144
265
|
h
|
145
266
|
end
|
146
267
|
end
|
268
|
+
|
269
|
+
def team?(type)
|
270
|
+
type == 'team'
|
271
|
+
end
|
272
|
+
|
273
|
+
def search_teams(team_names, global=false)
|
274
|
+
r = []
|
275
|
+
team_names.each do |team_name|
|
276
|
+
teams_for_name =
|
277
|
+
global ?
|
278
|
+
rest_client.search_teams(team_name, global) :
|
279
|
+
rest_client.search_owned_teams(team_name)
|
280
|
+
|
281
|
+
team_for_name = nil
|
282
|
+
suggestions = nil
|
283
|
+
|
284
|
+
if (exact_matches = teams_for_name.select {|t| t.name == team_name }).present?
|
285
|
+
if exact_matches.length == 1
|
286
|
+
team_for_name = exact_matches.first
|
287
|
+
else
|
288
|
+
raise RHC::TeamNotFoundException.new("There is more than one team named '#{team_name}'. " +
|
289
|
+
"Please use the --ids flag and specify the exact id of the team you want to manage.")
|
290
|
+
end
|
291
|
+
|
292
|
+
elsif (case_insensitive_matches = teams_for_name.select {|t| t.name =~ /^#{Regexp.escape(team_name)}$/i }).present?
|
293
|
+
if case_insensitive_matches.length == 1
|
294
|
+
team_for_name = case_insensitive_matches.first
|
295
|
+
else
|
296
|
+
suggestions = case_insensitive_matches
|
297
|
+
end
|
298
|
+
|
299
|
+
else
|
300
|
+
suggestions = teams_for_name
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
if team_for_name
|
305
|
+
r << team_for_name
|
306
|
+
elsif suggestions.present?
|
307
|
+
msg = global ? "No global team found with the name '#{team_name}'." : "You do not have a team named '#{team_name}'."
|
308
|
+
raise RHC::TeamNotFoundException.new(msg + " Did you mean one of the following?\n#{suggestions[0..50].map(&:name).join(", ")}")
|
309
|
+
else
|
310
|
+
msg = global ? "No global team found with the name '#{team_name}'." : "You do not have a team named '#{team_name}'."
|
311
|
+
raise RHC::TeamNotFoundException.new(msg)
|
312
|
+
end
|
313
|
+
|
314
|
+
end
|
315
|
+
r.flatten
|
316
|
+
end
|
317
|
+
|
318
|
+
def search_team_members(members, names)
|
319
|
+
r = []
|
320
|
+
team_members = members.select(&:team?)
|
321
|
+
names.each do |name|
|
322
|
+
|
323
|
+
team_for_name = nil
|
324
|
+
suggestions = nil
|
325
|
+
|
326
|
+
if (exact_matches = team_members.select{|team| team.name == name }).present?
|
327
|
+
if exact_matches.length == 1
|
328
|
+
team_for_name = exact_matches.first
|
329
|
+
else
|
330
|
+
raise RHC::MemberNotFoundException.new("There is more than one member team named '#{name}'. " +
|
331
|
+
"Please use the --ids flag and specify the exact id of the team you want to manage.")
|
332
|
+
end
|
333
|
+
|
334
|
+
elsif (case_insensitive_matches = team_members.select{|team| team.name =~ /^#{Regexp.escape(name)}$/i}).present?
|
335
|
+
if case_insensitive_matches.length == 1
|
336
|
+
team_for_name = case_insensitive_matches.first
|
337
|
+
else
|
338
|
+
suggestions = case_insensitive_matches
|
339
|
+
end
|
340
|
+
|
341
|
+
else
|
342
|
+
suggestions = team_members.select{|t| t.name =~ /#{Regexp.escape(name)}/i}
|
343
|
+
end
|
344
|
+
|
345
|
+
if team_for_name
|
346
|
+
r << team_for_name
|
347
|
+
elsif suggestions.present?
|
348
|
+
raise RHC::MemberNotFoundException.new("No member team found with the name '#{name}'. " +
|
349
|
+
"Did you mean one of the following?\n#{suggestions[0..50].map(&:name).join(", ")}")
|
350
|
+
else
|
351
|
+
raise RHC::MemberNotFoundException.new("No member team found with the name '#{name}'.")
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
r.flatten
|
356
|
+
end
|
357
|
+
|
358
|
+
def role_description(member, teams=[])
|
359
|
+
if member.owner?
|
360
|
+
"#{member.role} (owner)"
|
361
|
+
elsif member.explicit_role != member.role && member.from.all? {|f| f['type'] == 'domain'}
|
362
|
+
"#{member.role} (via domain)"
|
363
|
+
elsif member.explicit_role != member.role && teams.present? && (teams_with_role = teams.select{|t| t.role == member.role }).present?
|
364
|
+
"#{member.role} (via #{teams_with_role.map(&:name).sort.join(', ')})"
|
365
|
+
else
|
366
|
+
member.role
|
367
|
+
end
|
368
|
+
end
|
147
369
|
end
|
148
|
-
end
|
370
|
+
end
|