morpheus-cli 5.3.0.3 → 5.3.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/README.md +1 -3
  4. data/lib/morpheus/api/api_client.rb +48 -14
  5. data/lib/morpheus/api/certificate_types_interface.rb +14 -0
  6. data/lib/morpheus/api/certificates_interface.rb +9 -0
  7. data/lib/morpheus/api/integration_types_interface.rb +14 -0
  8. data/lib/morpheus/api/integrations_interface.rb +7 -22
  9. data/lib/morpheus/api/network_services_interface.rb +14 -0
  10. data/lib/morpheus/api/read_interface.rb +23 -0
  11. data/lib/morpheus/api/rest_interface.rb +12 -10
  12. data/lib/morpheus/api/roles_interface.rb +7 -0
  13. data/lib/morpheus/api/servers_interface.rb +7 -0
  14. data/lib/morpheus/api/user_settings_interface.rb +38 -18
  15. data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
  16. data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
  17. data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
  18. data/lib/morpheus/api/vdi_interface.rb +28 -0
  19. data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
  20. data/lib/morpheus/cli.rb +9 -2
  21. data/lib/morpheus/cli/apps.rb +59 -75
  22. data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
  23. data/lib/morpheus/cli/certificates_command.rb +575 -0
  24. data/lib/morpheus/cli/cli_command.rb +61 -6
  25. data/lib/morpheus/cli/clouds.rb +1 -0
  26. data/lib/morpheus/cli/clusters.rb +1 -1
  27. data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
  28. data/lib/morpheus/cli/hosts.rb +245 -224
  29. data/lib/morpheus/cli/instances.rb +150 -167
  30. data/lib/morpheus/cli/integrations_command.rb +588 -41
  31. data/lib/morpheus/cli/login.rb +7 -0
  32. data/lib/morpheus/cli/mixins/print_helper.rb +33 -18
  33. data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -3
  34. data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
  35. data/lib/morpheus/cli/network_routers_command.rb +22 -9
  36. data/lib/morpheus/cli/networks_command.rb +2 -2
  37. data/lib/morpheus/cli/option_types.rb +34 -33
  38. data/lib/morpheus/cli/remote.rb +1 -1
  39. data/lib/morpheus/cli/reports_command.rb +4 -1
  40. data/lib/morpheus/cli/roles.rb +215 -55
  41. data/lib/morpheus/cli/subnets_command.rb +11 -2
  42. data/lib/morpheus/cli/user_settings_command.rb +268 -57
  43. data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
  44. data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
  45. data/lib/morpheus/cli/vdi_command.rb +359 -0
  46. data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
  47. data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
  48. data/lib/morpheus/cli/version.rb +1 -1
  49. data/lib/morpheus/rest_client.rb +30 -0
  50. data/lib/morpheus/terminal.rb +15 -7
  51. metadata +18 -2
@@ -84,6 +84,16 @@ class Morpheus::Cli::Instances
84
84
  opts.on('--status STATUS', "Filter by status i.e. provisioning,running,starting,stopping") do |val|
85
85
  params['status'] = (params['status'] || []) + val.to_s.split(',').collect {|s| s.strip }.select {|s| s != "" }
86
86
  end
87
+ opts.on( '--type CODE', String, "Filter by Instance Type code" ) do |val|
88
+ # commas used in names a lot so use --plan one --plan two
89
+ params['instanceType'] ||= []
90
+ params['instanceType'] << val
91
+ end
92
+ opts.on( '--environment CODE', String, "Filter by Environment code(s)" ) do |val|
93
+ # commas used in names a lot so use --plan one --plan two
94
+ params['environment'] ||= []
95
+ params['environment'] << val
96
+ end
87
97
  opts.on('--pending-removal', "Include instances pending removal.") do
88
98
  options[:showDeleted] = true
89
99
  end
@@ -121,7 +131,7 @@ class Morpheus::Cli::Instances
121
131
  opts.on('-a', '--details', "Display all details: plan, stats, etc" ) do
122
132
  options[:details] = true
123
133
  end
124
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
134
+ build_standard_list_options(opts, options)
125
135
  opts.footer = "List instances."
126
136
  end
127
137
  optparse.parse!(args)
@@ -130,159 +140,150 @@ class Morpheus::Cli::Instances
130
140
  options[:phrase] = args.join(" ")
131
141
  end
132
142
  connect(options)
133
- begin
134
- params.merge!(parse_list_options(options))
135
- group = options[:group] ? find_group_by_name_or_id_for_provisioning(options[:group]) : nil
136
- if group
137
- params['siteId'] = group['id']
138
- end
139
143
 
140
- # argh, this doesn't work because group_id is required for options/clouds
141
- # cloud = options[:cloud] ? find_cloud_by_name_or_id_for_provisioning(group_id, options[:cloud]) : nil
142
- cloud = options[:cloud] ? find_zone_by_name_or_id(nil, options[:cloud]) : nil
143
- if cloud
144
- params['zoneId'] = cloud['id']
145
- end
144
+ params.merge!(parse_list_options(options))
145
+ group = options[:group] ? find_group_by_name_or_id_for_provisioning(options[:group]) : nil
146
+ if group
147
+ params['siteId'] = group['id']
148
+ end
146
149
 
147
- host = options[:host] ? find_host_by_name_or_id(options[:host]) : options[:host]
148
- if host
149
- params['serverId'] = host['id']
150
- end
150
+ # argh, this doesn't work because group_id is required for options/clouds
151
+ # cloud = options[:cloud] ? find_cloud_by_name_or_id_for_provisioning(group_id, options[:cloud]) : nil
152
+ cloud = options[:cloud] ? find_zone_by_name_or_id(nil, options[:cloud]) : nil
153
+ if cloud
154
+ params['zoneId'] = cloud['id']
155
+ end
151
156
 
152
- account = nil
153
- #todo: user = find_available_user_option(owner_id)
157
+ host = options[:host] ? find_host_by_name_or_id(options[:host]) : options[:host]
158
+ if host
159
+ params['serverId'] = host['id']
160
+ end
154
161
 
