morpheus-cli 0.1.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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,260 @@
1
+ require 'term/ansicolor'
2
+
3
+ module Morpheus
4
+ module Cli
5
+ module OptionTypes
6
+ include Term::ANSIColor
7
+
8
+
9
+ def self.confirm(message,options={})
10
+ if options[:yes] == true
11
+ return true
12
+ end
13
+ value_found = false
14
+ while value_found == false do
15
+ print "#{message} (yes/no): "
16
+ input = $stdin.gets.chomp!
17
+ if input.downcase == 'yes'
18
+ return true
19
+ elsif input.downcase == 'no'
20
+ return false
21
+ else
22
+ puts "Invalid Option... Please try again."
23
+ end
24
+ end
25
+ end
26
+
27
+ def self.prompt(option_types, options={}, api_client=nil,api_params={})
28
+ results = {}
29
+ options = options || {}
30
+ # puts "Options Prompt #{options}"
31
+ option_types.sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i }.each do |option_type|
32
+ context_map = results
33
+ value = nil
34
+ value_found=false
35
+ if option_type['fieldContext']
36
+ results[option_type['fieldContext']] ||= {}
37
+ context_map = results[option_type['fieldContext']]
38
+ if options[option_type['fieldContext']] and options[option_type['fieldContext']].key?(option_type['fieldLabel'])
39
+ value = options[option_type['fieldContext']][option_type['fieldLabel']]
40
+ value_found = true
41
+ end
42
+ end
43
+
44
+ if value_found == false && options.key?(option_type['fieldName'])
45
+ value = options[option_type['fieldName']]
46
+ value_found = true
47
+ end
48
+
49
+ if !value_found
50
+ if option_type['type'] == 'number'
51
+ value = number_prompt(option_type)
52
+ elsif option_type['type'] == 'password'
53
+ value = password_prompt(option_type)
54
+ elsif option_type['type'] == 'checkbox'
55
+ value = checkbox_prompt(option_type)
56
+ elsif option_type['type'] == 'radio'
57
+ value = radio_prompt(option_type)
58
+ elsif option_type['type'] == 'textarea'
59
+ value = multiline_prompt(option_type)
60
+ elsif option_type['type'] == 'code-editor'
61
+ value = multiline_prompt(option_type)
62
+ elsif option_type['type'] == 'select'
63
+ value = select_prompt(option_type,api_client, api_params)
64
+ elsif option_type['type'] == 'hidden'
65
+ value = option_type['defaultValue']
66
+ input = value
67
+ else
68
+ value = generic_prompt(option_type)
69
+ end
70
+
71
+ end
72
+ context_map[option_type['fieldName']] = value
73
+ end
74
+
75
+ return results
76
+ end
77
+
78
+
79
+ def self.radio_prompt(option_type)
80
+ value_found = false
81
+ value = nil
82
+ options = []
83
+ if option_type['config'] and option_type['config']['radioOptions']
84
+ option_type['config']['radioOptions'].each do |radio_option|
85
+ options << {key: radio_option['key'], checked: radio_option['checked']}
86
+ end
87
+ end
88
+ optionString = options.collect{ |b| b[:checked] ? "(#{b[:key]})" : b[:key]}.join(', ')
89
+ while !value_found do
90
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }[#{optionString}]: "
91
+ input = $stdin.gets.chomp!
92
+ if input == '?'
93
+ help_prompt(option_type)
94
+ else
95
+ if input.nil? || input.empty?
96
+ selectedOption = options.find{|o| o[:checked] == true}
97
+ else
98
+ selectedOption = options.find{|o| o[:key].downcase == input.downcase}
99
+ end
100
+
101
+ if selectedOption
102
+ value = selectedOption[:key]
103
+ else
104
+ puts "Invalid Option. Please select from #{optionString}."
105
+ end
106
+ if !value.nil? || option_type['required'] != true
107
+ value_found = true
108
+ end
109
+ end
110
+ end
111
+ return value
112
+ end
113
+
114
+ def self.number_prompt(option_type)
115
+ value_found = false
116
+ value = nil
117
+ while !value_found do
118
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}: "
119
+ input = $stdin.gets.chomp!
120
+ value = input.empty? ? option_type['defaultValue'] : input.to_i
121
+ if input == '?'
122
+ help_prompt(option_type)
123
+ elsif !value.nil? || option_type['required'] != true
124
+ value_found = true
125
+ end
126
+ end
127
+ return value
128
+ end
129
+
130
+ def self.select_prompt(option_type,api_client, api_params={})
131
+ value_found = false
132
+ value = nil
133
+ if option_type['optionSource']
134
+ source_options = load_source_options(option_type['optionSource'],api_client,api_params)
135
+ end
136
+ if !source_options['data'].nil? && !source_options['data'].count == 1 && option_type['skipSingleOption'] == true
137
+ value_found = true
138
+ value = source_option['value']
139
+ end
140
+ while !value_found do
141
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''} ['?' for options]: "
142
+ input = $stdin.gets.chomp!
143
+ if option_type['optionSource']
144
+ source_option = source_options.find{|b| b['name'] == input || (!b['value'].nil? && b['value'].to_s == input) || (b['value'].nil? && input.empty?)}
145
+ if source_option
146
+ value = source_option['value']
147
+ elsif !input.nil? && !input.empty?
148
+ input = '?'
149
+ end
150
+ else
151
+ value = input.empty? ? option_type['defaultValue'] : input
152
+ end
153
+
154
+ if input == '?'
155
+ help_prompt(option_type)
156
+ display_select_options(source_options)
157
+ elsif !value.nil? || option_type['required'] != true
158
+ value_found = true
159
+ end
160
+ end
161
+ return value
162
+ end
163
+
164
+ def self.checkbox_prompt(option_type)
165
+ value_found = false
166
+ value = nil
167
+ while !value_found do
168
+ print "#{option_type['fieldLabel']} (yes/no) [#{option_type['defaultValue'] == 'on' ? 'yes' : 'no'}]: "
169
+ input = $stdin.gets.chomp!
170
+ if input.downcase == 'yes'
171
+ value = 'on'
172
+ elsif input.downcase == 'no'
173
+ value = 'off'
174
+ else
175
+ value = option_type['defaultValue']
176
+ end
177
+ if input == '?'
178
+ help_prompt(option_type)
179
+ elsif !value.nil? || option_type['required'] != true
180
+ value_found = true
181
+ end
182
+ end
183
+ return value
184
+ end
185
+
186
+ def self.generic_prompt(option_type)
187
+ value_found = false
188
+ value = nil
189
+ while !value_found do
190
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}: "
191
+ input = $stdin.gets.chomp!
192
+ value = input.empty? ? option_type['defaultValue'] : input
193
+ if input == '?'
194
+ help_prompt(option_type)
195
+ elsif !value.nil? || option_type['required'] != true
196
+ value_found = true
197
+ end
198
+ end
199
+ return value
200
+ end
201
+
202
+ def self.multiline_prompt(option_type)
203
+ value_found = false
204
+ value = nil
205
+ while !value_found do
206
+ if value.nil?
207
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''} [Type 'EOF' to stop input]: \n"
208
+ end
209
+ input = $stdin.gets.chomp!
210
+ # value = input.empty? ? option_type['defaultValue'] : input
211
+ if input == '?' && value.nil?
212
+ help_prompt(option_type)
213
+ elsif (!value.nil? || option_type['required'] != true) && input.chomp == 'EOF'
214
+ value_found = true
215
+ else
216
+ if value.nil?
217
+ value = ''
218
+ end
219
+ value << input + "\n"
220
+ end
221
+ end
222
+ return value
223
+ end
224
+
225
+ def self.password_prompt(option_type)
226
+ value_found = false
227
+ while !value_found do
228
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}: "
229
+ input = STDIN.noecho(&:gets).chomp!
230
+ value = input
231
+ print "\n"
232
+ if input == '?'
233
+ help_prompt(option_type)
234
+ elsif !value.nil? || option_type['required'] != true
235
+ value_found = true
236
+ end
237
+ end
238
+ return value
239
+ end
240
+
241
+ def self.help_prompt(option_type)
242
+ print Term::ANSIColor.green," * #{option_type['fieldLabel']} [-O #{option_type['fieldName']}=] - ", Term::ANSIColor.reset , "#{option_type['description']}\n"
243
+ end
244
+
245
+
246
+ def self.load_source_options(source,api_client,params)
247
+ api_client.options.options_for_source(source,params)['data']
248
+ end
249
+
250
+ def self.display_select_options(select_options = [])
251
+ puts "\nOptions"
252
+ puts "==============="
253
+ select_options.each do |option|
254
+ puts " * #{option['name']} [#{option['value']}]"
255
+ end
256
+ puts "\n\n"
257
+ end
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,164 @@
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::Roles
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
+ if args.empty?
35
+ puts "\nUsage: morpheus roles [list]\n\n"
36
+ exit 1
37
+ end
38
+
39
+ case args[0]
40
+ when 'list'
41
+ list(args[1..-1])
42
+ when 'details'
43
+ details(args[1..-1])
44
+ when 'add'
45
+ add(args[1..-1])
46
+ when 'remove'
47
+ remove(args[1..-1])
48
+ else
49
+ puts "\nUsage: morpheus hosts [list] \n\n"
50
+ exit 127
51
+ end
52
+ end
53
+
54
+ def list(args)
55
+ account_name = nil
56
+ options = {}
57
+ params = {}
58
+ optparse = OptionParser.new do|opts|
59
+ Morpheus::Cli::CliCommand.accountScopeOptions(opts,options)
60
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
61
+ end
62
+ optparse.parse(args)
63
+ connect(options)
64
+ begin
65
+ account_id = nil
66
+ if !account_name.nil?
67
+ account = find_account_by_name(account_name)
68
+ exit 1 if account.nil?
69
+ account_id = account['id']
70
+ end
71
+
72
+ [:phrase, :offset, :max, :sort, :direction].each do |k|
73
+ params[k] = options[k] unless options[k].nil?
74
+ end
75
+
76
+ json_response = @roles_interface.list(account_id, params)
77
+ roles = json_response['roles']
78
+
79
+ if options[:json]
80
+ print JSON.pretty_generate(json_response)
81
+ print "\n"
82
+ else
83
+ print "\n" ,cyan, bold, "Morpheus Roles\n","==================", reset, "\n\n"
84
+ if roles.empty?
85
+ puts yellow,"No roles found.",reset
86
+ else
87
+ print_roles_table(roles)
88
+ end
89
+ print reset,"\n\n"
90
+ end
91
+ rescue RestClient::Exception => e
92
+ ::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
93
+ exit 1
94
+ end
95
+ end
96
+
97
+ def details(args)
98
+ usage = "Usage: morpheus roles details [name] [options]"
99
+ if args.count < 1
100
+ puts "\n#{usage}\n\n"
101
+ exit 1
102
+ end
103
+ account = nil
104
+ name = args[0]
105
+ options = {}
106
+ params = {}
107
+ optparse = OptionParser.new do|opts|
108
+ opts.banner = usage
109
+ Morpheus::Cli::CliCommand.accountScopeOptions(opts,options)
110
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
111
+ end
112
+ optparse.parse(args)
113
+ connect(options)
114
+ begin
115
+
116
+ account = find_account_from_options(options)
117
+ account_id = account ? account['id'] : nil
118
+
119
+ # todo: roles_response = @roles_interface.list(account_id, {name: name}) instead
120
+ # there may be response data outside of role that needs to be displayed
121
+ role = find_role_by_name(account_id, name)
122
+ exit 1 if role.nil?
123
+
124
+ if options[:json]
125
+ print JSON.pretty_generate(role)
126
+ print "\n"
127
+ else
128
+ print "\n" ,cyan, bold, "Role Details\n","==================", reset, "\n\n"
129
+ print cyan
130
+ puts "ID: #{role['id']}"
131
+ puts "Name: #{role['authority']}"
132
+ puts "Description: #{role['description']}"
133
+ puts "Scope: #{role['scope']}"
134
+ puts "Owner: #{role['owner'] ? role['owner']['name'] : nil}"
135
+ puts "Date Created: #{format_local_dt(role['dateCreated'])}"
136
+ puts "Last Updated: #{format_local_dt(role['lastUpdated'])}"
137
+ print "\n" ,cyan, bold, "Role Instance Limits\n","==================", reset, "\n\n"
138
+ print cyan
139
+ puts "Max Storage (bytes): #{role['instanceLimits'] ? role['instanceLimits']['maxStorage'] : 0}"
140
+ puts "Max Memory (bytes): #{role['instanceLimits'] ? role['instanceLimits']['maxMemory'] : 0}"
141
+ puts "CPU Count: #{role['instanceLimits'] ? role['instanceLimits']['maxCpu'] : 0}"
142
+ print cyan
143
+ print reset,"\n\n"
144
+ end
145
+ rescue RestClient::Exception => e
146
+ ::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
147
+ exit 1
148
+ end
149
+ end
150
+
151
+ def add(args)
152
+ print red,bold, "\nNOT YET IMPLEMENTED!\n\n",reset
153
+ exit 1
154
+ end
155
+
156
+ def remove(args)
157
+ print red,bold, "\nNOT YET IMPLEMENTED!\n\n",reset
158
+ exit 1
159
+ end
160
+
161
+ private
162
+
163
+
164
+ end
@@ -58,7 +58,7 @@ EOT
58
58
  security_group_id = nil
