morpheus-cli 4.2.16 → 4.2.21
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/README.md +8 -6
- data/lib/morpheus/api/api_client.rb +32 -14
- data/lib/morpheus/api/auth_interface.rb +4 -2
- data/lib/morpheus/api/backup_jobs_interface.rb +9 -0
- data/lib/morpheus/api/backups_interface.rb +16 -0
- data/lib/morpheus/api/deploy_interface.rb +25 -56
- data/lib/morpheus/api/deployments_interface.rb +44 -55
- data/lib/morpheus/api/doc_interface.rb +57 -0
- data/lib/morpheus/api/instances_interface.rb +5 -0
- data/lib/morpheus/api/rest_interface.rb +40 -0
- data/lib/morpheus/api/user_sources_interface.rb +0 -15
- data/lib/morpheus/api/users_interface.rb +2 -3
- data/lib/morpheus/benchmarking.rb +2 -2
- data/lib/morpheus/cli.rb +4 -1
- data/lib/morpheus/cli/access_token_command.rb +27 -10
- data/lib/morpheus/cli/apps.rb +21 -15
- data/lib/morpheus/cli/backup_jobs_command.rb +276 -0
- data/lib/morpheus/cli/backups_command.rb +271 -0
- data/lib/morpheus/cli/blueprints_command.rb +27 -61
- data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
- data/lib/morpheus/cli/budgets_command.rb +4 -4
- data/lib/morpheus/cli/cli_command.rb +99 -41
- data/lib/morpheus/cli/cloud_resource_pools_command.rb +16 -0
- data/lib/morpheus/cli/clouds.rb +7 -10
- data/lib/morpheus/cli/clusters.rb +0 -18
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +7 -7
- data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
- data/lib/morpheus/cli/credentials.rb +13 -9
- data/lib/morpheus/cli/deploy.rb +374 -0
- data/lib/morpheus/cli/deployments.rb +521 -197
- data/lib/morpheus/cli/deploys.rb +271 -126
- data/lib/morpheus/cli/doc.rb +182 -0
- data/lib/morpheus/cli/error_handler.rb +23 -8
- data/lib/morpheus/cli/errors.rb +3 -2
- data/lib/morpheus/cli/image_builder_command.rb +2 -2
- data/lib/morpheus/cli/instances.rb +136 -17
- data/lib/morpheus/cli/invoices_command.rb +59 -47
- data/lib/morpheus/cli/jobs_command.rb +2 -2
- data/lib/morpheus/cli/library_instance_types_command.rb +17 -3
- data/lib/morpheus/cli/library_layouts_command.rb +1 -1
- data/lib/morpheus/cli/login.rb +9 -3
- data/lib/morpheus/cli/mixins/accounts_helper.rb +158 -100
- data/lib/morpheus/cli/mixins/backups_helper.rb +115 -0
- data/lib/morpheus/cli/mixins/deployments_helper.rb +135 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +110 -74
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -2
- data/lib/morpheus/cli/mixins/whoami_helper.rb +19 -6
- data/lib/morpheus/cli/network_routers_command.rb +1 -1
- data/lib/morpheus/cli/option_parser.rb +48 -5
- data/lib/morpheus/cli/option_types.rb +1 -1
- data/lib/morpheus/cli/projects_command.rb +7 -7
- data/lib/morpheus/cli/provisioning_licenses_command.rb +2 -2
- data/lib/morpheus/cli/remote.rb +3 -2
- data/lib/morpheus/cli/roles.rb +49 -92
- data/lib/morpheus/cli/security_groups.rb +7 -1
- data/lib/morpheus/cli/service_plans_command.rb +10 -10
- data/lib/morpheus/cli/setup.rb +1 -1
- data/lib/morpheus/cli/shell.rb +7 -6
- data/lib/morpheus/cli/subnets_command.rb +1 -1
- data/lib/morpheus/cli/tasks.rb +24 -10
- data/lib/morpheus/cli/tenants_command.rb +133 -163
- data/lib/morpheus/cli/user_groups_command.rb +20 -65
- data/lib/morpheus/cli/user_settings_command.rb +115 -13
- data/lib/morpheus/cli/user_sources_command.rb +57 -24
- data/lib/morpheus/cli/users.rb +210 -186
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +29 -5
- data/lib/morpheus/cli/whoami.rb +113 -6
- data/lib/morpheus/cli/workflows.rb +11 -8
- data/lib/morpheus/ext/hash.rb +21 -0
- data/lib/morpheus/terminal.rb +1 -0
- metadata +12 -3
- data/lib/morpheus/cli/auth_command.rb +0 -105
data/lib/morpheus/cli/deploys.rb
CHANGED
@@ -1,176 +1,321 @@
|
|
1
|
-
# require 'yaml'
|
2
|
-
require 'io/console'
|
3
|
-
require 'rest_client'
|
4
|
-
require 'filesize'
|
5
1
|
require 'morpheus/cli/cli_command'
|
2
|
+
require 'yaml'
|
6
3
|
|
7
4
|
class Morpheus::Cli::Deploys
|
8
5
|
include Morpheus::Cli::CliCommand
|
6
|
+
include Morpheus::Cli::DeploymentsHelper
|
9
7
|
|
10
|
-
|
8
|
+
# hidden until api support is added
|
9
|
+
set_command_hidden
|
10
|
+
|
11
|
+
set_command_name :deploys
|
11
12
|
|
12
|
-
|
13
|
-
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
14
|
-
end
|
13
|
+
register_subcommands :list, :get, :add, :remove, :deploy
|
15
14
|
|
16
15
|
def connect(opts)
|
17
16
|
@api_client = establish_remote_appliance_connection(opts)
|
18
|
-
@instances_interface =
|
19
|
-
@deploy_interface =
|
17
|
+
@instances_interface = @api_client.instances
|
18
|
+
@deploy_interface = @api_client.deploy
|
19
|
+
@deployments_interface = @api_client.deployments
|
20
20
|
end
|
21
21
|
|
22
22
|
def handle(args)
|
23
|
-
|
23
|
+
handle_subcommand(args)
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
options={}
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
opts.
|
32
|
-
|
26
|
+
def list(args)
|
27
|
+
options = {}
|
28
|
+
params = {}
|
29
|
+
ref_ids = []
|
30
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
31
|
+
opts.banner = subcommand_usage("[search]")
|
32
|
+
build_standard_list_options(opts, options)
|
33
|
+
opts.footer = <<-EOT
|
34
|
+
List deploys.
|
35
|
+
EOT
|
33
36
|
end
|
34
37
|
optparse.parse!(args)
|
35
38
|
connect(options)
|
36
|
-
|
39
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
37
40
|
if args.count > 0
|
38
|
-
|
41
|
+
options[:phrase] = args.join(" ")
|
39
42
|
end
|
40
|
-
|
41
|
-
|
43
|
+
params.merge!(parse_list_options(options))
|
44
|
+
@deploy_interface.setopts(options)
|
45
|
+
if options[:dry_run]
|
46
|
+
print_dry_run @deploy_interface.dry.list(params)
|
42
47
|
return
|
43
48
|
end
|
49
|
+
json_response = @deploy_interface.list(params)
|
50
|
+
app_deploys = json_response[app_deploy_list_key]
|
51
|
+
render_response(json_response, options, app_deploy_list_key) do
|
52
|
+
print_h1 "Morpheus Deploys", parse_list_subtitles(options), options
|
53
|
+
if app_deploys.empty?
|
54
|
+
print cyan,"No deploys found.",reset,"\n"
|
55
|
+
else
|
56
|
+
print as_pretty_table(app_deploys, app_deploy_column_definitions.upcase_keys!, options)
|
57
|
+
print_results_pagination(json_response)
|
58
|
+
end
|
59
|
+
print reset,"\n"
|
60
|
+
end
|
61
|
+
if app_deploys.empty?
|
62
|
+
return 1, "no deploys found"
|
63
|
+
else
|
64
|
+
return 0, nil
|
65
|
+
end
|
66
|
+
end
|
44
67
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
68
|
+
def get(args)
|
69
|
+
params = {}
|
70
|
+
options = {}
|
71
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
72
|
+
opts.banner = subcommand_usage("[id]")
|
73
|
+
build_standard_get_options(opts, options)
|
74
|
+
opts.footer = <<-EOT
|
75
|
+
Get details about a specific instance deploy.
|
76
|
+
[id] is required. This is the name or id of a deployment.
|
77
|
+
EOT
|
49
78
|
end
|
79
|
+
optparse.parse!(args)
|
80
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
81
|
+
connect(options)
|
82
|
+
id_list = parse_id_list(args)
|
83
|
+
return run_command_for_each_arg(id_list) do |arg|
|
84
|
+
_get(arg, params, options)
|
85
|
+
end
|
86
|
+
end
|
50
87
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
88
|
+
def _get(id, params, options)
|
89
|
+
@deploy_interface.setopts(options)
|
90
|
+
if options[:dry_run]
|
91
|
+
print_dry_run @deploy_interface.dry.get(id, params)
|
92
|
+
return 0
|
93
|
+
end
|
94
|
+
json_response = @deploy_interface.get(id, params)
|
95
|
+
app_deploy = json_response[app_deploy_object_key]
|
96
|
+
render_response(json_response, options, app_deploy_object_key) do
|
97
|
+
print_h1 "Deploy Details", [], options
|
98
|
+
print cyan
|
99
|
+
print_description_list(app_deploy_column_definitions, app_deploy)
|
100
|
+
print reset,"\n"
|
55
101
|
end
|
56
|
-
|
57
|
-
|
58
|
-
print_h1 "Morpheus Deployment"
|
59
|
-
if !deploy_args['script'].nil?
|
60
|
-
print cyan, bold, " - Executing Pre Deploy Script...", reset, "\n"
|
102
|
+
return 0, nil
|
103
|
+
end
|
61
104
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
105
|
+
def add(args)
|
106
|
+
options = {}
|
107
|
+
params = {}
|
108
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
109
|
+
opts.banner = subcommand_usage("[instance] [deployment] [version] [options]")
|
110
|
+
build_option_type_options(opts, options, add_app_deploy_option_types)
|
111
|
+
build_option_type_options(opts, options, add_app_deploy_advanced_option_types)
|
112
|
+
build_standard_add_options(opts, options)
|
113
|
+
opts.footer = <<-EOT
|
114
|
+
Create a new instance deploy.
|
115
|
+
EOT
|
116
|
+
end
|
117
|
+
optparse.parse!(args)
|
118
|
+
verify_args!(args:args, optparse:optparse, min:0, max:3)
|
119
|
+
options[:options]['instance'] = args[0] if args[0]
|
120
|
+
options[:options]['deployment'] = args[1] if args[1]
|
121
|
+
options[:options]['version'] = args[2] if args[2]
|
122
|
+
connect(options)
|
123
|
+
payload = {}
|
124
|
+
if options[:payload]
|
125
|
+
payload = options[:payload]
|
126
|
+
payload.deep_merge!({app_deploy_object_key => parse_passed_options(options)})
|
127
|
+
else
|
128
|
+
payload.deep_merge!({app_deploy_object_key => parse_passed_options(options)})
|
129
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(add_app_deploy_option_types, options[:options], @api_client, options[:params])
|
130
|
+
params.deep_merge!(v_prompt)
|
131
|
+
advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_app_deploy_advanced_option_types, options[:options], @api_client, options[:params])
|
132
|
+
advanced_config.deep_compact!
|
133
|
+
params.deep_merge!(advanced_config)
|
134
|
+
payload[app_deploy_object_key].deep_merge!(params)
|
66
135
|
end
|
67
136
|
@deploy_interface.setopts(options)
|
68
|
-
@instances_interface.setopts(options)
|
69
137
|
if options[:dry_run]
|
70
|
-
print_dry_run @deploy_interface.create(
|
71
|
-
|
72
|
-
# Create a new deployment record
|
73
|
-
deploy_result = @deploy_interface.create(instance_id)
|
74
|
-
app_deploy = deploy_result['appDeploy']
|
75
|
-
deployment_id = app_deploy['id']
|
76
|
-
|
77
|
-
# Upload Files
|
78
|
-
print "\n",cyan, bold, "Uploading Files...", reset, "\n"
|
79
|
-
current_working_dir = Dir.pwd
|
80
|
-
deploy_args['files'].each do |fmap|
|
81
|
-
Dir.chdir(fmap['path'] || current_working_dir)
|
82
|
-
files = Dir.glob(fmap['pattern'] || '**/*')
|
83
|
-
files.each do |file|
|
84
|
-
if File.file?(file)
|
85
|
-
print cyan,bold, " - Uploading #{file} ...", reset, "\n"
|
86
|
-
destination = file.split("/")[0..-2].join("/")
|
87
|
-
if options[:dry_run]
|
88
|
-
print_dry_run @deploy_interface.upload_file(deployment_id,file,destination)
|
89
|
-
else
|
90
|
-
upload_result = @deploy_interface.upload_file(deployment_id,file,destination)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
138
|
+
print_dry_run @deploy_interface.dry.create(payload)
|
139
|
+
return 0, nil
|
94
140
|
end
|
95
|
-
|
96
|
-
|
141
|
+
json_response = @deploy_interface.create(payload)
|
142
|
+
app_deploy = json_response[app_deploy_object_key]
|
143
|
+
render_response(json_response, options, app_deploy_object_key) do
|
144
|
+
print_green_success "Deploying..."
|
145
|
+
return _get(app_deploy["id"], {}, options)
|
146
|
+
end
|
147
|
+
return 0, nil
|
148
|
+
end
|
97
149
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
150
|
+
def remove(args)
|
151
|
+
options = {}
|
152
|
+
params = {}
|
153
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
154
|
+
opts.banner = subcommand_usage("[id] [options]")
|
155
|
+
build_standard_remove_options(opts, options)
|
156
|
+
opts.footer = <<-EOT
|
157
|
+
Delete an instance deploy.
|
158
|
+
[id] is required. This is the name or id of a deploy.
|
159
|
+
EOT
|
160
|
+
end
|
161
|
+
optparse.parse!(args)
|
162
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
163
|
+
connect(options)
|
164
|
+
app_deploy = find_app_deploy_by_id(args[0])
|
165
|
+
return 1 if app_deploy.nil?
|
166
|
+
@deploy_interface.setopts(options)
|
167
|
+
if options[:dry_run]
|
168
|
+
print_dry_run @deploy_interface.dry.destroy(app_deploy['id'], params)
|
169
|
+
return
|
170
|
+
end
|
171
|
+
json_response = @deploy_interface.destroy(app_deploy['id'], params)
|
172
|
+
render_response(json_response, options) do
|
173
|
+
print_green_success "Removed deploy #{app_deploy['name']}"
|
104
174
|
end
|
175
|
+
return 0, nil
|
176
|
+
end
|
105
177
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
178
|
+
def deploy(args)
|
179
|
+
options = {}
|
180
|
+
params = {}
|
181
|
+
payload = {}
|
182
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
183
|
+
opts.banner = subcommand_usage("[id] [options]")
|
184
|
+
build_option_type_options(opts, options, update_app_deploy_option_types)
|
185
|
+
build_option_type_options(opts, options, update_app_deploy_advanced_option_types)
|
186
|
+
build_standard_update_options(opts, options)
|
187
|
+
opts.footer = <<-EOT
|
188
|
+
Update an instance deploy.
|
189
|
+
[id] is required. This is the name or id of an instance deploy.
|
190
|
+
EOT
|
120
191
|
end
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
192
|
+
optparse.parse!(args)
|
193
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
194
|
+
connect(options)
|
195
|
+
app_deploy = find_app_deploy_by_id(args[0])
|
196
|
+
return 1 if app_deploy.nil?
|
197
|
+
payload = {}
|
198
|
+
if options[:payload]
|
199
|
+
payload = options[:payload]
|
200
|
+
payload.deep_merge!({app_deploy_object_key => parse_passed_options(options)})
|
201
|
+
else
|
202
|
+
payload.deep_merge!({app_deploy_object_key => parse_passed_options(options)})
|
203
|
+
# do not prompt on update
|
204
|
+
v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_app_deploy_option_types, options[:options], @api_client, options[:params])
|
205
|
+
v_prompt.deep_compact!
|
206
|
+
params.deep_merge!(v_prompt)
|
207
|
+
advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_app_deploy_advanced_option_types, options[:options], @api_client, options[:params])
|
208
|
+
advanced_config.deep_compact!
|
209
|
+
params.deep_merge!(advanced_config)
|
210
|
+
payload.deep_merge!({app_deploy_object_key => params})
|
211
|
+
if payload[app_deploy_object_key].empty? # || options[:no_prompt]
|
212
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
213
|
+
end
|
127
214
|
end
|
215
|
+
@deploy_interface.setopts(options)
|
128
216
|
if options[:dry_run]
|
129
|
-
print_dry_run @deploy_interface.
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
217
|
+
print_dry_run @deploy_interface.dry.update(app_deploy['id'], payload)
|
218
|
+
return
|
219
|
+
end
|
220
|
+
json_response = @deploy_interface.update(app_deploy['id'], payload)
|
221
|
+
app_deploy = json_response[app_deploy_object_key]
|
222
|
+
render_response(json_response, options, app_deploy_object_key) do
|
223
|
+
print_green_success "Deploying..."
|
224
|
+
return _get(app_deploy["id"], {}, options)
|
134
225
|
end
|
135
|
-
|
226
|
+
return 0, nil
|
136
227
|
end
|
137
|
-
|
228
|
+
private
|
229
|
+
|
230
|
+
## Deploys (AppDeploy)
|
231
|
+
|
232
|
+
def app_deploy_object_key
|
233
|
+
'appDeploy'
|
138
234
|
end
|
139
235
|
|
140
|
-
def
|
236
|
+
def app_deploy_list_key
|
237
|
+
'appDeploys'
|
141
238
|
end
|
142
239
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# * +stage_deploy+ - If set to true the deploy will only be staged and not actually run
|
154
|
-
#
|
155
|
-
# +NOTE: + It is also possible to nest these properties in an "environments" map to override based on a passed environment deploy name
|
156
|
-
#
|
157
|
-
def load_deploy_file
|
158
|
-
if !File.exist? "morpheus.yml"
|
159
|
-
puts "No morpheus.yml file detected in the current directory. Nothing to do."
|
160
|
-
return nil
|
240
|
+
def find_app_deploy_by_id(id)
|
241
|
+
begin
|
242
|
+
json_response = @deploy_interface.get(id.to_i)
|
243
|
+
return json_response[app_deploy_object_key]
|
244
|
+
rescue RestClient::Exception => e
|
245
|
+
if e.response && e.response.code == 404
|
246
|
+
print_red_alert "Deploy not found by id '#{id}'"
|
247
|
+
else
|
248
|
+
raise e
|
249
|
+
end
|
161
250
|
end
|
251
|
+
end
|
162
252
|
|
163
|
-
|
164
|
-
|
253
|
+
def app_deploy_column_definitions
|
254
|
+
{
|
255
|
+
"ID" => 'id',
|
256
|
+
"Instance" => lambda {|it| it['instance'] ? it['instance']['name'] : it['instanceId'] },
|
257
|
+
"Deployment" => lambda {|it| it['deployment']['name'] rescue '' },
|
258
|
+
"Version" => lambda {|it| (it['deploymentVersion']['userVersion'] || it['deploymentVersion']['version']) rescue '' },
|
259
|
+
# "Version ID" => lambda {|it| (it['deploymentVersion']['id']) rescue '' },
|
260
|
+
"Deploy Date" => lambda {|it| format_local_dt(it['deployDate']) },
|
261
|
+
"Status" => lambda {|it| format_app_deploy_status(it['status']) },
|
262
|
+
}
|
165
263
|
end
|
166
264
|
|
167
|
-
def
|
168
|
-
|
265
|
+
def add_app_deploy_option_types
|
266
|
+
[
|
267
|
+
{'fieldName' => 'instance', 'fieldLabel' => 'Instance', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
|
268
|
+
@instances_interface.list({max:10000}.merge(api_params))['instances'].collect {|it|
|
269
|
+
{'name' => it['name'], 'value' => it['id'], 'id' => it['id']}
|
270
|
+
}
|
271
|
+
}, 'required' => true, 'displayOrder' => 1},
|
272
|
+
{'fieldName' => 'deployment', 'fieldLabel' => 'Deployment', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
|
273
|
+
@deployments_interface.list({max:10000})['deployments'].collect {|it|
|
274
|
+
{'name' => it['name'], 'value' => it['id'], 'id' => it['id']}
|
275
|
+
}
|
276
|
+
}, 'required' => true, 'displayOrder' => 2},
|
277
|
+
{'fieldName' => 'version', 'fieldLabel' => 'Version', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
|
278
|
+
@deployments_interface.list_versions(api_params['deployment'], {max:10000})['versions'].collect {|it|
|
279
|
+
{'name' => (it['userVersion'] || it['version']), 'value' => it['id'], 'id' => it['id']}
|
280
|
+
}
|
281
|
+
}, 'required' => true, 'displayOrder' => 3}
|
282
|
+
]
|
283
|
+
end
|
169
284
|
|
170
|
-
|
171
|
-
|
172
|
-
|
285
|
+
def add_app_deploy_advanced_option_types
|
286
|
+
[{'fieldName' => 'stageOnly', 'fieldLabel' => 'Stage Only', 'type' => 'checkbox', 'description' => 'If set to true the deploy will only be staged and not actually run', 'displayOrder' => 10}]
|
287
|
+
end
|
288
|
+
|
289
|
+
def update_app_deploy_option_types
|
290
|
+
add_app_deploy_option_types.collect {|it|
|
291
|
+
it.delete('required')
|
292
|
+
it.delete('defaultValue')
|
293
|
+
it
|
294
|
+
}
|
295
|
+
end
|
296
|
+
|
297
|
+
def update_app_deploy_advanced_option_types
|
298
|
+
add_app_deploy_advanced_option_types.collect {|it|
|
299
|
+
it.delete('required')
|
300
|
+
it.delete('defaultValue')
|
301
|
+
it
|
302
|
+
}
|
303
|
+
end
|
304
|
+
|
305
|
+
def format_app_deploy_status(status, return_color=cyan)
|
306
|
+
out = ""
|
307
|
+
s = status.to_s.downcase
|
308
|
+
if s == 'deployed'
|
309
|
+
out << "#{green}#{s.upcase}#{return_color}"
|
310
|
+
elsif s == 'open' || s == 'archived' || s == 'committed'
|
311
|
+
out << "#{cyan}#{s.upcase}#{return_color}"
|
312
|
+
elsif s == 'failed'
|
313
|
+
out << "#{red}#{s.upcase}#{return_color}"
|
314
|
+
else
|
315
|
+
out << "#{yellow}#{s.upcase}#{return_color}"
|
173
316
|
end
|
174
|
-
|
317
|
+
out
|
175
318
|
end
|
319
|
+
|
176
320
|
end
|
321
|
+
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
|
3
|
+
# This provides commands for authentication
|
4
|
+
# This also includes credential management.
|
5
|
+
class Morpheus::Cli::DocCommand
|
6
|
+
include Morpheus::Cli::CliCommand
|
7
|
+
|
8
|
+
set_command_name :'doc'
|
9
|
+
#set_command_name :'access'
|
10
|
+
register_subcommands :list
|
11
|
+
register_subcommands :get => :swagger
|
12
|
+
register_subcommands :download => :download_swagger
|
13
|
+
|
14
|
+
# hidden until doc complete (or close to it)
|
15
|
+
set_command_hidden
|
16
|
+
|
17
|
+
def initialize()
|
18
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle(args)
|
22
|
+
handle_subcommand(args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def connect(options)
|
26
|
+
@api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
|
27
|
+
@doc_interface = @api_client.doc
|
28
|
+
end
|
29
|
+
|
30
|
+
def list(args)
|
31
|
+
exit_code, err = 0, nil
|
32
|
+
params, options = {}, {}
|
33
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
34
|
+
opts.banner = subcommand_usage()
|
35
|
+
build_standard_get_options(opts, options)
|
36
|
+
opts.footer = <<-EOT
|
37
|
+
List documentation links.
|
38
|
+
EOT
|
39
|
+
end
|
40
|
+
optparse.parse!(args)
|
41
|
+
verify_args!(args:args, optparse:optparse, count:0)
|
42
|
+
connect(options)
|
43
|
+
# construct the api request
|
44
|
+
params.merge!(parse_list_options(options))
|
45
|
+
# execute the api request
|
46
|
+
@doc_interface.setopts(options)
|
47
|
+
if options[:dry_run]
|
48
|
+
print_dry_run @doc_interface.dry.list(params)
|
49
|
+
return 0, nil
|
50
|
+
end
|
51
|
+
json_response = @doc_interface.list(params)
|
52
|
+
render_response(json_response, options, "links") do
|
53
|
+
title = "Morpheus Documentation"
|
54
|
+
print_h1 title, options
|
55
|
+
if json_response['links'].empty?
|
56
|
+
print yellow, "No help links found.",reset,"\n"
|
57
|
+
else
|
58
|
+
columns = {
|
59
|
+
"Link Name" => 'name',
|
60
|
+
"URL" => 'url',
|
61
|
+
"Description" => {display_method:'description', max_width: (options[:wrap] ? nil : 50)},
|
62
|
+
}
|
63
|
+
print as_pretty_table(json_response['links'], columns.upcase_keys!, options)
|
64
|
+
# print_results_pagination(json_response)
|
65
|
+
end
|
66
|
+
print reset,"\n"
|
67
|
+
end
|
68
|
+
return exit_code, err
|
69
|
+
end
|
70
|
+
|
71
|
+
def swagger(args)
|
72
|
+
exit_code, err = 0, nil
|
73
|
+
params, options = {}, {}
|
74
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
75
|
+
opts.banner = subcommand_usage()
|
76
|
+
opts.on(nil, "--refresh", "Refresh the document. By default the swagger.yml and swagger.json are cached by the server.") do
|
77
|
+
params['refresh'] = true
|
78
|
+
end
|
79
|
+
opts.on('-g', '--generate', "Alias for --refresh") do
|
80
|
+
params['refresh'] = true
|
81
|
+
end
|
82
|
+
build_standard_get_options(opts, options, [], [:csv])
|
83
|
+
opts.footer = <<-EOT
|
84
|
+
Print the Morpheus API Swagger Documentation (openapi).
|
85
|
+
The default format is JSON. Supports json or yaml.
|
86
|
+
EOT
|
87
|
+
end
|
88
|
+
optparse.parse!(args)
|
89
|
+
verify_args!(args:args, optparse:optparse, count:0)
|
90
|
+
connect(options)
|
91
|
+
# construct the api request
|
92
|
+
params.merge!(parse_list_options(options))
|
93
|
+
# for now, always use .json, and just convert to yaml for display on cli side
|
94
|
+
openapi_format = options[:yaml] ? "yaml" : "json"
|
95
|
+
# params['format'] = openapi_format
|
96
|
+
# execute the api request
|
97
|
+
@doc_interface.setopts(options)
|
98
|
+
if options[:dry_run]
|
99
|
+
params['format'] = openapi_format
|
100
|
+
print_dry_run @doc_interface.dry.swagger(params)
|
101
|
+
return 0, nil
|
102
|
+
end
|
103
|
+
json_response = @doc_interface.swagger(params)
|
104
|
+
# default format is to print header and json
|
105
|
+
render_response(json_response, options) do
|
106
|
+
title = "Morpheus API swagger.#{openapi_format}"
|
107
|
+
print_h1 title, options
|
108
|
+
print cyan
|
109
|
+
print as_json(json_response, options)
|
110
|
+
print reset,"\n"
|
111
|
+
end
|
112
|
+
return exit_code, err
|
113
|
+
end
|
114
|
+
|
115
|
+
def download_swagger(args)
|
116
|
+
exit_code, err = 0, nil
|
117
|
+
params, options = {}, {}
|
118
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
119
|
+
opts.banner = subcommand_usage("[local-file]")
|
120
|
+
# build_standard_get_options(opts, options, [], [:csv,:out])
|
121
|
+
opts.on(nil, '--yaml', "YAML Output") do
|
122
|
+
options[:yaml] = true
|
123
|
+
options[:format] = :yaml
|
124
|
+
end
|
125
|
+
opts.on(nil, "--refresh", "Refresh the document. By default the swagger.yml and swagger.json are cached by the server.") do
|
126
|
+
params['refresh'] = true
|
127
|
+
end
|
128
|
+
opts.on('-g', '--generate', "Alias for --refresh") do
|
129
|
+
params['refresh'] = true
|
130
|
+
end
|
131
|
+
opts.on( '-f', '--force', "Overwrite existing [local-file] if it exists." ) do
|
132
|
+
options[:overwrite] = true
|
133
|
+
end
|
134
|
+
opts.on( '-p', '--mkdir', "Create missing directories for [local-file] if they do not exist." ) do
|
135
|
+
options[:mkdir] = true
|
136
|
+
end
|
137
|
+
build_common_options(opts, options, [:dry_run, :quiet, :remote])
|
138
|
+
opts.footer = <<-EOT
|
139
|
+
Download the Morpheus API Swagger Documentation (openapi).
|
140
|
+
[local-file] is required. This is the full local filepath for the downloaded file.
|
141
|
+
The default format is JSON. Supports json or yaml.
|
142
|
+
EOT
|
143
|
+
end
|
144
|
+
optparse.parse!(args)
|
145
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
146
|
+
connect(options)
|
147
|
+
# parse args
|
148
|
+
outfile = args[0]
|
149
|
+
if !validate_outfile(outfile, options)
|
150
|
+
return 1, "Failed to validate outfile"
|
151
|
+
end
|
152
|
+
# construct the api request
|
153
|
+
params.merge!(parse_list_options(options))
|
154
|
+
if outfile.include?(".yml") || outfile.include?(".yaml")
|
155
|
+
options[:yaml] = true
|
156
|
+
end
|
157
|
+
openapi_format = options[:yaml] ? "yaml" : "json"
|
158
|
+
params['format'] = openapi_format
|
159
|
+
# execute the api request
|
160
|
+
@doc_interface.setopts(options)
|
161
|
+
if options[:dry_run]
|
162
|
+
print_dry_run @doc_interface.dry.download_swagger(outfile, params)
|
163
|
+
return 0, nil
|
164
|
+
end
|
165
|
+
print cyan + "Downloading swagger.#{openapi_format} to #{outfile} ... " if !options[:quiet]
|
166
|
+
http_response = @doc_interface.download_swagger(outfile, params)
|
167
|
+
if http_response.code.to_i == 200
|
168
|
+
print green + "SUCCESS" + reset + "\n" if !options[:quiet]
|
169
|
+
return 0, nil
|
170
|
+
else
|
171
|
+
print red + "ERROR" + reset + " HTTP #{http_response.code}" + "\n" if !options[:quiet]
|
172
|
+
if File.exists?(outfile) && File.file?(outfile)
|
173
|
+
Morpheus::Logging::DarkPrinter.puts "Deleting bad file download: #{outfile}" if Morpheus::Logging.debug?
|
174
|
+
File.delete(outfile)
|
175
|
+
end
|
176
|
+
return 1, "HTTP #{http_response.code}"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
protected
|
181
|
+
|
182
|
+
end
|