155
- if options[:owner]
156
- created_by_ids = find_all_user_ids(account ? account['id'] : nil, options[:owner])
157
- return if created_by_ids.nil?
158
- params['createdBy'] = created_by_ids
159
- params['ownerId'] = created_by_ids # 4.2.1+
162
+ account = nil
163
+ #todo: user = find_available_user_option(owner_id)
164
+
165
+ if options[:owner]
166
+ created_by_ids = find_all_user_ids(account ? account['id'] : nil, options[:owner])
167
+ return if created_by_ids.nil?
168
+ params['createdBy'] = created_by_ids
169
+ params['ownerId'] = created_by_ids # 4.2.1+
170
+ end
171
+
172
+ params['showDeleted'] = true if options[:showDeleted]
173
+ params['deleted'] = true if options[:deleted]
174
+ params['labels'] = options[:labels] if options[:labels]
175
+ if options[:tags]
176
+ options[:tags].each do |k,v|
177
+ params['tags.' + k] = v
160
178
  end
179
+ end
161
180
 
162
- params['showDeleted'] = true if options[:showDeleted]
163
- params['deleted'] = true if options[:deleted]
164
- params['labels'] = options[:labels] if options[:labels]
165
- if options[:tags]
166
- options[:tags].each do |k,v|
167
- params['tags.' + k] = v
181
+ @instances_interface.setopts(options)
182
+ if options[:dry_run]
183
+ print_dry_run @instances_interface.dry.list(params)
184
+ return 0
185
+ end
186
+ json_response = @instances_interface.list(params)
187
+ all_stats = json_response['stats'] || {}
188
+ # merge stats into each record just to be nice...
189
+ if options[:include_fields] || options[:all_fields]
190
+ if json_response['instances']
191
+ if all_stats
192
+ json_response['instances'].each do |it|
193
+ it['stats'] ||= all_stats[it['id'].to_s] || all_stats[it['id']]
194
+ end
168
195
  end
169
196
  end
197
+ end
198
+ render_response(json_response, options, "instances") do
199
+ instances = json_response['instances']
170
200
 
171
- @instances_interface.setopts(options)
172
- if options[:dry_run]
173
- print_dry_run @instances_interface.dry.list(params)
174
- return 0
201
+ title = "Morpheus Instances"
202
+ subtitles = []
203
+ if group
204
+ subtitles << "Group: #{group['name']}".strip
175
205
  end
176
- json_response = @instances_interface.list(params)
177
- if options[:json]
178
- puts as_json(json_response, options, "instances")
179
- return 0
180
- elsif options[:yaml]
181
- puts as_yaml(json_response, options, "instances")
182
- return 0
183
- elsif options[:csv]
184
- # merge stats to be nice here..
185
- if json_response['instances']
186
- all_stats = json_response['stats'] || {}
187
- if all_stats
188
- json_response['instances'].each do |it|
189
- it['stats'] ||= all_stats[it['id'].to_s] || all_stats[it['id']]
206
+ if cloud
207
+ subtitles << "Cloud: #{cloud['name']}".strip
208
+ end
209
+ if host
210
+ subtitles << "Host: #{host['name']}".strip
211
+ end
212
+ if options[:owner]
213
+ subtitles << "Created By: #{options[:owner]}"
214
+ end
215
+ subtitles += parse_list_subtitles(options)
216
+ print_h1 title, subtitles, options
217
+ if instances.empty?
218
+ print cyan,"No instances found.",reset,"\n"
219
+ else
220
+ # print_instances_table(instances)
221
+ # server returns stats in a separate key stats => {"id" => {} }
222
+ # the id is a string right now..for some reason..
223
+ all_stats = json_response['stats'] || {}
224
+ if all_stats
225
+ instances.each do |it|
226
+ if !it['stats']
227
+ found_stats = all_stats[it['id'].to_s] || all_stats[it['id']]
228
+ it['stats'] = found_stats # || {}
190
229
  end
191
230
  end
192
231
  end
193
- puts records_as_csv(json_response['instances'], options)
194
- else
195
- instances = json_response['instances']
196
232
 
