morpheus-cli 2.10.0 → 2.10.1

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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/bin/morpheus +27 -32
  3. data/lib/morpheus/api/accounts_interface.rb +36 -47
  4. data/lib/morpheus/api/api_client.rb +141 -110
  5. data/lib/morpheus/api/app_templates_interface.rb +56 -72
  6. data/lib/morpheus/api/apps_interface.rb +111 -132
  7. data/lib/morpheus/api/auth_interface.rb +30 -0
  8. data/lib/morpheus/api/clouds_interface.rb +71 -76
  9. data/lib/morpheus/api/custom_instance_types_interface.rb +21 -46
  10. data/lib/morpheus/api/dashboard_interface.rb +10 -17
  11. data/lib/morpheus/api/deploy_interface.rb +60 -72
  12. data/lib/morpheus/api/deployments_interface.rb +53 -71
  13. data/lib/morpheus/api/groups_interface.rb +55 -45
  14. data/lib/morpheus/api/instance_types_interface.rb +19 -23
  15. data/lib/morpheus/api/instances_interface.rb +179 -177
  16. data/lib/morpheus/api/key_pairs_interface.rb +11 -17
  17. data/lib/morpheus/api/license_interface.rb +18 -23
  18. data/lib/morpheus/api/load_balancers_interface.rb +54 -69
  19. data/lib/morpheus/api/logs_interface.rb +25 -29
  20. data/lib/morpheus/api/options_interface.rb +13 -17
  21. data/lib/morpheus/api/provision_types_interface.rb +19 -22
  22. data/lib/morpheus/api/roles_interface.rb +75 -94
  23. data/lib/morpheus/api/security_group_rules_interface.rb +28 -37
  24. data/lib/morpheus/api/security_groups_interface.rb +39 -51
  25. data/lib/morpheus/api/servers_interface.rb +113 -115
  26. data/lib/morpheus/api/setup_interface.rb +31 -0
  27. data/lib/morpheus/api/task_sets_interface.rb +36 -38
  28. data/lib/morpheus/api/tasks_interface.rb +56 -69
  29. data/lib/morpheus/api/users_interface.rb +67 -76
  30. data/lib/morpheus/api/virtual_images_interface.rb +61 -61
  31. data/lib/morpheus/api/whoami_interface.rb +12 -15
  32. data/lib/morpheus/cli.rb +71 -60
  33. data/lib/morpheus/cli/accounts.rb +254 -315
  34. data/lib/morpheus/cli/alias_command.rb +219 -0
  35. data/lib/morpheus/cli/app_templates.rb +264 -272
  36. data/lib/morpheus/cli/apps.rb +608 -671
  37. data/lib/morpheus/cli/cli_command.rb +259 -21
  38. data/lib/morpheus/cli/cli_registry.rb +99 -14
  39. data/lib/morpheus/cli/clouds.rb +599 -372
  40. data/lib/morpheus/cli/config_file.rb +126 -0
  41. data/lib/morpheus/cli/credentials.rb +141 -117
  42. data/lib/morpheus/cli/dashboard_command.rb +48 -56
  43. data/lib/morpheus/cli/deployments.rb +254 -268
  44. data/lib/morpheus/cli/deploys.rb +150 -142
  45. data/lib/morpheus/cli/error_handler.rb +38 -0
  46. data/lib/morpheus/cli/groups.rb +551 -179
  47. data/lib/morpheus/cli/hosts.rb +862 -617
  48. data/lib/morpheus/cli/instance_types.rb +103 -95
  49. data/lib/morpheus/cli/instances.rb +1335 -1009
  50. data/lib/morpheus/cli/key_pairs.rb +82 -90
  51. data/lib/morpheus/cli/library.rb +498 -499
  52. data/lib/morpheus/cli/license.rb +83 -101
  53. data/lib/morpheus/cli/load_balancers.rb +314 -300
  54. data/lib/morpheus/cli/login.rb +66 -44
  55. data/lib/morpheus/cli/logout.rb +47 -46
  56. data/lib/morpheus/cli/mixins/accounts_helper.rb +69 -31
  57. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +106 -0
  58. data/lib/morpheus/cli/mixins/print_helper.rb +181 -17
  59. data/lib/morpheus/cli/mixins/provisioning_helper.rb +535 -458
  60. data/lib/morpheus/cli/mixins/whoami_helper.rb +2 -2
  61. data/lib/morpheus/cli/option_parser.rb +35 -0
  62. data/lib/morpheus/cli/option_types.rb +232 -192
  63. data/lib/morpheus/cli/recent_activity_command.rb +61 -65
  64. data/lib/morpheus/cli/remote.rb +446 -199
  65. data/lib/morpheus/cli/roles.rb +884 -906
  66. data/lib/morpheus/cli/security_group_rules.rb +213 -203
  67. data/lib/morpheus/cli/security_groups.rb +237 -192
  68. data/lib/morpheus/cli/shell.rb +338 -231
  69. data/lib/morpheus/cli/tasks.rb +326 -308
  70. data/lib/morpheus/cli/users.rb +457 -462
  71. data/lib/morpheus/cli/version.rb +1 -1
  72. data/lib/morpheus/cli/version_command.rb +16 -18
  73. data/lib/morpheus/cli/virtual_images.rb +526 -345
  74. data/lib/morpheus/cli/whoami.rb +125 -111
  75. data/lib/morpheus/cli/workflows.rb +338 -185
  76. data/lib/morpheus/formatters.rb +8 -1
  77. data/lib/morpheus/logging.rb +1 -1
  78. data/lib/morpheus/rest_client.rb +17 -8
  79. metadata +9 -3
  80. data/lib/morpheus/api/custom_instance_types.rb +0 -55
