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.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/README.md +1 -3
- data/lib/morpheus/api/api_client.rb +48 -14
- data/lib/morpheus/api/certificate_types_interface.rb +14 -0
- data/lib/morpheus/api/certificates_interface.rb +9 -0
- data/lib/morpheus/api/integration_types_interface.rb +14 -0
- data/lib/morpheus/api/integrations_interface.rb +7 -22
- data/lib/morpheus/api/network_services_interface.rb +14 -0
- data/lib/morpheus/api/read_interface.rb +23 -0
- data/lib/morpheus/api/rest_interface.rb +12 -10
- data/lib/morpheus/api/roles_interface.rb +7 -0
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/api/user_settings_interface.rb +38 -18
- data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
- data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
- data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
- data/lib/morpheus/api/vdi_interface.rb +28 -0
- data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
- data/lib/morpheus/cli.rb +9 -2
- data/lib/morpheus/cli/apps.rb +59 -75
- data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
- data/lib/morpheus/cli/certificates_command.rb +575 -0
- data/lib/morpheus/cli/cli_command.rb +61 -6
- data/lib/morpheus/cli/clouds.rb +1 -0
- data/lib/morpheus/cli/clusters.rb +1 -1
- data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
- data/lib/morpheus/cli/hosts.rb +245 -224
- data/lib/morpheus/cli/instances.rb +150 -167
- data/lib/morpheus/cli/integrations_command.rb +588 -41
- data/lib/morpheus/cli/login.rb +7 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +33 -18
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -3
- data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
- data/lib/morpheus/cli/network_routers_command.rb +22 -9
- data/lib/morpheus/cli/networks_command.rb +2 -2
- data/lib/morpheus/cli/option_types.rb +34 -33
- data/lib/morpheus/cli/remote.rb +1 -1
- data/lib/morpheus/cli/reports_command.rb +4 -1
- data/lib/morpheus/cli/roles.rb +215 -55
- data/lib/morpheus/cli/subnets_command.rb +11 -2
- data/lib/morpheus/cli/user_settings_command.rb +268 -57
- data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
- data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
- data/lib/morpheus/cli/vdi_command.rb +359 -0
- data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
- data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/rest_client.rb +30 -0
- data/lib/morpheus/terminal.rb +15 -7
- 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
|
-
|
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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
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
|
-
|
153
|
-
|
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
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
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
|
-
|
163
|
-
|
164
|
-
params
|
165
|
-
|
166
|
-
|
167
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
201
|
+
title = "Morpheus Instances"
|
202
|
+
subtitles = []
|
203
|
+
if group
|
204
|
+
subtitles << "Group: #{group['name']}".strip
|
175
205
|
end
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
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
|
-
|
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
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
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
|
279
|
+
print cyan
|
280
|
+
print as_pretty_table(rows, columns, options)
|
281
|
+
print reset
|
282
|
+
print_results_pagination(json_response)
|
281
283
|
end
|
282
|
-
|
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
|
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
|
-
|
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
|
-
|
1254
|
-
|
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
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
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
|
-
|
46
|
-
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
56
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
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
|
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
|