197
- title = "Morpheus Instances"
198
- subtitles = []
199
- if group
200
- subtitles << "Group: #{group['name']}".strip
201
- end
202
- if cloud
203
- subtitles << "Cloud: #{cloud['name']}".strip
204
- end
205
- if host
206
- subtitles << "Host: #{host['name']}".strip
207
- end
208
- if options[:owner]
209
- subtitles << "Created By: #{options[:owner]}"
210
- end
211
- subtitles += parse_list_subtitles(options)
212
- print_h1 title, subtitles, options
213
- if instances.empty?
214
- print cyan,"No instances found.",reset,"\n"
215
- else
216
- # print_instances_table(instances)
217
- # server returns stats in a separate key stats => {"id" => {} }
218
- # the id is a string right now..for some reason..
219
- all_stats = json_response['stats'] || {}
220
- if all_stats
221
- instances.each do |it|
222
- if !it['stats']
223
- found_stats = all_stats[it['id'].to_s] || all_stats[it['id']]
224
- it['stats'] = found_stats # || {}
225
- end
233
+ rows = instances.collect {|instance|
234
+ stats = instance['stats']
235
+ cpu_usage_str = !stats ? "" : generate_usage_bar((stats['usedCpu'] || stats['cpuUsage']).to_f, 100, {max_bars: 10})
236
+ memory_usage_str = !stats ? "" : generate_usage_bar(stats['usedMemory'], stats['maxMemory'], {max_bars: 10})
237
+ storage_usage_str = !stats ? "" : generate_usage_bar(stats['usedStorage'], stats['maxStorage'], {max_bars: 10})
238
+ if options[:details] || options[:stats]
239
+ if stats['maxMemory'] && stats['maxMemory'].to_i != 0
240
+ memory_usage_str = memory_usage_str + cyan + format_bytes_short(stats['usedMemory']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxMemory']).strip
226
241
  end
227
- end
228
-
229
- rows = instances.collect {|instance|
230
- stats = instance['stats']
231
- cpu_usage_str = !stats ? "" : generate_usage_bar((stats['usedCpu'] || stats['cpuUsage']).to_f, 100, {max_bars: 10})
232
- memory_usage_str = !stats ? "" : generate_usage_bar(stats['usedMemory'], stats['maxMemory'], {max_bars: 10})
233
- storage_usage_str = !stats ? "" : generate_usage_bar(stats['usedStorage'], stats['maxStorage'], {max_bars: 10})
234
- if options[:details] || options[:stats]
235
- if stats['maxMemory'] && stats['maxMemory'].to_i != 0
236
- memory_usage_str = memory_usage_str + cyan + format_bytes_short(stats['usedMemory']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxMemory']).strip
237
- end
238
- if stats['maxStorage'] && stats['maxStorage'].to_i != 0
239
- storage_usage_str = storage_usage_str + cyan + format_bytes_short(stats['usedStorage']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxStorage']).strip
240
- end
242
+ if stats['maxStorage'] && stats['maxStorage'].to_i != 0
243
+ storage_usage_str = storage_usage_str + cyan + format_bytes_short(stats['usedStorage']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxStorage']).strip
241
244
  end
242
- row = {
243
- id: instance['id'],
244
- name: instance['name'],
245
- connection: format_instance_connection_string(instance),
246
- environment: instance['instanceContext'],
247
- user: (instance['owner'] ? (instance['owner']['username'] || instance['owner']['id']) : (instance['createdBy'].is_a?(Hash) ? instance['createdBy']['username'] : instance['createdBy'])),
248
- tenant: (instance['owner'] ? (instance['owner']['username'] || instance['owner']['id']) : (instance['createdBy'].is_a?(Hash) ? instance['createdBy']['username'] : instance['createdBy'])),
249
- nodes: instance['containers'].count,
250
- status: format_instance_status(instance, cyan),
251
- type: instance['instanceType']['name'],
252
- group: instance['group'] ? instance['group']['name'] : nil,
253
- cloud: instance['cloud'] ? instance['cloud']['name'] : nil,
254
- plan: instance['plan'] ? instance['plan']['name'] : '',
255
- version: instance['instanceVersion'] ? instance['instanceVersion'] : '',
256
- created: format_local_dt(instance['dateCreated']),
257
- cpu: cpu_usage_str + cyan,
258
- memory: memory_usage_str + cyan,
259
- storage: storage_usage_str + cyan
260
- }
261
- row
262
- }
263
- columns = [:id, {:name => {:max_width => 50}}, :group, :cloud,
264
- :type, :version, :environment,
265
- {:created => {:display_name => "CREATED"}},
266
- # {:tenant => {:display_name => "TENANT"}},
267
- {:user => {:display_name => "OWNER", :max_width => 20}},
268
- :plan,
269
- :nodes, {:connection => {:max_width => 30}}, :status, :cpu, :memory, :storage]
270
- # custom pretty table columns ... this is handled in as_pretty_table now(),
271
- # todo: remove all these.. and try to always pass rows as the json data itself..
272
- if options[:details] != true
273
- columns.delete(:plan)
274
245
  end
275
- print cyan
276
- print as_pretty_table(rows, columns, options)
277
- print reset
278
- print_results_pagination(json_response)
246
+ row = {
247
+ id: instance['id'],
248
+ name: instance['name'],
249
+ connection: format_instance_connection_string(instance),
250
+ environment: instance['instanceContext'],
251
+ user: (instance['owner'] ? (instance['owner']['username'] || instance['owner']['id']) : (instance['createdBy'].is_a?(Hash) ? instance['createdBy']['username'] : instance['createdBy'])),
252
+ tenant: (instance['owner'] ? (instance['owner']['username'] || instance['owner']['id']) : (instance['createdBy'].is_a?(Hash) ? instance['createdBy']['username'] : instance['createdBy'])),
253
+ nodes: instance['containers'].count,
254
+ status: format_instance_status(instance, cyan),
255
+ type: instance['instanceType']['name'],
256
+ group: instance['group'] ? instance['group']['name'] : nil,
257
+ cloud: instance['cloud'] ? instance['cloud']['name'] : nil,
258
+ plan: instance['plan'] ? instance['plan']['name'] : '',
259
+ version: instance['instanceVersion'] ? instance['instanceVersion'] : '',
260
+ created: format_local_dt(instance['dateCreated']),
261
+ cpu: cpu_usage_str + cyan,
262
+ memory: memory_usage_str + cyan,
263
+ storage: storage_usage_str + cyan
264
+ }
265
+ row
266
+ }
267
+ columns = [:id, {:name => {:max_width => 50}}, :group, :cloud,
268
+ :type, :version, :environment,
269
+ {:created => {:display_name => "CREATED"}},
270
+ # {:tenant => {:display_name => "TENANT"}},
271
+ {:user => {:display_name => "OWNER", :max_width => 20}},
272
+ :plan,
273
+ :nodes, {:connection => {:max_width => 30}}, :status, :cpu, :memory, :storage]
274
+ # custom pretty table columns ... this is handled in as_pretty_table now(),
275
+ # todo: remove all these.. and try to always pass rows as the json data itself..
276
+ if options[:details] != true
277
+ columns.delete(:plan)
279
278
  end
280
- print reset,"\n"
279
+ print cyan
280
+ print as_pretty_table(rows, columns, options)
281
+ print reset
282
+ print_results_pagination(json_response)
281
283
  end
282
- rescue RestClient::Exception => e
283
- print_rest_exception(e, options)
284
- exit 1
284
+ print reset,"\n"
285
285
  end
286
+ return 0, nil
286
287
  end
287
288
 
288
289
  def count(args)
@@ -436,7 +437,7 @@ class Morpheus::Cli::Instances
436
437
  opts.on("--create-backup [on|off]", String, "Automation: Create Backups.") do |val|
437
438
  options[:create_backup] = ['on','true','1',''].include?(val.to_s.downcase) ? 'on' : 'off'
438
439
  end
439
- opts.on("--security-groups LIST", String, "Security Groups, comma sepearated list of security group IDs") do |val|
440
+ opts.on("--security-groups LIST", String, "Security Groups, comma separated list of security group IDs") do |val|
440
441
  options[:security_groups] = val.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
441
442
  end
442
443
  opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
@@ -1233,7 +1234,7 @@ class Morpheus::Cli::Instances
1233
1234
  # opts.on( nil, '--lb', "Display Load Balancer Details" ) do
1234
1235
  # options[:include_lb] = true
1235
1236
  # end
1236
- build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
1237
+ build_standard_get_options(opts, options)
1237
1238
  opts.footer = "Get details about an instance.\n" +
1238
1239
  "[instance] is required. This is the name or id of an instance. Supports 1-N [instance] arguments."
1239
1240
  end
@@ -1250,34 +1251,20 @@ class Morpheus::Cli::Instances
1250
1251
  end
1251
1252
 
1252
1253
  def _get(arg, options={})
1253
- begin
1254
- if options[:dry_run]
1255
- @instances_interface.setopts(options)
1256
- if arg.to_s =~ /\A\d{1,}\Z/
1257
- print_dry_run @instances_interface.dry.get(arg.to_i)
1258
- else
1259
- print_dry_run @instances_interface.dry.get({name:arg})
1260
- end
1261
- return
1262
- end
1263
- instance = find_instance_by_name_or_id(arg =~ /\A\d{1,}\Z/ ? arg.to_i : arg)
1254
+
1255
+ if options[:dry_run]
1264
1256
  @instances_interface.setopts(options)
1265
- json_response = @instances_interface.get(instance['id'])
1266
- if options[:quiet]
1267
- return 0
1268
- end
1269
- if options[:json]
1270
- puts as_json(json_response, options, "instance")
1271
- return 0
1272
- elsif options[:yaml]
1273
- puts as_yaml(json_response, options, "instance")
1274
- return 0
1275
- end
1276
-
1277
- if options[:csv]
1278
- puts records_as_csv([json_response['instance']], options)
1279
- return 0
1257
+ if arg.to_s =~ /\A\d{1,}\Z/
1258
+ print_dry_run @instances_interface.dry.get(arg.to_i)
1259
+ else
1260
+ print_dry_run @instances_interface.dry.get({name:arg})
1280
1261
  end
1262
+ return
1263
+ end
1264
+ instance = find_instance_by_name_or_id(arg =~ /\A\d{1,}\Z/ ? arg.to_i : arg)
1265
+ @instances_interface.setopts(options)
1266
+ json_response = @instances_interface.get(instance['id'])
1267
+ render_response(json_response, options, "instance") do
1281
1268
  instance = json_response['instance']
1282
1269
  stats = instance['stats'] || json_response['stats'] || {}
1283
1270
  # load_balancers = json_response['loadBalancers'] || {}
@@ -1494,12 +1481,8 @@ class Morpheus::Cli::Instances
1494
1481
  _get(arg, options)
1495
1482
  end
1496
1483
  end
1497
-
1498
- return 0
1499
- rescue RestClient::Exception => e
1500
- print_rest_exception(e, options)
1501
- exit 1
1502
1484
  end
1485
+ return 0, nil
1503
1486
  end
1504
1487
 
1505
1488
  def list_containers(args)
@@ -5,13 +5,15 @@ class Morpheus::Cli::IntegrationsCommand
5
5
  include Morpheus::Cli::AccountsHelper
6
6
 
7
7
  set_command_name :'integrations'
8
+ set_command_description "Integrations: View and manage integrations"
8
9
 
9
- register_subcommands :list
10
- set_default_subcommand :list
10
+ register_subcommands :list, :get, :add, :update, :remove, :refresh
11
+ register_subcommands :list_types, :get_type
11
12
 
12
13
  def connect(opts)
13
14
  @api_client = establish_remote_appliance_connection(opts)
14
15
  @integrations_interface = @api_client.integrations
16
+ @integration_types_interface = @api_client.integration_types
15
17
  end
16
18
 
17
19
  def handle(args)
@@ -22,68 +24,535 @@ class Morpheus::Cli::IntegrationsCommand
22
24
  options = {}
23
25
  params = {}
24
26
  optparse = Morpheus::Cli::OptionParser.new do |opts|
25
- opts.banner = subcommand_usage()
26
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
27
+ opts.banner = subcommand_usage("[search]")
28
+ opts.on('-t', '--type CODE', "Filter by type code(s), see `list-types` for available type codes") do |val|
29
+ params['type'] = val
30
+ end
31
+ opts.on('--url URL', String, "Filter by url") do |val|
32
+ params['url'] = val
33
+ end
34
+ build_standard_list_options(opts, options)
27
35
  opts.footer = "List integrations."
28
36
  end
29
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
30
42
  connect(options)
31
- if args.count != 0
32
- raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args}\n#{optparse}"
33
- return 1
43
+ params.merge!(parse_list_options(options))
44
+ @integrations_interface.setopts(options)
45
+ if options[:dry_run]
46
+ print_dry_run @integrations_interface.dry.list(params)
47
+ return
34
48
  end
49
+ json_response = @integrations_interface.list(params)
50
+ render_response(json_response, options, integration_list_key) do
51
+ integrations = json_response[integration_list_key]
52
+ print_h1 "Morpheus Integrations", parse_list_subtitles(options), options
53
+ if integrations.empty?
54
+ print cyan,"No integrations found.",reset,"\n"
55
+ else
56
+ list_columns = {
57
+ "ID" => 'id',
58
+ "Name" => 'name',
59
+ "Type" => lambda {|it| format_integration_type(it) },
60
+ "URL" => lambda {|it| it['url'] },
61
+ "Username" => lambda {|it| it['username'] },
62
+ "Enabled" => lambda {|it| format_boolean(it['enabled']) },
63
+ "Status Date" => lambda {|it| format_local_dt(it['statusDate']) },
64
+ "Status" => lambda {|it| format_integration_status(it) },
65
+ # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
66
+ # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
67
+ }.upcase_keys!
68
+ print as_pretty_table(integrations, list_columns, options)
69
+ print_results_pagination(json_response)
70
+ end
71
+ print reset,"\n"
72
+ end
73
+ return 0, nil
74
+ end
35
75
 
36
- begin
37
- params.merge!(parse_list_options(options))
38
- @integrations_interface.setopts(options)
39
- if options[:dry_run]
40
- print_dry_run @integrations_interface.dry.list(params)
41
- return
76
+ def get(args)
77
+ params = {}
78
+ options = {}
79
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
80
+ opts.banner = subcommand_usage("[integration]")
81
+ build_standard_get_options(opts, options)
82
+ opts.footer = <<-EOT
83
+ Get details about a specific integration.
84
+ [integration] is required. This is the name or id of an integration.
85
+ EOT
86
+ end
87
+ optparse.parse!(args)
88
+ verify_args!(args:args, optparse:optparse, min:1)
89
+ connect(options)
90
+ params.merge!(parse_query_options(options))
91
+ id_list = parse_id_list(args)
92
+ return run_command_for_each_arg(id_list) do |arg|
93
+ _get(arg, params, options)
94
+ end
95
+ end
96
+
97
+ def _get(id, params, options)
98
+ integration = nil
99
+ if id.to_s !~ /\A\d{1,}\Z/
100
+ integration = find_integration_by_name_or_id(id)
101
+ return 1, "integration not found for #{id}" if integration.nil?
102
+ id = integration['id']
103
+ end
104
+ @integrations_interface.setopts(options)
105
+ if options[:dry_run]
106
+ print_dry_run @integrations_interface.dry.get(id, params)
107
+ return
108
+ end
109
+ json_response = @integrations_interface.get(id, params)
110
+ integration = json_response[integration_object_key]
111
+ render_response(json_response, options, integration_object_key) do
112
+ print_h1 "Integration Details", [], options
113
+ print cyan
114
+ show_columns = {
115
+ "ID" => 'id',
116
+ "Name" => 'name',
117
+ "Type" => lambda {|it| format_integration_type(it) },
118
+ "URL" => lambda {|it| it['url'] },
119
+ "Host" => lambda {|it| it['host'] },
120
+ "Port" => lambda {|it| it['port'] },
121
+ "Username" => lambda {|it| it['username'] },
122
+ "Password" => lambda {|it| it['password'] },
123
+ "Token" => lambda {|it| it['token'] },
124
+ "Service Key" => lambda {|it| it['serviceKey'] ? it['serviceKey']['name'] : nil },
125
+ "Auth Key" => lambda {|it| it['authKey'] ? it['authKey']['name'] : nil },
126
+ "Enabled" => lambda {|it| format_boolean(it['enabled']) },
127
+ "Status Date" => lambda {|it| format_local_dt(it['statusDate']) },
128
+ "Status" => lambda {|it| format_integration_status(it) },
129
+ # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
130
+ # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
131
+ }
132
+ show_columns.delete("URL") if integration['url'].nil?
133
+ show_columns.delete("Host") if integration['host'].nil?
134
+ show_columns.delete("Port") if integration['port'].nil?
135
+ show_columns.delete("Password") if integration['password'].nil?
136
+ show_columns.delete("Token") if integration['token'].nil?
137
+ show_columns.delete("Service Key") if integration['serviceKey'].nil?
138
+ show_columns.delete("Auth Key") if integration['authKey'].nil?
139
+ print_description_list(show_columns, integration, options)
140
+ print reset,"\n"
141
+ end
142
+ return 0, nil
143
+ end
144
+
145
+ def add(args)
146
+ options = {}
147
+ params = {}
148
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
149
+ opts.banner = subcommand_usage("[name] -t CODE [options]")
150
+ # opts.on('-t', '--type CODE', "Integration Type code, see `#{command_name} list-types` for available type codes") do |val|
151
+ # options[:options]['type'] = val
152
+ # end
153
+ build_option_type_options(opts, options, add_integration_option_types)
154
+ build_option_type_options(opts, options, add_integration_advanced_option_types)
155
+ build_standard_add_options(opts, options)
156
+ opts.footer = <<-EOT
157
+ Create a new integration.
158
+ [name] is required. This is the name of the new integration
159
+ Configuration options vary by integration type.
160
+ EOT
161
+ end
162
+ optparse.parse!(args)
163
+ verify_args!(args:args, optparse:optparse, min:0, max:1)
164
+ options[:options]['name'] = args[0] if args[0]
165
+ connect(options)
166
+ payload = {}
167
+ if options[:payload]
168
+ payload = options[:payload]
169
+ payload.deep_merge!({integration_object_key => parse_passed_options(options)})
170
+ else
171
+ payload.deep_merge!({integration_object_key => parse_passed_options(options)})
172
+ # Type prompt first
173
+ #params['type'] = Morpheus::Cli::OptionTypes.no_prompt([{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Instance', 'value' => 'instance'}, {'name' => 'Blueprint', 'value' => 'blueprint'}, {'name' => 'Workflow', 'value' => 'workflow'}], 'defaultValue' => 'instance', 'required' => true}], options[:options], @api_client, options[:params])['type']
174
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(add_integration_option_types(), options[:options], @api_client, options[:params])
175
+ params.deep_merge!(v_prompt)
176
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_integration_advanced_option_types, options[:options], @api_client, options[:params])
177
+ advanced_config.deep_compact!
178
+ params.deep_merge!(advanced_config)
179
+
180
+ # lookup type by name or code to validate it exists and to prompt for its optionTypes
181
+ # set integration.type=code because the api expects it that way.
182
+ if params['type'].to_s.empty?
183
+ raise_command_error "missing required option: --type TYPE", args, optparse
184
+ end
185
+ integration_type = find_integration_type_by_name_or_code_id(params['type'])
186
+ if integration_type.nil?
187
+ return 1, "integration type not found for #{params['type']}"
188
+ end
189
+ params['type'] = integration_type['code']
190
+ config_option_types = integration_type['optionTypes']
191
+ if config_option_types.nil?
192
+ config_option_types = @integration_types_interface.option_types(integration_type['id'])['optionTypes']
193
+ end
194
+ if config_option_types.nil?
195
+ print yellow,"No option types found for integration type: #{integration_type['name']} (#{integration_type['code']})", reset, "\n"
196
+ end
197
+ if config_option_types && config_option_types.size > 0
198
+ # optionTypes do not need fieldContext: 'integration'
199
+ config_option_types.each do |opt|
200
+ if opt['fieldContext'] == 'integration' || opt['fieldContext'] == 'domain'
201
+ opt['fieldContext'] = nil
202
+ end
203
+ end
204
+ config_prompt = Morpheus::Cli::OptionTypes.prompt(config_option_types, options[:options], @api_client, options[:params])
205
+ config_prompt.deep_compact!
206
+ params.deep_merge!(config_prompt)
42
207
  end
43
- json_response = @integrations_interface.list(params)
208
+ # convert checkbox "on" and "off" to true and false
209
+ params.booleanize!
210
+ payload[integration_object_key].deep_merge!(params)
211
+ end
212
+ @integrations_interface.setopts(options)
213
+ if options[:dry_run]
214
+ print_dry_run @integrations_interface.dry.create(payload)
215
+ return 0, nil
216
+ end
217
+ json_response = @integrations_interface.create(payload)
218
+ integration = json_response[integration_object_key]
219
+ render_response(json_response, options, integration_object_key) do
220
+ print_green_success "Added integration #{integration['name']}"
221
+ return _get(integration["id"], {}, options)
222
+ end
223
+ return 0, nil
224
+ end
44
225
 
45
- render_result = render_with_format(json_response, options, 'integrations')
46
- return 0 if render_result
226
+ def update(args)
227
+ options = {}
228
+ params = {}
229
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
230
+ opts.banner = subcommand_usage("[integration] [options]")
231
+ build_option_type_options(opts, options, update_integration_option_types)
232
+ build_option_type_options(opts, options, update_integration_advanced_option_types)
233
+ opts.on(nil, '--no-refresh', "Skip refresh on update.") do
234
+ params['refresh'] = 'false'
235
+ end
236
+ build_standard_update_options(opts, options)
237
+ opts.footer = <<-EOT
238
+ Update an integration.
239
+ [integration] is required. This is the name or id of an integration.
240
+ EOT
241
+ end
242
+ optparse.parse!(args)
243
+ verify_args!(args:args, optparse:optparse, count:1)
244
+ connect(options)
245
+ integration = find_integration_by_name_or_id(args[0])
246
+ return 1 if integration.nil?
247
+ payload = {}
248
+ if options[:payload]
249
+ payload = options[:payload]
250
+ payload.deep_merge!({integration_object_key => parse_passed_options(options)})
251
+ else
252
+ payload.deep_merge!({integration_object_key => parse_passed_options(options)})
253
+ # do not prompt on update
254
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_integration_option_types, options[:options], @api_client, options[:params])
255
+ v_prompt.deep_compact!
256
+ params.deep_merge!(v_prompt)
257
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_integration_advanced_option_types, options[:options], @api_client, options[:params])
258
+ advanced_config.deep_compact!
259
+ params.deep_merge!(advanced_config)
260
+ # convert checkbox "on" and "off" to true and false
261
+ params.booleanize!
262
+ # massage association params a bit
263
+
264
+ payload.deep_merge!({integration_object_key => params})
265
+ if payload[integration_object_key].empty? # || options[:no_prompt]
266
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
267
+ end
268
+ end
269
+ @integrations_interface.setopts(options)
270
+ if options[:dry_run]
271
+ print_dry_run @integrations_interface.dry.update(integration['id'], payload)
272
+ return
273
+ end
274
+ json_response = @integrations_interface.update(integration['id'], payload)
275
+ integration = json_response[integration_object_key]
276
+ render_response(json_response, options, integration_object_key) do
277
+ print_green_success "Updated integration #{integration['name']}"
278
+ return _get(integration["id"], {}, options)
279
+ end
280
+ return 0, nil
281
+ end
282
+
283
+ def refresh(args)
284
+ options = {}
285
+ query_params = {}
286
+ params = {}
287
+ payload = {}
288
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
289
+ opts.banner = subcommand_usage("[integration] [options]")
290
+ build_option_type_options(opts, options, update_integration_option_types)
291
+ build_option_type_options(opts, options, update_integration_advanced_option_types)
292
+ build_standard_update_options(opts, options)
293
+ opts.footer = <<-EOT
294
+ Refresh an integration.
295
+ [integration] is required. This is the name or id of an integration.
296
+ EOT
297
+ end
298
+ optparse.parse!(args)
299
+ verify_args!(args:args, optparse:optparse, count:1)
300
+ connect(options)
301
+ query_params.merge!(parse_query_options(options))
302
+ integration = find_integration_by_name_or_id(args[0])
303
+ return 1 if integration.nil?
304
+ payload = {}
305
+ if options[:payload]
306
+ payload = options[:payload]
307
+ payload.deep_merge!({integration_object_key => parse_passed_options(options)})
308
+ else
309
+ payload.deep_merge!({integration_object_key => parse_passed_options(options)})
310
+ end
311
+ @integrations_interface.setopts(options)
312
+ if options[:dry_run]
313
+ print_dry_run @integrations_interface.dry.refresh(integration['id'], query_params, payload)
314
+ return
315
+ end
316
+ json_response = @integrations_interface.refresh(integration['id'], query_params, payload)
317
+ integration = json_response[integration_object_key]
318
+ render_response(json_response, options, integration_object_key) do
319
+ print_green_success "Refreshed integration #{integration['name']}"
320
+ return _get(integration["id"], {}, options)
321
+ end
322
+ return 0, nil
323
+ end
47
324
 
