morpheus-cli 0.1.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/morpheus/api/accounts_interface.rb +55 -0
  3. data/lib/morpheus/api/api_client.rb +48 -3
  4. data/lib/morpheus/api/apps_interface.rb +13 -13
  5. data/lib/morpheus/api/{zones_interface.rb → clouds_interface.rb} +10 -10
  6. data/lib/morpheus/api/deploy_interface.rb +4 -4
  7. data/lib/morpheus/api/groups_interface.rb +3 -3
  8. data/lib/morpheus/api/instance_types_interface.rb +2 -2
  9. data/lib/morpheus/api/instances_interface.rb +35 -19
  10. data/lib/morpheus/api/key_pairs_interface.rb +60 -0
  11. data/lib/morpheus/api/license_interface.rb +29 -0
  12. data/lib/morpheus/api/load_balancers_interface.rb +72 -0
  13. data/lib/morpheus/api/logs_interface.rb +37 -0
  14. data/lib/morpheus/api/options_interface.rb +20 -0
  15. data/lib/morpheus/api/provision_types_interface.rb +27 -0
  16. data/lib/morpheus/api/roles_interface.rb +73 -0
  17. data/lib/morpheus/api/security_group_rules_interface.rb +3 -3
  18. data/lib/morpheus/api/security_groups_interface.rb +5 -5
  19. data/lib/morpheus/api/servers_interface.rb +67 -3
  20. data/lib/morpheus/api/task_sets_interface.rb +46 -0
  21. data/lib/morpheus/api/tasks_interface.rb +72 -0
  22. data/lib/morpheus/api/users_interface.rb +72 -0
  23. data/lib/morpheus/cli.rb +27 -4
  24. data/lib/morpheus/cli/accounts.rb +306 -0
  25. data/lib/morpheus/cli/apps.rb +58 -1
  26. data/lib/morpheus/cli/cli_command.rb +87 -0
  27. data/lib/morpheus/cli/cli_registry.rb +6 -1
  28. data/lib/morpheus/cli/{zones.rb → clouds.rb} +99 -70
  29. data/lib/morpheus/cli/credentials.rb +23 -11
  30. data/lib/morpheus/cli/error_handler.rb +31 -11
  31. data/lib/morpheus/cli/groups.rb +1 -0
  32. data/lib/morpheus/cli/hosts.rb +567 -0
  33. data/lib/morpheus/cli/instances.rb +588 -292
  34. data/lib/morpheus/cli/key_pairs.rb +393 -0
  35. data/lib/morpheus/cli/license.rb +118 -0
  36. data/lib/morpheus/cli/load_balancers.rb +366 -0
  37. data/lib/morpheus/cli/mixins/accounts_helper.rb +193 -0
  38. data/lib/morpheus/cli/option_types.rb +260 -0
  39. data/lib/morpheus/cli/roles.rb +164 -0
  40. data/lib/morpheus/cli/security_group_rules.rb +4 -9
  41. data/lib/morpheus/cli/shell.rb +108 -0
  42. data/lib/morpheus/cli/tasks.rb +370 -0
  43. data/lib/morpheus/cli/users.rb +325 -0
  44. data/lib/morpheus/cli/version.rb +1 -1
  45. data/lib/morpheus/cli/workflows.rb +100 -0
  46. data/lib/morpheus/formatters.rb +43 -0
  47. data/morpheus-cli.gemspec +1 -1
  48. metadata +33 -10
  49. data/lib/morpheus/cli/servers.rb +0 -265
