morpheus-cli 3.5.2 → 3.5.3
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/lib/morpheus/api/api_client.rb +16 -0
- data/lib/morpheus/api/blueprints_interface.rb +84 -0
- data/lib/morpheus/api/execution_request_interface.rb +33 -0
- data/lib/morpheus/api/instances_interface.rb +21 -0
- data/lib/morpheus/api/packages_interface.rb +25 -5
- data/lib/morpheus/api/processes_interface.rb +34 -0
- data/lib/morpheus/api/roles_interface.rb +7 -0
- data/lib/morpheus/api/servers_interface.rb +8 -0
- data/lib/morpheus/api/user_settings_interface.rb +76 -0
- data/lib/morpheus/cli.rb +5 -1
- data/lib/morpheus/cli/alias_command.rb +1 -1
- data/lib/morpheus/cli/app_templates.rb +2 -1
- data/lib/morpheus/cli/apps.rb +173 -19
- data/lib/morpheus/cli/blueprints_command.rb +2134 -0
- data/lib/morpheus/cli/cli_command.rb +3 -1
- data/lib/morpheus/cli/clouds.rb +4 -10
- data/lib/morpheus/cli/coloring_command.rb +14 -8
- data/lib/morpheus/cli/containers_command.rb +92 -5
- data/lib/morpheus/cli/execution_request_command.rb +313 -0
- data/lib/morpheus/cli/hosts.rb +188 -7
- data/lib/morpheus/cli/instances.rb +472 -9
- data/lib/morpheus/cli/login.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +8 -0
- data/lib/morpheus/cli/mixins/processes_helper.rb +134 -0
- data/lib/morpheus/cli/option_types.rb +21 -16
- data/lib/morpheus/cli/packages_command.rb +469 -17
- data/lib/morpheus/cli/processes_command.rb +313 -0
- data/lib/morpheus/cli/remote.rb +20 -9
- data/lib/morpheus/cli/roles.rb +186 -6
- data/lib/morpheus/cli/shell.rb +10 -1
- data/lib/morpheus/cli/tasks.rb +4 -1
- data/lib/morpheus/cli/user_settings_command.rb +431 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whoami.rb +1 -1
- data/lib/morpheus/formatters.rb +14 -0
- data/lib/morpheus/morpkg.rb +119 -0
- data/morpheus-cli.gemspec +1 -0
- metadata +26 -2
@@ -762,7 +762,9 @@ module Morpheus
|
|
762
762
|
end
|
763
763
|
|
764
764
|
def default_command_name
|
765
|
-
|
765
|
+
class_name = self.name.split('::')[-1]
|
766
|
+
#class_name.sub!(/Command$/, '')
|
767
|
+
Morpheus::Cli::CliRegistry.cli_ize(class_name)
|
766
768
|
end
|
767
769
|
|
768
770
|
def command_name
|
data/lib/morpheus/cli/clouds.rb
CHANGED
@@ -640,14 +640,6 @@ class Morpheus::Cli::Clouds
|
|
640
640
|
def print_clouds_table(clouds, opts={})
|
641
641
|
table_color = opts[:color] || cyan
|
642
642
|
rows = clouds.collect do |cloud|
|
643
|
-
status = nil
|
644
|
-
if cloud['status'] == 'ok'
|
645
|
-
status = "#{green}OK#{table_color}"
|
646
|
-
elsif cloud['status'].nil?
|
647
|
-
status = "#{white}UNKNOWN#{table_color}"
|
648
|
-
else
|
649
|
-
status = "#{red}#{cloud['status'] ? cloud['status'].upcase : 'N/A'}#{cloud['statusMessage'] ? "#{table_color} - #{cloud['statusMessage']}" : ''}#{table_color}"
|
650
|
-
end
|
651
643
|
cloud_type = cloud_type_for_id(cloud['zoneTypeId'])
|
652
644
|
{
|
653
645
|
id: cloud['id'],
|
@@ -656,7 +648,7 @@ class Morpheus::Cli::Clouds
|
|
656
648
|
location: cloud['location'],
|
657
649
|
groups: (cloud['groups'] || []).collect {|it| it.instance_of?(Hash) ? it['name'] : it.to_s }.join(', '),
|
658
650
|
servers: cloud['serverCount'],
|
659
|
-
status:
|
651
|
+
status: format_cloud_status(cloud)
|
660
652
|
}
|
661
653
|
end
|
662
654
|
columns = [
|
@@ -714,7 +706,9 @@ class Morpheus::Cli::Clouds
|
|
714
706
|
def format_cloud_status(cloud, return_color=cyan)
|
715
707
|
out = ""
|
716
708
|
status_string = cloud['status']
|
717
|
-
if
|
709
|
+
if cloud['enabled'] == false
|
710
|
+
out << "#{red}DISABLED#{return_color}"
|
711
|
+
elsif status_string.nil? || status_string.empty? || status_string == "unknown"
|
718
712
|
out << "#{white}UNKNOWN#{return_color}"
|
719
713
|
elsif status_string == 'ok'
|
720
714
|
out << "#{green}#{status_string.upcase}#{return_color}"
|
@@ -22,18 +22,24 @@ class Morpheus::Cli::ColoringCommand
|
|
22
22
|
opts.footer = "Enable [on] or Disable [off] ANSI Colors for all output."
|
23
23
|
end
|
24
24
|
optparse.parse!(args)
|
25
|
-
if args.count
|
25
|
+
if args.count > 1
|
26
26
|
puts optparse
|
27
27
|
exit 1
|
28
28
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
if args.count == 1
|
30
|
+
is_on = ["on","true", "1"].include?(args[0].to_s.strip.downcase)
|
31
|
+
is_off = ["off","false", "0"].include?(args[0].to_s.strip.downcase)
|
32
|
+
if !is_on && !is_off
|
33
|
+
puts optparse
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
Term::ANSIColor::coloring = is_on
|
37
|
+
end
|
38
|
+
if Term::ANSIColor::coloring?
|
39
|
+
puts "#{cyan}coloring is #{bold}#{green}on#{reset}"
|
40
|
+
else
|
41
|
+
puts "coloring is off"
|
34
42
|
end
|
35
|
-
Term::ANSIColor::coloring = is_on
|
36
|
-
return true
|
37
43
|
end
|
38
44
|
|
39
45
|
end
|
@@ -14,10 +14,12 @@ class Morpheus::Cli::ContainersCommand
|
|
14
14
|
set_command_name :containers
|
15
15
|
|
16
16
|
register_subcommands :get, :stop, :start, :restart, :suspend, :eject, :action, :actions
|
17
|
+
register_subcommands :exec => :execution_request
|
17
18
|
|
18
19
|
def connect(opts)
|
19
20
|
@api_client = establish_remote_appliance_connection(opts)
|
20
21
|
@containers_interface = @api_client.containers
|
22
|
+
@execution_request_interface = @api_client.execution_request
|
21
23
|
end
|
22
24
|
|
23
25
|
def handle(args)
|
@@ -31,9 +33,9 @@ class Morpheus::Cli::ContainersCommand
|
|
31
33
|
opts.on( nil, '--actions', "Display Available Actions" ) do
|
32
34
|
options[:include_available_actions] = true
|
33
35
|
end
|
34
|
-
opts.on('--refresh
|
36
|
+
opts.on('--refresh [status]', String, "Refresh until status is reached. Default status is running.") do |val|
|
35
37
|
if val.to_s.empty?
|
36
|
-
options[:refresh_until_status] = "running"
|
38
|
+
options[:refresh_until_status] = "running,failed"
|
37
39
|
else
|
38
40
|
options[:refresh_until_status] = val.to_s.downcase
|
39
41
|
end
|
@@ -135,10 +137,13 @@ class Morpheus::Cli::ContainersCommand
|
|
135
137
|
if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
|
136
138
|
options[:refresh_interval] = 5
|
137
139
|
end
|
138
|
-
|
140
|
+
statuses = options[:refresh_until_status].to_s.downcase.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
|
141
|
+
if !statuses.include?(container['status'])
|
139
142
|
print cyan
|
140
|
-
print "
|
141
|
-
sleep(options[:refresh_interval])
|
143
|
+
print "Status is #{container['status'] || 'unknown'}. Refreshing in #{options[:refresh_interval]} seconds"
|
144
|
+
#sleep(options[:refresh_interval])
|
145
|
+
sleep_with_dots(options[:refresh_interval])
|
146
|
+
print "\n"
|
142
147
|
_get(arg, options)
|
143
148
|
end
|
144
149
|
end
|
@@ -493,6 +498,88 @@ class Morpheus::Cli::ContainersCommand
|
|
493
498
|
return 0
|
494
499
|
end
|
495
500
|
|
501
|
+
def execution_request(args)
|
502
|
+
options = {}
|
503
|
+
params = {}
|
504
|
+
script_content = nil
|
505
|
+
do_refresh = true
|
506
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
507
|
+
opts.banner = subcommand_usage("[id] [options]")
|
508
|
+
opts.on('--script SCRIPT', "Script to be executed" ) do |val|
|
509
|
+
script_content = val
|
510
|
+
end
|
511
|
+
opts.on('--file FILE', "File containing the script. This can be used instead of --script" ) do |filename|
|
512
|
+
full_filename = File.expand_path(filename)
|
513
|
+
if File.exists?(full_filename)
|
514
|
+
script_content = File.read(full_filename)
|
515
|
+
else
|
516
|
+
print_red_alert "File not found: #{full_filename}"
|
517
|
+
exit 1
|
518
|
+
end
|
519
|
+
end
|
520
|
+
opts.on(nil, '--no-refresh', "Do not refresh until finished" ) do
|
521
|
+
do_refresh = false
|
522
|
+
end
|
523
|
+
#build_option_type_options(opts, options, add_user_source_option_types())
|
524
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
|
525
|
+
opts.footer = "Execute an arbitrary command or script on a container." + "\n" +
|
526
|
+
"[id] is required. This is the id a container." + "\n" +
|
527
|
+
"[script] is required. This is the script that is to be executed."
|
528
|
+
end
|
529
|
+
optparse.parse!(args)
|
530
|
+
connect(options)
|
531
|
+
if args.count != 1
|
532
|
+
print_error Morpheus::Terminal.angry_prompt
|
533
|
+
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
534
|
+
return 1
|
535
|
+
end
|
536
|
+
|
537
|
+
|
538
|
+
begin
|
539
|
+
container = find_container_by_id(args[0])
|
540
|
+
return 1 if container.nil?
|
541
|
+
params['containerId'] = container['id']
|
542
|
+
# construct payload
|
543
|
+
payload = {}
|
544
|
+
if options[:payload]
|
545
|
+
payload = options[:payload]
|
546
|
+
else
|
547
|
+
payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
548
|
+
# prompt for Script
|
549
|
+
if script_content.nil?
|
550
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'script', 'type' => 'code-editor', 'fieldLabel' => 'Script', 'required' => true, 'description' => 'The script content'}], options[:options])
|
551
|
+
script_content = v_prompt['script']
|
552
|
+
end
|
553
|
+
payload['script'] = script_content
|
554
|
+
end
|
555
|
+
# dry run?
|
556
|
+
if options[:dry_run]
|
557
|
+
print_dry_run @execution_request_interface.dry.create(params, payload)
|
558
|
+
return 0
|
559
|
+
end
|
560
|
+
# do it
|
561
|
+
json_response = @execution_request_interface.create(params, payload)
|
562
|
+
# print and return result
|
563
|
+
if options[:quiet]
|
564
|
+
return 0
|
565
|
+
elsif options[:json]
|
566
|
+
puts as_json(json_response, options)
|
567
|
+
return 0
|
568
|
+
end
|
569
|
+
execution_request = json_response['executionRequest']
|
570
|
+
print_green_success "Executing request #{execution_request['uniqueId']}"
|
571
|
+
if do_refresh
|
572
|
+
Morpheus::Cli::ExecutionRequestCommand.new.handle(["get", execution_request['uniqueId'], "--refresh"])
|
573
|
+
else
|
574
|
+
Morpheus::Cli::ExecutionRequestCommand.new.handle(["get", execution_request['uniqueId']])
|
575
|
+
end
|
576
|
+
return 0
|
577
|
+
rescue RestClient::Exception => e
|
578
|
+
print_rest_exception(e, options)
|
579
|
+
exit 1
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
496
583
|
private
|
497
584
|
|
498
585
|
def find_container_by_id(id)
|
@@ -0,0 +1,313 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
# require 'morpheus/cli/mixins/provisioning_helper'
|
3
|
+
# require 'morpheus/cli/mixins/infrastructure_helper'
|
4
|
+
|
5
|
+
class Morpheus::Cli::ExecutionRequestCommand
|
6
|
+
include Morpheus::Cli::CliCommand
|
7
|
+
# include Morpheus::Cli::InfrastructureHelper
|
8
|
+
# include Morpheus::Cli::ProvisioningHelper
|
9
|
+
|
10
|
+
set_command_name :'execution-request'
|
11
|
+
|
12
|
+
register_subcommands :get, :execute
|
13
|
+
#register_subcommands :'execute-against-lease' => :execute_against_lease
|
14
|
+
|
15
|
+
# set_default_subcommand :list
|
16
|
+
|
17
|
+
def initialize()
|
18
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
19
|
+
end
|
20
|
+
|
21
|
+
def connect(opts)
|
22
|
+
@api_client = establish_remote_appliance_connection(opts)
|
23
|
+
# @instances_interface = @api_client.instances
|
24
|
+
# @containers_interface = @api_client.containers
|
25
|
+
# @servers_interface = @api_client.servers
|
26
|
+
@execution_request_interface = @api_client.execution_request
|
27
|
+
end
|
28
|
+
|
29
|
+
def handle(args)
|
30
|
+
handle_subcommand(args)
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(args)
|
34
|
+
raw_args = args
|
35
|
+
options = {}
|
36
|
+
params = {}
|
37
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
38
|
+
opts.banner = subcommand_usage("[uid]")
|
39
|
+
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
40
|
+
opts.on('--refresh', String, "Refresh until execution is finished.") do |val|
|
41
|
+
options[:refresh_until_finished] = true
|
42
|
+
end
|
43
|
+
opts.on('--refresh-interval seconds', String, "Refresh interval. Default is 5 seconds.") do |val|
|
44
|
+
options[:refresh_interval] = val.to_f
|
45
|
+
end
|
46
|
+
opts.footer = "Get details about an execution request." + "\n" +
|
47
|
+
"[uid] is required. This is the unique id of an execution request."
|
48
|
+
end
|
49
|
+
optparse.parse!(args)
|
50
|
+
connect(options)
|
51
|
+
if args.count != 1
|
52
|
+
print_error Morpheus::Terminal.angry_prompt
|
53
|
+
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
54
|
+
return 1
|
55
|
+
end
|
56
|
+
execution_request_id = args[0]
|
57
|
+
begin
|
58
|
+
params.merge!(parse_list_options(options))
|
59
|
+
if options[:dry_run]
|
60
|
+
print_dry_run @execution_request_interface.dry.get(execution_request_id, params)
|
61
|
+
return
|
62
|
+
end
|
63
|
+
json_response = @execution_request_interface.get(execution_request_id, params)
|
64
|
+
if options[:json]
|
65
|
+
puts as_json(json_response, options, "executionRequest")
|
66
|
+
return 0
|
67
|
+
elsif options[:yaml]
|
68
|
+
puts as_yaml(json_response, options, "executionRequest")
|
69
|
+
return 0
|
70
|
+
elsif options[:csv]
|
71
|
+
puts records_as_csv([json_response['executionRequest']], options)
|
72
|
+
return 0
|
73
|
+
end
|
74
|
+
|
75
|
+
execution_request = json_response['executionRequest']
|
76
|
+
|
77
|
+
# refresh until a status is reached
|
78
|
+
if options[:refresh_until_finished]
|
79
|
+
if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
|
80
|
+
options[:refresh_interval] = 5
|
81
|
+
end
|
82
|
+
if execution_request['exitCode'] || ['complete','failed','expired'].include?(execution_request['status'])
|
83
|
+
# it is finished
|
84
|
+
else
|
85
|
+
print cyan
|
86
|
+
print "Execution request has not yet finished. Refreshing every #{options[:refresh_interval]} seconds"
|
87
|
+
while execution_request['exitCode'].nil? do
|
88
|
+
sleep(options[:refresh_interval])
|
89
|
+
print cyan,".",reset
|
90
|
+
json_response = @execution_request_interface.get(execution_request_id, params)
|
91
|
+
execution_request = json_response['executionRequest']
|
92
|
+
end
|
93
|
+
#sleep_with_dots(options[:refresh_interval])
|
94
|
+
print "\n", reset
|
95
|
+
# get(raw_args)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
print_h1 "Execution Request Details"
|
100
|
+
print cyan
|
101
|
+
description_cols = {
|
102
|
+
#"ID" => lambda {|it| it['id'] },
|
103
|
+
"Unique ID" => lambda {|it| it['uniqueId'] },
|
104
|
+
"Server ID" => lambda {|it| it['serverId'] },
|
105
|
+
"Instance ID" => lambda {|it| it['instanceId'] },
|
106
|
+
"Container ID" => lambda {|it| it['containerId'] },
|
107
|
+
"Expires At" => lambda {|it| format_local_dt it['expiresAt'] },
|
108
|
+
"Exit Code" => lambda {|it| it['exitCode'] },
|
109
|
+
"Status" => lambda {|it| format_execution_request_status(it) },
|
110
|
+
#"Created By" => lambda {|it| it['createdById'] },
|
111
|
+
#"Subdomain" => lambda {|it| it['subdomain'] },
|
112
|
+
}
|
113
|
+
print_description_list(description_cols, execution_request)
|
114
|
+
|
115
|
+
if execution_request['stdErr']
|
116
|
+
print_h2 "Error"
|
117
|
+
puts execution_request['stdErr'].to_s.strip
|
118
|
+
end
|
119
|
+
if execution_request['stdOut']
|
120
|
+
print_h2 "Output"
|
121
|
+
puts execution_request['stdOut'].to_s.strip
|
122
|
+
end
|
123
|
+
print reset, "\n"
|
124
|
+
return 0
|
125
|
+
rescue RestClient::Exception => e
|
126
|
+
print_rest_exception(e, options)
|
127
|
+
return 1
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def execute(args)
|
132
|
+
options = {}
|
133
|
+
params = {}
|
134
|
+
script_content = nil
|
135
|
+
do_refresh = true
|
136
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
137
|
+
opts.banner = subcommand_usage("[options]")
|
138
|
+
opts.on('--server ID', String, "Server ID") do |val|
|
139
|
+
params['serverId'] = val
|
140
|
+
end
|
141
|
+
opts.on('--instance ID', String, "Instance ID") do |val|
|
142
|
+
params['instanceId'] = val
|
143
|
+
end
|
144
|
+
opts.on('--container ID', String, "Container ID") do |val|
|
145
|
+
params['containerId'] = val
|
146
|
+
end
|
147
|
+
opts.on('--request ID', String, "Execution Request ID") do |val|
|
148
|
+
params['requestId'] = val
|
149
|
+
end
|
150
|
+
opts.on('--script SCRIPT', "Script to be executed" ) do |val|
|
151
|
+
script_content = val
|
152
|
+
end
|
153
|
+
opts.on('--file FILE', "File containing the script. This can be used instead of --script" ) do |filename|
|
154
|
+
full_filename = File.expand_path(filename)
|
155
|
+
if File.exists?(full_filename)
|
156
|
+
script_content = File.read(full_filename)
|
157
|
+
else
|
158
|
+
print_red_alert "File not found: #{full_filename}"
|
159
|
+
exit 1
|
160
|
+
end
|
161
|
+
end
|
162
|
+
opts.on(nil, '--no-refresh', "Do not refresh until finished" ) do
|
163
|
+
do_refresh = false
|
164
|
+
end
|
165
|
+
#build_option_type_options(opts, options, add_user_source_option_types())
|
166
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
|
167
|
+
opts.footer = "Execute an arbitrary script." + "\n" +
|
168
|
+
"[server] or [instance] or [container] is required. This is the id of a server, instance or container." + "\n" +
|
169
|
+
"[script] is required. This is the script that is to be executed."
|
170
|
+
end
|
171
|
+
optparse.parse!(args)
|
172
|
+
connect(options)
|
173
|
+
if args.count != 0
|
174
|
+
print_error Morpheus::Terminal.angry_prompt
|
175
|
+
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
176
|
+
return 1
|
177
|
+
end
|
178
|
+
if params['serverId'].nil? && params['instanceId'].nil? && params['containerId'].nil? && params['requestId'].nil?
|
179
|
+
puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: --server or --instance or --container\n#{optparse}"
|
180
|
+
return 1
|
181
|
+
end
|
182
|
+
begin
|
183
|
+
# construct payload
|
184
|
+
payload = {}
|
185
|
+
if options[:payload]
|
186
|
+
payload = options[:payload]
|
187
|
+
else
|
188
|
+
payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
189
|
+
# could prompt for Server or Container or Instance
|
190
|
+
# prompt for Script
|
191
|
+
if script_content.nil?
|
192
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'script', 'type' => 'code-editor', 'fieldLabel' => 'Script', 'required' => true, 'description' => 'The script content'}], options[:options])
|
193
|
+
script_content = v_prompt['script']
|
194
|
+
end
|
195
|
+
payload['script'] = script_content
|
196
|
+
end
|
197
|
+
# dry run?
|
198
|
+
if options[:dry_run]
|
199
|
+
print_dry_run @execution_request_interface.dry.create(params, payload)
|
200
|
+
return 0
|
201
|
+
end
|
202
|
+
# do it
|
203
|
+
json_response = @execution_request_interface.create(params, payload)
|
204
|
+
# print and return result
|
205
|
+
if options[:quiet]
|
206
|
+
return 0
|
207
|
+
elsif options[:json]
|
208
|
+
puts as_json(json_response, options)
|
209
|
+
return 0
|
210
|
+
end
|
211
|
+
execution_request = json_response['executionRequest']
|
212
|
+
print_green_success "Executing request #{execution_request['uniqueId']}"
|
213
|
+
if do_refresh
|
214
|
+
get([execution_request['uniqueId'], "--refresh"])
|
215
|
+
else
|
216
|
+
get([execution_request['uniqueId']])
|
217
|
+
end
|
218
|
+
return 0
|
219
|
+
rescue RestClient::Exception => e
|
220
|
+
print_rest_exception(e, options)
|
221
|
+
exit 1
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def execute_against_lease(args)
|
226
|
+
options = {}
|
227
|
+
params = {}
|
228
|
+
do_refresh = true
|
229
|
+
script_content = nil
|
230
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
231
|
+
opts.banner = subcommand_usage("[uid] [options]")
|
232
|
+
opts.on('--script SCRIPT', "Script to be executed" ) do |val|
|
233
|
+
script_content = val
|
234
|
+
end
|
235
|
+
opts.on('--file FILE', "File containing the script. This can be used instead of --script" ) do |filename|
|
236
|
+
full_filename = File.expand_path(filename)
|
237
|
+
if File.exists?(full_filename)
|
238
|
+
script_content = File.read(full_filename)
|
239
|
+
else
|
240
|
+
print_red_alert "File not found: #{full_filename}"
|
241
|
+
exit 1
|
242
|
+
end
|
243
|
+
end
|
244
|
+
opts.on(nil, '--no-refresh', "Do not refresh until finished" ) do
|
245
|
+
do_refresh = false
|
246
|
+
end
|
247
|
+
#build_option_type_options(opts, options, add_user_source_option_types())
|
248
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
|
249
|
+
opts.footer = "Execute request against lease.\n" +
|
250
|
+
"[uid] is required. This is the unique id of the execution request.\n" +
|
251
|
+
"[script] is required. This is the script that is to be executed."
|
252
|
+
end
|
253
|
+
optparse.parse!(args)
|
254
|
+
connect(options)
|
255
|
+
if args.count != 1
|
256
|
+
print_error Morpheus::Terminal.angry_prompt
|
257
|
+
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
258
|
+
return 1
|
259
|
+
end
|
260
|
+
execution_request_id = args[0]
|
261
|
+
begin
|
262
|
+
# construct payload
|
263
|
+
payload = {}
|
264
|
+
if options[:payload]
|
265
|
+
payload = options[:payload]
|
266
|
+
else
|
267
|
+
payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
268
|
+
if script_content
|
269
|
+
payload['script'] = script_content
|
270
|
+
end
|
271
|
+
end
|
272
|
+
# dry run?
|
273
|
+
if options[:dry_run]
|
274
|
+
print_dry_run @execution_request_interface.dry.execute_against_lease(execution_request_id, params, payload)
|
275
|
+
return 0
|
276
|
+
end
|
277
|
+
# do it
|
278
|
+
json_response = @execution_request_interface.execute_against_lease(execution_request_id, params, payload)
|
279
|
+
# print and return result
|
280
|
+
if options[:quiet]
|
281
|
+
return 0
|
282
|
+
elsif options[:json]
|
283
|
+
puts as_json(json_response, options)
|
284
|
+
return 0
|
285
|
+
end
|
286
|
+
execution_request = json_response['executionRequest']
|
287
|
+
print_green_success "Executing request #{execution_request['uniqueId']} against lease"
|
288
|
+
if do_refresh
|
289
|
+
get([execution_request['uniqueId'], "--refresh"])
|
290
|
+
else
|
291
|
+
get([execution_request['uniqueId']])
|
292
|
+
end
|
293
|
+
return 0
|
294
|
+
rescue RestClient::Exception => e
|
295
|
+
print_rest_exception(e, options)
|
296
|
+
exit 1
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def format_execution_request_status(execution_request, return_color=cyan)
|
301
|
+
out = ""
|
302
|
+
status_str = execution_request['status']
|
303
|
+
if status_str == 'complete'
|
304
|
+
out << "#{green}#{status_str.upcase}#{return_color}"
|
305
|
+
elsif status_str == 'failed' || status_str == 'expired'
|
306
|
+
out << "#{red}#{status_str.upcase}#{return_color}"
|
307
|
+
else
|
308
|
+
out << "#{cyan}#{status_str.upcase}#{return_color}"
|
309
|
+
end
|
310
|
+
out
|
311
|
+
end
|
312
|
+
|
313
|
+
end
|