48
- title = "Morpheus Integrations"
49
- subtitles = []
50
- subtitles += parse_list_subtitles(options)
51
- print_h1 title, subtitles
325
+ def remove(args)
326
+ options = {}
327
+ params = {}
328
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
329
+ opts.banner = subcommand_usage("[integration] [options]")
330
+ build_standard_remove_options(opts, options)
331
+ opts.footer = <<-EOT
332
+ Delete an integration.
333
+ [integration] is required. This is the name or id of an integration.
334
+ EOT
335
+ end
336
+ optparse.parse!(args)
337
+ verify_args!(args:args, optparse:optparse, count:1)
338
+ connect(options)
339
+ integration = find_integration_by_name_or_id(args[0])
340
+ return 1 if integration.nil?
341
+ @integrations_interface.setopts(options)
342
+ if options[:dry_run]
343
+ print_dry_run @integrations_interface.dry.destroy(integration['id'], params)
344
+ return
345
+ end
346
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the integration #{integration['name']}?")
347
+ return 9, "aborted command"
348
+ end
349
+ json_response = @integrations_interface.destroy(integration['id'], params)
350
+ render_response(json_response, options) do
351
+ print_green_success "Removed integration #{integration['name']}"
352
+ end
353
+ return 0, nil
354
+ end
52
355
 
