morpheus-cli 7.0.7 → 8.0.0
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/api_client.rb +11 -0
- data/lib/morpheus/api/clusters_interface.rb +25 -0
- data/lib/morpheus/api/datastores_interface.rb +6 -0
- data/lib/morpheus/api/library_operating_systems_interface.rb +63 -0
- data/lib/morpheus/api/processes_interface.rb +17 -5
- data/lib/morpheus/cli/commands/backup_jobs_command.rb +50 -17
- data/lib/morpheus/cli/commands/backups_command.rb +36 -9
- data/lib/morpheus/cli/commands/clusters.rb +380 -6
- data/lib/morpheus/cli/commands/hosts.rb +3 -0
- data/lib/morpheus/cli/commands/instances.rb +33 -4
- data/lib/morpheus/cli/commands/library_container_types_command.rb +6 -0
- data/lib/morpheus/cli/commands/library_operating_systems_command.rb +671 -0
- data/lib/morpheus/cli/commands/license.rb +11 -1
- data/lib/morpheus/cli/commands/processes_command.rb +71 -1
- data/lib/morpheus/cli/commands/setup.rb +32 -18
- data/lib/morpheus/cli/commands/virtual_images.rb +10 -2
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +28 -2
- data/lib/morpheus/cli/option_types.rb +3 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/formatters.rb +12 -0
- metadata +5 -3
@@ -13,18 +13,20 @@ class Morpheus::Cli::Clusters
|
|
13
13
|
register_subcommands :upgrade_cluster
|
14
14
|
register_subcommands :list_volumes, :remove_volume
|
15
15
|
register_subcommands :list_namespaces, :get_namespace, :add_namespace, :update_namespace, :remove_namespace
|
16
|
-
register_subcommands :list_containers, :remove_container, :restart_container
|
16
|
+
register_subcommands :list_containers, :remove_container, :restart_container, :get_container
|
17
17
|
register_subcommands :list_deployments, :remove_deployment, :restart_deployment
|
18
18
|
register_subcommands :list_stateful_sets, :remove_stateful_set, :restart_stateful_set
|
19
19
|
register_subcommands :list_pods, :remove_pod, :restart_pod
|
20
20
|
register_subcommands :list_jobs, :remove_job
|
21
21
|
register_subcommands :list_services, :remove_service
|
22
|
-
register_subcommands :list_datastores, :get_datastore, :update_datastore
|
22
|
+
register_subcommands :list_datastores, :get_datastore, :update_datastore, :add_datastore, :remove_datastore
|
23
23
|
register_subcommands :update_permissions
|
24
24
|
register_subcommands :api_config, :view_api_token, :view_kube_config
|
25
25
|
register_subcommands :wiki, :update_wiki
|
26
26
|
register_subcommands :apply_template
|
27
27
|
register_subcommands :refresh
|
28
|
+
register_subcommands :list_replicasets, :list_daemonsets, :list_endpoints, :list_ingresses, :list_policies, :list_volumes, :list_volume_claims, :list_config_maps, :list_secrets
|
29
|
+
register_subcommands :get_pod, :get_deployment, :get_replicaset, :get_daemonset, :get_endpoint, :get_ingress, :get_policy, :get_volume_claim, :get_volume, :get_config_map, :get_secret, :get_stateful_set, :get_job, :get_service
|
28
30
|
|
29
31
|
def connect(opts)
|
30
32
|
@api_client = establish_remote_appliance_connection(opts)
|
@@ -32,6 +34,7 @@ class Morpheus::Cli::Clusters
|
|
32
34
|
@groups_interface = @api_client.groups
|
33
35
|
@cluster_layouts_interface = @api_client.library_cluster_layouts
|
34
36
|
@security_groups_interface = @api_client.security_groups
|
37
|
+
@datastores_interface = @api_client.datastores
|
35
38
|
#@security_group_rules_interface = @api_client.security_group_rules
|
36
39
|
@cloud_resource_pools_interface = @api_client.cloud_resource_pools
|
37
40
|
@resource_pool_groups_interface = @api_client.resource_pool_groups
|
@@ -220,6 +223,7 @@ class Morpheus::Cli::Clusters
|
|
220
223
|
"Cloud" => lambda { |it| it['zone']['name'] },
|
221
224
|
"Location" => lambda { |it| it['location'] },
|
222
225
|
"Layout" => lambda { |it| it['layout'] ? it['layout']['name'] : ''},
|
226
|
+
"Integrations" => lambda {|it| format_name_and_id(it['integrations']) },
|
223
227
|
"API Url" => 'serviceUrl',
|
224
228
|
"Visibility" => lambda { |it| it['visibility'].to_s.capitalize },
|
225
229
|
#"Groups" => lambda {|it| it['groups'].collect {|g| g.instance_of?(Hash) ? g['name'] : g.to_s }.join(', ') },
|
@@ -228,6 +232,8 @@ class Morpheus::Cli::Clusters
|
|
228
232
|
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
229
233
|
"Created By" => lambda {|it| it['createdBy'] ? it['createdBy']['username'] : '' },
|
230
234
|
"Enabled" => lambda { |it| format_boolean(it['enabled']) },
|
235
|
+
"Managed" => lambda { |it| format_boolean(it['managed']) },
|
236
|
+
"Auto Power On VMs" => lambda { |it| format_boolean(it['autoRecoverPowerState']) },
|
231
237
|
"Status" => lambda { |it| format_cluster_status(it) }
|
232
238
|
}
|
233
239
|
print_description_list(description_cols, cluster)
|
@@ -796,12 +802,18 @@ class Morpheus::Cli::Clusters
|
|
796
802
|
opts.on('--managed [on|off]', String, "Can be used to enable / disable managed cluster. Default is on") do |val|
|
797
803
|
options[:managed] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
798
804
|
end
|
805
|
+
opts.on('--autoRecoverPowerState [on|off]', String, "Automatically Power On VMs") do |val|
|
806
|
+
options[:autoRecoverPowerState] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
807
|
+
end
|
799
808
|
opts.on( nil, '--refresh', "Refresh cluster" ) do
|
800
809
|
options[:refresh] = true
|
801
810
|
end
|
802
811
|
opts.on("--tenant ACCOUNT", String, "Account ID or Name" ) do |val|
|
803
812
|
options[:tenant] = val
|
804
813
|
end
|
814
|
+
opts.on('--integrations [LIST]', Array, "Updates Cluster Integration(s), comma separated list of integration IDs") do |list|
|
815
|
+
options[:integrations] = list ? list.collect {|it| it.to_s.strip.to_i } : []
|
816
|
+
end
|
805
817
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
806
818
|
opts.footer = "Update a cluster.\n" +
|
807
819
|
"[cluster] is required. This is the name or id of an existing cluster."
|
@@ -831,15 +843,18 @@ class Morpheus::Cli::Clusters
|
|
831
843
|
else
|
832
844
|
cluster = find_cluster_by_name_or_id(args[0])
|
833
845
|
cluster_payload = {}
|
846
|
+
cluster_payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) })
|
834
847
|
cluster_payload['name'] = options[:name] if !options[:name].empty?
|
835
848
|
cluster_payload['description'] = options[:description] if !options[:description].empty?
|
836
849
|
cluster_payload['labels'] = options[:labels] if !options[:labels].nil?
|
837
850
|
cluster_payload['enabled'] = options[:active] if !options[:active].nil?
|
838
851
|
cluster_payload['managed'] = options[:managed] if !options[:managed].nil?
|
852
|
+
cluster_payload['autoRecoverPowerState'] = options[:autoRecoverPowerState] if !options[:autoRecoverPowerState].nil?
|
839
853
|
cluster_payload['serviceUrl'] = options[:apiUrl] if !options[:apiUrl].nil?
|
840
854
|
cluster_payload['serviceToken'] = options[:apiToken] if !options[:apiToken].nil?
|
841
855
|
cluster_payload['refresh'] = options[:refresh] if options[:refresh] == true
|
842
856
|
cluster_payload['tenant'] = options[:tenant] if !options[:tenant].nil?
|
857
|
+
cluster_payload['integrations'] = options[:integrations] if !options[:integrations].nil?
|
843
858
|
payload = {"cluster" => cluster_payload}
|
844
859
|
end
|
845
860
|
|
@@ -847,10 +862,9 @@ class Morpheus::Cli::Clusters
|
|
847
862
|
print_red_alert "No clusters available for update"
|
848
863
|
exit 1
|
849
864
|
end
|
850
|
-
|
851
|
-
if
|
852
|
-
|
853
|
-
exit 1
|
865
|
+
|
866
|
+
if payload['cluster'].empty?
|
867
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
854
868
|
end
|
855
869
|
|
856
870
|
@clusters_interface.setopts(options)
|
@@ -2205,6 +2219,7 @@ class Morpheus::Cli::Clusters
|
|
2205
2219
|
:id, :status, :name, :cpu, :memory, :storage
|
2206
2220
|
]
|
2207
2221
|
print as_pretty_table(rows, columns, options)
|
2222
|
+
print_results_pagination(json_response)
|
2208
2223
|
end
|
2209
2224
|
print reset,"\n"
|
2210
2225
|
return 0
|
@@ -2214,6 +2229,43 @@ class Morpheus::Cli::Clusters
|
|
2214
2229
|
end
|
2215
2230
|
end
|
2216
2231
|
|
2232
|
+
def _get_container_group(args, options, resource_type)
|
2233
|
+
begin
|
2234
|
+
cluster = find_cluster_by_name_or_id(args[0])
|
2235
|
+
id = args[1]
|
2236
|
+
return 1 if cluster.nil?
|
2237
|
+
|
2238
|
+
params = {}
|
2239
|
+
params.merge!(parse_list_options(options))
|
2240
|
+
params['resourceLevel'] = options[:resourceLevel] if !options[:resourceLevel].nil?
|
2241
|
+
@clusters_interface.setopts(options)
|
2242
|
+
if options[:dry_run]
|
2243
|
+
print_dry_run @clusters_interface.dry.get_container_group(cluster['id'], resource_type, id, params)
|
2244
|
+
return
|
2245
|
+
end
|
2246
|
+
container_group = @clusters_interface.get_container_group(cluster['id'], resource_type, id, params)['resource']
|
2247
|
+
|
2248
|
+
render_result = render_with_format(container_group, options, 'containers')
|
2249
|
+
return 0 if render_result
|
2250
|
+
resource_is = options['title'] ? options['title'].capitalize : resource_type.capitalize
|
2251
|
+
title = "Morpheus Cluster #{cluster['name']}: #{resource_is}"
|
2252
|
+
print_h1 title
|
2253
|
+
print cyan
|
2254
|
+
description_cols = {
|
2255
|
+
"ID" => 'id',
|
2256
|
+
"Name" => 'name',
|
2257
|
+
"Status" => 'status',
|
2258
|
+
"metadata" => lambda { |it| as_json(it['metadata']) }
|
2259
|
+
}
|
2260
|
+
print_description_list(description_cols, container_group)
|
2261
|
+
print reset,"\n"
|
2262
|
+
return 0
|
2263
|
+
rescue RestClient::Exception => e
|
2264
|
+
print_rest_exception(e, options)
|
2265
|
+
exit 1
|
2266
|
+
end
|
2267
|
+
end
|
2268
|
+
|
2217
2269
|
def _remove_container_group(args, options, resource_type)
|
2218
2270
|
begin
|
2219
2271
|
cluster = find_cluster_by_name_or_id(args[0])
|
@@ -2321,6 +2373,26 @@ class Morpheus::Cli::Clusters
|
|
2321
2373
|
_list_container_groups(args, options,resource_type)
|
2322
2374
|
end
|
2323
2375
|
|
2376
|
+
def get_deployment(args)
|
2377
|
+
resource_type = 'deployment'
|
2378
|
+
options = {}
|
2379
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2380
|
+
opts.banner = subcommand_usage( "[cluster]")
|
2381
|
+
opts.on("--resource-level LEVEL", String, "Resource Level") do |val|
|
2382
|
+
options[:resourceLevel] = val.to_s
|
2383
|
+
end
|
2384
|
+
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
2385
|
+
opts.footer = "get #{resource_type} for a cluster.\n" +
|
2386
|
+
"[cluster] and [#{resource_type}] is required. This is the name or id of an existing cluster, and the id of the #{resource_type}"
|
2387
|
+
end
|
2388
|
+
optparse.parse!(args)
|
2389
|
+
if args.count != 2
|
2390
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
2391
|
+
end
|
2392
|
+
connect(options)
|
2393
|
+
_get_container_group(args, options, resource_type)
|
2394
|
+
end
|
2395
|
+
|
2324
2396
|
def remove_deployment(args)
|
2325
2397
|
resource_type = 'deployment'
|
2326
2398
|
options = {}
|
@@ -2439,6 +2511,26 @@ class Morpheus::Cli::Clusters
|
|
2439
2511
|
_list_container_groups(args, options, resource_type)
|
2440
2512
|
end
|
2441
2513
|
|
2514
|
+
def get_pod(args)
|
2515
|
+
resource_type = 'pod'
|
2516
|
+
options = {}
|
2517
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2518
|
+
opts.banner = subcommand_usage( "[cluster]")
|
2519
|
+
opts.on("--resource-level LEVEL", String, "Resource Level") do |val|
|
2520
|
+
options[:resourceLevel] = val.to_s
|
2521
|
+
end
|
2522
|
+
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
2523
|
+
opts.footer = "get #{resource_type} for a cluster.\n" +
|
2524
|
+
"[cluster] and [#{resource_type}] is required. This is the name or id of an existing cluster, and the id of the #{resource_type}"
|
2525
|
+
end
|
2526
|
+
optparse.parse!(args)
|
2527
|
+
if args.count != 2
|
2528
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
2529
|
+
end
|
2530
|
+
connect(options)
|
2531
|
+
_get_container_group(args, options, resource_type)
|
2532
|
+
end
|
2533
|
+
|
2442
2534
|
def remove_pod(args)
|
2443
2535
|
resource_type = 'pod'
|
2444
2536
|
options = {}
|
@@ -2908,6 +3000,130 @@ class Morpheus::Cli::Clusters
|
|
2908
3000
|
end
|
2909
3001
|
end
|
2910
3002
|
|
3003
|
+
def add_datastore(args)
|
3004
|
+
options = {}
|
3005
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
3006
|
+
opts.banner = subcommand_usage( "[cluster] [options]")
|
3007
|
+
build_option_type_options(opts, options, add_datastore_option_types)
|
3008
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
3009
|
+
opts.footer = "Add datastore to a cluster.\n" +
|
3010
|
+
"[cluster] is required. This is the name or id of an existing cluster.\n" +
|
3011
|
+
"[name] is required. This is the name of the new datastore."
|
3012
|
+
end
|
3013
|
+
|
3014
|
+
optparse.parse!(args)
|
3015
|
+
if args.count != 1 and args.count != 2
|
3016
|
+
raise_command_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args}\n#{optparse}"
|
3017
|
+
end
|
3018
|
+
connect(options)
|
3019
|
+
|
3020
|
+
begin
|
3021
|
+
cluster = find_cluster_by_name_or_id(args[0])
|
3022
|
+
return 1 if cluster.nil?
|
3023
|
+
if options[:payload]
|
3024
|
+
payload = options[:payload]
|
3025
|
+
# support -O OPTION switch on top of --payload
|
3026
|
+
if options[:options]
|
3027
|
+
payload ||= {}
|
3028
|
+
payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) })
|
3029
|
+
end
|
3030
|
+
else
|
3031
|
+
options[:params] ||= {}
|
3032
|
+
options[:params].merge!({:serverGroupId => cluster['id']})
|
3033
|
+
|
3034
|
+
datastore = Morpheus::Cli::OptionTypes.prompt(add_datastore_option_types, options[:options], @api_client, options[:params])
|
3035
|
+
|
3036
|
+
datastore_type = find_datastore_type_by_code(datastore['datastoreType'])
|
3037
|
+
datastore['datastoreType'] = {id:datastore_type['id']}
|
3038
|
+
|
3039
|
+
# datastore type options
|
3040
|
+
unless datastore_type['optionTypes'].empty?
|
3041
|
+
datastore.merge!(Morpheus::Cli::OptionTypes.prompt(datastore_type['optionTypes'], options[:options].deep_merge({:context_map => {'domain' => ''}, :checkbox_as_boolean => true}), @api_client, options[:params]))
|
3042
|
+
end
|
3043
|
+
|
3044
|
+
# perms
|
3045
|
+
perms = prompt_permissions(options.merge({:for_datastore => true}), ['plans', 'groupDefaults'])
|
3046
|
+
|
3047
|
+
datastore['resourcePermissions'] = perms['resourcePermissions'] unless perms['resourcePermissions'].nil?
|
3048
|
+
datastore['tenants'] = perms['tenantPermissions'] unless perms['tenantPermissions'].nil?
|
3049
|
+
datastore['visibility'] = perms['resourcePool']['visibility'] if !perms['resourcePool'].nil? && !perms['resourcePool']['visibility'].nil?
|
3050
|
+
|
3051
|
+
payload = {datastore:datastore}
|
3052
|
+
end
|
3053
|
+
|
3054
|
+
@clusters_interface.setopts(options)
|
3055
|
+
if options[:dry_run]
|
3056
|
+
print_dry_run @clusters_interface.dry.create_datastore(cluster['id'], payload)
|
3057
|
+
return
|
3058
|
+
end
|
3059
|
+
json_response = @clusters_interface.create_datastore(cluster['id'], payload)
|
3060
|
+
if options[:json]
|
3061
|
+
puts as_json(json_response)
|
3062
|
+
elsif json_response['success']
|
3063
|
+
if json_response['msg'] == nil
|
3064
|
+
print_green_success "Added datastore to cluster #{cluster['name']}"
|
3065
|
+
else
|
3066
|
+
print_green_success json_response['msg']
|
3067
|
+
end
|
3068
|
+
end
|
3069
|
+
return 0
|
3070
|
+
rescue RestClient::Exception => e
|
3071
|
+
print_rest_exception(e, options)
|
3072
|
+
exit 1
|
3073
|
+
end
|
3074
|
+
end
|
3075
|
+
|
3076
|
+
def remove_datastore(args)
|
3077
|
+
params = {}
|
3078
|
+
options = {}
|
3079
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
3080
|
+
opts.banner = subcommand_usage("[cluster] [datastore]")
|
3081
|
+
opts.on( '-f', '--force', "Force Delete" ) do
|
3082
|
+
params[:force] = 'on'
|
3083
|
+
end
|
3084
|
+
build_standard_remove_options(opts, options)
|
3085
|
+
opts.footer = "Delete a datastore from a cluster.\n" +
|
3086
|
+
"[cluster] is required. This is the name or id of an existing cluster.\n" +
|
3087
|
+
"[datastore] is required. This is the name or id of an existing datastore."
|
3088
|
+
end
|
3089
|
+
optparse.parse!(args)
|
3090
|
+
verify_args!(args:args, optparse:optparse, count:2)
|
3091
|
+
connect(options)
|
3092
|
+
params.merge!(parse_query_options(options))
|
3093
|
+
|
3094
|
+
cluster = find_cluster_by_name_or_id(args[0])
|
3095
|
+
return 1 if cluster.nil?
|
3096
|
+
|
3097
|
+
datastore_id = args[1]
|
3098
|
+
if datastore_id.empty?
|
3099
|
+
raise_command_error "missing required worker parameter"
|
3100
|
+
end
|
3101
|
+
|
3102
|
+
datastore = find_datastore_by_name_or_id(cluster['id'], datastore_id)
|
3103
|
+
if datastore.nil?
|
3104
|
+
print_red_alert "Datastore not found for '#{datastore_id}'"
|
3105
|
+
return 1
|
3106
|
+
end
|
3107
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the cluster datastore '#{datastore['name'] || datastore['id']}'?", options)
|
3108
|
+
return 9, "aborted command"
|
3109
|
+
end
|
3110
|
+
|
3111
|
+
@clusters_interface.setopts(options)
|
3112
|
+
if options[:dry_run]
|
3113
|
+
print_dry_run @clusters_interface.dry.destroy_datastore(cluster['id'], datastore['id'], params)
|
3114
|
+
return
|
3115
|
+
end
|
3116
|
+
json_response = @clusters_interface.destroy_datastore(cluster['id'], datastore['id'], params)
|
3117
|
+
render_response(json_response, options) do
|
3118
|
+
msg = "Datastore #{datastore['name']} is being removed from cluster #{cluster['name']}..."
|
3119
|
+
if json_response['msg']
|
3120
|
+
msg = json_response['msg']
|
3121
|
+
end
|
3122
|
+
print_green_success msg
|
3123
|
+
end
|
3124
|
+
return 0, nil
|
3125
|
+
end
|
3126
|
+
|
2911
3127
|
def update_datastore(args)
|
2912
3128
|
options = {}
|
2913
3129
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
@@ -3970,6 +4186,25 @@ class Morpheus::Cli::Clusters
|
|
3970
4186
|
json_results['datastores'].empty? ? nil : json_results['datastores'][0]
|
3971
4187
|
end
|
3972
4188
|
|
4189
|
+
def find_datastore_type_by_code_or_id(val)
|
4190
|
+
(val.to_s =~ /\A\d{1,}\Z/) ? find_datastore_type_by_id(val) : find_datastore_type_by_code(val)
|
4191
|
+
end
|
4192
|
+
|
4193
|
+
def find_datastore_type_by_id(id)
|
4194
|
+
get_datastore_types.find { |it| it['id'] == id }
|
4195
|
+
end
|
4196
|
+
|
4197
|
+
def find_datastore_type_by_code(code)
|
4198
|
+
get_datastore_types.find { |it| it['code'].downcase == code.downcase }
|
4199
|
+
end
|
4200
|
+
|
4201
|
+
def get_datastore_types(refresh=false)
|
4202
|
+
if !@datastore_types || refresh
|
4203
|
+
@datastore_types = @datastores_interface.types()['datastoreTypes']
|
4204
|
+
end
|
4205
|
+
@datastore_types
|
4206
|
+
end
|
4207
|
+
|
3973
4208
|
def find_job_by_name_or_id(cluster_id, val)
|
3974
4209
|
if val.to_s =~ /\A\d{1,}\Z/
|
3975
4210
|
params = {jobId: val.to_i}
|
@@ -4275,6 +4510,14 @@ class Morpheus::Cli::Clusters
|
|
4275
4510
|
end
|
4276
4511
|
end
|
4277
4512
|
|
4513
|
+
def add_datastore_option_types
|
4514
|
+
[
|
4515
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
4516
|
+
{'fieldName' => 'datastoreType', 'fieldLabel' => 'Type', 'type' => 'select', 'optionSource' => 'datastoreTypes', 'description' => 'Choose a datastore type.', 'required' => true, 'displayOrder' => 2},
|
4517
|
+
{'fieldName' => 'active', 'fieldLabel' => 'Active', 'type' => 'checkbox', 'required' => true, 'displayOrder' => 3, 'defaultValue' => true},
|
4518
|
+
]
|
4519
|
+
end
|
4520
|
+
|
4278
4521
|
def prompt_resource_pool(group, cloud, service_plan, provision_type, options)
|
4279
4522
|
resource_pool = nil
|
4280
4523
|
|
@@ -4451,4 +4694,135 @@ class Morpheus::Cli::Clusters
|
|
4451
4694
|
exit 1
|
4452
4695
|
end
|
4453
4696
|
end
|
4697
|
+
|
4698
|
+
def list_replicasets(args)
|
4699
|
+
_list_resources(args, 'replicaset')
|
4700
|
+
end
|
4701
|
+
|
4702
|
+
def get_replicaset(args)
|
4703
|
+
_get_resource(args, 'replicaset')
|
4704
|
+
end
|
4705
|
+
|
4706
|
+
def list_daemonsets(args)
|
4707
|
+
_list_resources(args, 'daemonset')
|
4708
|
+
end
|
4709
|
+
|
4710
|
+
def get_daemonset(args)
|
4711
|
+
_get_resource(args, 'daemonset')
|
4712
|
+
end
|
4713
|
+
|
4714
|
+
|
4715
|
+
def list_endpoints(args)
|
4716
|
+
_list_resources(args, 'endpoint')
|
4717
|
+
end
|
4718
|
+
|
4719
|
+
def get_endpoint(args)
|
4720
|
+
_get_resource(args, 'endpoint')
|
4721
|
+
end
|
4722
|
+
|
4723
|
+
def list_ingresses(args)
|
4724
|
+
_list_resources(args, 'ingresse')
|
4725
|
+
end
|
4726
|
+
|
4727
|
+
def get_ingress(args)
|
4728
|
+
_get_resource(args, 'ingresse', {'title' => 'ingress'})
|
4729
|
+
end
|
4730
|
+
|
4731
|
+
def list_policies(args)
|
4732
|
+
_list_resources(args, 'policie')
|
4733
|
+
end
|
4734
|
+
|
4735
|
+
def get_policy(args)
|
4736
|
+
_get_resource(args, 'policie', {'title' => 'policy'})
|
4737
|
+
end
|
4738
|
+
|
4739
|
+
def list_volume_claims(args)
|
4740
|
+
_list_resources(args, 'volumeclaim')
|
4741
|
+
end
|
4742
|
+
|
4743
|
+
def get_volume_claim(args)
|
4744
|
+
_get_resource(args, 'volumeclaim')
|
4745
|
+
end
|
4746
|
+
|
4747
|
+
def list_volumes(args)
|
4748
|
+
_list_resources(args, 'volume')
|
4749
|
+
end
|
4750
|
+
|
4751
|
+
def get_volume(args)
|
4752
|
+
_get_resource(args, 'volume')
|
4753
|
+
end
|
4754
|
+
|
4755
|
+
|
4756
|
+
def list_config_maps(args)
|
4757
|
+
_list_resources(args, 'configmap')
|
4758
|
+
end
|
4759
|
+
|
4760
|
+
def get_config_map(args)
|
4761
|
+
_get_resource(args, 'configmap')
|
4762
|
+
end
|
4763
|
+
|
4764
|
+
def list_secrets(args)
|
4765
|
+
_list_resources(args, 'secret')
|
4766
|
+
end
|
4767
|
+
|
4768
|
+
def get_secret(args)
|
4769
|
+
_get_resource(args, 'secret')
|
4770
|
+
end
|
4771
|
+
|
4772
|
+
def get_container(args)
|
4773
|
+
_get_resource(args, 'container')
|
4774
|
+
end
|
4775
|
+
|
4776
|
+
def get_stateful_set(args)
|
4777
|
+
_get_resource(args, 'statefulset')
|
4778
|
+
|
4779
|
+
end
|
4780
|
+
|
4781
|
+
def get_job(args)
|
4782
|
+
_get_resource(args, 'job')
|
4783
|
+
end
|
4784
|
+
|
4785
|
+
def get_service(args)
|
4786
|
+
_get_resource(args, 'service')
|
4787
|
+
end
|
4788
|
+
|
4789
|
+
private
|
4790
|
+
|
4791
|
+
def _get_resource(args, resource_type, options = {})
|
4792
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
4793
|
+
opts.banner = subcommand_usage("[cluster] [id]")
|
4794
|
+
opts.on("--resource-level LEVEL", String, "Resource Level") do |val|
|
4795
|
+
options[:resourceLevel] = val.to_s
|
4796
|
+
end
|
4797
|
+
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
4798
|
+
opts.footer = "get #{resource_type} for a cluster.\n" +
|
4799
|
+
"[cluster] and [#{resource_type}] is required. This is the name or id of an existing cluster, and the id of the #{resource_type}"
|
4800
|
+
end
|
4801
|
+
optparse.parse!(args)
|
4802
|
+
|
4803
|
+
if args.count != 2
|
4804
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
4805
|
+
end
|
4806
|
+
|
4807
|
+
connect(options)
|
4808
|
+
_get_container_group(args, options, resource_type)
|
4809
|
+
end
|
4810
|
+
|
4811
|
+
def _list_resources(args, resource_type, options = {})
|
4812
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
4813
|
+
opts.banner = subcommand_usage( "[cluster]")
|
4814
|
+
opts.on("--resource-level LEVEL", String, "Resource Level") do |val|
|
4815
|
+
options[:resourceLevel] = val.to_s
|
4816
|
+
end
|
4817
|
+
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
4818
|
+
opts.footer = "List #{resource_type}s for a cluster.\n" +
|
4819
|
+
"[cluster] is required. This is the name or id of an existing cluster."
|
4820
|
+
end
|
4821
|
+
optparse.parse!(args)
|
4822
|
+
if args.count != 1
|
4823
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
4824
|
+
end
|
4825
|
+
connect(options)
|
4826
|
+
_list_container_groups(args, options, resource_type)
|
4827
|
+
end
|
4454
4828
|
end
|
@@ -1009,6 +1009,9 @@ class Morpheus::Cli::Hosts
|
|
1009
1009
|
opts.on('--ssh-password VALUE', String, "SSH Password") do |val|
|
1010
1010
|
params['sshPassword'] = val == "null" ? nil : val
|
1011
1011
|
end
|
1012
|
+
opts.on('--ssh-key-pair ID', String, "SSH Key Pair ID") do |val|
|
1013
|
+
params['sshKeyPair'] = val == "null" ? nil : {"id" => val.to_i}
|
1014
|
+
end
|
1012
1015
|
opts.on('--power-schedule-type ID', String, "Power Schedule Type ID") do |val|
|
1013
1016
|
params['powerScheduleType'] = val == "null" ? nil : val
|
1014
1017
|
end
|
@@ -2746,6 +2746,9 @@ class Morpheus::Cli::Instances
|
|
2746
2746
|
options = {}
|
2747
2747
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2748
2748
|
opts.banner = subcommand_usage("[instance]")
|
2749
|
+
opts.on('--include-network-interfaces','--include-network-interfaces', "Populate payload networkInterfaces with current interfaces") do
|
2750
|
+
options[:include_nics] = true
|
2751
|
+
end
|
2749
2752
|
build_standard_update_options(opts, options)
|
2750
2753
|
end
|
2751
2754
|
optparse.parse!(args)
|
@@ -2775,11 +2778,17 @@ class Morpheus::Cli::Instances
|
|
2775
2778
|
plan_id = instance['plan']['id']
|
2776
2779
|
resource_pool_id = instance['config']['resourcePoolId'] if instance['config']
|
2777
2780
|
current_plan_name = instance['plan']['name']
|
2778
|
-
current_interfaces = get_instance_interfaces(instance)
|
2779
|
-
if current_interfaces != false
|
2780
|
-
payload['networkInterfaces'] = current_interfaces
|
2781
|
-
end
|
2782
2781
|
|
2782
|
+
# JD: networkInterfaces should not be needed but pre 7.0.8/8.0.0 the API does expect it to be passed
|
2783
|
+
# However if the instance has more than one server this creates duplicate nics and breaks things
|
2784
|
+
# so only continue to do it if the instance has just one server and remote version is pre 7.0.8
|
2785
|
+
# should also only do this if remote version < 7.0.8
|
2786
|
+
if options[:include_nics] || (!remote_version_gte("7.0.8") && instance['servers'] && instance['servers'].size == 1)
|
2787
|
+
current_interfaces = get_instance_interfaces(instance)
|
2788
|
+
if current_interfaces != false
|
2789
|
+
payload['networkInterfaces'] = current_interfaces
|
2790
|
+
end
|
2791
|
+
end
|
2783
2792
|
|
2784
2793
|
# need to GET provision type for some settings...
|
2785
2794
|
provision_type = @provision_types_interface.get(instance['layout']['provisionTypeId'])['provisionType']
|
@@ -5576,6 +5585,8 @@ private
|
|
5576
5585
|
details['interfaces'].each do |inter|
|
5577
5586
|
interfaces.push(inter)
|
5578
5587
|
end
|
5588
|
+
# only include the first one or it will create duplicates
|
5589
|
+
break
|
5579
5590
|
end
|
5580
5591
|
return interfaces
|
5581
5592
|
rescue
|
@@ -5583,4 +5594,22 @@ private
|
|
5583
5594
|
end
|
5584
5595
|
end
|
5585
5596
|
|
5597
|
+
def remote_version_gte(required_version)
|
5598
|
+
version = @remote_appliance[:build_version]
|
5599
|
+
return false if version.nil?
|
5600
|
+
version_numbers = version.split(".")
|
5601
|
+
required_version_numbers = required_version.split(".")
|
5602
|
+
result = true
|
5603
|
+
required_version_numbers.each_with_index do |v, i|
|
5604
|
+
if version_numbers[i].to_i > v.to_i
|
5605
|
+
break
|
5606
|
+
elsif version_numbers[i].to_i < v.to_i
|
5607
|
+
result = false
|
5608
|
+
break
|
5609
|
+
else
|
5610
|
+
# keep going
|
5611
|
+
end
|
5612
|
+
end
|
5613
|
+
return result
|
5614
|
+
end
|
5586
5615
|
end
|
@@ -163,6 +163,9 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
163
163
|
"Virtual Image" => lambda {|it|
|
164
164
|
it['virtualImage'] ? it['virtualImage']['name'] : ''
|
165
165
|
},
|
166
|
+
"OsType" => lambda {|it|
|
167
|
+
it['osType'] ? it['osType']['name'] : ''
|
168
|
+
},
|
166
169
|
# "Category" => lambda {|it| it['category'].to_s.capitalize },
|
167
170
|
# # "Logo" => lambda {|it| it['logo'].to_s },
|
168
171
|
# "Visiblity" => lambda {|it| it['visibility'].to_s.capitalize },
|
@@ -474,6 +477,9 @@ class Morpheus::Cli::LibraryContainerTypesCommand
|
|
474
477
|
opts.on('--version VALUE', String, "Version") do |val|
|
475
478
|
params['containerVersion'] = val
|
476
479
|
end
|
480
|
+
opts.on('--osType VALUE', Integer, "OsType") do |val|
|
481
|
+
params['osTypeId'] = val
|
482
|
+
end
|
477
483
|
# opts.on('--technology CODE', String, "Technology") do |val|
|
478
484
|
# params['provisionTypeCode'] = val
|
479
485
|
# end
|