morpheus-cli 5.3.1.1 → 5.3.2.3

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/accounts_interface.rb +4 -30
  4. data/lib/morpheus/api/api_client.rb +12 -0
  5. data/lib/morpheus/api/load_balancer_pools_interface.rb +9 -0
  6. data/lib/morpheus/api/load_balancer_types_interface.rb +9 -0
  7. data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +9 -0
  8. data/lib/morpheus/api/load_balancers_interface.rb +4 -53
  9. data/lib/morpheus/api/network_routers_interface.rb +56 -0
  10. data/lib/morpheus/api/option_type_lists_interface.rb +19 -7
  11. data/lib/morpheus/api/secondary_read_interface.rb +25 -0
  12. data/lib/morpheus/api/secondary_rest_interface.rb +42 -0
  13. data/lib/morpheus/cli/cli_command.rb +9 -9
  14. data/lib/morpheus/cli/instances.rb +39 -37
  15. data/lib/morpheus/cli/library_cluster_layouts_command.rb +2 -3
  16. data/lib/morpheus/cli/library_container_scripts_command.rb +3 -4
  17. data/lib/morpheus/cli/library_container_templates_command.rb +4 -0
  18. data/lib/morpheus/cli/library_container_types_command.rb +2 -3
  19. data/lib/morpheus/cli/library_instance_types_command.rb +2 -3
  20. data/lib/morpheus/cli/library_layouts_command.rb +4 -0
  21. data/lib/morpheus/cli/library_option_lists_command.rb +68 -16
  22. data/lib/morpheus/cli/library_option_types_command.rb +4 -0
  23. data/lib/morpheus/cli/library_spec_templates_command.rb +3 -4
  24. data/lib/morpheus/cli/load_balancer_types.rb +37 -0
  25. data/lib/morpheus/cli/load_balancers.rb +149 -314
  26. data/lib/morpheus/cli/log_settings_command.rb +7 -3
  27. data/lib/morpheus/cli/mixins/load_balancers_helper.rb +156 -0
  28. data/lib/morpheus/cli/mixins/print_helper.rb +11 -0
  29. data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -7
  30. data/lib/morpheus/cli/mixins/rest_command.rb +657 -0
  31. data/lib/morpheus/cli/network_routers_command.rb +1183 -185
  32. data/lib/morpheus/cli/networks_command.rb +194 -101
  33. data/lib/morpheus/cli/option_types.rb +29 -39
  34. data/lib/morpheus/cli/tenants_command.rb +18 -20
  35. data/lib/morpheus/cli/version.rb +1 -1
  36. data/lib/morpheus/cli.rb +1 -0
  37. data/lib/morpheus/ext/string.rb +41 -0
  38. data/lib/morpheus/formatters.rb +4 -0
  39. metadata +11 -2
@@ -41,10 +41,9 @@ class Morpheus::Cli::LibraryClusterLayoutsCommand
41
41
  opts.footer = "List cluster layouts."
42
42
  end
43
43
  optparse.parse!(args)
44
+ # verify_args!(args:args, optparse:optparse, count:0)
44
45
  if args.count > 0
45
- print_error Morpheus::Terminal.angry_prompt
46
- puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
47
- return 1
46
+ options[:phrase] = args.join(" ")
48
47
  end
49
48
  connect(options)
50
49
  begin
@@ -25,12 +25,11 @@ class Morpheus::Cli::LibraryContainerScriptsCommand
25
25
  opts.footer = "List container scripts."
26
26
  end
27
27
  optparse.parse!(args)
28
- connect(options)
28
+ # verify_args!(args:args, optparse:optparse, count:0)
29
29
  if args.count > 0
30
- print_error Morpheus::Terminal.angry_prompt
31
- puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(', ')}\n#{optparse}"
32
- return 1
30
+ options[:phrase] = args.join(" ")
33
31
  end
32
+ connect(options)
34
33
  begin
35
34
  # construct payload
36
35
  params.merge!(parse_list_options(options))
@@ -26,6 +26,10 @@ class Morpheus::Cli::LibraryContainerTemplatesCommand
26
26
  build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote])
27
27
  end
28
28
  optparse.parse!(args)
29
+ # verify_args!(args:args, optparse:optparse, count:0)
30
+ if args.count > 0
31
+ options[:phrase] = args.join(" ")
32
+ end
29
33
  connect(options)
30
34
  begin
31
35
  [:phrase, :offset, :max, :sort, :direction, :lastUpdated].each do |k|
@@ -49,10 +49,9 @@ class Morpheus::Cli::LibraryContainerTypesCommand
49
49
  opts.footer = "List node types."
50
50
  end
51
51
  optparse.parse!(args)
52
+ # verify_args!(args:args, optparse:optparse, count:0)
52
53
  if args.count > 0
53
- print_error Morpheus::Terminal.angry_prompt
54
- puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
55
- return 1
54
+ options[:phrase] = args.join(" ")
56
55
  end
57
56
  connect(options)