53
- integrations = json_response['integrations']
54
356
 
55
- if integrations.empty?
56
- print cyan,"No integrations found.",reset,"\n"
357
+ def list_types(args)
358
+ options = {}
359
+ params = {}
360
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
361
+ opts.banner = subcommand_usage("[search]")
362
+ opts.on('--optionTypes [true|false]', String, "Include optionTypes in the response. Default is false.") do |val|
363
+ params['optionTypes'] = (val.to_s == '' || val.to_s == 'on' || val.to_s == 'true')
364
+ end
365
+ build_standard_list_options(opts, options)
366
+ opts.footer = "List integration types."
367
+ end
368
+ optparse.parse!(args)
369
+ connect(options)
370
+ # verify_args!(args:args, optparse:optparse, count:0)
371
+ if args.count > 0
372
+ options[:phrase] = args.join(" ")
373
+ end
374
+ params.merge!(parse_list_options(options))
375
+ @integration_types_interface.setopts(options)
376
+ if options[:dry_run]
377
+ print_dry_run @integration_types_interface.dry.list(params)
378
+ return
379
+ end
380
+ json_response = @integration_types_interface.list(params)
381
+ render_response(json_response, options, integration_type_list_key) do
382
+ integration_types = json_response[integration_type_list_key]
383
+ print_h1 "Morpheus Integration Types", parse_list_subtitles(options), options
384
+ if integration_types.empty?
385
+ print cyan,"No integration types found.",reset,"\n"
57
386
  else