@@ -10,472 +10,467 @@ require 'json'
10
10
  class Morpheus::Cli::Users
11
11
  include Morpheus::Cli::CliCommand
12
12
  include Morpheus::Cli::AccountsHelper
13
-
14
- def initialize()
15
- @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
16
- end
17
-
18
- def connect(opts)
19
- @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
20
- if @access_token.empty?
21
- print_red_alert "Invalid Credentials. Unable to acquire access token. Please verify your credentials and try again."
22
- exit 1
23
- end
24
- @api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
25
- @whoami_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).whoami
26
- @users_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).users
27
- @accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
28
- @roles_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).roles
29
- end
30
-
31
- def handle(args)
32
- usage = "Usage: morpheus users [list,details,add,update,remove] [username]"
33
- if args.empty?
34
- puts "\n#{usage}\n\n"
35
- return
36
- end
37
-
38
- case args[0]
39
- when 'list'
40
- list(args[1..-1])
41
- when 'details'
42
- details(args[1..-1])
43
- when 'add'
44
- add(args[1..-1])
45
- when 'update'
46
- update(args[1..-1])
47
- when 'remove'
48
- remove(args[1..-1])
49
- when 'feature-permissions'
50
- feature_permissions(args[1..-1])
51
- else
52
- puts "\n#{usage}\n\n"
53
- exit 127
54
- end
55
- end
56
-
57
- def list(args)
58
- usage = "Usage: morpheus users list [options]"
59
- options = {}
60
- optparse = OptionParser.new do|opts|
61
- opts.banner = usage
62
- build_common_options(opts, options, [:account, :list, :json])
63
- end
64
- optparse.parse(args)
65
- connect(options)
66
- begin
67
-
68
- account = find_account_from_options(options)
69
- account_id = account ? account['id'] : nil
70
-
71
- params = {}
72
- [:phrase, :offset, :max, :sort, :direction].each do |k|
73
- params[k] = options[k] unless options[k].nil?
74
- end
75
-
76
- json_response = @users_interface.list(account_id, params)
77
- users = json_response['users']
78
-
79
- if options[:json]
80
- print JSON.pretty_generate(json_response)
81
- print "\n"
82
- else
83
- print "\n" ,cyan, bold, "Morpheus Users\n","==================", reset, "\n\n"
84
- if users.empty?
85
- puts yellow,"No users found.",reset
86
- else
87
- print_users_table(users)
88
- end
89
- print reset,"\n"
90
- end
91
- rescue RestClient::Exception => e
92
- print_rest_exception(e, options)
93
- exit 1
94
- end
95
- end
96
-
97
- def details(args)
98
- usage = "Usage: morpheus users details [username] [options]"
99
- options = {}
100
- optparse = OptionParser.new do|opts|
101
- opts.banner = usage
102
- build_common_options(opts, options, [:account, :json])
13
+ register_subcommands :list, :get, :add, :update, :remove
14
+ alias_subcommand :details, :get
15
+ set_default_subcommand :list
16
+
17
+ def initialize()
18
+ # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
19
+ end
20
+
21
+ def connect(opts)
22
+ @api_client = establish_remote_appliance_connection(opts)
23
+ @whoami_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).whoami
24
+ @users_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).users
25
+ @accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
26
+ @roles_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).roles
27
+ end
28
+
29
+ def handle(args)
30
+ handle_subcommand(args)
31
+ end
32
+
33
+ def list(args)
34
+ options = {}
35
+ optparse = OptionParser.new do|opts|
36
+ opts.banner = subcommand_usage()
37
+ build_common_options(opts, options, [:account, :list, :json, :dry_run])
38
+ end
39
+ optparse.parse!(args)
40
+ connect(options)
41
+ begin
42
+
43
+ account = find_account_from_options(options)
44
+ account_id = account ? account['id'] : nil
45
+
46
+ params = {}
47
+ [:phrase, :offset, :max, :sort, :direction].each do |k|
48
+ params[k] = options[k] unless options[k].nil?
49
+ end
50
+ if options[:dry_run]
51
+ print_dry_run @users_interface.dry.list(account_id, params)
52
+ return
53
+ end
54
+ json_response = @users_interface.list(account_id, params)
55
+ users = json_response['users']
56
+
57
+ if options[:json]
58
+ print JSON.pretty_generate(json_response)
59
+ print "\n"
60
+ else
61
+ title = "Morpheus Users"
62
+ subtitles = []
63
+ if account
64
+ subtitles << "Account: #{account['name']}".strip
65
+ end
66
+ subtitle = subtitles.join(', ')
67
+ print "\n" ,cyan, bold, title, (subtitle.empty? ? "" : " - #{subtitle}"), "\n", "==================", reset, "\n\n"
68
+ if users.empty?
69
+ puts yellow,"No users found.",reset
70
+ else
71
+ print_users_table(users)
72
+ print_results_pagination(json_response)
73
+ end
74
+ print reset,"\n"
75
+ end
76
+ rescue RestClient::Exception => e
77
+ print_rest_exception(e, options)
78
+ exit 1
79
+ end
80
+ end
81
+
82
+ def get(args)
83
+ options = {}
84
+ optparse = OptionParser.new do|opts|
85
+ opts.banner = subcommand_usage("[username]")
103
86
  opts.on(nil,'--feature-access', "Display Feature Access") do |val|