58
57
  begin
@@ -47,10 +47,9 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
47
47
  opts.footer = "List instance types."
48
48
  end
49
49
  optparse.parse!(args)
50
+ # verify_args!(args:args, optparse:optparse, count:0)
50
51
  if args.count > 0
51
- print_error Morpheus::Terminal.angry_prompt
52
- puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
53
- return 1
52
+ options[:phrase] = args.join(" ")
54
53
  end
55
54
  connect(options)
56
55
  begin
@@ -59,6 +59,10 @@ class Morpheus::Cli::LibraryLayoutsCommand
59
59
  opts.footer = "List layouts."
60
60
  end
61
61
  optparse.parse!(args)
62
+ # verify_args!(args:args, optparse:optparse, count:0)
63
+ if args.count > 0
64
+ options[:phrase] = args.join(" ")
65
+ end
62
66
  connect(options)
63
67
  begin
64
68
  # construct payload
@@ -9,7 +9,7 @@ class Morpheus::Cli::LibraryOptionListsCommand
9
9
  include Morpheus::Cli::LibraryHelper
10
10
 
11
11
  set_command_name :'library-option-lists'
12
- register_subcommands :list, :get, :add, :update, :remove
12
+ register_subcommands :list, :get, :list_items, :add, :update, :remove
13
13
 
14
14
  def initialize()
15
15
  # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
@@ -35,6 +35,10 @@ class Morpheus::Cli::LibraryOptionListsCommand
35
35
  opts.footer = "List option lists."
36
36
  end
37
37
  optparse.parse!(args)
38
+ # verify_args!(args:args, optparse:optparse, count:0)
39
+ if args.count > 0
40
+ options[:phrase] = args.join(" ")
41
+ end
38
42
  connect(options)
39
43
  begin
40
44
  params = {}
@@ -61,16 +65,14 @@ class Morpheus::Cli::LibraryOptionListsCommand
61
65
  id: option_type_list['id'],
62
66
  name: option_type_list['name'],
63
67
  description: option_type_list['description'],
64
- type: option_type_list['type'],
65
- size: option_type_list['listItems'] ? option_type_list['listItems'].size : ''
68
+ type: ((option_type_list['type'] == 'api') ? "#{option_type_list['type']} (#{option_type_list['apiType']})" : option_type_list['type'])
66
69
  }
67
70
  end
68
71
  columns = [
69
72
  :id,
70
73
  :name,
71
74
  :description,
72
- :type,
73
- :size
75
+ :type
74
76
  ]
75
77
  print cyan
76
78
  print as_pretty_table(rows, columns, options)
@@ -90,8 +92,8 @@ class Morpheus::Cli::LibraryOptionListsCommand
90
92
  optparse = Morpheus::Cli::OptionParser.new do |opts|
91
93
  opts.banner = subcommand_usage("[name]")
92
94
  build_standard_get_options(opts, options)
93
- opts.on(nil,'--no-items', "Do not display List Items") do |val|
94
- options[:no_list_items] = true
95
+ opts.on(nil,'--items', "Load and display option list items") do |val|
96
+ options[:list_items] = true
95
97
  end
96
98
  opts.footer = "Get details about an option list.\n" +
97
99
  "[name] is required. This is the name or id of an option list. Supports 1-N [name] arguments."
@@ -108,20 +110,31 @@ class Morpheus::Cli::LibraryOptionListsCommand
108
110
  end
109
111
 
110
112
  def _get(id, options)
111
-
113
+ params = {}
114
+ params.merge!(parse_query_options(options))
112
115
  begin
113
116
  @option_type_lists_interface.setopts(options)
114
117
  if options[:dry_run]
115
118
  if id.to_s =~ /\A\d{1,}\Z/
116
- print_dry_run @option_type_lists_interface.dry.get(id.to_i)
119
+ print_dry_run @option_type_lists_interface.dry.get(id.to_i, params)
117
120
  else
118
- print_dry_run @option_type_lists_interface.dry.list({name: id})
121
+ print_dry_run @option_type_lists_interface.dry.list(params.merge({name: id}))
119
122
  end
120
123
  return
121
124
  end
122
125
  option_type_list = find_option_type_list_by_name_or_id(id)
123
126
  return 1 if option_type_list.nil?
124
-
127
+ list_items = nil
128
+ if options[:list_items]
129
+ list_items = option_type_list['listItems']
130
+ if list_items.nil?
131
+ begin
132
+ list_items = @option_type_lists_interface.list_items(option_type_list['id'])['listItems']
133
+ rescue => e
134
+ puts_error "Failed to load option list items: #{e.message}"
135
+ end
136
+ end
137
+ end
125
138
  json_response = {'optionTypeList' => option_type_list}
126
139
  render_result = render_with_format(json_response, options, 'optionTypeList')
127
140
  return 0 if render_result
@@ -142,12 +155,14 @@ class Morpheus::Cli::LibraryOptionListsCommand
142
155
  "ID" => 'id',
143
156
  "Name" => 'name',