58
- rows = integrations.collect do |it|
59
- {
60
- id: it['id'],
61
- name: it['name'],
62
- status: format_integration_status(it),
63
- last_updated: format_local_dt(it['statusDate']),
64
- type: it['integrationType'] ? it['integrationType']['name'] : ''
65
- }
66
- end
67
- columns = [ :id, :name, :status, :last_updated, :type]
68
- print as_pretty_table(rows, columns)
387
+ list_columns = integration_type_column_definitions.upcase_keys!
388
+ print as_pretty_table(integration_types, list_columns, options)
389
+ print_results_pagination(json_response)
69
390
  end
70
391
  print reset,"\n"
71
- return 0
72
- rescue RestClient::Exception => e
73
- print_rest_exception(e, options)
74
- exit 1
75
392
  end
393
+ return 0, nil
394
+ end
395
+
396
+ def get_type(args)
397
+ params = {'optionTypes' => true}
398
+ options = {}
399
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
400
+ opts.banner = subcommand_usage("[type]")
401
+ build_standard_get_options(opts, options)
402
+ opts.on('--optionTypes [true|false]', String, "Include optionTypes in the response. Default is true.") do |val|
403
+ params['optionTypes'] = (val.to_s == '' || val.to_s == 'on' || val.to_s == 'true')
404
+ end
405
+ opts.footer = <<-EOT
406
+ Get details about a specific integration type.
407
+ [type] is required. This is the name or id of an integration type.
408
+ EOT
409
+ end
410
+ optparse.parse!(args)
411
+ verify_args!(args:args, optparse:optparse, min:1)
412
+ connect(options)
413
+ params.merge!(parse_query_options(options))
414
+ id_list = parse_id_list(args)
415
+ return run_command_for_each_arg(id_list) do |arg|
416
+ _get_type(arg, params, options)
417
+ end
418
+ end
419
+
420
+ def _get_type(id, params, options)
421
+ integration_type = nil
422
+ if id.to_s !~ /\A\d{1,}\Z/
423
+ integration_type = find_integration_type_by_name_or_code(id)
424
+ return 1, "integration type not found for name or code '#{id}'" if integration_type.nil?
425
+ id = integration_type['id']
426
+ end
427
+ # /api/integration-types does not return optionTypes by default, use ?optionTypes=true
428
+ @integration_types_interface.setopts(options)
429
+ if options[:dry_run]
430
+ print_dry_run @integration_types_interface.dry.get(id, params)
431
+ return
432
+ end
433
+ json_response = @integration_types_interface.get(id, params)
434
+ integration_type = json_response[integration_type_object_key]
435
+ render_response(json_response, options, integration_type_object_key) do
436
+ print_h1 "Integration Type Details", [], options
437
+ print cyan
438
+ show_columns = integration_type_column_definitions
439
+ print_description_list(show_columns, integration_type)
440
+
441
+ if integration_type['optionTypes'] && integration_type['optionTypes'].size > 0
442
+ print_h2 "Option Types"
443
+ opt_columns = [
444
+ # {"ID" => lambda {|it| it['id'] } },
445
+ {"FIELD NAME" => lambda {|it| (it['fieldContext'] && it['fieldContext'] != 'integration') ? [it['fieldContext'], it['fieldName']].join('.') : it['fieldName'] } },
446
+ {"FIELD LABEL" => lambda {|it| it['fieldLabel'] } },
447
+ {"TYPE" => lambda {|it| it['type'] } },
448
+ {"DEFAULT" => lambda {|it| it['defaultValue'] } },
449
+ {"REQUIRED" => lambda {|it| format_boolean it['required'] } },
450
+ # {"DESCRIPTION" => lambda {|it| it['description'] }, # do it!
451
+ ]
452
+ print as_pretty_table(integration_type['optionTypes'], opt_columns)
453
+ else
454
+ # print cyan,"No option types found for this integration type.","\n",reset
455
+ end
456
+
457
+ print reset,"\n"
458
+ end
459
+ return 0, nil
76
460
  end