@@ -0,0 +1,325 @@
1
+ # require 'yaml'
2
+ require 'io/console'
3
+ require 'rest_client'
4
+ require 'term/ansicolor'
5
+ require 'optparse'
6
+ require 'morpheus/cli/cli_command'
7
+ require 'morpheus/cli/option_types'
8
+ require 'morpheus/cli/mixins/accounts_helper'
9
+ require 'json'
10
+
11
+ class Morpheus::Cli::Users
12
+ include Term::ANSIColor
13
+ include Morpheus::Cli::CliCommand
14
+ include Morpheus::Cli::AccountsHelper
15
+
16
+ def initialize()
17
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
18
+ #@active_groups = ::Morpheus::Cli::Groups.load_group_file
19
+ end
20
+
21
+ def connect(opts)
22
+ @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials()
23
+ if @access_token.empty?
24
+ print red,bold, "\nInvalid Credentials. Unable to acquire access token. Please verify your credentials and try again.\n\n",reset
25
+ exit 1
26
+ end
27
+ @api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
28
+ @users_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).users
29
+ @accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
30
+ @roles_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).roles
31
+ end
32
+
33
+ def handle(args)
34
+ usage = "Usage: morpheus users [list,details,add,update,remove] [username]"
35
+ if args.empty?
36
+ puts "\n#{usage}\n\n"
37
+ return
38
+ end
39
+
40
+ case args[0]
41
+ when 'list'
42
+ list(args[1..-1])
43
+ when 'details'
44
+ details(args[1..-1])
45
+ when 'add'
46
+ add(args[1..-1])
47
+ when 'update'
48
+ update(args[1..-1])
49
+ when 'remove'
50
+ remove(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
+ params = {}
61
+ account = nil
62
+ optparse = OptionParser.new do|opts|
63
+ opts.banner = usage
64
+ Morpheus::Cli::CliCommand.accountScopeOptions(opts,options)
65
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
66
+ end
67
+ optparse.parse(args)
68
+ connect(options)
69
+ begin
70
+
71
+ account = find_account_from_options(options)
72
+ account_id = account ? account['id'] : nil
73
+
74
+ [:phrase, :offset, :max, :sort, :direction].each do |k|
75
+ params[k] = options[k] unless options[k].nil?
76
+ end
77
+
78
+ json_response = @users_interface.list(account_id, params)
79
+ users = json_response['users']
80
+
81
+ if options[:json]
82
+ print JSON.pretty_generate(json_response)
83
+ print "\n"
84
+ else
85
+ print "\n" ,cyan, bold, "Morpheus Users\n","==================", reset, "\n\n"
86
+ if users.empty?
87
+ puts yellow,"No users found.",reset
88
+ else
89
+ print_users_table(users)
90
+ end
91
+ print reset,"\n\n"
92
+ end
93
+ rescue RestClient::Exception => e
94
+ ::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
95
+ exit 1
96
+ end
97
+ end
98
+
99
+ def details(args)
100
+ usage = "Usage: morpheus users details [username] [options]"
101
+ if args.count < 1
102
+ puts "\n#{usage}\n\n"
103
+ exit 1
104
+ end
105
+ account = nil
106
+ username = args[0]
107
+ options = {}
108
+ params = {}
109
+ optparse = OptionParser.new do|opts|
110
+ opts.banner = usage
111
+ Morpheus::Cli::CliCommand.accountScopeOptions(opts,options)
112
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
113
+ end
114
+ optparse.parse(args)
115
+ connect(options)
116
+ begin
117
+
118
+ account = find_account_from_options(options)
119
+ account_id = account ? account['id'] : nil
120
+
121
+ # todo: users_response = @users_interface.list(account_id, {name: name})
122
+ # there may be response data outside of user that needs to be displayed
123
+ user = find_user_by_username(account_id, username)
124
+ exit 1 if user.nil?
125
+
126
+ if options[:json]
127
+ print JSON.pretty_generate(user)
128
+ print "\n"
129
+ else
130
+ print "\n" ,cyan, bold, "User Details\n","==================", reset, "\n\n"
131
+ print cyan
132
+ puts "ID: #{user['id']}"
133
+ puts "Account: #{user['account'] ? user['account']['name'] : nil}"
134
+ puts "First Name: #{user['firstName']}"
135
+ puts "Last Name: #{user['firstName']}"
136
+ puts "Username: #{user['username']}"
137
+ puts "Role: #{user['role'] ? user['role']['authority'] : nil}"
138
+ puts "Date Created: #{format_local_dt(user['dateCreated'])}"
139
+ puts "Last Updated: #{format_local_dt(user['lastUpdated'])}"
140
+ print "\n" ,cyan, bold, "User Instance Limits\n","==================", reset, "\n\n"
141
+ print cyan
142
+ puts "Max Storage (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxStorage'] : 0}"
143
+ puts "Max Memory (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxMemory'] : 0}"
144
+ puts "CPU Count: #{user['instanceLimits'] ? user['instanceLimits']['maxCpu'] : 0}"
145
+ print cyan
146
+ print reset,"\n\n"
147
+ end
148
+ rescue RestClient::Exception => e
149
+ ::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
150
+ exit 1
151
+ end
152
+ end
153
+
154
+ def add(args)
155
+ usage = "Usage: morpheus users add [options]"
156
+ # if args.count > 0
157
+ # puts "\#{usage}\n\n"
158
+ # exit 1
159
+ # end
160
+ options = {}
161
+ #options['username'] = args[0] if args[0]
162
+ account = nil
163
+ optparse = OptionParser.new do|opts|
164
+ opts.banner = usage
165
+ Morpheus::Cli::CliCommand.accountScopeOptions(opts,options)
166
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
167
+ end
168
+ optparse.parse(args)
169
+
170
+ connect(options)
171
+
172
+ begin
173
+
174
+ account = find_account_from_options(options)
175
+ account_id = account ? account['id'] : nil
176
+
177
+ #params = Morpheus::Cli::OptionTypes.prompt(add_user_option_types, options)
178
+ params = Morpheus::Cli::OptionTypes.prompt(add_user_option_types, options[:options], @api_client, options[:params]) # options[:params] is mysterious
179
+
180
+ #puts "parsed params is : #{params.inspect}"
181
+ user_keys = ['username', 'firstName', 'lastName', 'email', 'password', 'passwordConfirmation', 'instanceLimits']
182
+ user_payload = params.select {|k,v| user_keys.include?(k) }
183
+ if params['role'].to_s != ''
184
+ role = find_role_by_name(account_id, params['role'])
185
+ exit 1 if role.nil?
186
+ user_payload['role'] = {id: role['id']}
187
+ end
188
+ request_payload = {user: user_payload}
189
+ response = @users_interface.create(account_id, request_payload)
190
+
191
+ if account
192
+ print_green_success "Added user #{user_payload['username']} to account #{account['name']}"
193
+ else
194
+ print_green_success "Added user #{user_payload['username']}"
195
+ end
196
+
197
+ details_options = [user_payload["username"]]
198
+ if account
199
+ details_options.push "--account-id", account['id'].to_s
200
+ end
201
+ details(details_options)
202
+
203
+ rescue RestClient::Exception => e
204
+ ::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
205
+ exit 1
206
+ end
207
+ end
208
+
209
+ def update(args)
210
+ usage = "Usage: morpheus users update [username] [options]"
211
+ if args.count < 1
212
+ puts "\n#{usage}\n\n"
213
+ exit 1
214
+ end
215
+ account = nil
216
+ username = args[0]
217
+ options = {}
218
+ #options['username'] = args[0] if args[0]
219
+ optparse = OptionParser.new do|opts|
220
+ opts.banner = usage
221
+ Morpheus::Cli::CliCommand.accountScopeOptions(opts,options)
222
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
223
+ end
224
+ optparse.parse(args)
225
+
226
+ connect(options)
227
+
228
+ begin
229
+
230
+ account = find_account_from_options(options)
231
+ account_id = account ? account['id'] : nil
232
+
233
+ user = find_user_by_username(account_id, username)
234
+ exit 1 if user.nil?
235
+
236
+ #params = Morpheus::Cli::OptionTypes.prompt(add_user_option_types, options[:options], @api_client, options[:params]) # options[:params] is mysterious
237
+ params = options[:options] || {}
238
+
239
+ if params.empty?
240
+ puts "\n#{usage}\n"
241
+ option_lines = update_user_option_types.collect {|it| "\t-O #{it['fieldName']}=\"value\"" }.join("\n")
242
+ puts "\nAvailable Options:\n#{option_lines}\n\n"
243
+ exit 1
244
+ end
245
+
246
+ #puts "parsed params is : #{params.inspect}"
247
+ user_keys = ['username', 'firstName', 'lastName', 'email', 'password', 'instanceLimits']
248
+ user_payload = params.select {|k,v| user_keys.include?(k) }
249
+ if params['role'].to_s != ''
250
+ role = find_role_by_name(account_id, params['role'])
251
+ exit 1 if role.nil?
252
+ user_payload['role'] = {id: role['id']}
253
+ end
254
+ request_payload = {user: user_payload}
255
+ response = @users_interface.update(account_id, user['id'], request_payload)
256
+
257
+ print_green_success "Updated user #{user_payload['username']}"
258
+
259
+ details_options = [user_payload["username"] || user['username']]
260
+ if account
261
+ details_options.push "--account-id", account['id'].to_s
262
+ end
263
+ details(details_options)
264
+
265
+ rescue RestClient::Exception => e
266
+ ::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
267
+ exit 1
268
+ end
269
+ end
270
+
271
+ def remove(args)
272
+ usage = "Usage: morpheus users remove [username]"
273
+ if args.count < 1
274
+ puts "\n#{usage}\n"
275
+ exit 1
276
+ end
277
+ account = nil
278
+ username = args[0]
279
+ options = {}
280
+ optparse = OptionParser.new do|opts|
281
+ opts.banner = usage
282
+ Morpheus::Cli::CliCommand.accountScopeOptions(opts,options)
283
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
284
+ end
285
+ optparse.parse(args)
286
+ connect(options)
287
+ begin
288
+
289
+ account = find_account_from_options(options)
290
+ account_id = account ? account['id'] : nil
291
+
292
+ user = find_user_by_username(account_id, username)
293
+ exit 1 if user.nil?
294
+ exit unless Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the user #{user['username']}?")
295
+ @users_interface.destroy(account_id, user['id'])
296
+ # list([])
297
+ print "\n", cyan, "User #{username} removed", reset, "\n\n"
298
+ rescue RestClient::Exception => e
299
+ ::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
300
+ exit 1
301
+ end
302
+ end
303
+
304
+ private
305
+
306
+ def add_user_option_types
307
+ [
308
+ {'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
309
+ {'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => true, 'displayOrder' => 2},
310
+ {'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => true, 'displayOrder' => 3},
311
+ {'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'displayOrder' => 4},
312
+ {'fieldName' => 'role', 'fieldLabel' => 'Role', 'type' => 'text', 'displayOrder' => 5},
313
+ {'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'displayOrder' => 6},
314
+ {'fieldName' => 'passwordConfirmation', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'displayOrder' => 7},
315
+ {'fieldName' => 'instanceLimits.maxStorage', 'fieldLabel' => 'Max Storage (bytes)', 'type' => 'text', 'displayOrder' => 8},
316
+ {'fieldName' => 'instanceLimits.maxMemory', 'fieldLabel' => 'Max Memory (bytes)', 'type' => 'text', 'displayOrder' => 9},
317
+ {'fieldName' => 'instanceLimits.maxCpu', 'fieldLabel' => 'CPU Count', 'type' => 'text', 'displayOrder' => 10},
318
+ ]
319
+ end
320
+
321
+ def update_user_option_types
322
+ add_user_option_types.reject {|it| ['passwordConfirmation'].include?(it['fieldName']) }
323
+ end
324
+
325
+ end
@@ -1,5 +1,5 @@
1
1
  module Morpheus
2
2
  module Cli
3
- VERSION = "0.1.1"
3
+ VERSION = "0.9.0"
4
4
  end
5
5
  end
@@ -0,0 +1,100 @@
1
+ # require 'yaml'
2
+ require 'io/console'
3
+ require 'rest_client'
4
+ require 'term/ansicolor'
5
+ require 'optparse'
6
+ require 'table_print'
7
+ require 'morpheus/cli/cli_command'
8
+
9
+ class Morpheus::Cli::Workflows
10
+ include Morpheus::Cli::CliCommand
11
+ include Term::ANSIColor
12
+ def initialize()
13
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
14
+ end
15
+
16
+ def connect(opts)
17
+ if opts[:remote]
18
+ @appliance_url = opts[:remote]
19
+ @appliance_name = opts[:remote]
20
+ @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials(opts)
21
+ else
22
+ @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials(opts)
23
+ end
24
+ @api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
25
+ @tasks_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).tasks
26
+ @task_sets_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).task_sets
27
+ if @access_token.empty?
28
+ print red,bold, "\nInvalid Credentials. Unable to acquire access token. Please verify your credentials and try again.\n\n",reset
29
+ exit 1
30
+ end
31
+ end
32
+
33
+
34
+ def handle(args)
35
+ if args.empty?
36
+ puts "\nUsage: morpheus workflows [list,add,remove]\n\n"
37
+ return
38
+ end
39
+
40
+ case args[0]
41
+ when 'list'
42
+ list(args[1..-1])
43
+ when 'add'
44
+ add(args[1..-1])
45
+ when 'remove'
46
+ remove(args[1..-1])
47
+ else
48
+ puts "\nUsage: morpheus workflows [list,add,remove]\n\n"
49
+ exit 127
50
+ end
51
+ end
52
+
53
+ def list(args)
54
+ options = {}
55
+ optparse = OptionParser.new do|opts|
56
+ opts.banner = "Usage: morpheus workflows list [-s] [-o] [-m]"
57
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
58
+ end
59
+ optparse.parse(args)
60
+ connect(options)
61
+ begin
62
+ params = {}
63
+ if options[:offset]
64
+ params[:offset] = options[:offset]
65
+ end
66
+ if options[:max]
67
+ params[:max] = options[:max]
68
+ end
69
+ if options[:phrase]
70
+ params[:phrase] = options[:phrase]
71
+ end
72
+ json_response = @task_sets_interface.get(params)
73
+ if options[:json]
74
+ print JSON.pretty_generate(json_response)
75
+ else
76
+ task_sets = json_response['taskSets']
77
+ print "\n" ,cyan, bold, "Morpheus Workflows\n","==================", reset, "\n\n"
78
+ if task_sets.empty?
79
+ puts yellow,"No workflows currently configured.",reset
80
+ else
81
+ print cyan
82
+ tasks_table_data = task_sets.collect do |task_set|
83
+ {name: task_set['name'], id: task_set['id']}
84
+ end
85
+ tp tasks_table_data, :id, :name
86
+ end
87
+ print reset,"\n\n"
88
+ end
89
+ rescue RestClient::Exception => e
90
+ ::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
91
+ exit 1
92
+ end
93
+ end
94
+
95
+ def add(args)
96
+ end
97
+
98
+ def remove(args)
99
+ end
100
+ end
@@ -0,0 +1,43 @@
1
+ require 'time'
2
+
3
+ # returns an instance of Time
4
+ def parse_time(dt)
5
+ if dt.nil? || dt == '' || dt.to_i == 0
6
+ return nil
7
+ elsif dt.is_a?(Time)
8
+ return dt
9
+ elsif dt.is_a?(String)
10
+ return Time.parse(dt)
11
+ elsif dt.is_a?(Numeric)
12
+ return Time.at(dt)
13
+ else
14
+ raise "bad argument type for parse_time() #{dt.class} #{dt.inspect}"
15
+ end
16
+ end
17
+
18
+ def format_dt(dt, options={})
19
+ dt = parse_time(dt)
20
+ if options[:local]
21
+ dt = dt.getlocal
22
+ end
23
+ format = options[:format] || "%x %I:%M %p %Z"
24
+ return dt.strftime(format)
25
+ end
26
+
27
+ def format_local_dt(dt, options={})
28
+ format_dt(dt, {local: true}.merge(options))
29
+ end
30
+
31
+ def format_date(dt, options={})
32
+ format_dt(dt, options.merge({local: true}))
33
+ end
34
+
35
+ def format_local_date(dt, options={})
36
+ format_dt(dt, {local: true, format: "%x"}.merge(options))
37
+ end
38
+
39
+ # returns
40
+ def format_dt_as_param(dt)
41
+ dt = dt.getutc
42
+ format_dt(dt, {format: "%Y-%m-%d %X"})
43
+ end