morpheus-cli 5.4.0 → 5.4.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/lib/morpheus/api/account_users_interface.rb +68 -0
- data/lib/morpheus/api/api_client.rb +55 -10
- data/lib/morpheus/api/audit_interface.rb +9 -0
- data/lib/morpheus/api/catalog_item_types_interface.rb +20 -0
- data/lib/morpheus/api/instances_interface.rb +49 -0
- data/lib/morpheus/api/load_balancer_monitors_interface.rb +9 -0
- data/lib/morpheus/api/load_balancer_pools_interface.rb +4 -4
- data/lib/morpheus/api/load_balancer_profiles_interface.rb +4 -5
- data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +13 -4
- data/lib/morpheus/api/load_balancers_interface.rb +5 -0
- data/lib/morpheus/api/network_routers_interface.rb +9 -0
- data/lib/morpheus/api/network_static_routes_interface.rb +36 -0
- data/lib/morpheus/api/ping_interface.rb +2 -0
- data/lib/morpheus/api/read_interface.rb +4 -3
- data/lib/morpheus/api/rest_interface.rb +3 -3
- data/lib/morpheus/api/secondary_read_interface.rb +1 -1
- data/lib/morpheus/api/secondary_rest_interface.rb +19 -19
- data/lib/morpheus/api/setup_interface.rb +4 -0
- data/lib/morpheus/api/snapshots_interface.rb +19 -0
- data/lib/morpheus/api/storage_server_types_interface.rb +14 -0
- data/lib/morpheus/api/storage_servers_interface.rb +9 -0
- data/lib/morpheus/api/storage_volume_types_interface.rb +9 -0
- data/lib/morpheus/api/storage_volumes_interface.rb +9 -0
- data/lib/morpheus/api/users_interface.rb +16 -63
- data/lib/morpheus/cli/cli_command.rb +253 -5
- data/lib/morpheus/cli/cli_registry.rb +1 -1
- data/lib/morpheus/cli/commands/alias_command.rb +1 -1
- data/lib/morpheus/cli/commands/apps.rb +14 -78
- data/lib/morpheus/cli/commands/audit.rb +188 -0
- data/lib/morpheus/cli/commands/blueprints_command.rb +1 -1
- data/lib/morpheus/cli/commands/catalog_item_types_command.rb +88 -0
- data/lib/morpheus/cli/commands/change_password_command.rb +4 -4
- data/lib/morpheus/cli/commands/clusters.rb +96 -58
- data/lib/morpheus/cli/commands/hosts.rb +27 -15
- data/lib/morpheus/cli/commands/image_builder_command.rb +4 -8
- data/lib/morpheus/cli/commands/instances.rb +359 -3
- data/lib/morpheus/cli/commands/integrations_command.rb +1 -12
- data/lib/morpheus/cli/commands/library_instance_types_command.rb +3 -0
- data/lib/morpheus/cli/commands/load_balancer_monitors.rb +70 -0
- data/lib/morpheus/cli/commands/load_balancer_pools.rb +29 -50
- data/lib/morpheus/cli/commands/load_balancer_profiles.rb +64 -0
- data/lib/morpheus/cli/commands/load_balancer_types.rb +9 -4
- data/lib/morpheus/cli/commands/load_balancer_virtual_servers.rb +69 -58
- data/lib/morpheus/cli/commands/load_balancers.rb +109 -6
- data/lib/morpheus/cli/commands/network_firewalls_command.rb +22 -5
- data/lib/morpheus/cli/commands/network_routers_command.rb +96 -45
- data/lib/morpheus/cli/commands/network_static_routes_command.rb +451 -0
- data/lib/morpheus/cli/commands/network_transport_zones_command.rb +4 -4
- data/lib/morpheus/cli/commands/networks_command.rb +2 -2
- data/lib/morpheus/cli/commands/open_command.rb +30 -0
- data/lib/morpheus/cli/commands/options.rb +98 -0
- data/lib/morpheus/cli/commands/ping.rb +3 -5
- data/lib/morpheus/cli/commands/policies_command.rb +2 -2
- data/lib/morpheus/cli/commands/prices_command.rb +7 -7
- data/lib/morpheus/cli/commands/provisioning_settings_command.rb +1 -0
- data/lib/morpheus/cli/commands/remote.rb +20 -12
- data/lib/morpheus/cli/commands/roles.rb +1 -1
- data/lib/morpheus/cli/commands/security_groups.rb +2 -2
- data/lib/morpheus/cli/commands/service_plans_command.rb +1 -1
- data/lib/morpheus/cli/commands/setup.rb +1 -1
- data/lib/morpheus/cli/commands/shell.rb +2 -2
- data/lib/morpheus/cli/commands/snapshots.rb +139 -0
- data/lib/morpheus/cli/commands/storage_server_types.rb +50 -0
- data/lib/morpheus/cli/commands/storage_servers.rb +122 -0
- data/lib/morpheus/cli/commands/storage_volume_types.rb +50 -0
- data/lib/morpheus/cli/commands/storage_volumes.rb +103 -0
- data/lib/morpheus/cli/commands/tasks.rb +5 -5
- data/lib/morpheus/cli/commands/tenants_command.rb +1 -1
- data/lib/morpheus/cli/commands/user_groups_command.rb +1 -1
- data/lib/morpheus/cli/commands/user_settings_command.rb +3 -2
- data/lib/morpheus/cli/commands/user_sources_command.rb +1 -1
- data/lib/morpheus/cli/commands/users.rb +28 -28
- data/lib/morpheus/cli/commands/view.rb +102 -0
- data/lib/morpheus/cli/commands/virtual_images.rb +4 -1
- data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -5
- data/lib/morpheus/cli/mixins/load_balancers_helper.rb +24 -4
- data/lib/morpheus/cli/mixins/print_helper.rb +50 -18
- data/lib/morpheus/cli/mixins/processes_helper.rb +1 -2
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +96 -6
- data/lib/morpheus/cli/mixins/rest_command.rb +148 -74
- data/lib/morpheus/cli/mixins/secondary_rest_command.rb +174 -82
- data/lib/morpheus/cli/mixins/storage_servers_helper.rb +156 -0
- data/lib/morpheus/cli/mixins/storage_volumes_helper.rb +119 -0
- data/lib/morpheus/cli/option_types.rb +95 -28
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/ext/string.rb +29 -6
- data/lib/morpheus/routes.rb +238 -0
- data/lib/morpheus/util.rb +6 -1
- metadata +26 -2
|
@@ -189,7 +189,7 @@ class Morpheus::Cli::NetworksCommand
|
|
|
189
189
|
print cyan
|
|
190
190
|
description_cols = {
|
|
191
191
|
"ID" => 'id',
|
|
192
|
-
"Name" => 'name',
|
|
192
|
+
"Name" => lambda {|it| it['displayName'] ? it['displayName'] : it['name'] },
|
|
193
193
|
"Description" => 'description',
|
|
194
194
|
"Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
|
|
195
195
|
"Group" => lambda {|it| it['group'] ? it['group']['name'] : 'Shared' },
|
|
@@ -242,7 +242,7 @@ class Morpheus::Cli::NetworksCommand
|
|
|
242
242
|
subnet_rows = subnets.collect { |subnet|
|
|
243
243
|
{
|
|
244
244
|
id: subnet['id'],
|
|
245
|
-
name: " #{subnet['name']}",
|
|
245
|
+
name: " #{subnet['displayName'] || subnet['name']}",
|
|
246
246
|
# type: subnet['type'] ? subnet['type']['name'] : '',
|
|
247
247
|
type: "Subnet",
|
|
248
248
|
cloud: network['zone'] ? network['zone']['name'] : '',
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
|
2
|
+
|
|
3
|
+
# This is for opening a file
|
|
4
|
+
class Morpheus::Cli::OpenCommand
|
|
5
|
+
include Morpheus::Cli::CliCommand
|
|
6
|
+
set_command_name :open
|
|
7
|
+
set_command_hidden
|
|
8
|
+
|
|
9
|
+
def handle(args)
|
|
10
|
+
append_newline = true
|
|
11
|
+
options = {}
|
|
12
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
13
|
+
opts.banner = "Usage: morpheus #{command_name} [file ...]"
|
|
14
|
+
build_common_options(opts, options, [:dry_run])
|
|
15
|
+
opts.footer = "Open file(s)." + "\n" +
|
|
16
|
+
"[file] is required. This is the name of a file. Supports many [file] arguments."
|
|
17
|
+
end
|
|
18
|
+
optparse.parse!(args)
|
|
19
|
+
verify_args!(args:args, optparse:optparse, min: 1)
|
|
20
|
+
open_args = args.join(" ")
|
|
21
|
+
if options[:dry_run]
|
|
22
|
+
print "\n"
|
|
23
|
+
print "#{cyan}#{bold}#{dark}SYSTEM COMMAND#{reset}\n"
|
|
24
|
+
puts Morpheus::Util.open_url_command(open_args)
|
|
25
|
+
return 0, nil
|
|
26
|
+
end
|
|
27
|
+
return Morpheus::Util.open_url(open_args)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
|
2
|
+
|
|
3
|
+
class Morpheus::Cli::Options
|
|
4
|
+
include Morpheus::Cli::CliCommand
|
|
5
|
+
|
|
6
|
+
set_command_description "List options by source name or option type"
|
|
7
|
+
set_command_name :'options'
|
|
8
|
+
|
|
9
|
+
# options is not published yet
|
|
10
|
+
set_command_hidden
|
|
11
|
+
|
|
12
|
+
def connect(opts)
|
|
13
|
+
@api_client = establish_remote_appliance_connection(opts)
|
|
14
|
+
@options_interface = @api_client.options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def handle(args)
|
|
18
|
+
list(args)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def list(args)
|
|
22
|
+
options = {}
|
|
23
|
+
params = {}
|
|
24
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
25
|
+
opts.banner = "Usage: morpheus #{command_name} [source] [option-type]"
|
|
26
|
+
# build_standard_list_options(opts, options)
|
|
27
|
+
build_standard_get_options(opts, options)
|
|
28
|
+
opts.footer = <<-EOT
|
|
29
|
+
View options by source name or list options for a specific library option type.
|
|
30
|
+
[source] is required. This is the name of the options source to load eg. "currencies"
|
|
31
|
+
[option-type] is required when [source] is 'list'. This is the name or id of an option type to view.
|
|
32
|
+
|
|
33
|
+
Examples:
|
|
34
|
+
options currencies
|
|
35
|
+
options dnsRecordType
|
|
36
|
+
options list "widgets"
|
|
37
|
+
EOT
|
|
38
|
+
end
|
|
39
|
+
optparse.parse!(args)
|
|
40
|
+
source_name = args[0]
|
|
41
|
+
option_type_id = args.size > 1 ? args[1..-1].join(" ") : nil
|
|
42
|
+
if source_name == "list"
|
|
43
|
+
verify_args!(args:args, optparse:optparse, min: 2)
|
|
44
|
+
else
|
|
45
|
+
verify_args!(args:args, optparse:optparse, count: 1)
|
|
46
|
+
end
|
|
47
|
+
connect(options)
|
|
48
|
+
params.merge!(parse_list_options(options))
|
|
49
|
+
if source_name == "list"
|
|
50
|
+
if option_type_id.to_s =~ /\A\d{1,}\Z/
|
|
51
|
+
params["optionTypeId"] = option_type_id
|
|
52
|
+
else
|
|
53
|
+
option_type = find_by_name_or_id(:option_type, option_type_id)
|
|
54
|
+
if option_type.nil?
|
|
55
|
+
return 1, "Option Type not found by name '#{option_type_id}'"
|
|
56
|
+
end
|
|
57
|
+
params["optionTypeId"] = option_type["id"]
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
# could find_by_name_or_id for params['servers'] and params['containers']
|
|
61
|
+
@options_interface.setopts(options)
|
|
62
|
+
if options[:dry_run]
|
|
63
|
+
print_dry_run @options_interface.dry.options_for_source(source_name, params)
|
|
64
|
+
return
|
|
65
|
+
end
|
|
66
|
+
json_response = nil
|
|
67
|
+
begin
|
|
68
|
+
json_response = @options_interface.options_for_source(source_name, params)
|
|
69
|
+
rescue RestClient::Exception => e
|
|
70
|
+
if e.response && e.response.code == 404
|
|
71
|
+
raise_command_error("Options source not found by name '#{source_name}'", args, optparse)
|
|
72
|
+
elsif e.response && e.response.code == 500
|
|
73
|
+
# API is actually returning 500, so just expect it
|
|
74
|
+
if e.response.body.to_s.include?("groovy.lang.MissingMethodException")
|
|
75
|
+
raise_command_error("Options source not found by name '#{source_name}'", args, optparse)
|
|
76
|
+
else
|
|
77
|
+
raise e
|
|
78
|
+
end
|
|
79
|
+
else
|
|
80
|
+
raise e
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
render_response(json_response, options, "data") do
|
|
84
|
+
records = json_response["data"]
|
|
85
|
+
# print_h1 "Morpheus Options: #{source}", parse_list_subtitles(options), options
|
|
86
|
+
print_h1 "Morpheus Options", ["Source: #{source_name}"] + parse_list_subtitles(options), options
|
|
87
|
+
if records.nil? || records.empty?
|
|
88
|
+
print cyan,"No options found.",reset,"\n"
|
|
89
|
+
else
|
|
90
|
+
print as_pretty_table(records, [:name, :value], options)
|
|
91
|
+
print_results_pagination(json_response)
|
|
92
|
+
end
|
|
93
|
+
print reset,"\n"
|
|
94
|
+
end
|
|
95
|
+
return 0, nil
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
@@ -106,14 +106,12 @@ EOT
|
|
|
106
106
|
if json_response['applianceUrl']
|
|
107
107
|
appliance[:appliance_url] = json_response['applianceUrl']
|
|
108
108
|
end
|
|
109
|
-
#
|
|
110
|
-
if appliance[:build_version] && appliance[:status].nil?
|
|
111
|
-
appliance[:status] = 'ready'
|
|
112
|
-
end
|
|
113
|
-
# update setupNeeded?
|
|
109
|
+
# setupNeeded?
|
|
114
110
|
if json_response['setupNeeded'] == true
|
|
115
111
|
# appliance[:setup_needed] = true
|
|
116
112
|
appliance[:status] = 'fresh'
|
|
113
|
+
else
|
|
114
|
+
appliance[:status] = 'ready'
|
|
117
115
|
end
|
|
118
116
|
# if took_sec
|
|
119
117
|
# appliance[:last_check] ||= {}
|
|
@@ -24,7 +24,7 @@ class Morpheus::Cli::PoliciesCommand
|
|
|
24
24
|
@cloud_policies_interface = @api_client.cloud_policies
|
|
25
25
|
@clouds_interface = @api_client.clouds
|
|
26
26
|
@groups_interface = @api_client.groups
|
|
27
|
-
@
|
|
27
|
+
@account_users_interface = @api_client.account_users
|
|
28
28
|
@roles_interface = @api_client.roles
|
|
29
29
|
@active_group_id = Morpheus::Cli::Groups.active_groups[@appliance_name]
|
|
30
30
|
end
|
|
@@ -511,7 +511,7 @@ class Morpheus::Cli::PoliciesCommand
|
|
|
511
511
|
policy_type_option_types = policy_type['optionTypes']
|
|
512
512
|
# puts "POLICY OPTION TYPES:\n #{policy_type_option_types.inspect}"
|
|
513
513
|
if policy_type_option_types
|
|
514
|
-
config_prompt = Morpheus::Cli::OptionTypes.prompt(policy_type_option_types, options, @api_client)
|
|
514
|
+
config_prompt = Morpheus::Cli::OptionTypes.prompt(policy_type_option_types, options, @api_client, {}, false, true, true)
|
|
515
515
|
# everything should be under fieldContext:'config'
|
|
516
516
|
# payload['policy'].deep_merge!(config_prompt)
|
|
517
517
|
if config_prompt['config']
|
|
@@ -211,11 +211,11 @@ class Morpheus::Cli::PricesCommand
|
|
|
211
211
|
raise_command_error "Invalid price unit '#{val}'. Available price units: #{price_units.join(', ')}"
|
|
212
212
|
end
|
|
213
213
|
end
|
|
214
|
-
opts.on("--platform [PLATFORM]", String, "Price platform [linux|windows]. Required for platform price type") do |val|
|
|
215
|
-
if ['linux', 'windows'].include?(val)
|
|
214
|
+
opts.on("--platform [PLATFORM]", String, "Price platform [centos|debian|fedora|canonical|opensuse|redhat|suse|xen|linux|windows]. Required for platform price type") do |val|
|
|
215
|
+
if ['centos','debian','fedora','canonical','opensuse','redhat','suse','xen','linux', 'windows'].include?(val)
|
|
216
216
|
params['platform'] = val
|
|
217
217
|
else
|
|
218
|
-
raise_command_error "Invalid platform '#{val}'. Available platforms: linux, windows"
|
|
218
|
+
raise_command_error "Invalid platform '#{val}'. Available platforms/vendors: centos, debian, fedora, canonical, opensuse, redhat, suse, xen, linux, windows"
|
|
219
219
|
end
|
|
220
220
|
end
|
|
221
221
|
opts.on("--software [TEXT]", String, "Price software. Required for software price type") do |val|
|
|
@@ -375,11 +375,11 @@ class Morpheus::Cli::PricesCommand
|
|
|
375
375
|
raise_command_error "Invalid price unit '#{val}'. Available price units: #{price_units.join(', ')}"
|
|
376
376
|
end
|
|
377
377
|
end
|
|
378
|
-
opts.on("--platform [PLATFORM]", String, "Price platform [linux|windows]. Required for platform price type") do |val|
|
|
379
|
-
if ['linux', 'windows'].include?(val)
|
|
378
|
+
opts.on("--platform [PLATFORM]", String, "Price platform [centos|debian|fedora|canonical|opensuse|redhat|suse|xen|linux|windows]. Required for platform price type") do |val|
|
|
379
|
+
if ['centos','debian','fedora','canonical','opensuse','redhat','suse','xen','linux', 'windows'].include?(val)
|
|
380
380
|
params['platform'] = val
|
|
381
381
|
else
|
|
382
|
-
raise_command_error "Invalid platform '#{val}'. Available platforms: linux, windows"
|
|
382
|
+
raise_command_error "Invalid platform '#{val}'. Available platforms: centos, debian, fedora, canonical, opensuse, redhat, suse, xen, linux, windows"
|
|
383
383
|
end
|
|
384
384
|
end
|
|
385
385
|
opts.on("--software [TEXT]", String, "Price software. Required for software price type") do |val|
|
|
@@ -614,7 +614,7 @@ class Morpheus::Cli::PricesCommand
|
|
|
614
614
|
def prompt_for_price_type(params, options, price={})
|
|
615
615
|
case params['priceType']
|
|
616
616
|
when 'platform'
|
|
617
|
-
params['platform'] ||= price['platform'] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'platform', 'type' => 'select', 'fieldLabel' => 'Platform', 'required' => true, 'description' => 'Select platform for platform price type', 'selectOptions' => [{'name' => 'Linux', 'value' => 'linux'}, {'name' => 'Windows', 'value' => 'windows'}]}], options[:options], @api_client, {}, options[:no_prompt])['platform']
|
|
617
|
+
params['platform'] ||= price['platform'] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'platform', 'type' => 'select', 'fieldLabel' => 'Platform', 'required' => true, 'description' => 'Select platform for platform price type', 'selectOptions' => [ {'name' => 'CentOS', 'value' => 'centos'}, {'name' => 'Debian', 'value' => 'debian'}, {'name' => 'Fedora', 'value' => 'fedora'}, {'name' => 'Canonical', 'value' => 'canonical'}, {'name' => 'openSUSE', 'value' => 'opensuse'}, {'name' => 'Red Hat', 'value' => 'redhat'}, {'name' => 'SUSE', 'value' => 'suse'}, {'name' => 'Xen', 'value' => 'xen'}, {'name' => 'Linux', 'value' => 'linux'}, {'name' => 'Windows', 'value' => 'windows'}]}], options[:options], @api_client, {}, options[:no_prompt])['platform']
|
|
618
618
|
when 'software'
|
|
619
619
|
params['software'] ||= price['software'] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'software', 'type' => 'text', 'fieldLabel' => 'Software', 'required' => true, 'description' => 'Set software for software price type'}], options[:options], @api_client,{}, options[:no_prompt])['software']
|
|
620
620
|
when 'datastore'
|
|
@@ -69,6 +69,7 @@ class Morpheus::Cli::ProvisioningSettingsCommand
|
|
|
69
69
|
"Hide Datastore Stats On Selection" => lambda {|it| format_boolean(it['hideDatastoreStats'])},
|
|
70
70
|
"Cross-Tenant Naming Policies" => lambda {|it| format_boolean(it['crossTenantNamingPolicies'])},
|
|
71
71
|
"Reuse Naming Sequence Numbers" => lambda {|it| format_boolean(it['reuseSequence'])},
|
|
72
|
+
"Show Console Keyboard Layout Settings" => lambda {|it| format_boolean(it['showConsoleKeyboardSettings'])},
|
|
72
73
|
"Deployment Archive Store" => lambda {|it| it['deployStorageProvider'] ? it['deployStorageProvider']['name'] : nil},
|
|
73
74
|
# Cloud-Init Settings
|
|
74
75
|
"Cloud-Init Username" => lambda {|it| it['cloudInitUsername']},
|
|
@@ -17,7 +17,8 @@ class Morpheus::Cli::Remote
|
|
|
17
17
|
|
|
18
18
|
set_default_subcommand :list
|
|
19
19
|
|
|
20
|
-
set_subcommands_hidden :setup #
|
|
20
|
+
set_subcommands_hidden :setup # moved to 'setup'
|
|
21
|
+
set_subcommands_hidden :view # moved to 'view'
|
|
21
22
|
|
|
22
23
|
def initialize()
|
|
23
24
|
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
|
@@ -101,7 +102,7 @@ EOT
|
|
|
101
102
|
"URL" => lambda {|it| it[:url] || it[:host] },
|
|
102
103
|
"Status" => lambda {|it| format_appliance_status(it, cyan) },
|
|
103
104
|
"Version" => lambda {|it| it[:build_version] ? "#{it[:build_version]}" : '' },
|
|
104
|
-
"Appliance URL" => lambda {|it| it[:appliance_url] ? "#{it[:appliance_url]}" : '' },
|
|
105
|
+
#"Appliance URL" => lambda {|it| it[:appliance_url] ? "#{it[:appliance_url]}" : '' },
|
|
105
106
|
"Secure" => lambda {|it| format_boolean(it[:insecure] != true && (it[:url] || it[:host]).to_s.include?("https")) },
|
|
106
107
|
"Active" => lambda {|it| it[:active] ? "Yes " + format_is_current() : "No" },
|
|
107
108
|
#"Authenticated" => lambda {|it| format_boolean it[:authenticated] },
|
|
@@ -335,7 +336,7 @@ EOT
|
|
|
335
336
|
print cyan,"Added remote #{new_appliance_name}, status is #{format_appliance_status(appliance)}",reset,"\n"
|
|
336
337
|
end
|
|
337
338
|
|
|
338
|
-
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name.to_sym)
|
|
339
|
+
#appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name.to_sym)
|
|
339
340
|
# if !options[:quiet]
|
|
340
341
|
# print cyan
|
|
341
342
|
# puts "Status: #{format_appliance_status(appliance)}"
|
|
@@ -389,7 +390,8 @@ EOT
|
|
|
389
390
|
end
|
|
390
391
|
|
|
391
392
|
end
|
|
392
|
-
|
|
393
|
+
# refresh to get buildVersion now that we are logged in
|
|
394
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name.to_sym)
|
|
393
395
|
else
|
|
394
396
|
#puts "Status is #{format_appliance_status(appliance)}"
|
|
395
397
|
end
|
|
@@ -895,6 +897,7 @@ EOT
|
|
|
895
897
|
end
|
|
896
898
|
|
|
897
899
|
def view(args)
|
|
900
|
+
print_error "#{yellow}DEPRECATION WARNING: `remote view` has been deprecated and replaced with `view`. Please use `view` instead.#{reset}\n"
|
|
898
901
|
options = {}
|
|
899
902
|
path = "/"
|
|
900
903
|
no_auth = false
|
|
@@ -903,7 +906,7 @@ EOT
|
|
|
903
906
|
opts.on('--path PATH', String, "Specify a path to load. eg '/logs'" ) do |val|
|
|
904
907
|
path = val
|
|
905
908
|
end
|
|
906
|
-
opts.on('--no-auth
|
|
909
|
+
opts.on('--no-auth', "Do not attempt to login with access token." ) do |val|
|
|
907
910
|
no_auth = true
|
|
908
911
|
end
|
|
909
912
|
build_common_options(opts, options, [:dry_run])
|
|
@@ -1276,7 +1279,7 @@ EOT
|
|
|
1276
1279
|
"URL" => lambda {|it| it[:url] || it[:host] },
|
|
1277
1280
|
#"Status" => lambda {|it| format_appliance_status(it, cyan) },
|
|
1278
1281
|
"Version" => lambda {|it| it[:build_version] ? "#{it[:build_version]}" : '' },
|
|
1279
|
-
"Appliance URL" => lambda {|it| it[:appliance_url] ? "#{it[:appliance_url]}" : '' },
|
|
1282
|
+
#"Appliance URL" => lambda {|it| it[:appliance_url] ? "#{it[:appliance_url]}" : '' },
|
|
1280
1283
|
"Secure" => lambda {|it| format_appliance_secure(it) },
|
|
1281
1284
|
"Active" => lambda {|it| it[:active] ? "Yes " + format_is_current() : "No" },
|
|
1282
1285
|
# "Active" => lambda {|it| format_boolean(it[:active]) },
|
|
@@ -1694,7 +1697,10 @@ EOT
|
|
|
1694
1697
|
# wtf, no url...
|
|
1695
1698
|
return appliance, json_response
|
|
1696
1699
|
else
|
|
1697
|
-
|
|
1700
|
+
# access token is needed for buildVersion
|
|
1701
|
+
wallet = Morpheus::Cli::Credentials.new(app_name, appliance_url).load_saved_credentials()
|
|
1702
|
+
setup_interface = Morpheus::SetupInterface.new({url:appliance_url, verify_ssl: !appliance[:insecure], timeout: timeout,
|
|
1703
|
+
access_token: (wallet && wallet['access_token']) ? wallet['access_token'] : nil})
|
|
1698
1704
|
start_time = Time.now
|
|
1699
1705
|
begin
|
|
1700
1706
|
json_response = setup_interface.check(params)
|
|
@@ -1732,17 +1738,19 @@ EOT
|
|
|
1732
1738
|
appliance[:last_check][:took] = (took_sec.to_f*1000).round
|
|
1733
1739
|
end
|
|
1734
1740
|
if json_response
|
|
1735
|
-
if json_response.key?('applianceUrl')
|
|
1736
|
-
|
|
1737
|
-
end
|
|
1738
|
-
if json_response
|
|
1739
|
-
appliance[:build_version] = json_response['buildVersion']
|
|
1741
|
+
# if json_response.key?('applianceUrl')
|
|
1742
|
+
# appliance[:appliance_url] = json_response['applianceUrl']
|
|
1743
|
+
# end
|
|
1744
|
+
if json_response['success'] == true
|
|
1740
1745
|
appliance[:status] = 'ready'
|
|
1741
1746
|
appliance[:last_check][:success] = true
|
|
1742
1747
|
# consider bumping this after every successful api command
|
|
1743
1748
|
appliance[:last_success_at] = Time.now.to_i
|
|
1744
1749
|
appliance.delete(:error)
|
|
1745
1750
|
end
|
|
1751
|
+
if !json_response['buildVersion'].to_s.empty?
|
|
1752
|
+
appliance[:build_version] = json_response['buildVersion']
|
|
1753
|
+
end
|
|
1746
1754
|
if json_response.key?('setupNeeded')
|
|
1747
1755
|
if json_response['setupNeeded'] == true
|
|
1748
1756
|
appliance[:setup_needed] = true
|
|
@@ -20,7 +20,7 @@ class Morpheus::Cli::Roles
|
|
|
20
20
|
def connect(opts)
|
|
21
21
|
@api_client = establish_remote_appliance_connection(opts)
|
|
22
22
|
@whoami_interface = @api_client.whoami
|
|
23
|
-
@
|
|
23
|
+
@account_users_interface = @api_client.account_users
|
|
24
24
|
@accounts_interface = @api_client.accounts
|
|
25
25
|
@roles_interface = @api_client.roles
|
|
26
26
|
@groups_interface = @api_client.groups
|
|
@@ -855,7 +855,7 @@ class Morpheus::Cli::SecurityGroups
|
|
|
855
855
|
|
|
856
856
|
end
|
|
857
857
|
|
|
858
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'sourceType', 'fieldLabel' => 'Source Type', 'type' => 'select', 'optionSource' => 'securityGroupSourceType', 'required' => true, 'defaultValue' => 'cidr'}], options[:options], @api_client)
|
|
858
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'sourceType', 'fieldLabel' => 'Source Type', 'type' => 'select', 'optionSource' => 'securityGroupSourceType', 'required' => true, 'defaultValue' => 'cidr'}], options[:options], @api_client, {'rule.securityGroupId': security_group['id'], 'securityGroupRule.direction': payload['rule']['direction']})
|
|
859
859
|
payload['rule']['sourceType'] = v_prompt['sourceType'] unless v_prompt['sourceType'].nil?
|
|
860
860
|
|
|
861
861
|
if payload['rule']['sourceType'] == 'cidr'
|
|
@@ -869,7 +869,7 @@ class Morpheus::Cli::SecurityGroups
|
|
|
869
869
|
payload['rule']['sourceTier'] = {"id" => v_prompt['sourceTier']} unless v_prompt['sourceTier'].nil?
|
|
870
870
|
end
|
|
871
871
|
|
|
872
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'destinationType', 'fieldLabel' => 'Destination Type', 'type' => 'select', 'optionSource' => 'securityGroupDestinationType', 'required' => true, 'defaultValue' => 'instance'}], options[:options], @api_client)
|
|
872
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'destinationType', 'fieldLabel' => 'Destination Type', 'type' => 'select', 'optionSource' => 'securityGroupDestinationType', 'required' => true, 'defaultValue' => 'instance'}], options[:options], @api_client, {'rule.securityGroupId': security_group['id'], 'securityGroupRule.direction': payload['rule']['direction']})
|
|
873
873
|
payload['rule']['destinationType'] = v_prompt['destinationType'] unless v_prompt['destinationType'].nil?
|
|
874
874
|
|
|
875
875
|
if payload['rule']['destinationType'] == 'cidr'
|
|
@@ -575,7 +575,7 @@ class Morpheus::Cli::ServicePlanCommand
|
|
|
575
575
|
options[:provisionType] = options[:provisionType] || (args.count > 1 ? args[1] : nil)
|
|
576
576
|
|
|
577
577
|
if !options[:provisionType].nil?
|
|
578
|
-
provision_types = @service_plans_interface.provision_types()['provisionTypes']
|
|
578
|
+
provision_types = @service_plans_interface.provision_types({max: 10000})['provisionTypes']
|
|
579
579
|
provision_type = provision_types.find {|it| it['name'] == options[:provisionType] || it['code'] == options[:provisionType] || it['id'] == options[:provisionType].to_i}
|
|
580
580
|
|
|
581
581
|
if provision_type.nil?
|
|
@@ -95,7 +95,7 @@ EOT
|
|
|
95
95
|
# my_terminal.execute("setup needed?")
|
|
96
96
|
# theres a bug here with --remote-url :status == "unknown"
|
|
97
97
|
# but hey, we got json back, so set status to "ready"
|
|
98
|
-
if appliance_status_json
|
|
98
|
+
if appliance_status_json
|
|
99
99
|
@remote_appliance[:status] == 'ready'
|
|
100
100
|
end
|
|
101
101
|
remote_status_string = format_appliance_status(@remote_appliance, cyan)
|
|
@@ -723,10 +723,10 @@ class Morpheus::Cli::Shell
|
|
|
723
723
|
end
|
|
724
724
|
if options[:show_pagination]
|
|
725
725
|
if options[:phrase] || options[:sort] || options[:direction] || options[:offset]
|
|
726
|
-
print_results_pagination(
|
|
726
|
+
print_results_pagination(history_result[:meta])
|
|
727
727
|
else
|
|
728
728
|
# default order is weird, it's the last page of results, 1-25 is misleading and showing the indexes is stranger
|
|
729
|
-
print_results_pagination(
|
|
729
|
+
print_results_pagination(history_result[:meta], {:message =>"Viewing most recent %{size} of %{total} %{label}"})
|
|
730
730
|
end
|
|
731
731
|
print reset, "\n"
|
|
732
732
|
else
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
|
2
|
+
|
|
3
|
+
class Morpheus::Cli::Snapshots
|
|
4
|
+
include Morpheus::Cli::CliCommand
|
|
5
|
+
|
|
6
|
+
set_command_name :snapshots
|
|
7
|
+
set_command_description "View or remove snapshot"
|
|
8
|
+
register_subcommands :get, :remove
|
|
9
|
+
|
|
10
|
+
alias_subcommand :details, :get
|
|
11
|
+
set_default_subcommand :get
|
|
12
|
+
|
|
13
|
+
def connect(opts)
|
|
14
|
+
@api_client = establish_remote_appliance_connection(opts)
|
|
15
|
+
@snapshots_interface = @api_client.snapshots
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def handle(args)
|
|
19
|
+
handle_subcommand(args)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get(args)
|
|
23
|
+
options = {}
|
|
24
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
25
|
+
opts.banner = subcommand_usage("[id]")
|
|
26
|
+
opts.footer = "Get Snapshot details." + "\n" +
|
|
27
|
+
"[snapshotId] is required. This is the id of the snapshot."
|
|
28
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
|
29
|
+
end
|
|
30
|
+
optparse.parse!(args)
|
|
31
|
+
if args.count < 1
|
|
32
|
+
puts_error "[id] argument is required"
|
|
33
|
+
puts_error optparse
|
|
34
|
+
return 1
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
connect(options)
|
|
38
|
+
id_list = parse_id_list(args)
|
|
39
|
+
|
|
40
|
+
return run_command_for_each_arg(id_list) do |arg|
|
|
41
|
+
_get(arg, options)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def _get(arg, options)
|
|
46
|
+
begin
|
|
47
|
+
|
|
48
|
+
@snapshots_interface.setopts(options)
|
|
49
|
+
if options[:dry_run]
|
|
50
|
+
print_dry_run @snapshots_interface.dry.get(arg.to_i)
|
|
51
|
+
return
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
json_response = @snapshots_interface.get(arg.to_i)
|
|
55
|
+
if options[:json]
|
|
56
|
+
puts as_json(json_response, options, "snapshot")
|
|
57
|
+
return 0
|
|
58
|
+
elsif options[:yaml]
|
|
59
|
+
puts as_yaml(json_response, options, "snapshot")
|
|
60
|
+
return 0
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if options[:csv]
|
|
64
|
+
puts records_as_csv([json_response['snapshot']], options)
|
|
65
|
+
return 0
|
|
66
|
+
end
|
|
67
|
+
snapshot = json_response['snapshot']
|
|
68
|
+
|
|
69
|
+
print_h1 "Snapshot Details"
|
|
70
|
+
print cyan
|
|
71
|
+
description_cols = {
|
|
72
|
+
"ID" => 'id',
|
|
73
|
+
"Name" => 'name',
|
|
74
|
+
"Description" => 'description',
|
|
75
|
+
"External Id" => 'externalId',
|
|
76
|
+
"Status" => 'status',
|
|
77
|
+
"State" => 'state',
|
|
78
|
+
"Snapshot Type" => 'snapshotType',
|
|
79
|
+
"Snapshot Created" => 'snapshotCreated',
|
|
80
|
+
"Cloud" => 'zone.name',
|
|
81
|
+
"Datastore" => 'datastore',
|
|
82
|
+
"Parent Snapshot" => 'parentSnapshot',
|
|
83
|
+
"Active" => 'currentlyActive',
|
|
84
|
+
"Date Created" => 'dateCreated'
|
|
85
|
+
}
|
|
86
|
+
print_description_list(description_cols, snapshot)
|
|
87
|
+
|
|
88
|
+
print reset, "\n"
|
|
89
|
+
|
|
90
|
+
return 0
|
|
91
|
+
rescue RestClient::Exception => e
|
|
92
|
+
print_rest_exception(e, options)
|
|
93
|
+
return 1
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def remove(args)
|
|
98
|
+
options = {}
|
|
99
|
+
instance = nil
|
|
100
|
+
snapshot_id = nil
|
|
101
|
+
|
|
102
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
103
|
+
opts.banner = subcommand_usage("[instance]")
|
|
104
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
|
105
|
+
opts.footer = "Remove/Delete a snapshot." + "\n" +
|
|
106
|
+
"[snapshotId] is required. This is the id of the snapshot to delete."
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
optparse.parse!(args)
|
|
110
|
+
if args.count != 1
|
|
111
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
112
|
+
end
|
|
113
|
+
snapshot_id = args[0].to_i
|
|
114
|
+
connect(options)
|
|
115
|
+
begin
|
|
116
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove a snapshot?", options)
|
|
117
|
+
exit 1
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
payload = {}
|
|
121
|
+
if options[:dry_run]
|
|
122
|
+
print_dry_run @snapshots_interface.dry.remove(snapshot_id, payload)
|
|
123
|
+
return
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
json_response = @snapshots_interface.remove(snapshot_id, payload)
|
|
127
|
+
if options[:json]
|
|
128
|
+
puts as_json(json_response, options)
|
|
129
|
+
else
|
|
130
|
+
print_green_success "Snapshot delete initiated."
|
|
131
|
+
end
|
|
132
|
+
return 0
|
|
133
|
+
|
|
134
|
+
rescue RestClient::Exception => e
|
|
135
|
+
print_rest_exception(e, options)
|
|
136
|
+
exit 1
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
|
2
|
+
|
|
3
|
+
class Morpheus::Cli::StorageServerTypes
|
|
4
|
+
include Morpheus::Cli::CliCommand
|
|
5
|
+
include Morpheus::Cli::RestCommand
|
|
6
|
+
include Morpheus::Cli::StorageServersHelper
|
|
7
|
+
|
|
8
|
+
set_command_description "View storage server types"
|
|
9
|
+
set_command_name :'storage-server-types'
|
|
10
|
+
register_subcommands :list, :get
|
|
11
|
+
|
|
12
|
+
# register_interfaces :storage_server_types
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
def storage_server_type_list_column_definitions(options)
|
|
17
|
+
{
|
|
18
|
+
"ID" => 'id',
|
|
19
|
+
"Name" => 'name',
|
|
20
|
+
"Code" => 'code',
|
|
21
|
+
"Description" => 'description',
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def storage_server_type_column_definitions(options)
|
|
26
|
+
{
|
|
27
|
+
"ID" => 'id',
|
|
28
|
+
"Name" => 'name',
|
|
29
|
+
"Code" => 'code',
|
|
30
|
+
"Description" => 'description',
|
|
31
|
+
"Creatable" => lambda {|it| format_boolean(it['creatable']) },
|
|
32
|
+
"Create Namespaces" => lambda {|it| format_boolean(it['createNamespaces']) },
|
|
33
|
+
"Create Groups" => lambda {|it| format_boolean(it['createGroups']) },
|
|
34
|
+
"Create Hosts" => lambda {|it| format_boolean(it['createHosts']) },
|
|
35
|
+
"Create Disks" => lambda {|it| format_boolean(it['createDisks']) },
|
|
36
|
+
"Has Namespaces" => lambda {|it| format_boolean(it['hasNamespaces']) },
|
|
37
|
+
"Has Groups" => lambda {|it| format_boolean(it['hasGroups']) },
|
|
38
|
+
"Has Hosts" => lambda {|it| format_boolean(it['hasHosts']) },
|
|
39
|
+
"Has Disks" => lambda {|it| format_boolean(it['hasDisks']) },
|
|
40
|
+
"Has File Browser" => lambda {|it| format_boolean(it['hasFileBrowser']) },
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# overridden to support name or code
|
|
45
|
+
def find_storage_server_type_by_name_or_id(name)
|
|
46
|
+
storage_server_type_for_name_or_id(name)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
|