77
461
 
78
462
  private
79
463
 
464
+ def format_integration_type(integration)
465
+ (integration['integrationType']['name'] || integration['integrationType']['code']) rescue integration['integrationType'].to_s
466
+ end
467
+
468
+ def add_integration_option_types
469
+ [
470
+ {'code' => 'integration.type', 'shorthand' => '-t', 'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
471
+ # @integration_types_interface.list(max:-1)[integration_list_key].collect {|it|
472
+ get_available_integration_types().collect {|it|
473
+ {'name' => it['name'], 'value' => it['code']}
474
+ } }, 'required' => true, 'description' => "Integration Type code, see `#{command_name} list-types` for available type codes"},
475
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name of the integration'},
476
+ # {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text'},
477
+ {'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'defaultValue' => true, 'description' => 'Can be used to disable an integration'}
478
+ ]
479
+ end
480
+
481
+ def add_integration_advanced_option_types
482
+ []
483
+ end
484
+
485
+ def update_integration_option_types
486
+ list = add_integration_option_types.collect {|it|
487
+ it.delete('required')
488
+ it.delete('defaultValue')
489
+ it
490
+ }
491
+ list = list.reject {|it| ["type"].include? it['fieldName'] }
492
+ list
493
+ end
494
+
495
+ def update_integration_advanced_option_types
496
+ add_integration_advanced_option_types.collect {|it|
497
+ it.delete('required')
498
+ it.delete('defaultValue')
499
+ it
500
+ }
501
+ end
502
+
503
+ def integration_object_key
504
+ 'integration'
505
+ end
506
+
507
+ def integration_list_key
508
+ 'integrations'
509
+ end
510
+
511
+ def find_integration_by_name_or_id(val)
512
+ if val.to_s =~ /\A\d{1,}\Z/
513
+ return find_integration_by_id(val)
514
+ else
515
+ return find_integration_by_name(val)
516
+ end
517
+ end
518
+
519
+ def find_integration_by_id(id)
520
+ begin
521
+ json_response = @integrations_interface.get(id.to_i)
522
+ return json_response[integration_object_key]
523
+ rescue RestClient::Exception => e
524
+ if e.response && e.response.code == 404
525
+ print_red_alert "integration not found by id '#{id}'"
526
+ else
527
+ raise e
528
+ end
529
+ end
530
+ end
531
+
532
+ def find_integration_by_name(name)
533
+ json_response = @integrations_interface.list({name: name.to_s})
534
+ integrations = json_response[integration_list_key]
535
+ if integrations.empty?
536
+ print_red_alert "integration not found by name '#{name}'"
537
+ return nil
538
+ elsif integrations.size > 1
539
+ print_red_alert "#{integrations.size} integrations found by name '#{name}'"
540
+ puts_error as_pretty_table(integrations, [:id, :name], {color:red})
541
+ print_red_alert "Try using ID instead"
542
+ print reset,"\n"
543
+ return nil
544
+ else
545
+ return integrations[0]
546
+ end
547
+ end
548
+
80
549
  def format_integration_status(integration, return_color=cyan)