59
59
  optparse = OptionParser.new do|opts|
60
60
  opts.banner = "\nUsage: morpheus security-group-rules add_custom_rule SOURCE_CIDR PORT_RANGE PROTOCOL [options]"
61
- opts.on( '-s', '--secgroup secgroup', "Security Group ID (Use will use security as set with 'security-groups use id'" ) do |id|
61
+ opts.on( '-s', '--secgroup SECGROUP', "Security Group ID (Use will use security as set with 'security-groups use id'" ) do |id|
62
62
  security_group_id = id
63
63
  end
64
64
  opts.on( '-h', '--help', "Prints this help" ) do
@@ -158,15 +158,10 @@ EOT
158
158
  options = {}
159
159
  security_group_id = nil
160
160
  optparse = OptionParser.new do|opts|
161
- opts.banner = "\nUsage: morpheus security-group-rules list [options]"
162
- opts.on( '-s', '--secgroup secgroup', "Security Group ID (Use will use security as set with 'security-groups use id'" ) do |id|
163
- security_group_id = id
164
- end
165
- opts.on( '-h', '--help', "Prints this help" ) do
166
- puts opts
167
- exit
168
- end
161
+ opts.banner = "\nUsage: morpheus security-group-rules list [ID]"
162
+ Morpheus::Cli::CliCommand.genericOptions(opts,options)
169
163
  end
164
+ security_group_id = args[0].to_i
170
165
  optparse.parse(args)
171
166
 
172
167
  if security_group_id.nil?