104
- options[:include_feature_access] = true
105
- end
106
- # opts.on(nil,'--group-access', "Display Group Access") do
107
- # options[:include_group_access] = true
108
- # end
109
- # opts.on(nil,'--cloud-access', "Display Cloud Access") do
110
- # options[:include_cloud_access] = true
111
- # end
112
- # opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
113
- # options[:include_instance_type_access] = true
114
- # end
115
- opts.on(nil,'--all-access', "Display All Access Lists") do
116
- options[:include_feature_access] = true
117
- options[:include_group_access] = true
118
- options[:include_cloud_access] = true
119
- options[:include_instance_type_access] = true
120
- end
121
- end
122
- optparse.parse(args)
123
-
124
- if args.count < 1
125
- puts "\n#{usage}\n\n"
126
- exit 1
127
- end
128
- username = args[0]
129
-
130
- connect(options)
131
- begin
132
-
133
- account = find_account_from_options(options)
134
- account_id = account ? account['id'] : nil
135
-
136
- # todo: users_response = @users_interface.list(account_id, {name: name})
137
- # there may be response data outside of user that needs to be displayed
138
- user = find_user_by_username(account_id, username)
139
- exit 1 if user.nil?
140
-
141
- # meh, this should just always be returned with GET /api/users/:id
142
- user_feature_permissions_json = nil
143
- user_feature_permissions = nil
144
- if options[:include_feature_access]
145
- user_feature_permissions_json = @users_interface.feature_permissions(account_id, user['id'])
146
- user_feature_permissions = user_feature_permissions_json['featurePermissions']
147
- end
148
-
149
- if options[:json]
150
- print JSON.pretty_generate({user:user})
151
- print "\n"
152
- if (user_feature_permissions_json)
153
- print JSON.pretty_generate(user_feature_permissions_json)
154
- print "\n"
155
- end
156
- else
157
- print "\n" ,cyan, bold, "User Details\n","==================", reset, "\n\n"
158
- print cyan
159
- puts "ID: #{user['id']}"
160
- puts "Account: #{user['account'] ? user['account']['name'] : nil}"
161
- puts "First Name: #{user['firstName']}"
162
- puts "Last Name: #{user['lastName']}"
163
- puts "Username: #{user['username']}"
164
- puts "Email: #{user['email']}"
165
- puts "Role: #{format_user_role_names(user)}"
166
- puts "Date Created: #{format_local_dt(user['dateCreated'])}"
167
- puts "Last Updated: #{format_local_dt(user['lastUpdated'])}"
168
- print "\n" ,cyan, bold, "User Instance Limits\n","==================", reset, "\n\n"
169
- print cyan
170
- puts "Max Storage (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxStorage'] : 0}"
171
- puts "Max Memory (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxMemory'] : 0}"
172
- puts "CPU Count: #{user['instanceLimits'] ? user['instanceLimits']['maxCpu'] : 0}"
173
-
174
- if options[:include_feature_access] && user_feature_permissions
175
- if user_feature_permissions
176
- print "\n" ,cyan, bold, "Feature Permissions\n","==================", reset, "\n\n"
177
- print cyan
178
- rows = user_feature_permissions.collect do |code, access|
179
- {code: code, access: get_access_string(access) }
180
- end
181
- tp rows, [:code, :access]
182
- else
183
- puts yellow,"No permissions found.",reset
184
- end
185
- end
186
-
187
- print cyan
188
- print reset,"\n"
189
- end
190
- rescue RestClient::Exception => e
191
- print_rest_exception(e, options)
192
- exit 1
193
- end
194
- end
195
-
196
- def add(args)
197
- usage = "Usage: morpheus users add [options]"
198
- options = {}
199
- optparse = OptionParser.new do|opts|
200
- opts.banner = usage
201
- build_common_options(opts, options, [:account, :options, :json])
202
- opts.on('-h', '--help', "Prints this help" ) do
87
+ options[:include_feature_access] = true
88
+ end
89
+ # opts.on(nil,'--group-access', "Display Group Access") do
90
+ # options[:include_group_access] = true
91
+ # end
92
+ # opts.on(nil,'--cloud-access', "Display Cloud Access") do
93
+ # options[:include_cloud_access] = true
94
+ # end
95
+ # opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
96
+ # options[:include_instance_type_access] = true
97
+ # end
98
+ opts.on(nil,'--all-access', "Display All Access Lists") do
99
+ options[:include_feature_access] = true
100
+ options[:include_group_access] = true
101
+ options[:include_cloud_access] = true
102
+ options[:include_instance_type_access] = true
103
+ end
104
+ build_common_options(opts, options, [:account, :json, :dry_run])
105
+ end
106
+ optparse.parse!(args)
107
+
108
+ if args.count < 1
109
+ puts optparse
110
+ exit 1
111
+ end
112
+
113
+ connect(options)
114
+ begin
115
+ account = find_account_from_options(options)
116
+ account_id = account ? account['id'] : nil
117
+ if options[:dry_run]
118
+ if args[0].to_s =~ /\A\d{1,}\Z/
119
+ print_dry_run @users_interface.dry.get(account_id, args[0].to_i)
120
+ else
121
+ print_dry_run @users_interface.dry.get(account_id, {username: args[0]})
122
+ end
123
+ if options[:include_feature_access]
124
+ print_dry_run @users_interface.dry.feature_permissions(account_id, ":id")
125
+ end
126
+ return
127
+ end
128
+ # todo: users_response = @users_interface.list(account_id, {name: name})
129
+ # there may be response data outside of user that needs to be displayed
130
+ user = find_user_by_username_or_id(account_id, args[0])
131
+ exit 1 if user.nil?
132
+
133
+ # meh, this should just always be returned with GET /api/users/:id
134
+ user_feature_permissions_json = nil
135
+ user_feature_permissions = nil
136
+ if options[:include_feature_access]
137
+ user_feature_permissions_json = @users_interface.feature_permissions(account_id, user['id'])
138
+ user_feature_permissions = user_feature_permissions_json['featurePermissions']
139
+ end
140
+
141
+ if options[:json]
142
+ print JSON.pretty_generate({user:user})
143
+ print "\n"
144
+ if (user_feature_permissions_json)
145
+ print JSON.pretty_generate(user_feature_permissions_json)
146
+ print "\n"
147
+ end
148
+ else
149
+ print "\n" ,cyan, bold, "User Details\n","==================", reset, "\n\n"
150
+ print cyan
151
+ puts "ID: #{user['id']}"
152
+ puts "Account: #{user['account'] ? user['account']['name'] : nil}"
153
+ puts "First Name: #{user['firstName']}"
154
+ puts "Last Name: #{user['lastName']}"
155
+ puts "Username: #{user['username']}"
156
+ puts "Email: #{user['email']}"
157
+ puts "Role: #{format_user_role_names(user)}"
158
+ puts "Date Created: #{format_local_dt(user['dateCreated'])}"
159
+ puts "Last Updated: #{format_local_dt(user['lastUpdated'])}"
160
+ print "\n" ,cyan, bold, "User Instance Limits\n","==================", reset, "\n\n"
161
+ print cyan
162
+ puts "Max Storage (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxStorage'] : 0}"
163
+ puts "Max Memory (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxMemory'] : 0}"
164
+ puts "CPU Count: #{user['instanceLimits'] ? user['instanceLimits']['maxCpu'] : 0}"
165
+
166
+ if options[:include_feature_access] && user_feature_permissions
167
+ if user_feature_permissions
168
+ print "\n" ,cyan, bold, "Feature Permissions\n","==================", reset, "\n\n"
169
+ print cyan
170
+ rows = user_feature_permissions.collect do |code, access|
171
+ {code: code, access: get_access_string(access) }
172
+ end
173
+ tp rows, [:code, :access]
174
+ else
175
+ puts yellow,"No permissions found.",reset
176
+ end
177
+ end
178
+
179
+ print cyan
180
+ print reset,"\n"
181
+ end
182
+ rescue RestClient::Exception => e
183
+ print_rest_exception(e, options)
184
+ exit 1
185
+ end
186
+ end
187
+
188
+ def add(args)
189
+ options = {}
190
+ optparse = OptionParser.new do|opts|
191
+ opts.banner = subcommand_usage("[options]")
192
+ build_common_options(opts, options, [:account, :options, :json, :dry_run])
193
+ opts.on('-h', '--help', "Prints this help" ) do
203
194
  puts opts
