morpheus-cli 2.10.0 → 2.10.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/bin/morpheus +27 -32
- data/lib/morpheus/api/accounts_interface.rb +36 -47
- data/lib/morpheus/api/api_client.rb +141 -110
- data/lib/morpheus/api/app_templates_interface.rb +56 -72
- data/lib/morpheus/api/apps_interface.rb +111 -132
- data/lib/morpheus/api/auth_interface.rb +30 -0
- data/lib/morpheus/api/clouds_interface.rb +71 -76
- data/lib/morpheus/api/custom_instance_types_interface.rb +21 -46
- data/lib/morpheus/api/dashboard_interface.rb +10 -17
- data/lib/morpheus/api/deploy_interface.rb +60 -72
- data/lib/morpheus/api/deployments_interface.rb +53 -71
- data/lib/morpheus/api/groups_interface.rb +55 -45
- data/lib/morpheus/api/instance_types_interface.rb +19 -23
- data/lib/morpheus/api/instances_interface.rb +179 -177
- data/lib/morpheus/api/key_pairs_interface.rb +11 -17
- data/lib/morpheus/api/license_interface.rb +18 -23
- data/lib/morpheus/api/load_balancers_interface.rb +54 -69
- data/lib/morpheus/api/logs_interface.rb +25 -29
- data/lib/morpheus/api/options_interface.rb +13 -17
- data/lib/morpheus/api/provision_types_interface.rb +19 -22
- data/lib/morpheus/api/roles_interface.rb +75 -94
- data/lib/morpheus/api/security_group_rules_interface.rb +28 -37
- data/lib/morpheus/api/security_groups_interface.rb +39 -51
- data/lib/morpheus/api/servers_interface.rb +113 -115
- data/lib/morpheus/api/setup_interface.rb +31 -0
- data/lib/morpheus/api/task_sets_interface.rb +36 -38
- data/lib/morpheus/api/tasks_interface.rb +56 -69
- data/lib/morpheus/api/users_interface.rb +67 -76
- data/lib/morpheus/api/virtual_images_interface.rb +61 -61
- data/lib/morpheus/api/whoami_interface.rb +12 -15
- data/lib/morpheus/cli.rb +71 -60
- data/lib/morpheus/cli/accounts.rb +254 -315
- data/lib/morpheus/cli/alias_command.rb +219 -0
- data/lib/morpheus/cli/app_templates.rb +264 -272
- data/lib/morpheus/cli/apps.rb +608 -671
- data/lib/morpheus/cli/cli_command.rb +259 -21
- data/lib/morpheus/cli/cli_registry.rb +99 -14
- data/lib/morpheus/cli/clouds.rb +599 -372
- data/lib/morpheus/cli/config_file.rb +126 -0
- data/lib/morpheus/cli/credentials.rb +141 -117
- data/lib/morpheus/cli/dashboard_command.rb +48 -56
- data/lib/morpheus/cli/deployments.rb +254 -268
- data/lib/morpheus/cli/deploys.rb +150 -142
- data/lib/morpheus/cli/error_handler.rb +38 -0
- data/lib/morpheus/cli/groups.rb +551 -179
- data/lib/morpheus/cli/hosts.rb +862 -617
- data/lib/morpheus/cli/instance_types.rb +103 -95
- data/lib/morpheus/cli/instances.rb +1335 -1009
- data/lib/morpheus/cli/key_pairs.rb +82 -90
- data/lib/morpheus/cli/library.rb +498 -499
- data/lib/morpheus/cli/license.rb +83 -101
- data/lib/morpheus/cli/load_balancers.rb +314 -300
- data/lib/morpheus/cli/login.rb +66 -44
- data/lib/morpheus/cli/logout.rb +47 -46
- data/lib/morpheus/cli/mixins/accounts_helper.rb +69 -31
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +106 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +181 -17
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +535 -458
- data/lib/morpheus/cli/mixins/whoami_helper.rb +2 -2
- data/lib/morpheus/cli/option_parser.rb +35 -0
- data/lib/morpheus/cli/option_types.rb +232 -192
- data/lib/morpheus/cli/recent_activity_command.rb +61 -65
- data/lib/morpheus/cli/remote.rb +446 -199
- data/lib/morpheus/cli/roles.rb +884 -906
- data/lib/morpheus/cli/security_group_rules.rb +213 -203
- data/lib/morpheus/cli/security_groups.rb +237 -192
- data/lib/morpheus/cli/shell.rb +338 -231
- data/lib/morpheus/cli/tasks.rb +326 -308
- data/lib/morpheus/cli/users.rb +457 -462
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/version_command.rb +16 -18
- data/lib/morpheus/cli/virtual_images.rb +526 -345
- data/lib/morpheus/cli/whoami.rb +125 -111
- data/lib/morpheus/cli/workflows.rb +338 -185
- data/lib/morpheus/formatters.rb +8 -1
- data/lib/morpheus/logging.rb +1 -1
- data/lib/morpheus/rest_client.rb +17 -8
- metadata +9 -3
- data/lib/morpheus/api/custom_instance_types.rb +0 -55
data/lib/morpheus/cli/whoami.rb
CHANGED
@@ -11,128 +11,142 @@ class Morpheus::Cli::Whoami
|
|
11
11
|
include Morpheus::Cli::CliCommand
|
12
12
|
include Morpheus::Cli::WhoamiHelper
|
13
13
|
include Morpheus::Cli::AccountsHelper
|
14
|
-
|
15
|
-
def initialize()
|
16
|
-
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
17
|
-
end
|
14
|
+
include Morpheus::Cli::InfrastructureHelper
|
18
15
|
|
19
|
-
|
20
|
-
@access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).load_saved_credentials()
|
21
|
-
# always try this.. it will 401
|
22
|
-
# if @access_token.empty?
|
23
|
-
# print_red_alert "Invalid Credentials. Unable to acquire access token. Please verify your credentials and try again."
|
24
|
-
# exit 1
|
25
|
-
# end
|
26
|
-
@api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
|
27
|
-
|
16
|
+
set_command_name :whoami
|
28
17
|
|
29
|
-
|
18
|
+
# no subcommands, just show()
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
|
20
|
+
def initialize()
|
21
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
22
|
+
end
|
34
23
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
options = {}
|
41
|
-
optparse = OptionParser.new do|opts|
|
42
|
-
opts.banner = usage
|
43
|
-
opts.on(nil,'--feature-access', "Display Feature Access") do |val|
|
44
|
-
options[:include_feature_access] = true
|
45
|
-
end
|
46
|
-
# opts.on(nil,'--group-access', "Display Group Access") do
|
47
|
-
# options[:include_group_access] = true
|
48
|
-
# end
|
49
|
-
# opts.on(nil,'--cloud-access', "Display Cloud Access") do
|
50
|
-
# options[:include_cloud_access] = true
|
51
|
-
# end
|
52
|
-
# opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
|
53
|
-
# options[:include_instance_type_access] = true
|
54
|
-
# end
|
55
|
-
opts.on(nil,'--all-access', "Display All Access Lists") do
|
56
|
-
options[:include_feature_access] = true
|
57
|
-
options[:include_group_access] = true
|
58
|
-
options[:include_cloud_access] = true
|
59
|
-
options[:include_instance_type_access] = true
|
60
|
-
end
|
61
|
-
build_common_options(opts, options, [:json]) # todo: support :remote too
|
62
|
-
end
|
63
|
-
optparse.parse(args)
|
24
|
+
def connect(opts)
|
25
|
+
@api_client = establish_remote_appliance_connection(opts)
|
26
|
+
@groups_interface = @api_client.groups
|
27
|
+
@active_group_id = Morpheus::Cli::Groups.active_group
|
28
|
+
end
|
64
29
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
json_response = load_whoami()
|
69
|
-
|
70
|
-
if options[:json]
|
71
|
-
print JSON.pretty_generate(json_response)
|
72
|
-
print "\n"
|
73
|
-
else
|
74
|
-
user = @current_user
|
75
|
-
if !user
|
76
|
-
puts yellow,"No active session. Please login",reset
|
77
|
-
exit 1
|
78
|
-
end
|
30
|
+
def handle(args)
|
31
|
+
show(args)
|
32
|
+
end
|
79
33
|
|
80
|
-
|
34
|
+
def show(args)
|
35
|
+
options = {}
|
36
|
+
optparse = OptionParser.new do|opts|
|
37
|
+
opts.banner = usage
|
38
|
+
opts.on(nil,'--feature-access', "Display Feature Access") do |val|
|
39
|
+
options[:include_feature_access] = true
|
40
|
+
end
|
41
|
+
# opts.on(nil,'--group-access', "Display Group Access") do
|
42
|
+
# options[:include_group_access] = true
|
43
|
+
# end
|
44
|
+
# opts.on(nil,'--cloud-access', "Display Cloud Access") do
|
45
|
+
# options[:include_cloud_access] = true
|
46
|
+
# end
|
47
|
+
# opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
|
48
|
+
# options[:include_instance_type_access] = true
|
49
|
+
# end
|
50
|
+
opts.on(nil,'--all-access', "Display All Access Lists") do
|
51
|
+
options[:include_feature_access] = true
|
52
|
+
options[:include_group_access] = true
|
53
|
+
options[:include_cloud_access] = true
|
54
|
+
options[:include_instance_type_access] = true
|
55
|
+
end
|
56
|
+
build_common_options(opts, options, [:json, :remote]) # todo: support :remote too
|
57
|
+
end
|
58
|
+
optparse.parse!(args)
|
59
|
+
# todo: check to see if they have credentials instead of just trying to connect (and prompting)
|
60
|
+
connect(options)
|
61
|
+
begin
|
62
|
+
json_response = load_whoami()
|
63
|
+
group = nil
|
64
|
+
begin
|
65
|
+
group = @active_group_id ? find_group_by_name_or_id(@active_group_id) : nil # via InfrastructureHelper mixin
|
66
|
+
rescue => err
|
67
|
+
if options[:debug]
|
68
|
+
print red,"Unable to determine active group: #{err}\n",reset
|
69
|
+
end
|
70
|
+
end
|
71
|
+
if options[:json]
|
72
|
+
print JSON.pretty_generate(json_response)
|
73
|
+
print "\n"
|
74
|
+
else
|
75
|
+
user = @current_user
|
76
|
+
if !user
|
77
|
+
puts yellow,"No active session. Please login",reset
|
78
|
+
exit 1
|
79
|
+
end
|
81
80
|
|
82
|
-
|
83
|
-
print cyan
|
84
|
-
# if @is_master_account
|
85
|
-
puts "ID: #{user['id']}"
|
86
|
-
puts "Account: #{user['account'] ? user['account']['name'] : nil}" + (@is_master_account ? " (Master Account)" : "")
|
87
|
-
# end
|
88
|
-
puts "First Name: #{user['firstName']}"
|
89
|
-
puts "Last Name: #{user['lastName']}"
|
90
|
-
puts "Username: #{user['username']}"
|
91
|
-
puts "Email: #{user['email']}"
|
92
|
-
puts "Role: #{format_user_role_names(user)}"
|
93
|
-
# puts "Date Created: #{format_local_dt(user['dateCreated'])}"
|
94
|
-
# puts "Last Updated: #{format_local_dt(user['lastUpdated'])}"
|
95
|
-
# print "\n" ,cyan, bold, "User Instance Limits\n","==================", reset, "\n\n"
|
96
|
-
# print cyan
|
97
|
-
# puts "Max Storage (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxStorage'] : 0}"
|
98
|
-
# puts "Max Memory (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxMemory'] : 0}"
|
99
|
-
# puts "CPU Count: #{user['instanceLimits'] ? user['instanceLimits']['maxCpu'] : 0}"
|
81
|
+
# todo: impersonate command and show that info here
|
100
82
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
83
|
+
print "\n" ,cyan, bold, "Current User\n","==================", reset, "\n\n"
|
84
|
+
# print cyan
|
85
|
+
# if @is_master_account
|
86
|
+
puts "ID: #{user['id']}"
|
87
|
+
puts "Account: #{user['account'] ? user['account']['name'] : nil}" + (@is_master_account ? " (Master Account)" : "")
|
88
|
+
# end
|
89
|
+
puts "First Name: #{user['firstName']}"
|
90
|
+
puts "Last Name: #{user['lastName']}"
|
91
|
+
puts "Username: #{user['username']}"
|
92
|
+
puts "Email: #{user['email']}"
|
93
|
+
puts "Role: #{format_user_role_names(user)}"
|
94
|
+
# puts "Date Created: #{format_local_dt(user['dateCreated'])}"
|
95
|
+
# puts "Last Updated: #{format_local_dt(user['lastUpdated'])}"
|
96
|
+
# print "\n" ,cyan, bold, "User Instance Limits\n","==================", reset, "\n\n"
|
97
|
+
# print cyan
|
98
|
+
# puts "Max Storage (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxStorage'] : 0}"
|
99
|
+
# puts "Max Memory (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxMemory'] : 0}"
|
100
|
+
# puts "CPU Count: #{user['instanceLimits'] ? user['instanceLimits']['maxCpu'] : 0}"
|
113
101
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
102
|
+
if options[:include_feature_access]
|
103
|
+
if @user_permissions
|
104
|
+
print "\n" ,cyan, bold, "Feature Permissions\n","==================", reset, "\n\n"
|
105
|
+
print cyan
|
106
|
+
rows = @user_permissions.collect do |code, access|
|
107
|
+
{code: code, access: get_access_string(access) }
|
108
|
+
end
|
109
|
+
tp rows, [:code, :access]
|
110
|
+
else
|
111
|
+
puts yellow,"No permissions found.",reset
|
112
|
+
end
|
113
|
+
end
|
126
114
|
|
127
|
-
|
115
|
+
print "\n" ,cyan, bold, "Remote Appliance\n","==================", reset, "\n\n"
|
116
|
+
# print cyan
|
117
|
+
if @appliance_name
|
118
|
+
puts "Name: #{@appliance_name}"
|
119
|
+
end
|
120
|
+
if @appliance_url
|
121
|
+
puts "Url: #{@appliance_url}"
|
122
|
+
end
|
123
|
+
if @appliance_build_verison
|
124
|
+
puts "Build Version: #{@appliance_build_verison}"
|
125
|
+
end
|
126
|
+
# print cyan
|
128
127
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
128
|
+
if group
|
129
|
+
print "\n" ,cyan, bold, "Active Group\n","==================", reset, "\n\n"
|
130
|
+
print "ID: #{group['id']}\n"
|
131
|
+
print "Name: #{group['name']}\n"
|
132
|
+
else
|
133
|
+
print "\n"
|
134
|
+
print "No active group. See `groups use`\n",reset
|
135
|
+
end
|
136
|
+
|
137
|
+
print reset,"\n"
|
138
|
+
end
|
139
|
+
rescue RestClient::Exception => e
|
140
|
+
print_rest_exception(e, options)
|
141
|
+
if e.response && e.response.code == 401
|
142
|
+
puts "It looks like you need to login to the remote appliance [#{@appliance_name}] #{@appliance_url}"
|
143
|
+
if Morpheus::Cli::OptionTypes.confirm("Would you like to login now?")
|
144
|
+
return Morpheus::Cli::Login.new.login([])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
exit 1
|
148
|
+
end
|
149
|
+
end
|
135
150
|
|
136
|
-
|
137
151
|
|
138
152
|
end
|
@@ -6,189 +6,342 @@ require 'table_print'
|
|
6
6
|
require 'morpheus/cli/cli_command'
|
7
7
|
|
8
8
|
class Morpheus::Cli::Workflows
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
9
|
+
include Morpheus::Cli::CliCommand
|
10
|
+
|
11
|
+
register_subcommands :list, :get, :add, :update, :remove
|
12
|
+
set_default_subcommand :list
|
13
|
+
|
14
|
+
# def initialize()
|
15
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
16
|
+
# end
|
17
|
+
|
18
|
+
def connect(opts)
|
19
|
+
@api_client = establish_remote_appliance_connection(opts)
|
20
|
+
@tasks_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).tasks
|
21
|
+
@task_sets_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).task_sets
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def handle(args)
|
26
|
+
handle_subcommand(args)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def list(args)
|
31
|
+
options = {}
|
32
|
+
optparse = OptionParser.new do|opts|
|
33
|
+
opts.banner = subcommand_usage()
|
34
|
+
build_common_options(opts, options, [:list, :json, :dry_run, :remote])
|
35
|
+
end
|
36
|
+
optparse.parse!(args)
|
37
|
+
connect(options)
|
38
|
+
begin
|
39
|
+
params = {}
|
40
|
+
[:phrase, :offset, :max, :sort, :direction].each do |k|
|
41
|
+
params[k] = options[k] unless options[k].nil?
|
42
|
+
end
|
43
|
+
if options[:dry_run]
|
44
|
+
print_dry_run @task_sets_interface.dry.get(params)
|
45
|
+
return
|
46
|
+
end
|
47
|
+
json_response = @task_sets_interface.get(params)
|
48
|
+
if options[:json]
|
49
|
+
print JSON.pretty_generate(json_response)
|
50
|
+
else
|
51
|
+
task_sets = json_response['taskSets']
|
52
|
+
print "\n" ,cyan, bold, "Morpheus Workflows\n","==================", reset, "\n\n"
|
53
|
+
if task_sets.empty?
|
54
|
+
puts yellow,"No workflows currently configured.",reset
|
55
|
+
else
|
56
|
+
print cyan
|
57
|
+
print_workflows_table(task_sets)
|
58
|
+
print_results_pagination(json_response)
|
59
|
+
end
|
60
|
+
print reset,"\n"
|
61
|
+
end
|
62
|
+
rescue RestClient::Exception => e
|
63
|
+
print_rest_exception(e, options)
|
64
|
+
exit 1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def add(args)
|
69
|
+
options = {}
|
70
|
+
optparse = OptionParser.new do|opts|
|
71
|
+
opts.banner = subcommand_usage("[name] --tasks x,y,z")
|
72
|
+
opts.on("--tasks x,y,z", Array, "List of tasks to run in order") do |list|
|
73
|
+
options[:task_names] = list
|
74
|
+
end
|
75
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
76
|
+
end
|
77
|
+
optparse.parse!(args)
|
78
|
+
if args.count < 1 || options[:task_names].empty?
|
79
|
+
puts optparse
|
80
|
+
exit 1
|
81
|
+
end
|
82
|
+
workflow_name = args[0]
|
83
|
+
connect(options)
|
84
|
+
begin
|
85
|
+
tasks = []
|
86
|
+
options[:task_names].each do |task_name|
|
87
|
+
tasks << find_task_by_name_or_id(task_name.to_s.strip)['id']
|
88
|
+
end
|
89
|
+
|
90
|
+
payload = {taskSet: {name: workflow_name, tasks: tasks}}
|
91
|
+
if options[:dry_run]
|
92
|
+
print_dry_run @task_sets_interface.dry.create(payload)
|
93
|
+
return
|
94
|
+
end
|
95
|
+
json_response = @task_sets_interface.create(payload)
|
96
|
+
if options[:json]
|
97
|
+
print JSON.pretty_generate(json_response)
|
98
|
+
else
|
99
|
+
print "\n", cyan, "Workflow #{json_response['taskSet']['name']} created successfully", reset, "\n\n"
|
100
|
+
end
|
101
|
+
rescue RestClient::Exception => e
|
102
|
+
print_rest_exception(e, options)
|
103
|
+
exit 1
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def get(args)
|
108
|
+
options = {}
|
109
|
+
optparse = OptionParser.new do|opts|
|
110
|
+
opts.banner = subcommand_usage("[task]")
|
111
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
112
|
+
end
|
113
|
+
optparse.parse!(args)
|
114
|
+
if args.count < 1
|
115
|
+
puts optparse
|
116
|
+
exit 1
|
117
|
+
end
|
118
|
+
workflow_name = args[0]
|
119
|
+
connect(options)
|
120
|
+
begin
|
121
|
+
if options[:dry_run]
|
122
|
+
if workflow_name.to_s =~ /\A\d{1,}\Z/
|
123
|
+
print_dry_run @task_sets_interface.dry.get(workflow_name.to_i)
|
124
|
+
else
|
125
|
+
print_dry_run @task_sets_interface.dry.get({name: workflow_name})
|
126
|
+
end
|
127
|
+
return
|
128
|
+
end
|
129
|
+
workflow = find_workflow_by_name_or_id(workflow_name)
|
130
|
+
exit 1 if workflow.nil?
|
131
|
+
# refetch it..
|
132
|
+
json_response = @task_sets_interface.get(workflow['id'])
|
133
|
+
workflow = json_response['taskSet']
|
134
|
+
|
135
|
+
if options[:json]
|
136
|
+
#puts JSON.pretty_generate(workflow)
|
137
|
+
puts JSON.pretty_generate(json_response)
|
138
|
+
print "\n"
|
139
|
+
else
|
140
|
+
# tasks = []
|
141
|
+
# (workflow['tasks'] || []).each do |task_name|
|
142
|
+
# tasks << find_task_by_name_or_id(task_name)['id']
|
143
|
+
# end
|
144
|
+
tasks = workflow['taskSetTasks'].sort { |x,y| x['taskOrder'].to_i <=> y['taskOrder'].to_i }
|
145
|
+
print "\n" ,cyan, bold, "Workflow Details\n","==================", reset, "\n\n"
|
146
|
+
print cyan
|
147
|
+
puts "ID: #{workflow['id']}"
|
148
|
+
puts "Name: #{workflow['name']}"
|
149
|
+
#puts "Description: #{workflow['description']}"
|
150
|
+
#task_names = tasks.collect {|it| it['name'] }
|
151
|
+
print "\n", cyan, "Tasks:\n"
|
152
|
+
tasks.each_with_index do |taskSetTask, index|
|
153
|
+
puts "#{(index+1).to_s.rjust(3, ' ')}. #{taskSetTask['task']['name']}"
|
154
|
+
end
|
155
|
+
print reset,"\n"
|
156
|
+
end
|
157
|
+
rescue RestClient::Exception => e
|
158
|
+
print_rest_exception(e, options)
|
159
|
+
exit 1
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def update(args)
|
164
|
+
options = {}
|
165
|
+
optparse = OptionParser.new do|opts|
|
166
|
+
opts.banner = subcommand_usage("[name] --tasks x,y,z")
|
167
|
+
opts.on("--tasks x,y,z", Array, "New list of tasks to run in order") do |list|
|
168
|
+
options[:task_names]= list
|
169
|
+
end
|
170
|
+
opts.on("--name NAME", String, "New name for workflow") do |val|
|
171
|
+
options[:new_name] = val
|
172
|
+
end
|
173
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
174
|
+
end
|
175
|
+
optparse.parse!(args)
|
176
|
+
if args.count < 1 || (options[:new_name].empty? && options[:task_names].empty?)
|
177
|
+
puts optparse
|
178
|
+
exit 1
|
179
|
+
end
|
180
|
+
workflow_name = args[0]
|
181
|
+
connect(options)
|
182
|
+
begin
|
183
|
+
workflow = find_workflow_by_name_or_id(workflow_name)
|
184
|
+
payload = {taskSet: {id: workflow['id']} }
|
185
|
+
tasks = []
|
186
|
+
if options[:task_names]
|
187
|
+
options[:task_names].each do |task_name|
|
188
|
+
tasks << find_task_by_name_or_id(task_name)['id']
|
189
|
+
end
|
190
|
+
payload[:taskSet][:tasks] = tasks
|
191
|
+
else
|
192
|
+
payload[:taskSet][:tasks] = workflow['tasks']
|
193
|
+
end
|
194
|
+
if options[:new_name]
|
195
|
+
payload[:taskSet][:name] = options[:new_name]
|
196
|
+
end
|
197
|
+
if options[:dry_run]
|
198
|
+
print_dry_run @task_sets_interface.dry.update(workflow['id'], payload)
|
199
|
+
return
|
200
|
+
end
|
201
|
+
json_response = @task_sets_interface.update(workflow['id'], payload)
|
202
|
+
if options[:json]
|
203
|
+
print JSON.pretty_generate(json_response)
|
204
|
+
elsif !options[:quiet]
|
205
|
+
print "\n", cyan, "Workflow #{json_response['taskSet']['name']} updated successfully", reset, "\n\n"
|
206
|
+
get([workflow['id']])
|
207
|
+
end
|
208
|
+
rescue RestClient::Exception => e
|
209
|
+
print_rest_exception(e, options)
|
210
|
+
exit 1
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def remove(args)
|
215
|
+
options = {}
|
216
|
+
optparse = OptionParser.new do|opts|
|
217
|
+
opts.banner = "Usage: morpheus workflows remove [name]"
|
218
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
219
|
+
end
|
220
|
+
optparse.parse!(args)
|
221
|
+
if args.count < 1
|
222
|
+
puts optparse
|
223
|
+
exit 1
|
224
|
+
end
|
225
|
+
workflow_name = args[0]
|
226
|
+
connect(options)
|
227
|
+
begin
|
228
|
+
workflow = find_workflow_by_name_or_id(workflow_name)
|
229
|
+
exit 1 if workflow.nil?
|
230
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the workflow #{workflow['name']}?")
|
231
|
+
exit 1
|
232
|
+
end
|
233
|
+
if options[:dry_run]
|
234
|
+
print_dry_run @task_sets_interface.dry.destroy(workflow['id'])
|
235
|
+
return
|
236
|
+
end
|
237
|
+
json_response = @task_sets_interface.destroy(workflow['id'])
|
238
|
+
if options[:json]
|
239
|
+
print JSON.pretty_generate(json_response)
|
240
|
+
elsif !options[:quiet]
|
241
|
+
print "\n", cyan, "Workflow #{workflow['name']} removed", reset, "\n\n"
|
242
|
+
end
|
243
|
+
rescue RestClient::Exception => e
|
244
|
+
print_rest_exception(e, options)
|
245
|
+
exit 1
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
private
|
251
|
+
|
252
|
+
def find_workflow_by_name_or_id(val)
|
253
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
254
|
+
return find_workflow_by_id(val)
|
255
|
+
else
|
256
|
+
return find_workflow_by_name(val)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def find_workflow_by_id(id)
|
261
|
+
begin
|
262
|
+
json_response = @task_sets_interface.get(id.to_i)
|
263
|
+
return json_response['taskSet']
|
264
|
+
rescue RestClient::Exception => e
|
265
|
+
if e.response && e.response.code == 404
|
266
|
+
print_red_alert "Workflow not found by id #{id}"
|
267
|
+
else
|
268
|
+
raise e
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def find_workflow_by_name(name)
|
274
|
+
workflows = @task_sets_interface.get({name: name.to_s})['taskSets']
|
275
|
+
if workflows.empty?
|
276
|
+
print_red_alert "Workflow not found by name #{name}"
|
277
|
+
return nil
|
278
|
+
elsif workflows.size > 1
|
279
|
+
print_red_alert "#{workflows.size} workflows by name #{name}"
|
280
|
+
print_workflows_table(workflows, {color: red})
|
281
|
+
print reset,"\n\n"
|
282
|
+
return nil
|
283
|
+
else
|
284
|
+
return workflows[0]
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def find_task_by_name_or_id(val)
|
289
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
290
|
+
return find_task_by_id(val)
|
291
|
+
else
|
292
|
+
return find_task_by_name(val)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def find_task_by_id(id)
|
297
|
+
begin
|
298
|
+
json_response = @tasks_interface.get(id.to_i)
|
299
|
+
return json_response['task']
|
300
|
+
rescue RestClient::Exception => e
|
301
|
+
if e.response && e.response.code == 404
|
302
|
+
print_red_alert "Task not found by id #{id}"
|
303
|
+
else
|
304
|
+
raise e
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def find_task_by_name(name)
|
310
|
+
tasks = @tasks_interface.get({name: name.to_s})['tasks']
|
311
|
+
if tasks.empty?
|
312
|
+
print_red_alert "Task not found by name #{name}"
|
313
|
+
return nil
|
314
|
+
elsif tasks.size > 1
|
315
|
+
print_red_alert "#{tasks.size} tasks by name #{name}"
|
316
|
+
print_tasks_table(tasks, {color: red})
|
317
|
+
print reset,"\n\n"
|
318
|
+
return nil
|
319
|
+
else
|
320
|
+
return tasks[0]
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def print_workflows_table(workflows, opts={})
|
325
|
+
table_color = opts[:color] || cyan
|
326
|
+
rows = workflows.collect do |workflow|
|
327
|
+
task_names = []
|
328
|
+
workflow['taskSetTasks'].sort { |x,y| x['taskOrder'].to_i <=> y['taskOrder'].to_i }.each do |taskSetTask|
|
329
|
+
task_names << taskSetTask['task']['name']
|
330
|
+
end
|
331
|
+
{
|
332
|
+
id: workflow['id'],
|
333
|
+
name: workflow['name'],
|
334
|
+
tasks: task_names.join(', '),
|
335
|
+
dateCreated: format_local_dt(workflow['dateCreated'])
|
336
|
+
}
|
337
|
+
end
|
338
|
+
print table_color
|
339
|
+
tp rows, [
|
340
|
+
:id,
|
341
|
+
:name,
|
342
|
+
:tasks
|
343
|
+
]
|
344
|
+
print reset
|
345
|
+
end
|
346
|
+
|
194
347
|
end
|