81
550
  out = ""
82
551
  status_string = integration['status']
83
- if integration['enabled'] == false
84
- out << "#{red}DISABLED#{integration['statusMessage'] ? "#{return_color} - #{integration['statusMessage']}" : ''}#{return_color}"
85
- elsif status_string.nil? || status_string.empty? || status_string == "unknown"
552
+ if status_string.nil? || status_string.empty? || status_string == "unknown"
86
553
  out << "#{white}UNKNOWN#{integration['statusMessage'] ? "#{return_color} - #{integration['statusMessage']}" : ''}#{return_color}"
554
+ # elsif integration['enabled'] == false
555
+ # out << "#{red}DISABLED#{integration['statusMessage'] ? "#{return_color} - #{integration['statusMessage']}" : ''}#{return_color}"
87
556
  elsif status_string == 'ok'
88
557
  out << "#{green}#{status_string.upcase}#{return_color}"
89
558
  elsif status_string == 'error' || status_string == 'offline'
@@ -94,4 +563,82 @@ class Morpheus::Cli::IntegrationsCommand
94
563
  out
95
564
  end
96
565
 
566
+
567
+ def integration_type_column_definitions()
568
+ {
569
+ "ID" => 'id',
570
+ "Code" => 'code',
571
+ "Name" => 'name',
572
+ # "Description" => 'description',
573
+ "Category" => 'category',
574
+ # "Enabled" => lambda {|it| format_boolean(it['enabled']) },
575
+ "Creatable" => lambda {|it| format_boolean(it['creatable']) },
576
+ }
577
+ end
578
+
579
+ def integration_type_object_key
580
+ 'integrationType'
581
+ end
582
+
583
+ def integration_type_list_key
584
+ 'integrationTypes'
585
+ end
586
+
587
+ def find_integration_type_by_name_or_code_id(val, params={})
588
+ if val.to_s =~ /\A\d{1,}\Z/
589
+ return find_integration_type_by_id(val, params)
590
+ else
591
+ return find_integration_type_by_name_or_code(val)
592
+ end
593
+ end
594
+
595
+ def find_integration_type_by_id(id, params={})
596
+ begin
597
+ json_response = @integration_types_interface.get(id.to_i, params)
598
+ return json_response[integration_object_key]
599
+ rescue RestClient::Exception => e
600
+ if e.response && e.response.code == 404
601
+ print_red_alert "integration not found by id '#{id}'"
602
+ else
603
+ raise e
604
+ end
605
+ end
606
+ end
607
+
608
+ def find_integration_type_by_name(name, params={})
609
+ json_response = @integration_types_interface.list(params.merge({name: name.to_s}))
610
+ integration_types = json_response[integration_type_list_key]
611
+ if integration_types.empty?
612
+ print_red_alert "integration type not found by name '#{name}'"
613
+ return nil
614
+ elsif integration_types.size > 1
615
+ print_red_alert "#{integration_types.size} integration types found by name '#{name}'"
616
+ puts_error as_pretty_table(integration_types, [:id, :code, :name], {color:red})
617
+ print_red_alert "Try using ID instead"
618
+ print reset,"\n"
619
+ return nil
620
+ else
621
+ return integration_types[0]
622
+ end
623
+ end
624
+
625
+ def get_available_integration_types(refresh=false)
626
+ if !@available_integration_types || refresh
627
+ @available_integration_types = @integration_types_interface.list(max:10000)[integration_type_list_key]
628
+ end
629
+ return @available_integration_types
630
+ end
631
+
632
+ def find_integration_type_by_name_or_code(name)
633
+ records = get_available_integration_types()
634
+ record = records.find { |z| z['name'].downcase == name.downcase || z['code'].downcase == name.downcase}
635
+ record = record ? record : records.find { |z| z['id'].to_s == name.to_s }
636
+ if record
637
+ return record
638
+ else
639
+ print_red_alert "integration type not found by '#{name}'"
640
+ return nil
641
+ end
642
+ end
643
+
97
644
  end