204
- puts Morpheus::Cli::OptionTypes.display_option_types_help(add_user_option_types)
195
+ puts Morpheus::Cli::OptionTypes.display_option_types_help(add_user_option_types)
205
196
  exit
206
197
  end
207
- end
208
- optparse.parse(args)
209
-
210
- connect(options)
211
-
212
- begin
213
-
214
- account = find_account_from_options(options)
215
- account_id = account ? account['id'] : nil
216
-
217
- # remove role option_type, it is just for help display, the role prompt is separate down below
218
- prompt_option_types = add_user_option_types().reject {|it| ['role'].include?(it['fieldName']) }
219
-
220
- params = Morpheus::Cli::OptionTypes.prompt(prompt_option_types, options[:options], @api_client, options[:params])
221
-
222
- #puts "parsed params is : #{params.inspect}"
223
- user_keys = ['username', 'firstName', 'lastName', 'email', 'password', 'passwordConfirmation', 'instanceLimits']
224
- user_payload = params.select {|k,v| user_keys.include?(k) }
225
- if !user_payload['instanceLimits']
226
- user_payload['instanceLimits'] = {}
227
- user_payload['instanceLimits']['maxStorage'] = params['instanceLimits.maxStorage'].to_i if params['instanceLimits.maxStorage'].to_s.strip != ''
228
- user_payload['instanceLimits']['maxMemory'] = params['instanceLimits.maxMemory'].to_i if params['instanceLimits.maxMemory'].to_s.strip != ''
229
- user_payload['instanceLimits']['maxCpu'] = params['instanceLimits.maxCpu'].to_i if params['instanceLimits.maxCpu'].to_s.strip != ''
230
- end
231
-
232
- roles = prompt_user_roles(account_id, nil, options)
233
- if !roles.empty?
234
- user_payload['roles'] = roles.collect {|r| {id: r['id']} }
235
- end
236
-
237
- request_payload = {user: user_payload}
238
- json_response = @users_interface.create(account_id, request_payload)
239
-
240
- if options[:json]
241
- print JSON.pretty_generate(json_response)
242
- print "\n"
243
- else
244
- if account
245
- print_green_success "Added user #{user_payload['username']} to account #{account['name']}"
246
- else
247
- print_green_success "Added user #{user_payload['username']}"
248
- end
249
-
250
- details_options = [user_payload["username"]]
251
- if account
252
- details_options.push "--account-id", account['id'].to_s
253
- end
254
- details(details_options)
255
- end
256
-
257
- rescue RestClient::Exception => e
258
- print_rest_exception(e, options)
259
- exit 1
260
- end
261
- end
262
-
263
- def update(args)
264
- usage = "Usage: morpheus users update [username] [options]"
265
- options = {}
266
- optparse = OptionParser.new do|opts|
267
- opts.banner = usage
268
- build_common_options(opts, options, [:account, :options, :json])
269
- opts.on('-h', '--help', "Prints this help" ) do
198
+ end
199
+ optparse.parse!(args)
200
+
201
+ connect(options)
202
+ begin
203
+
204
+ account = find_account_from_options(options)
205
+ account_id = account ? account['id'] : nil
206
+
207
+ # remove role option_type, it is just for help display, the role prompt is separate down below
208
+ prompt_option_types = add_user_option_types().reject {|it| ['role'].include?(it['fieldName']) }
209
+ params = Morpheus::Cli::OptionTypes.prompt(prompt_option_types, options[:options], @api_client, options[:params])
210
+
211
+ #puts "parsed params is : #{params.inspect}"
212
+ user_keys = ['username', 'firstName', 'lastName', 'email', 'password', 'passwordConfirmation', 'instanceLimits']
213
+ user_payload = params.select {|k,v| user_keys.include?(k) }
214
+ if !user_payload['instanceLimits']
215
+ user_payload['instanceLimits'] = {}
216
+ user_payload['instanceLimits']['maxStorage'] = params['instanceLimits.maxStorage'].to_i if params['instanceLimits.maxStorage'].to_s.strip != ''
217
+ user_payload['instanceLimits']['maxMemory'] = params['instanceLimits.maxMemory'].to_i if params['instanceLimits.maxMemory'].to_s.strip != ''
218
+ user_payload['instanceLimits']['maxCpu'] = params['instanceLimits.maxCpu'].to_i if params['instanceLimits.maxCpu'].to_s.strip != ''
219
+ end
220
+
221
+ roles = prompt_user_roles(account_id, nil, options)
222
+ if !roles.empty?
223
+ user_payload['roles'] = roles.collect {|r| {id: r['id']} }
224
+ end
225
+
226
+ payload = {user: user_payload}
227
+
228
+ if options[:dry_run]
229
+ print_dry_run @users_interface.dry.create(account_id, payload)
230
+ return
231
+ end
232
+ json_response = @users_interface.create(account_id, payload)
233
+ if options[:json]
234
+ print JSON.pretty_generate(json_response)
235
+ print "\n"
236
+ else
237
+ if account
238
+ print_green_success "Added user #{user_payload['username']} to account #{account['name']}"
239
+ else
240
+ print_green_success "Added user #{user_payload['username']}"
241
+ end
242
+
243
+ details_options = [user_payload["username"]]
244
+ if account
245
+ details_options.push "--account-id", account['id'].to_s
246
+ end
247
+ get(details_options)
248
+ end
249
+
250
+ rescue RestClient::Exception => e
251
+ print_rest_exception(e, options)
252
+ exit 1
253
+ end
254
+ end
255
+
256
+ def update(args)
257
+ options = {}
258
+ optparse = OptionParser.new do|opts|
259
+ opts.banner = subcommand_usage("[username] [options]")
260
+ build_common_options(opts, options, [:account, :options, :json, :dry_run])
261
+ opts.on('-h', '--help', "Prints this help" ) do
270
262
  puts opts
