morpheus-cli 5.5.1.2 → 5.5.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/instances_interface.rb +8 -0
- data/lib/morpheus/cli/commands/clusters.rb +9 -3
- data/lib/morpheus/cli/commands/deployments.rb +4 -4
- data/lib/morpheus/cli/commands/hosts.rb +1 -0
- data/lib/morpheus/cli/commands/instances.rb +51 -1
- data/lib/morpheus/cli/commands/library_container_types_command.rb +40 -6
- data/lib/morpheus/cli/commands/library_instance_types_command.rb +1 -1
- data/lib/morpheus/cli/commands/library_layouts_command.rb +1 -1
- data/lib/morpheus/cli/commands/price_sets_command.rb +15 -4
- data/lib/morpheus/cli/commands/users.rb +2 -1
- data/lib/morpheus/cli/commands/virtual_images.rb +14 -2
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +8 -0
- data/lib/morpheus/cli/option_types.rb +73 -0
- data/lib/morpheus/cli/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8637acf5e4ce4a0673114edf18f3b69604574905bf6507272411efb1abd6c684
|
4
|
+
data.tar.gz: 5cc836f09c1aa1cf164d5e7ae8fb3fa9a793cfbff0192543f45fe313404226ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4adf8fb42bfe890394b8c988144ad9153f70e0ff1e4d2159b71557c14360b0b3dd1a11aff94409a8b4bbb61b17c27af5a6ebd61ff484182fd85812c5e0d5b0e
|
7
|
+
data.tar.gz: '09af6071b1536a08fad258e3ff01330916a6e7a7c655359618d7f2ce9f00f24879b451a70cfd4ebf32498e7a048423addf9af472873fdcd5236ea04730d4fd3d'
|
data/Dockerfile
CHANGED
@@ -407,4 +407,12 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
|
|
407
407
|
execute(opts)
|
408
408
|
end
|
409
409
|
|
410
|
+
def remove_from_control(ids, params={})
|
411
|
+
url = "#{@base_url}/api/instances/removeFromControl"
|
412
|
+
payload = { ids: ids }
|
413
|
+
headers = { :params => params,:authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
414
|
+
opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
|
415
|
+
execute(opts)
|
416
|
+
end
|
417
|
+
|
410
418
|
end
|
@@ -736,9 +736,15 @@ class Morpheus::Cli::Clusters
|
|
736
736
|
opts.on("--api-url [TEXT]", String, "Updates Cluster API Url") do |val|
|
737
737
|
options[:apiUrl] = val.to_s
|
738
738
|
end
|
739
|
+
opts.on("--api-token [TEXT]", String, "Updates Cluster API Token") do |val|
|
740
|
+
options[:apiToken] = val.to_s
|
741
|
+
end
|
739
742
|
opts.on('--active [on|off]', String, "Can be used to enable / disable the cluster. Default is on") do |val|
|
740
743
|
options[:active] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
741
744
|
end
|
745
|
+
opts.on('--managed [on|off]', String, "Can be used to enable / disable managed cluster. Default is on") do |val|
|
746
|
+
options[:managed] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
747
|
+
end
|
742
748
|
opts.on( nil, '--refresh', "Refresh cluster" ) do
|
743
749
|
options[:refresh] = true
|
744
750
|
end
|
@@ -777,7 +783,9 @@ class Morpheus::Cli::Clusters
|
|
777
783
|
cluster_payload['name'] = options[:name] if !options[:name].empty?
|
778
784
|
cluster_payload['description'] = options[:description] if !options[:description].empty?
|
779
785
|
cluster_payload['enabled'] = options[:active] if !options[:active].nil?
|
786
|
+
cluster_payload['managed'] = options[:managed] if !options[:managed].nil?
|
780
787
|
cluster_payload['serviceUrl'] = options[:apiUrl] if !options[:apiUrl].nil?
|
788
|
+
cluster_payload['serviceToken'] = options[:apiToken] if !options[:apiToken].nil?
|
781
789
|
cluster_payload['refresh'] = options[:refresh] if options[:refresh] == true
|
782
790
|
cluster_payload['tenant'] = options[:tenant] if !options[:tenant].nil?
|
783
791
|
payload = {"cluster" => cluster_payload}
|
@@ -788,9 +796,7 @@ class Morpheus::Cli::Clusters
|
|
788
796
|
exit 1
|
789
797
|
end
|
790
798
|
|
791
|
-
|
792
|
-
|
793
|
-
if !has_field_updates && cluster_payload['refresh'].nil? && cluster_payload['tenant'].nil?
|
799
|
+
if cluster_payload.empty?
|
794
800
|
print_green_success "Nothing to update"
|
795
801
|
exit 1
|
796
802
|
end
|
@@ -879,10 +879,10 @@ EOT
|
|
879
879
|
def add_deployment_version_option_types
|
880
880
|
[
|
881
881
|
{'fieldName' => 'userVersion', 'fieldLabel' => 'Version', 'type' => 'text', 'required' => true, 'displayOrder' => 1, 'description' => 'This is the deployment version identifier (userVersion)'},
|
882
|
-
{'fieldName' => 'deployType', 'fieldLabel' => 'Deploy Type', 'type' => 'select', 'optionSource' => 'deployTypes', 'required' => true, 'displayOrder' =>
|
883
|
-
{'fieldName' => 'fetchUrl', 'fieldLabel' => 'Fetch URL', 'type' => '
|
884
|
-
{'fieldName' => 'gitUrl', 'fieldLabel' => 'Git URL', 'type' => 'string', 'required' => true, 'displayOrder' =>
|
885
|
-
{'fieldName' => 'gitRef', 'fieldLabel' => 'Git Ref', 'type' => 'string', 'displayOrder' =>
|
882
|
+
{'fieldName' => 'deployType', 'fieldLabel' => 'Deploy Type', 'type' => 'select', 'optionSource' => 'deployTypes', 'required' => true, 'displayOrder' => 2, 'description' => 'This is the deployment version identifier (userVersion)', 'defaultValue' => 'file', 'code' => 'deployment.deployType'},
|
883
|
+
{'fieldName' => 'fetchUrl', 'fieldLabel' => 'Fetch URL', 'type' => 'string', 'required' => true, 'displayOrder' => 3, 'description' => 'The URL to fetch the deployment file(s) from.', 'dependsOnCode' => 'deployment.deployType:fetch'},
|
884
|
+
{'fieldName' => 'gitUrl', 'fieldLabel' => 'Git URL', 'type' => 'string', 'required' => true, 'displayOrder' => 4, 'description' => 'The URL to fetch the deployment file(s) from.', 'dependsOnCode' => 'deployment.deployType:git'},
|
885
|
+
{'fieldName' => 'gitRef', 'fieldLabel' => 'Git Ref', 'type' => 'string', 'displayOrder' => 5, 'description' => 'The Git Reference to use, this the branch or tag name, defaults to master.', 'dependsOnCode' => 'deployment.deployType:git'}
|
886
886
|
]
|
887
887
|
end
|
888
888
|
|
@@ -537,6 +537,7 @@ class Morpheus::Cli::Hosts
|
|
537
537
|
# "Status" => lambda {|it| format_server_status(it) },
|
538
538
|
# "Power" => lambda {|it| format_server_power_state(it) },
|
539
539
|
"Status" => lambda {|it| format_server_status_friendly(it) }, # combo
|
540
|
+
"Managed" => lambda {|it| it['computeServerType'] ? it['computeServerType']['managed'] : ''}
|
540
541
|
}
|
541
542
|
server_columns.delete("Hostname") if server['hostname'].to_s.empty? || server['hostname'] == server['name']
|
542
543
|
server_columns.delete("IP") if server['externalIp'].to_s.empty?
|
@@ -13,7 +13,7 @@ class Morpheus::Cli::Instances
|
|
13
13
|
set_command_name :instances
|
14
14
|
set_command_description "View and manage instances."
|
15
15
|
register_subcommands :list, :count, :get, :view, :add, :update, :remove,
|
16
|
-
:cancel_removal, :cancel_expiration, :cancel_shutdown, :extend_expiration, :extend_shutdown,
|
16
|
+
:cancel_removal, :cancel_expiration, :cancel_shutdown, :extend_expiration, :extend_shutdown, :remove_from_control,
|
17
17
|
:history, {:'history-details' => :history_details}, {:'history-event' => :history_event_details},
|
18
18
|
:logs, :stats, :stop, :start, :restart, :actions, :action, :suspend, :eject, :stop_service, :start_service, :restart_service,
|
19
19
|
:backup, :backups, :resize, :clone, :envs, :setenv, :delenv,
|
@@ -3054,6 +3054,56 @@ EOT
|
|
3054
3054
|
return 0, nil
|
3055
3055
|
end
|
3056
3056
|
|
3057
|
+
def remove_from_control(args)
|
3058
|
+
params = {}
|
3059
|
+
options = {}
|
3060
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
3061
|
+
opts.banner = subcommand_usage("[name or id]")
|
3062
|
+
opts.footer = "Remove a brownfield instance from Morpheus. This does not delete the cloud instance, only Morpheus' record of it.\n" +
|
3063
|
+
"[name or id] is required. The name or the id of the instance may be listed.\n" +
|
3064
|
+
"[name or id] [name or id] [name or id] ... A list of names or ids, separated by a space, may be used for bulk removal."
|
3065
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
3066
|
+
end
|
3067
|
+
optparse.parse!(args)
|
3068
|
+
if args.count < 1
|
3069
|
+
puts optparse
|
3070
|
+
exit 1
|
3071
|
+
end
|
3072
|
+
connect(options)
|
3073
|
+
begin
|
3074
|
+
instance_ids = parse_id_list(args)
|
3075
|
+
instances = []
|
3076
|
+
instance_ids.each do |instance_id|
|
3077
|
+
instance = find_instance_by_name_or_id(instance_id)
|
3078
|
+
return 1 if instance.nil?
|
3079
|
+
instances << instance
|
3080
|
+
end
|
3081
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove #{instances.size == 1 ? 'instance' : (instances.size.to_s + ' instances')} #{anded_list(instances.collect {|it| it['name'] })}?", options)
|
3082
|
+
return 9, "aborted command"
|
3083
|
+
end
|
3084
|
+
@instances_interface.setopts(options)
|
3085
|
+
if options[:dry_run]
|
3086
|
+
print_dry_run @instances_interface.dry.remove_from_control(instances.collect {|it| it['id'] }, params)
|
3087
|
+
return
|
3088
|
+
end
|
3089
|
+
json_response = @instances_interface.remove_from_control(instances.collect {|it| it['id'] }, params)
|
3090
|
+
if options[:json]
|
3091
|
+
puts as_json(json_response, options)
|
3092
|
+
elsif !options[:quiet]
|
3093
|
+
puts json_response
|
3094
|
+
if json_response['success'] == false
|
3095
|
+
print_red_alert json_response['msg']
|
3096
|
+
else
|
3097
|
+
print_green_success json_response['msg']
|
3098
|
+
end
|
3099
|
+
end
|
3100
|
+
return 0
|
3101
|
+
rescue RestClient::Exception => e
|
3102
|
+
print_rest_exception(e, options)
|
3103
|
+
exit 1
|
3104
|
+
end
|
3105
|
+
end
|
3106
|
+
|
3057
3107
|
def firewall_disable(args)
|
3058
3108
|
options = {}
|
3059
3109
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
@@ -180,7 +180,7 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
180
180
|
{"VALUE" => lambda {|it| it['defaultValue'] } },
|
181
181
|
{"TYPE" => lambda {|it| it['valueType'].to_s.capitalize } },
|
182
182
|
{"EXPORT" => lambda {|it| format_boolean it['export'] } },
|
183
|
-
{"MASKED" => lambda {|it| format_boolean it['
|
183
|
+
{"MASKED" => lambda {|it| format_boolean it['masked'] } },
|
184
184
|
]
|
185
185
|
print as_pretty_table(evars, evar_columns)
|
186
186
|
else
|
@@ -255,6 +255,21 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
255
255
|
opts.on('--technology CODE', String, "Technology. This is the provision type code.") do |val|
|
256
256
|
params['provisionTypeCode'] = val
|
257
257
|
end
|
258
|
+
opts.on('--evars-json JSON', String, 'Environment variables JSON: {"name":"Foo", "value":"Bar", "masked":true, "export":true}' ) do |val|
|
259
|
+
begin
|
260
|
+
evars = JSON.parse(val.to_s)
|
261
|
+
evars = evars.kind_of?(Array) ? evars : [evars]
|
262
|
+
rescue JSON::ParserError => e
|
263
|
+
print_red_alert "Unable to parse evars JSON"
|
264
|
+
exit 1
|
265
|
+
end
|
266
|
+
end
|
267
|
+
opts.on('-e', '--evars LIST', Array, "Environment variables list. Comma delimited list of name=value pairs") do |val|
|
268
|
+
evars = val.collect do |nv|
|
269
|
+
parts = nv.split('=')
|
270
|
+
{'name' => parts[0].strip, 'value' => (parts.count > 1 ? parts[1].strip : '')}
|
271
|
+
end
|
272
|
+
end
|
258
273
|
opts.on('--ports NAME=PORT,NAME=PORT', String, "List of exposed port definitions in the format NAME=PORT|PROTOCOL, Example: \"WEB=80|HTTP,SECURE=443|HTTPS\"") do |val|
|
259
274
|
params['containerPorts'] ||= []
|
260
275
|
parsed_ports = val.split(",").each do |value_pair|
|
@@ -358,7 +373,7 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
358
373
|
# print "\n"
|
359
374
|
puts field_group_name
|
360
375
|
puts "==============="
|
361
|
-
provision_type_v_prompt = Morpheus::Cli::OptionTypes.prompt(provision_type_custom_option_types,options[:options],@api_client, {
|
376
|
+
provision_type_v_prompt = Morpheus::Cli::OptionTypes.prompt(provision_type_custom_option_types,options[:options],@api_client, {provisionTypeCode: params['provisionTypeCode']})
|
362
377
|
end
|
363
378
|
|
364
379
|
# payload.deep_merge!(provision_type_v_prompt)
|
@@ -371,7 +386,9 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
371
386
|
|
372
387
|
# ENVIRONMENT VARIABLES
|
373
388
|
if evars
|
374
|
-
|
389
|
+
# bug before 5.4.10/5.5.2 requires this to be passed at the root of the request instead of under containerType.
|
390
|
+
# params['environmentVariables'] = evars
|
391
|
+
payload['environmentVariables'] = evars
|
375
392
|
else
|
376
393
|
# prompt
|
377
394
|
# parsed_evars = parse_environment_variables
|
@@ -386,7 +403,7 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
386
403
|
|
387
404
|
# FILE TEMPLATES
|
388
405
|
if file_template_ids
|
389
|
-
params['
|
406
|
+
params['templates'] = file_template_ids.collect {|it| it.to_i }.select { |it| it != 0 }
|
390
407
|
else
|
391
408
|
# prompt
|
392
409
|
end
|
@@ -447,6 +464,21 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
447
464
|
# opts.on('--technology CODE', String, "Technology") do |val|
|
448
465
|
# params['provisionTypeCode'] = val
|
449
466
|
# end
|
467
|
+
opts.on('--evars-json JSON', String, 'Environment variables JSON: {"name":"Foo", "value":"Bar", "masked":true, "export":true}' ) do |val|
|
468
|
+
begin
|
469
|
+
evars = JSON.parse(val.to_s)
|
470
|
+
evars = evars.kind_of?(Array) ? evars : [evars]
|
471
|
+
rescue JSON::ParserError => e
|
472
|
+
print_red_alert "Unable to parse evars JSON"
|
473
|
+
exit 1
|
474
|
+
end
|
475
|
+
end
|
476
|
+
opts.on('-e', '--evars LIST', Array, "Environment variables list. Comma delimited list of name=value pairs") do |val|
|
477
|
+
evars = val.collect do |nv|
|
478
|
+
parts = nv.split('=')
|
479
|
+
{'name' => parts[0].strip, 'value' => (parts.count > 1 ? parts[1].strip : '')}
|
480
|
+
end
|
481
|
+
end
|
450
482
|
opts.on('--ports NAME=PORT,NAME=PORT', String, "List of exposed port definitions in the format NAME=PORT|PROTOCOL, Example: \"WEB=80|HTTP,SECURE=443|HTTPS\"") do |val|
|
451
483
|
params['containerPorts'] ||= []
|
452
484
|
parsed_ports = val.split(",").each do |value_pair|
|
@@ -506,7 +538,9 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
506
538
|
|
507
539
|
# ENVIRONMENT VARIABLES
|
508
540
|
if evars
|
509
|
-
|
541
|
+
# bug before 5.4.10/5.5.2 requires this to be passed at the root of the request instead of under containerType.
|
542
|
+
# params['environmentVariables'] = evars
|
543
|
+
payload['environmentVariables'] = evars
|
510
544
|
else
|
511
545
|
# prompt
|
512
546
|
end
|
@@ -525,7 +559,7 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
525
559
|
# prompt
|
526
560
|
end
|
527
561
|
|
528
|
-
if params.empty? && passed_options.empty?
|
562
|
+
if params.empty? && passed_options.empty? && evars.nil?
|
529
563
|
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
530
564
|
end
|
531
565
|
|
@@ -187,7 +187,7 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
|
|
187
187
|
{"VALUE" => lambda {|it| it['defaultValue'] } },
|
188
188
|
{"TYPE" => lambda {|it| it['valueType'].to_s.capitalize } },
|
189
189
|
{"EXPORT" => lambda {|it| format_boolean it['export'] } },
|
190
|
-
{"MASKED" => lambda {|it| format_boolean it['
|
190
|
+
{"MASKED" => lambda {|it| format_boolean it['masked'] } },
|
191
191
|
]
|
192
192
|
print as_pretty_table(instance_type_evars, evar_columns)
|
193
193
|
else
|
@@ -214,7 +214,7 @@ EOT
|
|
214
214
|
{"VALUE" => lambda {|it| it['defaultValue'] } },
|
215
215
|
{"TYPE" => lambda {|it| it['valueType'].to_s.capitalize } },
|
216
216
|
{"EXPORT" => lambda {|it| format_boolean it['export'] } },
|
217
|
-
{"MASKED" => lambda {|it| format_boolean it['
|
217
|
+
{"MASKED" => lambda {|it| format_boolean it['masked'] } },
|
218
218
|
]
|
219
219
|
print as_pretty_table(layout_evars, evar_columns)
|
220
220
|
else
|
@@ -193,7 +193,7 @@ class Morpheus::Cli::PriceSetsCommand
|
|
193
193
|
end
|
194
194
|
end
|
195
195
|
opts.on('-t', "--type [TYPE]", String, "Price set type") do |val|
|
196
|
-
if ['fixed', 'compute_plus_storage', 'component'].include?(val)
|
196
|
+
if ['fixed', 'compute_plus_storage', 'component','load_balancer','snapshot','virtual_image','software_or_service'].include?(val)
|
197
197
|
params['type'] = val
|
198
198
|
else
|
199
199
|
raise_command_error "Unrecognized price set type #{val}"
|
@@ -268,7 +268,7 @@ class Morpheus::Cli::PriceSetsCommand
|
|
268
268
|
end
|
269
269
|
|
270
270
|
# type
|
271
|
-
params['type'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'type' => 'select', 'fieldLabel' => 'Price Set Type', 'selectOptions' => [{'name' => 'Everything', 'value' => 'fixed'}, {'name' => 'Compute + Storage', 'value' => 'compute_plus_storage'}, {'name' => 'Component', 'value' => 'component'}], 'required' => true, 'description' => 'Price Set Type.'}],options[:options],@api_client,{}, options[:no_prompt])['type']
|
271
|
+
params['type'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'type' => 'select', 'fieldLabel' => 'Price Set Type', 'selectOptions' => [{'name' => 'Everything', 'value' => 'fixed'}, {'name' => 'Compute + Storage', 'value' => 'compute_plus_storage'}, {'name' => 'Component', 'value' => 'component'}, {'name' => 'Load Balancer', 'value' => 'load_balancer'},{'name' => 'Snapshot', 'value' => 'snapshot'},{'name' => 'Virtual Image', 'value' => 'virtual_image'},{'name' => 'Software / Service', 'value' => 'software_or_service'}], 'required' => true, 'description' => 'Price Set Type.'}],options[:options],@api_client,{}, options[:no_prompt])['type']
|
272
272
|
if params['type'].nil?
|
273
273
|
print_red_alert "Type is required"
|
274
274
|
exit 1
|
@@ -491,7 +491,12 @@ class Morpheus::Cli::PriceSetsCommand
|
|
491
491
|
end
|
492
492
|
|
493
493
|
def price_set_type_label(type)
|
494
|
-
price_set_types[type]
|
494
|
+
price_set_type = price_set_types[type]
|
495
|
+
if price_set_type.nil?
|
496
|
+
type.capitalize
|
497
|
+
else
|
498
|
+
price_set_type[:label]
|
499
|
+
end
|
495
500
|
end
|
496
501
|
|
497
502
|
def price_type_label(type)
|
@@ -503,7 +508,9 @@ class Morpheus::Cli::PriceSetsCommand
|
|
503
508
|
'storage' => 'Disk Only (per GB)',
|
504
509
|
'datastore' => 'Datastore (per GB)',
|
505
510
|
'platform' => 'Platform',
|
506
|
-
'software' => 'Software'
|
511
|
+
'software' => 'Software',
|
512
|
+
'load_balancer' => 'Load Balancer',
|
513
|
+
'load_balancer_virtual_server' => 'Load Balancer Virtual Server'
|
507
514
|
}[type] || type.capitalize
|
508
515
|
end
|
509
516
|
|
@@ -516,6 +523,10 @@ class Morpheus::Cli::PriceSetsCommand
|
|
516
523
|
'fixed' => {:label => 'Everything', :requires => ['fixed'], :allows => ['platform', 'software']},
|
517
524
|
'compute_plus_storage' => {:label => 'Compute + Storage', :requires => ['compute', 'storage'], :allows => ['platform', 'software']},
|
518
525
|
'component' => {:label => 'Component', :requires => ['memory', 'cores', 'storage'], :allows => ['platform', 'software']},
|
526
|
+
'load_balancer' => {:label => 'Load Balancer', :requires => ['load_balancer'], :allows => ['load_balancer_virtual_server']},
|
527
|
+
'snapshot' => {:label => 'Snapshot', :requires => ['storage'], :allows => ['storage', 'datastore']},
|
528
|
+
'virtual_image' => {:label => 'Virtual Image', :requires => ['storage'], :allows => []},
|
529
|
+
'software_or_service' => {:label => 'Software / Service', :requires => ['software'], :allows => []},
|
519
530
|
}
|
520
531
|
end
|
521
532
|
|
@@ -577,6 +577,7 @@ EOT
|
|
577
577
|
def change_password(args)
|
578
578
|
params = {}
|
579
579
|
options = {}
|
580
|
+
payload = {}
|
580
581
|
new_password = nil
|
581
582
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
582
583
|
opts.banner = subcommand_usage("[user] [password] [options]")
|
@@ -651,7 +652,7 @@ EOT
|
|
651
652
|
return
|
652
653
|
end
|
653
654
|
json_response = @account_users_interface.update(account_id, user['id'], payload)
|
654
|
-
render_response(json_response,
|
655
|
+
render_response(json_response, options, "user") do
|
655
656
|
print_green_success "Updated password for user #{user['username']}"
|
656
657
|
end
|
657
658
|
return exit_code, err
|
@@ -1019,7 +1019,14 @@ EOT
|
|
1019
1019
|
|
1020
1020
|
# Marketplace Publisher & Offer
|
1021
1021
|
marketplace_api_params = {'zoneId' => cloud_id}
|
1022
|
-
v_prompt =
|
1022
|
+
v_prompt = nil
|
1023
|
+
# API endpoints moved from /api/options to /api/options/azure...
|
1024
|
+
begin
|
1025
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'offer', 'fieldLabel' => 'Azure Marketplace Offer', 'type' => 'typeahead', 'optionSourceType' => 'azure', 'optionSource' => 'searchAzureMarketplace', 'required' => true, 'description' => "Select Azure Marketplace Offer."}], options[:options],@api_client, marketplace_api_params)
|
1026
|
+
rescue => ex
|
1027
|
+
Morpheus::Logging::DarkPrinter.puts "Failed to load azure marketplace offers, trying older endpoint" if Morpheus::Logging.debug?
|
1028
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'offer', 'fieldLabel' => 'Azure Marketplace Offer', 'type' => 'typeahead', 'optionSource' => 'searchAzureMarketplace', 'required' => true, 'description' => "Select Azure Marketplace Offer."}], options[:options],@api_client, marketplace_api_params)
|
1029
|
+
end
|
1023
1030
|
# offer_value = v_prompt['marketplace']
|
1024
1031
|
# actually need both offer and publisher of these to query correctly..sigh
|
1025
1032
|
marketplace_option = Morpheus::Cli::OptionTypes.get_last_select()
|
@@ -1032,7 +1039,12 @@ EOT
|
|
1032
1039
|
options[:options]['sku'] = options[:options]['sku'] + '|' + options[:options]['version']
|
1033
1040
|
end
|
1034
1041
|
sku_api_params = {'zoneId' => cloud_id, publisher: publisher_value, offer: offer_value}
|
1035
|
-
|
1042
|
+
begin
|
1043
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'sku', 'fieldLabel' => 'Azure Marketplace SKU', 'type' => 'select', 'optionSourceType' => 'azure', 'optionSource' => 'searchAzureMarketplaceSkus', 'required' => true, 'description' => "Select Azure Marketplace SKU and Version, the format is SKU|Version"}], options[:options],@api_client, sku_api_params)
|
1044
|
+
rescue => ex
|
1045
|
+
Morpheus::Logging::DarkPrinter.puts "Failed to load azure marketplace offers, trying older endpoint" if Morpheus::Logging.debug?
|
1046
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'sku', 'fieldLabel' => 'Azure Marketplace SKU', 'type' => 'select', 'optionSource' => 'searchAzureMarketplaceSkus', 'required' => true, 'description' => "Select Azure Marketplace SKU and Version, the format is SKU|Version"}], options[:options],@api_client, sku_api_params)
|
1047
|
+
end
|
1036
1048
|
# marketplace_option = Morpheus::Cli::OptionTypes.get_last_select()
|
1037
1049
|
# sku_value = marketplace_option['sku']
|
1038
1050
|
# version_value = marketplace_option['version']
|
@@ -577,6 +577,10 @@ module Morpheus::Cli::ProvisioningHelper
|
|
577
577
|
(2..10).each {|i| arbitrary_options.delete('dataVolume' + i.to_s) }
|
578
578
|
arbitrary_options.delete('lockedFields')
|
579
579
|
# arbitrary_options.delete('ports')
|
580
|
+
arbitrary_options.delete('marketplacePublisher')
|
581
|
+
arbitrary_options.delete('marketplaceOffer')
|
582
|
+
arbitrary_options.delete('marketplaceSku')
|
583
|
+
arbitrary_options.delete('marketplaceVersion')
|
580
584
|
payload.deep_merge!(arbitrary_options)
|
581
585
|
end
|
582
586
|
|
@@ -1664,6 +1668,10 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1664
1668
|
end
|
1665
1669
|
end
|
1666
1670
|
|
1671
|
+
if ip_required == false && network_interface['ipAddress'] == nil && selected_network['dhcpServer'] == true
|
1672
|
+
network_interface['ipMode'] = 'dhcp'
|
1673
|
+
end
|
1674
|
+
|
1667
1675
|
network_interfaces << network_interface
|
1668
1676
|
interface_index += 1
|
1669
1677
|
if options[:options] && options[:options]['networkInterfaces'] && options[:options]['networkInterfaces'][interface_index]
|
@@ -252,6 +252,15 @@ module Morpheus
|
|
252
252
|
if !value_found
|
253
253
|
# select type is special because it supports skipSingleOption
|
254
254
|
# and prints the available options on error
|
255
|
+
if option_type['type'] == 'azureMarketplace'
|
256
|
+
value = azure_marketplace_prompt(option_type, options, api_client, option_params)
|
257
|
+
# inject {marketplacePublisher:'...',} into config, not as config.azureMarketplace = {}
|
258
|
+
# and remove any passed in values from
|
259
|
+
if value.is_a?(Hash)
|
260
|
+
context_map.merge!(value)
|
261
|
+
end
|
262
|
+
next
|
263
|
+
end
|
255
264
|
if ['select', 'multiSelect'].include?(option_type['type'])
|
256
265
|
value = select_prompt(option_type, api_client, option_params, true, nil, false, ignore_empty)
|
257
266
|
value_found = !!value
|
@@ -334,6 +343,14 @@ module Morpheus
|
|
334
343
|
value = file_content_prompt(option_type, options, api_client, {})
|
335
344
|
elsif option_type['type'] == 'multiText'
|
336
345
|
value = multitext_prompt(option_type)
|
346
|
+
elsif option_type['type'] == 'azureMarketplace'
|
347
|
+
value = azure_marketplace_prompt(option_type, options, api_client, option_params)
|
348
|
+
# inject {marketplacePublisher:'...',} into config, not as config.azureMarketplace = {}
|
349
|
+
# and remove any passed in values from
|
350
|
+
if value.is_a?(Hash)
|
351
|
+
context_map.merge!(value)
|
352
|
+
end
|
353
|
+
next
|
337
354
|
else
|
338
355
|
value = generic_prompt(option_type)
|
339
356
|
end
|
@@ -1033,6 +1050,62 @@ module Morpheus
|
|
1033
1050
|
rtn
|
1034
1051
|
end
|
1035
1052
|
|
1053
|
+
# file_content_prompt() prompts for source (local,repository,url) and then content or repo or.
|
1054
|
+
# returns a Hash like {sourceType:"local",content:"yadda",contentPath:null,contentRef:null}
|
1055
|
+
def self.azure_marketplace_prompt(option_type, options={}, api_client=nil, api_params={})
|
1056
|
+
cloud_id = api_params[:zoneId] || api_params[:cloudId] || api_params["zoneId"] || api_params["cloudId"]
|
1057
|
+
if cloud_id.nil?
|
1058
|
+
Morpheus::Logging::DarkPrinter.puts "Failed to load azure marketplace offers without a zoneId" if Morpheus::Logging.debug?
|
1059
|
+
return nil
|
1060
|
+
end
|
1061
|
+
# lets go!
|
1062
|
+
rtn = {}
|
1063
|
+
publisher_value, offer_value, sku_value, version_value = nil, nil, nil, nil
|
1064
|
+
|
1065
|
+
# Marketplace Publisher & Offer
|
1066
|
+
marketplace_api_params = {'zoneId' => cloud_id}
|
1067
|
+
v_prompt = nil
|
1068
|
+
# API endpoints moved from /api/options to /api/options/azure...
|
1069
|
+
begin
|
1070
|
+
v_prompt = prompt([{'fieldName' => 'marketplaceOffer', 'fieldLabel' => 'Azure Marketplace Offer', 'type' => 'typeahead', 'optionSourceType' => 'azure', 'optionSource' => 'searchAzureMarketplace', 'required' => true, 'description' => "Select Azure Marketplace Offer."}], options,api_client, marketplace_api_params)
|
1071
|
+
rescue => ex
|
1072
|
+
Morpheus::Logging::DarkPrinter.puts "Failed to load azure marketplace offers, trying older endpoint" if Morpheus::Logging.debug?
|
1073
|
+
v_prompt = prompt([{'fieldName' => 'marketplaceOffer', 'fieldLabel' => 'Azure Marketplace Offer', 'type' => 'typeahead', 'optionSource' => 'searchAzureMarketplace', 'required' => true, 'description' => "Select Azure Marketplace Offer."}], options,api_client, marketplace_api_params)
|
1074
|
+
end
|
1075
|
+
# offer_value = v_prompt['marketplaceOffer']
|
1076
|
+
# actually need both offer and publisher of these to query correctly..sigh
|
1077
|
+
marketplace_option = Morpheus::Cli::OptionTypes.get_last_select()
|
1078
|
+
offer_value = marketplace_option['offer']
|
1079
|
+
publisher_value = marketplace_option['publisher']
|
1080
|
+
|
1081
|
+
# SKU & VERSION
|
1082
|
+
if options && options['marketplaceSku'] && options['marketplaceVersion']
|
1083
|
+
# the value to match on is actually sku|version
|
1084
|
+
options['marketplaceSku'] = options['marketplaceSku'] + '|' + options['marketplaceVersion']
|
1085
|
+
end
|
1086
|
+
sku_api_params = {'zoneId' => cloud_id, publisher: publisher_value, offer: offer_value}
|
1087
|
+
begin
|
1088
|
+
v_prompt = prompt([{'fieldName' => 'marketplaceSku', 'fieldLabel' => 'Azure Marketplace SKU', 'type' => 'select', 'optionSourceType' => 'azure', 'optionSource' => 'searchAzureMarketplaceSkus', 'required' => true, 'description' => "Select Azure Marketplace SKU and Version, the format is SKU|Version"}], options,api_client, sku_api_params)
|
1089
|
+
rescue => ex
|
1090
|
+
Morpheus::Logging::DarkPrinter.puts "Failed to load azure marketplace offers, trying older endpoint" if Morpheus::Logging.debug?
|
1091
|
+
v_prompt = prompt([{'fieldName' => 'marketplaceSku', 'fieldLabel' => 'Azure Marketplace SKU', 'type' => 'select', 'optionSource' => 'searchAzureMarketplaceSkus', 'required' => true, 'description' => "Select Azure Marketplace SKU and Version, the format is SKU|Version"}], options,api_client, sku_api_params)
|
1092
|
+
end
|
1093
|
+
# marketplace_option = Morpheus::Cli::OptionTypes.get_last_select()
|
1094
|
+
# sku_value = marketplace_option['sku']
|
1095
|
+
# version_value = marketplace_option['version']
|
1096
|
+
sku_value = v_prompt['marketplaceSku']
|
1097
|
+
if sku_value && sku_value.include?("|")
|
1098
|
+
sku_value, version_value = sku_value.split("|")
|
1099
|
+
end
|
1100
|
+
# rtn['publisher'] = publisher_value
|
1101
|
+
# rtn['offer'] = offer_value
|
1102
|
+
# rtn['sku'] = sku_value
|
1103
|
+
# rtn['version'] = version_value
|
1104
|
+
# return rtn
|
1105
|
+
# instance provisioning expects these parameters...
|
1106
|
+
return {'marketplacePublisher' => publisher_value, 'marketplaceOffer' => offer_value, 'marketplaceSku' => sku_value, 'marketplaceVersion' => version_value}
|
1107
|
+
end
|
1108
|
+
|
1036
1109
|
def self.load_options(option_type, api_client, api_params, query_value=nil)
|
1037
1110
|
field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
|
1038
1111
|
help_field_key = option_type[:help_field_prefix] ? "#{option_type[:help_field_prefix]}.#{field_key}" : field_key
|
data/lib/morpheus/cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morpheus-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.5.1.
|
4
|
+
version: 5.5.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Estes
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2022-
|
14
|
+
date: 2022-09-06 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|