144
157
  "Description" => 'description',
145
- "Type" => lambda {|it| it['type'].to_s.capitalize },
158
+ "Type" => lambda {|it| it['type'] },
159
+ "API Type" => lambda {|it| it['apiType'] },
146
160
  "Source URL" => 'sourceUrl',
147
161
  "Real Time" => lambda {|it| format_boolean it['realTime'] },
148
162
  "Ignore SSL Errors" => lambda {|it| format_boolean it['ignoreSSLErrors'] },
149
163
  "Source Method" => lambda {|it| it['sourceMethod'].to_s.upcase }
150
164
  }
165
+ option_list_columns.delete("API Type") if option_type_list['type'] != 'api'
151
166
  source_headers = []
152
167
  if option_type_list['config'] && option_type_list['config']['sourceHeaders']
153
168
  source_headers = option_type_list['config']['sourceHeaders'].collect do |header|
@@ -174,12 +189,13 @@ class Morpheus::Cli::LibraryOptionListsCommand
174
189
  print reset,"#{option_type_list['requestScript']}","\n",reset
175
190
  end
176
191
  end
177
- if options[:no_list_items] != true
178
- list_items = option_type_list['listItems']
192
+ if options[:list_items]
193
+ print_h2 "List Items"
179
194
  if list_items && list_items.size > 0
180
- print_h2 "List Items"
181
195
  print as_pretty_table(list_items, [:name, :value], options)
182
196
  print_results_pagination({size: list_items.size, total: list_items.size})
197
+ else
198
+ print cyan,"No list items found.",reset,"\n"
183
199
  end
184
200
  end
185
201
  print reset,"\n"
@@ -189,6 +205,42 @@ class Morpheus::Cli::LibraryOptionListsCommand
189
205
  end
190
206
  end
191
207
 
208
+ def list_items(args)
209
+ params = {}
210
+ options = {}
211
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
212
+ opts.banner = subcommand_usage("[name]")
213
+ build_standard_get_options(opts, options)
214
+ opts.footer = "List items for an option list.\n" +
215
+ "[name] is required. This is the name or id of an option list."
216
+ end
217
+ optparse.parse!(args)
218
+ verify_args!(args:args, optparse:optparse, count:1)
219
+ connect(options)
220
+ option_type_list = find_option_type_list_by_name_or_id(args[0])
221
+ return 1 if option_type_list.nil?
222
+
223
+ params.merge!(parse_list_options(options))
224
+ @option_type_lists_interface.setopts(options)
225
+ if options[:dry_run]
226
+ print_dry_run @option_type_lists_interface.dry.list_items(option_type_list['id'], params)
227
+ return
228
+ end
229
+ json_response = @option_type_lists_interface.list_items(option_type_list['id'], params)
230
+ list_items = json_response['listItems']
231
+ render_response(json_response, options, "listItems") do
232
+ print_h2 "List Items"
233
+ if list_items && list_items.size > 0
234
+ print as_pretty_table(list_items, [:name, :value], options)
235
+ print_results_pagination({size: list_items.size, total: list_items.size})
236
+ else
237
+ print cyan,"No list items found.",reset,"\n"
238
+ end
239
+ print reset,"\n"
240
+ end
241
+ return 0, nil
242
+ end
243
+
192
244
  def add(args)
193
245
  options = {}
194
246
  my_option_types = nil