271
- puts Morpheus::Cli::OptionTypes.display_option_types_help(update_user_option_types)
263
+ puts Morpheus::Cli::OptionTypes.display_option_types_help(update_user_option_types)
272
264
  exit
273
265
  end
274
- end
275
- optparse.parse(args)
276
-
277
- if args.count < 1
278
- puts "#{usage}\n\n"
279
- puts Morpheus::Cli::OptionTypes.display_option_types_help(update_user_option_types)
280
- exit 1
281
- end
282
- username = args[0]
283
-
284
- connect(options)
285
-
286
- begin
287
-
288
- account = find_account_from_options(options)
289
- account_id = account ? account['id'] : nil
290
-
291
- user = find_user_by_username(account_id, username)
292
- exit 1 if user.nil?
293
-
294
- #params = Morpheus::Cli::OptionTypes.prompt(update_user_option_types, options[:options], @api_client, options[:params])
295
- params = options[:options] || {}
296
- roles = prompt_user_roles(account_id, user['id'], options.merge(no_prompt: true))
297
- if !roles.empty?
298
- params['roles'] = roles.collect {|r| {id: r['id']} }
299
- end
300
-
301
- if params.empty?
302
- puts "\n#{usage}\n\n"
303
- puts Morpheus::Cli::OptionTypes.display_option_types_help(update_user_option_types)
304
- exit 1
305
- end
306
-
307
- #puts "parsed params is : #{params.inspect}"
308
- user_keys = ['username', 'firstName', 'lastName', 'email', 'password', 'instanceLimits', 'roles']
309
- user_payload = params.select {|k,v| user_keys.include?(k) }
310
- if !user_payload['instanceLimits']
311
- user_payload['instanceLimits'] = {}
312
- user_payload['instanceLimits']['maxStorage'] = params['instanceLimits.maxStorage'].to_i if params['instanceLimits.maxStorage'].to_s.strip != ''
313
- user_payload['instanceLimits']['maxMemory'] = params['instanceLimits.maxMemory'].to_i if params['instanceLimits.maxMemory'].to_s.strip != ''
314
- user_payload['instanceLimits']['maxCpu'] = params['instanceLimits.maxCpu'].to_i if params['instanceLimits.maxCpu'].to_s.strip != ''
315
- end
316
-
317
- request_payload = {user: user_payload}
318
- json_response = @users_interface.update(account_id, user['id'], request_payload)
319
-
320
- if options[:json]
321
- print JSON.pretty_generate(json_response)
322
- print "\n"
323
- else
324
- print_green_success "Updated user #{user_payload['username']}"
325
- details_options = [user_payload["username"] || user['username']]
326
- if account
327
- details_options.push "--account-id", account['id'].to_s
328
- end
329
- details(details_options)
330
- end
331
-
332
- rescue RestClient::Exception => e
333
- print_rest_exception(e, options)
334
- exit 1
335
- end
336
- end
337
-
338
- def remove(args)
339
- usage = "Usage: morpheus users remove [username]"
340
- options = {}
341
- optparse = OptionParser.new do|opts|
342
- opts.banner = usage
343
- build_common_options(opts, options, [:account, :auto_confirm, :json])
344
- end
345
- optparse.parse(args)
346
-
347
- if args.count < 1
348
- puts "\n#{usage}\n\n"
349
- exit 1
350
- end
351
- username = args[0]
352
-
353
- connect(options)
354
- begin
355
-
356
- account = find_account_from_options(options)
357
- account_id = account ? account['id'] : nil
358
-
359
- user = find_user_by_username(account_id, username)
360
- exit 1 if user.nil?
361
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the user #{user['username']}?")
362
- exit
363
- end
364
- json_response = @users_interface.destroy(account_id, user['id'])
365
-
366
- if options[:json]
367
- print JSON.pretty_generate(json_response)
368
- print "\n"
369
- else
370
- print_green_success "User #{username} removed"
371
- # list([])
372
- end
373
-
374
- rescue RestClient::Exception => e
375
- print_rest_exception(e, options)
376
- exit 1
377
- end
378
- end
379
-
380
- private
381
-
382
- def add_user_option_types
383
- [
384
- {'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1},
385
- {'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
386
- {'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'displayOrder' => 3},
387
- {'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'displayOrder' => 4},
388
- {'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'displayOrder' => 6},
389
- {'fieldName' => 'passwordConfirmation', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'displayOrder' => 7},
390
- {'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8},
391
- {'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9},
392
- {'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10},
393
- {'fieldName' => 'role', 'fieldLabel' => 'Role', 'type' => 'text', 'displayOrder' => 11, 'description' => "Role names (comma separated)"},
394
- ]
395
- end
396
-
397
- def update_user_option_types
398
- [
399
- {'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1},
400
- {'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
401
- {'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => false, 'displayOrder' => 3},
402
- {'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => false, 'displayOrder' => 4},
403
- {'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => false, 'displayOrder' => 6},
404
- {'fieldName' => 'passwordConfirmation', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => false, 'displayOrder' => 7},
405
- {'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8},
406
- {'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9},
407
- {'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10},
408
- {'fieldName' => 'role', 'fieldLabel' => 'Role', 'type' => 'text', 'displayOrder' => 11, 'description' => "Role names (comma separated)"},
409
- ]
410
- end
411
-
412
- # prompt user to select roles for a new or existing user
413
- # options['role'] can be passed as comma separated role names
414
- # if so, it will be used instead of prompting
415
- # returns array of role objects
416
- def prompt_user_roles(account_id, user_id, options={})
417
-
418
- passed_role_string = nil
419
- if options['role'] || (options[:options] && (options[:options]['role'] || options[:options]['roles']))
420
- passed_role_string = options['role'] || (options[:options] && (options[:options]['role'] || options[:options]['roles']))
421
- end
422
- passed_role_names = []
423
- if !passed_role_string.empty?
424
- passed_role_names = passed_role_string.split(',').uniq.compact.collect {|r| r.strip}
425
- end
426
-
427
- available_roles = @users_interface.available_roles(account_id, user_id)['roles']
428
-
429
- if available_roles.empty?
430
- print_red_alert "No available roles found."
431
- exit 1
432
- end
433
- role_options = available_roles.collect {|role|
434
- {'name' => role['authority'], 'value' => role['id']}
435
- }
436
-
437
- # found_roles = []
438
- roles = []
439
-
440
- if !passed_role_names.empty?
441
- invalid_role_names = []
442
- passed_role_names.each do |role_name|
443
- found_role = available_roles.find {|ar| ar['authority'] == role_name}
444
- if found_role
445
- # found_roles << found_role
446
- roles << found_role
447
- else
448
- invalid_role_names << role_name
449
- end
450
- end
451
- if !invalid_role_names.empty?
452
- print_red_alert "Invalid Roles: #{invalid_role_names.join(', ')}"
453
- exit 1
454
- end
455
- end
456
-
457
- if roles.empty?
458
- no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
459
- if !no_prompt
460
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleId', 'fieldLabel' => 'Role', 'type' => 'select', 'selectOptions' => role_options, 'required' => true}], options[:options])
461
- role_id = v_prompt['roleId']
462
- roles << available_roles.find {|r| r['id'].to_i == role_id.to_i }
463
- add_another_role = true
464
- while add_another_role do
465
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleId', 'fieldLabel' => 'Another Role', 'type' => 'select', 'selectOptions' => role_options, 'required' => false}], options[:options])
466
- if v_prompt['roleId'].to_s.empty?
467
- add_another_role = false
468
- else
469
- role_id = v_prompt['roleId']
470
- roles << available_roles.find {|r| r['id'].to_i == role_id.to_i }
471
- end
472
- end
473
- end
474
- end
475
-
476
- roles = roles.compact
477
- return roles
478
-
479
- end
480
-
481
- end
266
+ end
267
+ optparse.parse!(args)
268
+
269
+ if args.count < 1
270
+ puts optparse
271
+ puts Morpheus::Cli::OptionTypes.display_option_types_help(update_user_option_types)
272
+ exit 1
273
+ end
274
+
275
+ connect(options)
276
+ begin
277
+
278
+ account = find_account_from_options(options)
279
+ account_id = account ? account['id'] : nil
280
+
281
+ user = find_user_by_username_or_id(account_id, args[0])
282
+ exit 1 if user.nil?
283
+
284
+ #params = Morpheus::Cli::OptionTypes.prompt(update_user_option_types, options[:options], @api_client, options[:params])
285
+ params = options[:options] || {}
286
+ roles = prompt_user_roles(account_id, user['id'], options.merge(no_prompt: true))
287
+ if !roles.empty?
288
+ params['roles'] = roles.collect {|r| {id: r['id']} }
289
+ end
290
+ if params.empty?
291
+ puts optparse.banner
292
+ puts Morpheus::Cli::OptionTypes.display_option_types_help(update_user_option_types)
293
+ exit 1
294
+ end
295
+
296
+ #puts "parsed params is : #{params.inspect}"
297
+ user_keys = ['username', 'firstName', 'lastName', 'email', 'password', 'instanceLimits', 'roles']
298
+ user_payload = params.select {|k,v| user_keys.include?(k) }
299
+ if !user_payload['instanceLimits']
300
+ user_payload['instanceLimits'] = {}
301
+ user_payload['instanceLimits']['maxStorage'] = params['instanceLimits.maxStorage'].to_i if params['instanceLimits.maxStorage'].to_s.strip != ''
302
+ user_payload['instanceLimits']['maxMemory'] = params['instanceLimits.maxMemory'].to_i if params['instanceLimits.maxMemory'].to_s.strip != ''
303
+ user_payload['instanceLimits']['maxCpu'] = params['instanceLimits.maxCpu'].to_i if params['instanceLimits.maxCpu'].to_s.strip != ''
304
+ end
305
+
306
+ payload = {user: user_payload}
307
+ json_response = @users_interface.update(account_id, user['id'], payload)
308
+ if options[:dry_run]
309
+ print_dry_run @users_interface.dry.update(account_id, user['id'], payload)
310
+ return
311
+ end
312
+
313
+ if options[:json]
314
+ print JSON.pretty_generate(json_response)
315
+ print "\n"
316
+ else
317
+ print_green_success "Updated user #{user_payload['username']}"
318
+ details_options = [user_payload["username"] || user['username']]
319
+ if account
320
+ details_options.push "--account-id", account['id'].to_s
321
+ end
322
+ get(details_options)
323
+ end
324
+
325
+ rescue RestClient::Exception => e
326
+ print_rest_exception(e, options)
327
+ exit 1
328
+ end
329
+ end
330
+
331
+ def remove(args)
332
+ usage = "Usage: morpheus users remove [username]"
333
+ options = {}
334
+ optparse = OptionParser.new do|opts|
335
+ opts.banner = subcommand_usage("[username]")
336
+ build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run])
337
+ end
338
+ optparse.parse!(args)
339
+
340
+ if args.count < 1
341
+ puts optparse
342
+ exit 1
343
+ end
344
+
345
+ connect(options)
346
+ begin
347
+
348
+ account = find_account_from_options(options)
349
+ account_id = account ? account['id'] : nil
350
+
351
+ user = find_user_by_username_or_id(account_id, args[0])
352
+ exit 1 if user.nil?
353
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the user #{user['username']}?")
354
+ exit
355
+ end
356
+ if options[:dry_run]
357
+ print_dry_run @users_interface.dry.destroy(account_id, user['id'])
358
+ return
359
+ end
360
+ json_response = @users_interface.destroy(account_id, user['id'])
361
+
362
+ if options[:json]
363
+ print JSON.pretty_generate(json_response)
364
+ print "\n"
365
+ else
366
+ print_green_success "User #{user['username']} removed"
367
+ # list([])
368
+ end
369
+ rescue RestClient::Exception => e
370
+ print_rest_exception(e, options)
371
+ exit 1
372
+ end
373
+ end
374
+
375
+ private
376
+
377
+ def add_user_option_types
378
+ [
379
+ {'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1},
380
+ {'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
381
+ {'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'displayOrder' => 3},
382
+ {'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'displayOrder' => 4},
383
+ {'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'displayOrder' => 6},
384
+ {'fieldName' => 'passwordConfirmation', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'displayOrder' => 7},
385
+ {'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8},
386
+ {'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9},
387
+ {'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10},
388
+ {'fieldName' => 'role', 'fieldLabel' => 'Role', 'type' => 'text', 'displayOrder' => 11, 'description' => "Role names (comma separated)"},
389
+ ]
390
+ end
391
+
392
+ def update_user_option_types
393
+ [
394
+ {'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1},
395
+ {'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
396
+ {'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => false, 'displayOrder' => 3},
397
+ {'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => false, 'displayOrder' => 4},
398
+ {'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => false, 'displayOrder' => 6},
399
+ {'fieldName' => 'passwordConfirmation', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => false, 'displayOrder' => 7},
400
+ {'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8},
401
+ {'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9},
402
+ {'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10},
403
+ {'fieldName' => 'role', 'fieldLabel' => 'Role', 'type' => 'text', 'displayOrder' => 11, 'description' => "Role names (comma separated)"},
404
+ ]
405
+ end
406
+
407
+ # prompt user to select roles for a new or existing user
408
+ # options['role'] can be passed as comma separated role names
409
+ # if so, it will be used instead of prompting
410
+ # returns array of role objects
411
+ def prompt_user_roles(account_id, user_id, options={})
412
+
413
+ passed_role_string = nil
414
+ if options['role'] || (options[:options] && (options[:options]['role'] || options[:options]['roles']))
415
+ passed_role_string = options['role'] || (options[:options] && (options[:options]['role'] || options[:options]['roles']))
416
+ end
417
+ passed_role_names = []
418
+ if !passed_role_string.empty?
419
+ passed_role_names = passed_role_string.split(',').uniq.compact.collect {|r| r.strip}
420
+ end
421
+
422
+ available_roles = @users_interface.available_roles(account_id, user_id)['roles']
423
+
424
+ if available_roles.empty?
425
+ print_red_alert "No available roles found."
426
+ exit 1
427
+ end
428
+ role_options = available_roles.collect {|role|
429
+ {'name' => role['authority'], 'value' => role['id']}
430
+ }
431
+
432
+ # found_roles = []
433
+ roles = []
434
+
435
+ if !passed_role_names.empty?
436
+ invalid_role_names = []
437
+ passed_role_names.each do |role_name|
438
+ found_role = available_roles.find {|ar| ar['authority'] == role_name}
439
+ if found_role
440
+ # found_roles << found_role
441
+ roles << found_role
442
+ else
443
+ invalid_role_names << role_name
444
+ end
445
+ end
446
+ if !invalid_role_names.empty?
447
+ print_red_alert "Invalid Roles: #{invalid_role_names.join(', ')}"
448
+ exit 1
449
+ end
450
+ end
451
+
452
+ if roles.empty?
453
+ no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
454
+ if !no_prompt
455
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleId', 'fieldLabel' => 'Role', 'type' => 'select', 'selectOptions' => role_options, 'required' => true}], options[:options])
456
+ role_id = v_prompt['roleId']
457
+ roles << available_roles.find {|r| r['id'].to_i == role_id.to_i }
458
+ add_another_role = true
459
+ while add_another_role do
460
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'roleId', 'fieldLabel' => 'Another Role', 'type' => 'select', 'selectOptions' => role_options, 'required' => false}], options[:options])
461
+ if v_prompt['roleId'].to_s.empty?
462
+ add_another_role = false
463
+ else
464
+ role_id = v_prompt['roleId']
465
+ roles << available_roles.find {|r| r['id'].to_i == role_id.to_i }
466
+ end
467
+ end
468
+ end
469
+ end
470
+
471
+ roles = roles.compact
472
+ return roles
473
+
474
+ end
475
+
476
+ end