morpheus-cli 8.0.3 → 8.0.4
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/license_interface.rb +2 -4
- data/lib/morpheus/cli/commands/clusters.rb +5 -5
- data/lib/morpheus/cli/commands/hosts.rb +33 -0
- data/lib/morpheus/cli/commands/license.rb +170 -87
- data/lib/morpheus/cli/commands/networks_command.rb +5 -4
- 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: 7cbc73275f4621016909ca9b3d12fcdf879a27d948c5d0e2b5e168d849850954
|
4
|
+
data.tar.gz: c30e3333325812730d68d16fa340ed8f858926b22aaf8d3ffd95fc9d4f9d2ef8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9b1b734e792e44addc36e281765be1598d7e9d94e312f4e8c7cdd5a0da8ade497d8989421e56793dc86897a37d1fdafca26da81bda67f0591481ddec642099f
|
7
|
+
data.tar.gz: e6ff86116594db8837b84a0baa8b15e0f6bb777dd3df415fad23f6918a9f097b210026b2479391decaac93c1a21177f082fd4449914d9bcb910f899228b60a70
|
data/Dockerfile
CHANGED
@@ -8,18 +8,16 @@ class Morpheus::LicenseInterface < Morpheus::APIClient
|
|
8
8
|
execute(method: :get, url: url, headers: headers)
|
9
9
|
end
|
10
10
|
|
11
|
-
def install(
|
11
|
+
def install(payload)
|
12
12
|
url = "#{@base_url}/api/license"
|
13
13
|
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
14
|
-
payload = {license: key}
|
15
14
|
execute(method: :post, url: url, headers: headers, payload: payload.to_json)
|
16
15
|
end
|
17
16
|
|
18
|
-
def test(
|
17
|
+
def test(payload)
|
19
18
|
# use /test instead, since 4.1.1
|
20
19
|
url = "#{@base_url}/api/license/decode"
|
21
20
|
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
22
|
-
payload = {license: key}
|
23
21
|
execute(method: :post, url: url, headers: headers, payload: payload.to_json)
|
24
22
|
end
|
25
23
|
|
@@ -422,7 +422,7 @@ class Morpheus::Cli::Clusters
|
|
422
422
|
options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
|
423
423
|
end
|
424
424
|
opts.on('--workflow ID', String, "Workflow") do |val|
|
425
|
-
options[
|
425
|
+
options[:workflow] = val.to_i
|
426
426
|
end
|
427
427
|
add_server_options(opts, options)
|
428
428
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
@@ -608,13 +608,12 @@ class Morpheus::Cli::Clusters
|
|
608
608
|
end
|
609
609
|
|
610
610
|
# Controller type
|
611
|
-
server_types = @server_types_interface.list({computeTypeId: cluster_type['controllerTypes'].first['id'], zoneTypeId: cloud['zoneType']['id'], useZoneProvisionTypes: true})['serverTypes'].reject {|it| it['provisionType']['code'] == 'manual'} unless ['
|
611
|
+
server_types = @server_types_interface.list({computeTypeId: cluster_type['controllerTypes'].first['id'], zoneTypeId: cloud['zoneType']['id'], useZoneProvisionTypes: true})['serverTypes'].reject {|it| it['provisionType']['code'] == 'manual'} unless ['mvm-cluster'].include?(cluster_type_code)
|
612
612
|
controller_provision_type = nil
|
613
613
|
resource_pool = nil
|
614
614
|
|
615
615
|
if !server_types.empty?
|
616
616
|
controller_type = server_types.first
|
617
|
-
|
618
617
|
if controller_type['provisionType']
|
619
618
|
if provision_type && provision_type['id'] == controller_type['provisionType']['id']
|
620
619
|
controller_provision_type = provision_type
|
@@ -747,10 +746,11 @@ class Morpheus::Cli::Clusters
|
|
747
746
|
|
748
747
|
# Workflow / Automation
|
749
748
|
if provision_type['code'] != 'manual' && controller_type && controller_type['hasAutomation']
|
750
|
-
task_set_id = options[:
|
749
|
+
task_set_id = options[:workflow] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'taskSetId', 'fieldLabel' => 'Workflow', 'type' => 'select', 'required' => false, 'optionSource' => 'taskSets'}], options[:options], @api_client, api_params.merge({'phase' => 'postProvision'}))['taskSetId']
|
751
750
|
|
752
751
|
if !task_set_id.nil?
|
753
|
-
server_payload['taskSet'] = {'id' => task_set_id}
|
752
|
+
# server_payload['taskSet'] = {'id' => task_set_id}
|
753
|
+
cluster_payload['taskSetId'] = task_set_id
|
754
754
|
end
|
755
755
|
end
|
756
756
|
|
@@ -2229,6 +2229,18 @@ EOT
|
|
2229
2229
|
options = {}
|
2230
2230
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2231
2231
|
opts.banner = subcommand_usage("[host]")
|
2232
|
+
opts.on('--ignoreDaemonsets [on|off]', String, "Ignore Daemonsets") do |val|
|
2233
|
+
options[:ignoreDaemonsets] = (val.to_s.empty? || val.to_s == 'on' || val.to_s == 'true')
|
2234
|
+
end
|
2235
|
+
opts.on('--force [on|off]', String, "Force") do |val|
|
2236
|
+
options[:force] = (val.to_s.empty? || val.to_s == 'on' || val.to_s == 'true')
|
2237
|
+
end
|
2238
|
+
opts.on('--deleteEmptyDir [on|off]', String, "Delete Empty Directories") do |val|
|
2239
|
+
options[:deleteEmptyDir] = (val.to_s.empty? || val.to_s == 'on' || val.to_s == 'true')
|
2240
|
+
end
|
2241
|
+
opts.on('--deleteLocalData [on|off]', String, "Delete Local Data") do |val|
|
2242
|
+
options[:deleteLocalData] = (val.to_s == 'on' || val.to_s == 'true')
|
2243
|
+
end
|
2232
2244
|
build_standard_update_options(opts, options, [:auto_confirm])
|
2233
2245
|
opts.footer = <<-EOT
|
2234
2246
|
Enable maintenance mode for a host.
|
@@ -2252,6 +2264,27 @@ EOT
|
|
2252
2264
|
# end
|
2253
2265
|
|
2254
2266
|
payload = {}
|
2267
|
+
|
2268
|
+
if server.dig('config', 'kubernetesRole')
|
2269
|
+
payload[:server] = {}
|
2270
|
+
payload[:server][:ignoreDaemonsets] = options.fetch(:ignoreDaemonsets) do
|
2271
|
+
prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ignoreDaemonsets', 'fieldLabel' => 'Ignore Daemonsets', 'type' => 'checkbox', 'defaultValue' => true, 'required' => false}], options, @api_client, {})
|
2272
|
+
prompt['ignoreDaemonsets'] == 'on'
|
2273
|
+
end
|
2274
|
+
payload[:server][:force] = options.fetch(:force) do
|
2275
|
+
prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'force', 'fieldLabel' => 'Force', 'type' => 'checkbox', 'defaultValue' => true, 'required' => false}], options, @api_client, {})
|
2276
|
+
prompt['force'] == 'on'
|
2277
|
+
end
|
2278
|
+
payload[:server][:deleteEmptyDir] = options.fetch(:deleteEmptyDir) do
|
2279
|
+
prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'deleteEmptyDir', 'fieldLabel' => 'Delete Empty Directories', 'type' => 'checkbox', 'defaultValue' => true, 'required' => false}], options, @api_client, {})
|
2280
|
+
prompt['deleteEmptyDir'] == 'on'
|
2281
|
+
end
|
2282
|
+
payload[:server][:deleteLocalData] = options.fetch(:deleteLocalData) do
|
2283
|
+
prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'deleteLocalData', 'fieldLabel' => 'Delete Local Data', 'type' => 'checkbox', 'defaultValue' => false, 'required' => false}], options, @api_client, {})
|
2284
|
+
prompt['force'] == 'on'
|
2285
|
+
end
|
2286
|
+
end
|
2287
|
+
|
2255
2288
|
if options[:payload]
|
2256
2289
|
payload = options[:payload]
|
2257
2290
|
payload.deep_merge!(parse_passed_options(options))
|
@@ -55,6 +55,10 @@ class Morpheus::Cli::License
|
|
55
55
|
print "#{yellow}No license currently installed#{reset}\n\n"
|
56
56
|
else
|
57
57
|
print_license_details(json_response)
|
58
|
+
licenses = json_response['installedLicenses']
|
59
|
+
if licenses
|
60
|
+
print_installed_licenses(licenses, options)
|
61
|
+
end
|
58
62
|
print_h2 "Current Usage", [], options
|
59
63
|
print_license_usage(license, current_usage)
|
60
64
|
print reset,"\n"
|
@@ -72,40 +76,55 @@ class Morpheus::Cli::License
|
|
72
76
|
account_name = nil
|
73
77
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
74
78
|
opts.banner = subcommand_usage("[key]")
|
75
|
-
|
79
|
+
opts.on('-a', '--add', "Stack this license on top of existing licenses. Without this option all existing licenses will be replaced." ) do
|
80
|
+
options[:options]['installAction'] = 'add'
|
81
|
+
end
|
82
|
+
opts.on('--stack', '--stack', "Alias for --add" ) do
|
83
|
+
options[:options]['installAction'] = 'add'
|
84
|
+
end
|
85
|
+
opts.on('--replace', '--replace', "Replace existing licenses with this new license. This is the default behavior." ) do
|
86
|
+
options[:options]['installAction'] = 'replace'
|
87
|
+
end
|
88
|
+
build_standard_add_options(opts, options)
|
76
89
|
opts.footer = "Install a new license key.\n" +
|
77
90
|
"This will potentially change the enabled features and capabilities of your appliance."
|
78
91
|
end
|
79
92
|
optparse.parse!(args)
|
80
|
-
|
81
|
-
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
82
|
-
end
|
93
|
+
verify_args!(args:args, optparse:optparse, min:0, max:1)
|
83
94
|
connect(options)
|
84
|
-
|
95
|
+
payload = {}
|
96
|
+
if options[:payload]
|
97
|
+
payload = options[:payload]
|
98
|
+
payload.deep_merge!(parse_passed_options(options))
|
99
|
+
else
|
100
|
+
payload.deep_merge!(parse_passed_options(options))
|
85
101
|
if args[0]
|
86
|
-
key = args[0]
|
102
|
+
key = args[0].strip
|
87
103
|
else
|
88
104
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'licenseKey', 'fieldLabel' => 'License Key', 'type' => 'text', 'required' => true}], options[:options])
|
89
|
-
key = v_prompt['licenseKey']
|
105
|
+
key = v_prompt['licenseKey'].to_s.strip
|
90
106
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
puts JSON.pretty_generate(json_response)
|
100
|
-
else
|
101
|
-
print_green_success "License installed!"
|
102
|
-
get([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
107
|
+
payload['license'] = key
|
108
|
+
# Stack Licenses?
|
109
|
+
# load current licenses to see if this prompt is required
|
110
|
+
json_response = @license_interface.get()
|
111
|
+
licenses = json_response['installedLicenses']
|
112
|
+
if licenses && !(licenses.size == 1 && key.index(licenses[0]['keyId']) == 0)
|
113
|
+
install_actions = [{'name' => 'Add', 'value' => 'add'},{'name' => 'Replace', 'value' => 'replace'}]
|
114
|
+
payload['installAction'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'installAction', 'fieldLabel' => 'Install Action', 'type' => 'select', 'selectOptions' => install_actions, 'required' => true, 'defaultValue' => 'replace', 'description' => "Install action to perform. Use add to stack this license on top of existing licenses. Use replace (default) to remove any existing license(s)."}], options[:options])['installAction']
|
103
115
|
end
|
116
|
+
end
|
117
|
+
@license_interface.setopts(options)
|
118
|
+
if options[:dry_run]
|
119
|
+
print_dry_run @license_interface.dry.install(payload)
|
104
120
|
return 0
|
105
|
-
rescue RestClient::Exception => e
|
106
|
-
print_rest_exception(e, options)
|
107
|
-
return false
|
108
121
|
end
|
122
|
+
json_response = @license_interface.install(payload)
|
123
|
+
render_response(json_response, options) do
|
124
|
+
print_green_success "License installed!"
|
125
|
+
get([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
126
|
+
end
|
127
|
+
return 0, nil
|
109
128
|
end
|
110
129
|
|
111
130
|
def decode(args)
|
@@ -117,7 +136,16 @@ class Morpheus::Cli::License
|
|
117
136
|
options = {}
|
118
137
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
119
138
|
opts.banner = subcommand_usage("[key]")
|
120
|
-
|
139
|
+
opts.on('-a', '--add', "Stack this license on top of existing licenses. Without this option all existing licenses will be replaced." ) do
|
140
|
+
options[:options]['installAction'] = 'add'
|
141
|
+
end
|
142
|
+
opts.on('--stack', '--stack', "Alias for --add" ) do
|
143
|
+
options[:options]['installAction'] = 'add'
|
144
|
+
end
|
145
|
+
opts.on('--replace', '--replace', "Replace existing licenses with this new license. This is the default behavior." ) do
|
146
|
+
options[:options]['installAction'] = 'replace'
|
147
|
+
end
|
148
|
+
build_standard_add_options(opts, options, [:fields])
|
121
149
|
opts.footer = "Test a license key.\n" +
|
122
150
|
"This is a way to decode and view a license key before installing it."
|
123
151
|
end
|
@@ -126,50 +154,48 @@ class Morpheus::Cli::License
|
|
126
154
|
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
127
155
|
end
|
128
156
|
connect(options)
|
129
|
-
|
130
|
-
if
|
131
|
-
|
157
|
+
payload = {}
|
158
|
+
if options[:payload]
|
159
|
+
payload = options[:payload]
|
160
|
+
payload.deep_merge!(parse_passed_options(options))
|
132
161
|
else
|
133
|
-
|
134
|
-
key =
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
return
|
141
|
-
end
|
142
|
-
json_response = @license_interface.test(key)
|
143
|
-
license = json_response['license']
|
144
|
-
current_usage = json_response['currentUsage'] || {}
|
145
|
-
exit_code, err = 0, nil
|
146
|
-
if license.nil?
|
147
|
-
err = "Unable to decode license."
|
148
|
-
exit_code = 1
|
149
|
-
#return err, exit_code
|
150
|
-
end
|
151
|
-
render_result = render_with_format(json_response, options)
|
152
|
-
if render_result
|
153
|
-
return exit_code, err
|
154
|
-
end
|
155
|
-
if options[:quiet]
|
156
|
-
return exit_code, err
|
162
|
+
payload.deep_merge!(parse_passed_options(options))
|
163
|
+
key = nil
|
164
|
+
if args[0]
|
165
|
+
key = args[0].strip
|
166
|
+
else
|
167
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'licenseKey', 'fieldLabel' => 'License Key', 'type' => 'text', 'required' => true}], options[:options])
|
168
|
+
key = v_prompt['licenseKey'] || ''
|
157
169
|
end
|
158
|
-
|
159
|
-
|
160
|
-
|
170
|
+
payload['license'] = key
|
171
|
+
# Stack Licenses?
|
172
|
+
# load current licenses to see if this prompt is required
|
173
|
+
json_response = @license_interface.get()
|
174
|
+
licenses = json_response['installedLicenses']
|
175
|
+
if licenses && !(licenses.size == 1 && key.index(licenses[0]['keyId']) == 0)
|
176
|
+
install_actions = [{'name' => 'Add', 'value' => 'add'},{'name' => 'Replace', 'value' => 'replace'}]
|
177
|
+
payload['installAction'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'installAction', 'fieldLabel' => 'Install Action', 'type' => 'select', 'selectOptions' => install_actions, 'required' => true, 'defaultValue' => 'replace', 'description' => "Install action to perform. Use add to stack this license on top of existing licenses. Use replace (default) to remove any existing license(s)."}], options[:options])['installAction']
|
161
178
|
end
|
162
|
-
|
179
|
+
end
|
180
|
+
@license_interface.setopts(options)
|
181
|
+
if options[:dry_run]
|
182
|
+
print_dry_run @license_interface.dry.test(payload)
|
183
|
+
return
|
184
|
+
end
|
185
|
+
json_response = @license_interface.test(payload)
|
186
|
+
render_response(json_response, options) do
|
187
|
+
license = json_response['license']
|
188
|
+
current_usage = json_response['currentUsage'] || {}
|
163
189
|
# all good
|
164
190
|
print_h1 "License"
|
165
191
|
print_license_details(json_response)
|
192
|
+
licenses = json_response['installedLicenses']
|
193
|
+
if licenses
|
194
|
+
print_installed_licenses(licenses, options)
|
195
|
+
end
|
166
196
|
print_h2 "License Usage", [], options
|
167
197
|
print_license_usage(license, current_usage)
|
168
198
|
print reset,"\n"
|
169
|
-
return exit_code, err
|
170
|
-
rescue RestClient::Exception => e
|
171
|
-
print_rest_exception(e, options)
|
172
|
-
return 1
|
173
199
|
end
|
174
200
|
end
|
175
201
|
|
@@ -177,44 +203,58 @@ class Morpheus::Cli::License
|
|
177
203
|
options = {}
|
178
204
|
params = {}
|
179
205
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
180
|
-
opts.banner = subcommand_usage("[key]")
|
206
|
+
opts.banner = subcommand_usage("[key ID]")
|
207
|
+
opts.on('--key KEY', String, "License Key ID to uninstall (only the first 8 characters are required to identify license to uninstall). By default all licenses are uninstalled.") do |val|
|
208
|
+
options[:key] = val.to_s
|
209
|
+
end
|
181
210
|
build_common_options(opts, options, [:auto_confirm, :json, :yaml, :dry_run, :remote])
|
182
|
-
opts.footer = "Uninstall
|
183
|
-
"
|
211
|
+
opts.footer = "Uninstall license key(s).\n" +
|
212
|
+
"Use [key] or --key to uninstall only the specified license key.\n" +
|
213
|
+
"By default all currently installed license keys are uninstalled.\n" +
|
184
214
|
"The function of the remote appliance will be restricted without a license installed.\n" +
|
185
215
|
"Be careful using this."
|
186
216
|
end
|
187
217
|
optparse.parse!(args)
|
188
|
-
|
189
|
-
raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
190
|
-
end
|
218
|
+
verify_args!(args:args, optparse:optparse, min:0, max:1)
|
191
219
|
connect(options)
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
220
|
+
key_id = nil
|
221
|
+
if args[0] || options[:key]
|
222
|
+
key_id = (args[0] || options[:key])[0..7]
|
223
|
+
end
|
224
|
+
# load current licenses to prompt user which to uninstall
|
225
|
+
json_response = @license_interface.get()
|
226
|
+
licenses = json_response['installedLicenses'] # || [json_response['licenses']]
|
227
|
+
if key_id
|
228
|
+
# appliance version < 8.0.4 does not return installedLicenses list
|
229
|
+
if licenses.nil?
|
230
|
+
raise_command_error "Appliance version does not support uninstalling specific keys"
|
203
231
|
end
|
204
|
-
|
205
|
-
|
206
|
-
|
232
|
+
matching_license = licenses.find {|it| it['keyId'] == key_id }
|
233
|
+
if matching_license.nil?
|
234
|
+
raise_command_error "Unable to find installed license key '#{key_id}'"
|
207
235
|
end
|
236
|
+
params['keyId'] = key_id
|
237
|
+
end
|
238
|
+
|
239
|
+
unless options[:quiet]
|
240
|
+
print cyan,"#{bold}WARNING!#{reset}#{cyan} You are about to uninstall your license key (#{key_id ? key_id : 'ALL'})",reset,"\n"
|
241
|
+
print yellow, "Be careful using this. Make sure you have a copy of your key somewhere if you intend to use it again.",reset, "\n"
|
242
|
+
print "\n"
|
243
|
+
end
|
244
|
+
|
245
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you want to uninstall the license key (#{key_id ? key_id : 'ALL'}) for remote #{@appliance_name} - #{@appliance_url}?")
|
246
|
+
return 9, "command aborted"
|
247
|
+
end
|
208
248
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
return
|
249
|
+
@license_interface.setopts(options)
|
250
|
+
if options[:dry_run]
|
251
|
+
print_dry_run @license_interface.dry.uninstall(params)
|
252
|
+
return
|
253
|
+
end
|
254
|
+
json_response = @license_interface.uninstall(params)
|
255
|
+
|
256
|
+
render_response(json_response, options) do
|
213
257
|
print_green_success "License uninstalled!"
|
214
|
-
return 0
|
215
|
-
rescue RestClient::Exception => e
|
216
|
-
print_rest_exception(e, options)
|
217
|
-
return 1
|
218
258
|
end
|
219
259
|
end
|
220
260
|
|
@@ -267,8 +307,10 @@ class Morpheus::Cli::License
|
|
267
307
|
|
268
308
|
def print_license_details(json_response)
|
269
309
|
license = json_response['license']
|
310
|
+
licenses = json_response['installedLicenses']
|
270
311
|
current_usage = json_response['currentUsage'] || {}
|
271
312
|
description_cols = {
|
313
|
+
"Key ID" => lambda {|it| licenses ? licenses.collect {|li| li['keyId'] }.join(", ") : it['keyId'] },
|
272
314
|
"Account" => 'accountName',
|
273
315
|
"Product Tier" => lambda {|it| format_product_tier(it) },
|
274
316
|
"Start Date" => lambda {|it| format_local_dt(it['startDate']) },
|
@@ -285,7 +327,7 @@ class Morpheus::Cli::License
|
|
285
327
|
"Hard Limit" => lambda {|it| format_boolean it["hardLimit"] },
|
286
328
|
"Limit Type" => lambda {|it| format_limit_type(it) },
|
287
329
|
}
|
288
|
-
|
330
|
+
description_cols.delete("Key ID") if !license['keyId']
|
289
331
|
description_cols.delete("Multi-Tenant") if !license['multiTenant']
|
290
332
|
description_cols.delete("White Label") if !license['whitelabel']
|
291
333
|
|
@@ -373,5 +415,46 @@ class Morpheus::Cli::License
|
|
373
415
|
cyan + label.rjust(label_width, ' ') + ": " + generate_usage_bar(used, max, chart_opts) + cyan + used.to_s.rjust(label_width, ' ') + " / " + (max.to_i > 0 ? max.to_s : unlimited_label).to_s.ljust(label_width, ' ') + "\n"
|
374
416
|
end
|
375
417
|
|
418
|
+
def print_installed_licenses(licenses, options)
|
419
|
+
print_h2 "Installed Licenses", [], options
|
420
|
+
license_columns = {
|
421
|
+
"Key ID" => 'keyId',
|
422
|
+
"Account" => 'accountName',
|
423
|
+
"Product Tier" => lambda {|it| format_product_tier(it) },
|
424
|
+
"Start Date" => lambda {|it| format_local_dt(it['startDate']) },
|
425
|
+
"End Date" => lambda {|it|
|
426
|
+
if it['endDate']
|
427
|
+
format_local_dt(it['endDate']).to_s + ' (' + format_duration(Time.now, it['endDate']).to_s + ')'
|
428
|
+
else
|
429
|
+
'Never'
|
430
|
+
end
|
431
|
+
},
|
432
|
+
"Multi-Tenant" => lambda {|it| format_boolean it["multiTenant"] },
|
433
|
+
"White Label" => lambda {|it| format_boolean it["whitelabel"] },
|
434
|
+
"Stats Reporting" => lambda {|it| format_boolean it["reportStatus"] },
|
435
|
+
"Hard Limit" => lambda {|it| format_boolean it["hardLimit"] },
|
436
|
+
"Limit Type" => lambda {|it| format_limit_type(it) },
|
437
|
+
"Limit Type" => lambda {|it| format_limit_type(it) },
|
438
|
+
}
|
439
|
+
if licenses[0] && licenses[0]['limitType'] == 'workload'
|
440
|
+
license_columns.merge!({
|
441
|
+
"Workloads" => 'maxInstances'
|
442
|
+
})
|
443
|
+
else
|
444
|
+
license_columns.merge!({
|
445
|
+
"Managed Servers" => 'maxManagedServers',
|
446
|
+
"Discovered Servers" => 'maxDiscoveredServers',
|
447
|
+
"Hosts" => 'maxHosts',
|
448
|
+
"HPE VM Hosts" => 'maxMvm',
|
449
|
+
"HPE VM Sockets" => 'maxMvmSockets',
|
450
|
+
"Iac Deployments" => 'maxIac',
|
451
|
+
"Xaas Instances" => 'maxXaas',
|
452
|
+
"Executions" => 'maxExecutions',
|
453
|
+
"Distributed Workers" => 'maxDistributedWorkers',
|
454
|
+
# "Discovered Objects" => 'maxDiscoveredObjects'
|
455
|
+
})
|
456
|
+
end
|
457
|
+
print as_pretty_table(licenses, license_columns, options)
|
458
|
+
end
|
376
459
|
|
377
460
|
end
|
@@ -493,6 +493,9 @@ class Morpheus::Cli::NetworksCommand
|
|
493
493
|
# allow arbitrary -O options
|
494
494
|
payload['network'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
495
495
|
|
496
|
+
# all of these prompts pass in options instead of options[:options] so merge them here
|
497
|
+
options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
498
|
+
|
496
499
|
# Name
|
497
500
|
if options['name']
|
498
501
|
payload['network']['name'] = options['name']
|
@@ -813,16 +816,14 @@ class Morpheus::Cli::NetworksCommand
|
|
813
816
|
## Advanced Options
|
814
817
|
|
815
818
|
# Network Domain
|
816
|
-
if
|
817
|
-
|
818
|
-
if options['domain'].to_s.empty? # clear it?
|
819
|
+
if payload['network']['networkDomain'].nil?
|
820
|
+
if options.key?('domain') && options['domain'].to_s.empty? # clear it?
|
819
821
|
payload['network']['networkDomain'] = {'id' => nil}
|
820
822
|
else
|
821
823
|
# always prompt to handle value as name instead of id...
|
822
824
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'domain', 'fieldLabel' => 'Network Domain', 'type' => 'select', 'optionSource' => 'networkDomains', 'required' => false, 'description' => ''}], options, @api_client)
|
823
825
|
payload['network']['networkDomain'] = {'id' => v_prompt['domain'].to_i} unless v_prompt['domain'].to_s.empty?
|
824
826
|
end
|
825
|
-
end
|
826
827
|
end
|
827
828
|
|
828
829
|
# Search Domains
|
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: 8.0.
|
4
|
+
version: 8.0.4
|
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: 2025-
|
14
|
+
date: 2025-03-14 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: public_suffix
|