@@ -373,7 +425,7 @@ class Morpheus::Cli::LibraryOptionListsCommand
373
425
  {'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'realTime', 'fieldLabel' => 'Real Time', 'type' => 'checkbox', 'defaultValue' => false, 'displayOrder' => 7},
374
426
  {'dependsOnCode' => 'optionTypeList.type:rest', 'fieldName' => 'sourceMethod', 'fieldLabel' => 'Source Method', 'type' => 'select', 'selectOptions' => [{'name' => 'GET', 'value' => 'GET'}, {'name' => 'POST', 'value' => 'POST'}], 'defaultValue' => 'GET', 'required' => true, 'displayOrder' => 8},
375
427
  # sourceHeaders component (is done afterwards manually)
376
- {'dependsOnCode' => 'optionTypeList.type:api', 'fieldName' => 'apiType', 'fieldLabel' => 'Option List', 'type' => 'select', 'optionSource' => 'apiOptionLists', 'required' => true, 'description' => 'The code of the api list to use, eg. clouds, servers, etc.', 'displayOrder' => 9},
428
+ {'dependsOnCode' => 'optionTypeList.type:api', 'fieldName' => 'apiType', 'fieldLabel' => 'Option List', 'type' => 'select', 'optionSource' => 'apiOptionLists', 'required' => true, 'description' => 'The code of the api option list to use, eg. clouds, environments, groups, instances, instance-wiki, networks, servicePlans, resourcePools, securityGroups, servers, server-wiki', 'displayOrder' => 9},
377
429
  {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'sourceUsername', 'fieldLabel' => 'Source Username', 'type' => 'text', 'description' => "An LDAP Username for use when type is 'ldap'.", 'displayOrder' => 10},
378
430
  {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'sourcePassword', 'fieldLabel' => 'Source Username', 'type' => 'text', 'description' => "An LDAP Password for use when type is 'ldap'.", 'displayOrder' => 11},
379
431
  {'dependsOnCode' => 'optionTypeList.type:ldap', 'fieldName' => 'ldapQuery', 'fieldLabel' => 'LDAP Query', 'type' => 'text', 'description' => "LDAP Queries are standard LDAP formatted queries where different objects can be searched. Dependent parameters can be loaded into the query using the <%=phrase%> syntax.", 'displayOrder' => 12},
@@ -35,6 +35,10 @@ class Morpheus::Cli::LibraryOptionTypesCommand
35
35
  opts.footer = "List option types."
36
36
  end
37
37
  optparse.parse!(args)
38
+ # verify_args!(args:args, optparse:optparse, count:0)
39
+ if args.count > 0
40
+ options[:phrase] = args.join(" ")
41
+ end
38
42
  connect(options)
39
43
  begin
40
44
  params = {}
@@ -26,12 +26,11 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
26
26
  opts.footer = "List spec templates."
27
27
  end
28
28
  optparse.parse!(args)
29
- connect(options)
29
+ # verify_args!(args:args, optparse:optparse, count:0)
30
30
  if args.count > 0
31
- print_error Morpheus::Terminal.angry_prompt
32
- puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
33
- return 1
31
+ options[:phrase] = args.join(" ")
34
32
  end
33
+ connect(options)
35
34
  begin
36
35
  # construct payload
37
36
  params.merge!(parse_list_options(options))
@@ -0,0 +1,37 @@
1
+ # require 'yaml'
2
+ require 'io/console'
3
+ require 'rest_client'
4
+ require 'optparse'
5
+ require 'morpheus/cli/cli_command'
6
+
7
+ class Morpheus::Cli::LoadBalancerTypes
8
+ include Morpheus::Cli::CliCommand
9
+ include Morpheus::Cli::RestCommand
10
+ include Morpheus::Cli::LoadBalancersHelper
11
+
12
+ set_command_name :'load-balancer-types'
13
+ register_subcommands :list, :get
14
+
15
+ # register_interfaces :load_balancer_types
16
+
17
+ protected
18
+
19
+ def load_balancer_type_column_definitions
20
+ {
21
+ "ID" => 'id',
22
+ "Name" => 'name',
23
+ "Code" => 'code'
24
+ }
25
+ end
26
+
27
+ def load_balancer_type_list_column_definitions
28
+ load_balancer_type_column_definitions
29
+ end
30
+
31
+ # overridden to support name or code
32
+ def find_load_balancer_type_by_name_or_id(name)
33
+ load_balancer_type_for_name_or_id(name)
34
+ end
35
+
36
+ end
37
+
@@ -1,161 +1,106 @@
1
1
  # require 'yaml'
2
- require 'io/console'
3
- require 'rest_client'
4
- require 'optparse'
5
2
  require 'morpheus/cli/cli_command'
6
3
 
7
4
  class Morpheus::Cli::LoadBalancers
8
5
  include Morpheus::Cli::CliCommand
6
+ include Morpheus::Cli::RestCommand
7
+ include Morpheus::Cli::LoadBalancersHelper
9
8
 
10
- register_subcommands :list, :get, :add, :update, :remove, {:types => :lb_types}
11
- alias_subcommand :details, :get
12
-
13
- def initialize()
14
- # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
15
- end
16
-
17
- def connect(opts)
18
- @api_client = establish_remote_appliance_connection(opts)
19
- @load_balancers_interface = @api_client.load_balancers
20
- end
9
+ set_command_name :'load-balancers'
10
+ register_subcommands :list, :get, :add, :update, :remove
21
11
 
12
+ # deprecated the `load-balancers types` command in 5.3.2, it moved to `load-balancer-types list`
13
+ register_subcommands :types
14
+ set_subcommands_hidden :types
22
15
 
23
- def handle(args)
24
- handle_subcommand(args)
25
- end
16
+ # RestCommand settings
17
+ register_interfaces :load_balancers, :load_balancer_types
18
+ set_rest_has_type true
19
+ # set_rest_type :load_balancer_types
26
20
 
27
- def list(args)
28
- options = {}
29
- optparse = Morpheus::Cli::OptionParser.new do |opts|
30
- opts.banner = subcommand_usage()
31
- build_common_options(opts, options, [:list, :json, :csv, :yaml, :fields, :dry_run, :remote])
32
- end
33
- optparse.parse!(args)
34
- connect(options)
35
- begin
36
- params = {}
37
- [:phrase, :offset, :max, :sort, :direction].each do |k|
38
- params[k] = options[k] unless options[k].nil?
39
- end
40
- @load_balancers_interface.setopts(options)
41
- if options[:dry_run]
42
- print_dry_run @load_balancers_interface.dry.list(params)
43
- return
44
- end
45
- json_response = @load_balancers_interface.list(params)
46
- if options[:json]
47
- puts as_json(json_response, options, "loadBalancers")
48
- return 0
49
- elsif options[:csv]
50
- puts records_as_csv(json_response["loadBalancers"], options)
51
- return 0
52
- elsif options[:yaml]
53
- puts as_yaml(json_response, options, "loadBalancers")
54
- return 0
55
- else
56
- lbs = json_response['loadBalancers']
57
- print_h1 "Morpheus Load Balancers"
58
- if lbs.empty?
59
- print cyan,"No load balancers found.",reset,"\n"
60
- else
61
- columns = [
62
- {"ID" => 'id'},
63
- {"Name" => 'name'},
64
- {"Type" => lambda {|it| it['type'] ? it['type']['name'] : '' } },
65
- {"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' } },
66
- {"Host" => lambda {|it| it['host'] } },
67
- ]
68
- print as_pretty_table(lbs, columns, options)
69
- end
70
- print reset,"\n"
71
- return 0
21
+ def render_response_for_get(json_response, options)
22
+ render_response(json_response, options, rest_object_key) do
23
+ record = json_response[rest_object_key]
24
+ print_h1 rest_label, [], options
25
+ print cyan
26
+ print_description_list(rest_column_definitions, record, options)
27
+ # show LB Ports
28
+ ports = record['ports']
29
+ if ports && ports.size > 0
30
+ print_h2 "LB Ports", options
31
+ columns = [
32
+ {"ID" => 'id'},
33
+ {"Name" => 'name'},
34
+ #{"Description" => 'description'},
35
+ {"Port" => lambda {|it| it['port'] } },
36
+ {"Protocol" => lambda {|it| it['proxyProtocol'] } },
37
+ {"SSL" => lambda {|it| it['sslEnabled'] ? "Yes (#{it['sslCert'] ? it['sslCert']['name'] : 'none'})" : "No" } },
38
+ ]
39
+ print as_pretty_table(ports, columns, options)
72
40
  end
73
- rescue RestClient::Exception => e
74
- print_rest_exception(e, options)
75
- return 1
41
+ print reset,"\n"
76
42
  end
77
43
  end
78
44
 
79
- def get(args)
45
+ =begin
46
+
47
+ # now using RestCommand
48
+
49
+ def add(args)
50
+ lb_type_name = nil
80
51
  options = {}
81
52
  optparse = Morpheus::Cli::OptionParser.new do |opts|
82
- opts.banner = subcommand_usage("[name]")
83
- build_common_options(opts, options, [:json, :csv, :yaml, :fields, :dry_run, :remote])
53
+ opts.banner = subcommand_usage("[name] -t LB_TYPE")
54
+ opts.on( '-t', '--type CODE', "Load Balancer Type" ) do |val|
55
+ lb_type_name = val
56
+ end
57
+ #build_option_type_options(opts, options, add_load_balancer_option_types)
58
+ build_standard_add_options(opts, options)
84
59
  end
85
60
  optparse.parse!(args)
86
- if args.count < 1
61
+ lb_name = args[0]
62
+ # verify_args!(args:args, optparse:optparse, min:0, max: 1)
63
+ verify_args!(args:args, optparse:optparse, min:1, max: 1)
64
+ if lb_type_name.nil?
65
+ raise_command_error "Load Balancer Type is required.\n#{optparse}"
87
66
  puts optparse
88
67
  exit 1
89
68
  end
90
- lb_name = args[0]
91
69
  connect(options)
92
- begin
93
- @load_balancers_interface.setopts(options)
94
- if options[:dry_run]
95
- if lb_name.to_s =~ /\A\d{1,}\Z/
96
- print_dry_run @load_balancers_interface.dry.get(lb_name.to_i)
97
- else
98
- print_dry_run @load_balancers_interface.dry.list({name:lb_name})
99
- end
100
- return
101
- end
102
- lb = find_lb_by_name_or_id(lb_name)
103
- exit 1 if lb.nil?
104
- # refetch
105
- json_response = @load_balancers_interface.get(lb['id'])
106
- lb_type = load_balancer_type_for_name_or_id(lb['type']['code'])
107
- #puts "LB TYPE: #{lb_type}"
108
- if options[:json]
109
- puts JSON.pretty_generate({loadBalancer: lb})
110
- puts as_json(json_response, options, "loadBalancer")
111
- return 0
112
- elsif options[:csv]
113
- puts records_as_csv(json_response["loadBalancer"], options)
114
- return 0
115
- elsif options[:yaml]
116
- puts as_yaml(json_response, options, "loadBalancer")
117
- return 0
118
- else
119
- print_h1 "Load Balancer Details"
120
- description_cols = {
121
- "ID" => 'id',
122
- "Name" => 'name',
123
- "Description" => 'description',
124
- "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
125
- "Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
126
- "Visibility" => 'visibility',
127
- "IP" => 'ip',
128
- "Host" => 'host',
129
- "Port" => 'port',
130
- "Username" => 'username',
131
- # "SSL Enabled" => lambda {|it| format_boolean it['sslEnabled'] },
132
- # "SSL Cert" => lambda {|it| it['sslCert'] ? it['sslCert']['name'] : '' },
133
- # "SSL" => lambda {|it| it['sslEnabled'] ? "Yes (#{it['sslCert'] ? it['sslCert']['name'] : 'none'})" : "No" },
134
- "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
135
- "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
136
- }
137
- print_description_list(description_cols, lb)
138
-
139
-
140
- if lb['ports'] && lb['ports'].size > 0
141
- print_h2 "LB Ports"
142
- columns = [
143
- {"ID" => 'id'},
144
- {"Name" => 'name'},
145
- #{"Description" => 'description'},
146
- {"Port" => lambda {|it| it['port'] } },
147
- {"Protocol" => lambda {|it| it['proxyProtocol'] } },
148
- {"SSL" => lambda {|it| it['sslEnabled'] ? "Yes (#{it['sslCert'] ? it['sslCert']['name'] : 'none'})" : "No" } },
149
- ]
150
- print as_pretty_table(lb['ports'], columns, options)
151
- end
152
- print reset,"\n"
153
- return 0
154
- end
155
- rescue RestClient::Exception => e
156
- print_rest_exception(e, options)
70
+ lb_type = load_balancer_type_for_name_or_id(lb_type_name)
71
+ if lb_type.nil?
72
+ print_red_alert "LB Type #{lb_type_name} not found!"
157
73
  exit 1
158
74
  end
75
+ passed_options = parse_passed_options(options)
76
+ payload = {}
77
+ if options[:payload]
78
+ payload = options[:payload]
79
+ payload.deep_merge!({load_balancer_object_key => passed_options})
80
+ else
81
+ load_balancer_payload = {'name' => lb_name, 'type' => {'code' => lb_type['code'], 'id' => lb_type['id']}}
82
+ load_balancer_payload.deep_merge!({load_balancer_object_key => passed_options})
83
+ # options by type
84
+ my_option_types = lb_type['optionTypes']
85
+ if my_option_types && !my_option_types.empty?
86
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, options[:params])
87
+ v_prompt.deep_compact!
88
+ load_balancer_payload.deep_merge!(v_prompt)
89
+ end
90
+ payload[load_balancer_object_key] = load_balancer_payload
91
+ end
92
+ @load_balancers_interface.setopts(options)
93
+ if options[:dry_run]
94
+ print_dry_run @load_balancers_interface.dry.create(payload)
95
+ return
96
+ end
97
+ json_response = @load_balancers_interface.create(payload)
98
+ render_response(json_response, options, load_balancer_object_key) do
99
+ load_balancer = json_response[load_balancer_object_key]
100
+ print_green_success "Added load balancer #{load_balancer['name']}"
101
+ return _get(load_balancer["id"], {}, options)
102
+ end
103
+ return 0, nil
159
104
  end
160
105
 
161
106
  def update(args)
@@ -163,8 +108,8 @@ class Morpheus::Cli::LoadBalancers
163
108
  options = {}
164
109
  account_name = nil
165
110
  optparse = Morpheus::Cli::OptionParser.new do |opts|
166
- opts.banner = subcommand_usage("[name] [options]")
167
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
111
+ opts.banner = subcommand_usage("[lb] [options]")
112
+ build_standard_update_options(opts, options)
168
113
  end
169
114
  optparse.parse!(args)
170
115
  if args.count < 1
@@ -172,141 +117,47 @@ class Morpheus::Cli::LoadBalancers
172
117
  exit 1
173
118
  end
174
119
  connect(options)
175
- begin
176
-
177
- lb = find_lb_by_name_or_id(lb_name)
178
- exit 1 if lb.nil?
179
- lb_type = load_balancer_type_for_name_or_id(lb['type']['code'])
180
-
181
- #params = Morpheus::Cli::OptionTypes.prompt(add_load_balancer_option_types, options[:options], @api_client, options[:params]) # options[:params] is mysterious
182
- params = options[:options] || {}
183
-
184
- if params.empty?
185
- puts optparse
186
- option_lines = update_task_option_types(lb_type).collect {|it| "\t-O #{it['fieldContext'] ? (it['fieldContext'] + '.') : ''}#{it['fieldName']}=\"value\"" }.join("\n")
187
- puts "\nAvailable Options:\n#{option_lines}\n\n"
188
- exit 1
189
- end
190
120
 
191
- # todo: fix this...
192
- #puts "parsed params is : #{params.inspect}"
193
- lb_keys = ['name']
194
- changes_payload = (params.select {|k,v| task_keys.include?(k) })
195
- task_payload = task
196
- if changes_payload
197
- task_payload.merge!(changes_payload)
198
- end
199
- puts params
200
- if params['taskOptions']
201
- task_payload['taskOptions'].merge!(params['taskOptions'])
202
- end
203
- payload = {task: task_payload}
204
- @load_balancers_interface.setopts(options)
205
- if options[:dry_run]
206
- print_dry_run @load_balancers_interface.dry.update(task['id'], payload)
207
- return
121
+ passed_options = parse_passed_options(options)
122
+ payload = nil
123
+ if options[:payload]
124
+ payload = options[:payload]
125
+ payload.deep_merge!({load_balancer_object_key => passed_options}) unless passed_options.empty?
126
+ else
127
+ load_balancer_payload = passed_options
128
+ if tenants_list
129
+ load_balancer_payload['accounts'] = tenants_list
208
130
  end
209
- response = @load_balancers_interface.update(task['id'], payload)
210
- if options[:json]
211
- print JSON.pretty_generate(json_response)
212
- if !response['success']
213
- exit 1
214
- end
131
+ # metadata tags
132
+ if options[:tags]
133
+ load_balancer_payload['tags'] = parse_metadata(options[:tags])
215
134
  else
216
- print "\n", cyan, "Task #{response['task']['name']} updated", reset, "\n\n"
135
+ # tags = prompt_metadata(options)
136
+ # payload[load_balancer_object_key]['tags'] = tags of tags
217
137
  end
218
- rescue RestClient::Exception => e
219
- print_rest_exception(e, options)
220
- exit 1
221
- end
222
- end
223
-
224
-
225
- def lb_types(args)
226
- options = {}
227
- optparse = Morpheus::Cli::OptionParser.new do |opts|
228
- opts.banner = subcommand_usage()
229
- build_common_options(opts, options, [:json, :dry_run, :remote])
230
- end
231
- optparse.parse!(args)
232
- connect(options)
233
- begin
234
- @load_balancers_interface.setopts(options)
235
- if options[:dry_run]
236
- print_dry_run @load_balancers_interface.dry.load_balancer_types()
237
- return
138
+ # metadata tags
139
+ if options[:add_tags]
140
+ load_balancer_payload['addTags'] = parse_metadata(options[:add_tags])
238
141
  end
239
- json_response = @load_balancers_interface.load_balancer_types()
240
- if options[:json]
241
- print JSON.pretty_generate(json_response)
242
- else
243
- lb_types = json_response['loadBalancerTypes']
244
- print_h1 "Morpheus Load Balancer Types"
245
- if lb_types.nil? || lb_types.empty?
246
- print cyan,"No load balancer types found.",reset,"\n"
247
- else
248
- print cyan
249
- lb_table_data = lb_types.collect do |lb_type|
250
- {name: lb_type['name'], id: lb_type['id'], code: lb_type['code']}
251
- end
252
- print as_pretty_table(lb_table_data, [:id, :name, :code], options)
253
- end
254
-
255
- print reset,"\n"
142
+ if options[:remove_tags]
143
+ load_balancer_payload['removeTags'] = parse_metadata(options[:remove_tags])
256
144
  end
257
- rescue RestClient::Exception => e
258
- print_rest_exception(e, options)
259
- exit 1
260
- end
261
- end
262
-
263
- # JD: This is broken.. copied from tasks? should optionTypes exist?
264
- def add(args)
265
- lb_type_name = nil
266
- options = {}
267
- optparse = Morpheus::Cli::OptionParser.new do |opts|
268
- opts.banner = subcommand_usage("[name] -t LB_TYPE")
269
- opts.on( '-t', '--type LB_TYPE', "Load Balancer Type" ) do |val|
270
- lb_type_name = val
145
+ if load_balancer_payload.empty?
146
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
271
147
  end
272
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
273
- end
274
- optparse.parse!(args)
275
- lb_name = args[0]
276
- if args.count < 1
277
- puts optparse
278
- exit 1
148
+ payload = {'virtualImage' => load_balancer_payload}
279
149
  end
280
- if lb_type_name.nil?
281
- puts optparse
282
- exit 1
150
+ @load_balancers_interface.setopts(options)
151
+ if options[:dry_run]
152
+ print_dry_run @load_balancers_interface.dry.update(load_balancer['id'], payload)
153
+ return
283
154
  end
284
- connect(options)
285
- begin
286
- lb_type = load_balancer_type_for_name_or_id(lb_type_name)
287
- if lb_type.nil?
288
- print_red_alert "LB Type #{lb_type_name} not found!"
289
- exit 1
290
- end
291
-
292
- payload = {loadBalancer: {name: lb_name, type: {code: lb_type['code'], id: lb_type['id']}}}
293
- # todo: The options available here are specific by type...
294
- #input_options = Morpheus::Cli::OptionTypes.prompt(lb_type['optionTypes'],options[:options],@api_client, options[:params])
295
- @load_balancers_interface.setopts(options)
296
- if options[:dry_run]
297
- print_dry_run @load_balancers_interface.dry.create(payload)
298
- return
299
- end
300
- json_response = @load_balancers_interface.create(payload)
301
- if options[:json]
302
- print JSON.pretty_generate(json_response)
303
- else
304
- print "\n", cyan, "LB #{json_response['loadBalancer']['name']} created successfully", reset, "\n\n"
305
- end
306
- rescue RestClient::Exception => e
307
- print_rest_exception(e, options)
308
- exit 1
155
+ json_response = @load_balancers_interface.update(load_balancer['id'], payload)
156
+ render_response(json_response, options, 'virtualImage') do
157
+ print_green_success "Updated virtual image #{load_balancer['name']}"
158
+ _get(load_balancer["id"], {}, options)
309
159
  end
160
+ return 0, nil
310
161
  end
311
162
 
312
163
  def remove(args)
@@ -323,7 +174,7 @@ class Morpheus::Cli::LoadBalancers
323
174
  end
324
175
  connect(options)
325
176
  begin
326
- lb = find_lb_by_name_or_id(lb_name)
177
+ lb = find_load_balancer_by_name_or_id(lb_name)
327
178
  exit 1 if lb.nil?
328
179
  unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the load balancer #{lb['name']}?")
329
180
  exit
@@ -344,67 +195,51 @@ class Morpheus::Cli::LoadBalancers
344
195
  exit 1
345
196
  end
346
197
  end
198
+ =end
347
199
 
348
-
349
- private
350
-
351
- def find_lb_by_name_or_id(val)
352
- if val.to_s =~ /\A\d{1,}\Z/
353
- return find_lb_by_id(val)
354
- else
355
- return find_lb_by_name(val)
356
- end
200
+ # deprecated, to be removed in the future.
201
+ def types(args)
202
+ print_error yellow,"[DEPRECATED] The command `load-balancers types` is deprecated and replaced by `load-balancer-types list`.",reset,"\n"
203
+ my_terminal.execute("load-balancer-types list #{args.join(' ')}")
357
204
  end
358
205
 
359
- def find_lb_by_id(id)
360
- begin
361
- json_response = @load_balancers_interface.get(id.to_i)
362
- return json_response['loadBalancer']
363
- rescue RestClient::Exception => e
364
- if e.response && e.response.code == 404
365
- print_red_alert "Load Balancer not found by id #{id}"
366
- else
367
- raise e
368
- end
369
- end
370
- end
206
+ protected
371
207
 
372
- def find_lb_by_name(name)
373
- lbs = @load_balancers_interface.list({name: name.to_s})['loadBalancers']
374
- if lbs.empty?
375
- print_red_alert "Load Balancer not found by name #{name}"
376
- return nil
377
- elsif lbs.size > 1
378
- print_red_alert "#{lbs.size} load balancers found by name #{name}"
379
- #print_lbs_table(lbs, {color: red})
380
- print reset,"\n\n"
381
- return nil
382
- else
383
- return lbs[0]
384
- end
208
+ def load_balancer_list_column_definitions()
209
+ {
210
+ "ID" => 'id',
211
+ "Name" => 'name',
212
+ "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
213
+ "Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
214
+ "Host" => lambda {|it| it['host'] }
215
+ }
385
216
  end
386
217
 
387
- def get_available_load_balancer_types(refresh=false)
388
- if !@available_load_balancer_types || refresh
389
- @available_load_balancer_types = @load_balancers_interface.load_balancer_types['loadBalancerTypes']
390
- end
391
- return @available_load_balancer_types
218
+ def load_balancer_column_definitions()
219
+ {
220
+ "ID" => 'id',
221
+ "Name" => 'name',
222
+ "Description" => 'description',
223
+ "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
224
+ "Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
225
+ "Visibility" => 'visibility',
226
+ "IP" => 'ip',
227
+ "Host" => 'host',
228
+ "Port" => 'port',
229
+ "Username" => 'username',
230
+ # "SSL Enabled" => lambda {|it| format_boolean it['sslEnabled'] },
231
+ # "SSL Cert" => lambda {|it| it['sslCert'] ? it['sslCert']['name'] : '' },
232
+ # "SSL" => lambda {|it| it['sslEnabled'] ? "Yes (#{it['sslCert'] ? it['sslCert']['name'] : 'none'})" : "No" },
233
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
234
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
235
+ }
392
236
  end
393
237
 
394
- def load_balancer_type_for_name_or_id(val)
395
- if val.to_s =~ /\A\d{1,}\Z/
396
- return load_balancer_type_for_id(val)
397
- else
398
- return load_balancer_type_for_name(val)
399
- end
238
+ # overridden to work with name or code
239
+ def find_load_balancer_type_by_name_or_id(name)
240
+ load_balancer_type_for_name_or_id(name)
400
241
  end
401
242
 
402
- def load_balancer_type_for_id(id)
403
- return get_available_load_balancer_types().find { |z| z['id'].to_i == id.to_i}
404
- end
405
243
 
406
- def load_balancer_type_for_name(name)
407
- return get_available_load_balancer_types().find { |z| z['name'].downcase == name.downcase || z['code'].downcase == name.downcase}
408
- end
409
244
 
410
245
  end