morpheus-cli 4.2.14 → 4.2.19

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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/README.md +8 -6
  4. data/lib/morpheus/api/api_client.rb +32 -14
  5. data/lib/morpheus/api/auth_interface.rb +4 -2
  6. data/lib/morpheus/api/backup_jobs_interface.rb +9 -0
  7. data/lib/morpheus/api/backups_interface.rb +16 -0
  8. data/lib/morpheus/api/deploy_interface.rb +25 -56
  9. data/lib/morpheus/api/deployments_interface.rb +44 -55
  10. data/lib/morpheus/api/doc_interface.rb +57 -0
  11. data/lib/morpheus/api/instances_interface.rb +5 -0
  12. data/lib/morpheus/api/rest_interface.rb +40 -0
  13. data/lib/morpheus/api/user_sources_interface.rb +0 -15
  14. data/lib/morpheus/api/users_interface.rb +2 -3
  15. data/lib/morpheus/benchmarking.rb +2 -2
  16. data/lib/morpheus/cli.rb +4 -1
  17. data/lib/morpheus/cli/access_token_command.rb +27 -10
  18. data/lib/morpheus/cli/apps.rb +21 -15
  19. data/lib/morpheus/cli/backup_jobs_command.rb +276 -0
  20. data/lib/morpheus/cli/backups_command.rb +271 -0
  21. data/lib/morpheus/cli/blueprints_command.rb +27 -61
  22. data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
  23. data/lib/morpheus/cli/cli_command.rb +183 -45
  24. data/lib/morpheus/cli/cli_registry.rb +3 -0
  25. data/lib/morpheus/cli/clouds.rb +7 -10
  26. data/lib/morpheus/cli/clusters.rb +0 -18
  27. data/lib/morpheus/cli/commands/standard/benchmark_command.rb +23 -20
  28. data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
  29. data/lib/morpheus/cli/credentials.rb +13 -9
  30. data/lib/morpheus/cli/deploy.rb +374 -0
  31. data/lib/morpheus/cli/deployments.rb +521 -197
  32. data/lib/morpheus/cli/deploys.rb +271 -126
  33. data/lib/morpheus/cli/doc.rb +182 -0
  34. data/lib/morpheus/cli/error_handler.rb +23 -8
  35. data/lib/morpheus/cli/errors.rb +3 -2
  36. data/lib/morpheus/cli/image_builder_command.rb +2 -2
  37. data/lib/morpheus/cli/instances.rb +136 -17
  38. data/lib/morpheus/cli/invoices_command.rb +339 -225
  39. data/lib/morpheus/cli/jobs_command.rb +2 -2
  40. data/lib/morpheus/cli/library_layouts_command.rb +1 -1
  41. data/lib/morpheus/cli/library_option_lists_command.rb +61 -125
  42. data/lib/morpheus/cli/library_option_types_command.rb +32 -37
  43. data/lib/morpheus/cli/login.rb +9 -3
  44. data/lib/morpheus/cli/mixins/accounts_helper.rb +158 -100
  45. data/lib/morpheus/cli/mixins/backups_helper.rb +115 -0
  46. data/lib/morpheus/cli/mixins/deployments_helper.rb +135 -0
  47. data/lib/morpheus/cli/mixins/library_helper.rb +32 -0
  48. data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
  49. data/lib/morpheus/cli/mixins/print_helper.rb +149 -84
  50. data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -2
  51. data/lib/morpheus/cli/mixins/whoami_helper.rb +19 -6
  52. data/lib/morpheus/cli/network_routers_command.rb +1 -1
  53. data/lib/morpheus/cli/option_parser.rb +48 -5
  54. data/lib/morpheus/cli/option_types.rb +46 -10
  55. data/lib/morpheus/cli/price_sets_command.rb +1 -1
  56. data/lib/morpheus/cli/projects_command.rb +7 -7
  57. data/lib/morpheus/cli/remote.rb +3 -2
  58. data/lib/morpheus/cli/roles.rb +49 -92
  59. data/lib/morpheus/cli/security_groups.rb +7 -1
  60. data/lib/morpheus/cli/service_plans_command.rb +10 -10
  61. data/lib/morpheus/cli/setup.rb +1 -1
  62. data/lib/morpheus/cli/shell.rb +7 -6
  63. data/lib/morpheus/cli/subnets_command.rb +1 -1
  64. data/lib/morpheus/cli/tasks.rb +24 -10
  65. data/lib/morpheus/cli/tenants_command.rb +133 -163
  66. data/lib/morpheus/cli/user_groups_command.rb +20 -65
  67. data/lib/morpheus/cli/user_settings_command.rb +115 -13
  68. data/lib/morpheus/cli/user_sources_command.rb +57 -24
  69. data/lib/morpheus/cli/users.rb +210 -186
  70. data/lib/morpheus/cli/version.rb +1 -1
  71. data/lib/morpheus/cli/whitelabel_settings_command.rb +29 -5
  72. data/lib/morpheus/cli/whoami.rb +113 -6
  73. data/lib/morpheus/cli/workflows.rb +11 -8
  74. data/lib/morpheus/ext/hash.rb +21 -0
  75. data/lib/morpheus/formatters.rb +7 -19
  76. data/lib/morpheus/terminal.rb +1 -0
  77. metadata +12 -3
  78. data/lib/morpheus/cli/auth_command.rb +0 -105
@@ -1,12 +1,12 @@
1
- require 'io/console'
2
- require 'rest_client'
3
- require 'optparse'
4
1
  require 'morpheus/cli/cli_command'
5
2
 
6
3
  class Morpheus::Cli::Deployments
7
4
  include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::DeploymentsHelper
8
6
 
9
- register_subcommands :list, :add, :update, :remove, {:versions => 'list_versions'}
7
+ register_subcommands :list, :get, :add, :update, :remove
8
+ register_subcommands :list_versions, :get_version, :add_version, :update_version, :remove_version
9
+ alias_subcommand :versions, :'list-versions'
10
10
 
11
11
  def initialize()
12
12
  # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
@@ -14,7 +14,7 @@ class Morpheus::Cli::Deployments
14
14
 
15
15
  def connect(opts)
16
16
  @api_client = establish_remote_appliance_connection(opts)
17
- @deployments_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).deployments
17
+ @deployments_interface = @api_client.deployments
18
18
  end
19
19
 
20
20
  def handle(args)
@@ -23,264 +23,588 @@ class Morpheus::Cli::Deployments
23
23
 
24
24
  def list(args)
25
25
  options = {}
26
+ params = {}
27
+ ref_ids = []
26
28
  optparse = Morpheus::Cli::OptionParser.new do |opts|
27
- opts.banner = subcommand_usage()
28
- build_common_options(opts, options, [:list, :json, :dry_run, :remote])
29
+ opts.banner = subcommand_usage("[search]")
30
+ build_standard_list_options(opts, options)
31
+ opts.footer = "List deployments."
29
32
  end
30
33
  optparse.parse!(args)
31
34
  connect(options)
32
- begin
33
- params = {}
34
- [:phrase, :offset, :max, :sort, :direction].each do |k|
35
- params[k] = options[k] unless options[k].nil?
36
- end
37
- @deployments_interface.setopts(options)
38
- if options[:dry_run]
39
- print_dry_run @deployments_interface.dry.list(params)
40
- return
35
+ # verify_args!(args:args, optparse:optparse, count:0)
36
+ if args.count > 0
37
+ options[:phrase] = args.join(" ")
38
+ end
39
+ params.merge!(parse_list_options(options))
40
+ @deployments_interface.setopts(options)
41
+ if options[:dry_run]
42
+ print_dry_run @deployments_interface.dry.list(params)
43
+ return
44
+ end
45
+ json_response = @deployments_interface.list(params)
46
+ deployments = json_response['deployments']
47
+ render_response(json_response, options, 'deployments') do
48
+ print_h1 "Morpheus Deployments", parse_list_subtitles(options), options
49
+ if deployments.empty?
50
+ print cyan,"No deployments found.",reset,"\n"
51
+ else
52
+ print as_pretty_table(deployments, deployment_column_definitions.upcase_keys!, options)
53
+ print_results_pagination(json_response)
41
54
  end
42
- json_response = @deployments_interface.list(params)
43
- if options[:json]
44
- puts JSON.pretty_generate(json_response)
55
+ print reset,"\n"
56
+ end
57
+ if deployments.empty?
58
+ return 1, "no deployments found"
59
+ else
60
+ return 0, nil
61
+ end
62
+ end
63
+
64
+ def get(args)
65
+ params = {}
66
+ options = {}
67
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
68
+ opts.banner = subcommand_usage("[deployment]")
69
+ build_standard_get_options(opts, options)
70
+ opts.footer = <<-EOT
71
+ Get details about a specific deployment.
72
+ [deployment] is required. This is the name or id of a deployment.
73
+ EOT
74
+ end
75
+ optparse.parse!(args)
76
+ verify_args!(args:args, optparse:optparse, min:1)
77
+ connect(options)
78
+ id_list = parse_id_list(args)
79
+ # lookup IDs if names are given
80
+ id_list = id_list.collect do |id|
81
+ if id.to_s =~ /\A\d{1,}\Z/
82
+ id
45
83
  else
46
- deployments = json_response['deployments']
47
- print_h1 "Morpheus Deployments"
48
- if deployments.empty?
49
- print cyan,"No deployments found.",reset,"\n"
84
+ deployment = find_deployment_by_name(id)
85
+ if deployment
86
+ deployment['id']
50
87
  else
51
- print cyan
52
- rows = deployments.collect do |deployment|
53
- {name: deployment['name'], id: deployment['id'], description: deployment['description'], updated: format_local_dt(deployment['lastUpdated'])}
54
- end
55
- columns = [:id, :name, :description, :updated]
56
- print as_pretty_table(rows, columns, options)
88
+ raise_command_error "deployment not found for name '#{id}'"
57
89
  end
58
- print reset,"\n"
59
90
  end
60
- rescue RestClient::Exception => e
61
- print_rest_exception(e, options)
62
- exit 1
91
+ end
92
+ return run_command_for_each_arg(id_list) do |arg|
93
+ _get(arg, params, options)
63
94
  end
64
95
  end
65
96
 
97
+ def _get(id, params, options)
98
+ @deployments_interface.setopts(options)
99
+ if options[:dry_run]
100
+ print_dry_run @deployments_interface.dry.get(id, params)
101
+ print_dry_run @deployments_interface.dry.list_versions(id, {})
102
+ return
103
+ end
104
+ json_response = @deployments_interface.get(id, params)
105
+ deployment_versions = @deployments_interface.list_versions(id)['versions']
106
+ deployment = json_response['deployment']
107
+ render_response(json_response, options, 'deployment') do
108
+ print_h1 "Deployment Details", [], options
109
+ print cyan
110
+ print_description_list(deployment_column_definitions, deployment)
111
+ print_h2 "Versions", options
112
+ if deployment_versions.empty?
113
+ print cyan,"No versions found.",reset,"\n"
114
+ else
115
+ print as_pretty_table(deployment_versions, deployment_version_column_definitions.upcase_keys!, options)
116
+ print_results_pagination({'size' => deployment_versions.size(), 'total' => deployment['versionCount']}, {:label => "version", :n_label => "versions"})
117
+ end
118
+ print reset,"\n"
119
+ end
120
+ return 0, nil
121
+ end
122
+
66
123
  def list_versions(args)
124
+ params = {}
67
125
  options = {}
68
126
  optparse = Morpheus::Cli::OptionParser.new do |opts|
69
- opts.banner = subcommand_usage("[name] versions")
70
- build_common_options(opts, options, [:list, :json, :dry_run, :remote])
127
+ opts.banner = subcommand_usage("[deployment] [search]")
128
+ build_standard_list_options(opts, options)
129
+ opts.footer = <<-EOT
130
+ List versions of a specific deployment.
131
+ [deployment] is required. This is the name or id of a deployment.
132
+ EOT
71
133
  end
72
134
  optparse.parse!(args)
73
- if args.count < 1
74
- puts optparse
75
- exit 1
76
- end
135
+ verify_args!(args:args, optparse:optparse, min:1,max:2)
77
136
  deployment_name = args[0]
137
+ if args.count > 1
138
+ options[:phrase] = args[1]
139
+ end
78
140
  connect(options)
79
- begin
80
- params = {}
81
- [:phrase, :offset, :max, :sort, :direction].each do |k|
82
- params[k] = options[k] unless options[k].nil?
83
- end
84
- deployment = find_deployment_by_name_or_id(deployment_name)
85
- exit 1 if deployment.nil?
86
- @deployments_interface.setopts(options)
87
- if options[:dry_run]
88
- print_dry_run @deployments_interface.dry.list_versions(deployment['id'],params)
89
- return
90
- end
91
- json_response = @deployments_interface.list_versions(deployment['id'],params)
92
- if options[:json]
93
- puts JSON.pretty_generate(json_response)
141
+ params.merge!(parse_list_options(options))
142
+ @deployments_interface.setopts(options)
143
+ if options[:dry_run]
144
+ print_dry_run @deployments_interface.dry.list(params)
145
+ return
146
+ end
147
+ deployment = find_deployment_by_name_or_id(deployment_name)
148
+ exit 1 if deployment.nil?
149
+ json_response = @deployments_interface.list_versions(deployment['id'], params)
150
+ deployment_versions = json_response['versions']
151
+ render_response(json_response, options, 'versions') do
152
+ print_h1 "Deployment Versions", ["#{deployment['name']}"] + parse_list_subtitles(options), options
153
+ if deployment_versions.empty?
154
+ print cyan,"No versions found.",reset,"\n"
94
155
  else
95
- versions = json_response['versions']
96
- print_h1 "Deployment Versions: #{deployment['name']}"
97
- if versions.empty?
98
- print cyan,"No deployment versions found.",reset,"\n"
99
- else
100
- print cyan
101
- rows = versions.collect do |version|
102
- {version: version['userVersion'], type: version['deployType'], updated: format_local_dt(version['lastUpdated'])}
103
- end
104
- columns = [:version, :type, :updated]
105
- print as_pretty_table(rows, columns, options)
106
- end
107
- print reset,"\n"
156
+ print as_pretty_table(deployment_versions, deployment_version_column_definitions.upcase_keys!, options)
157
+ print_results_pagination(json_response)
108
158
  end
109
- rescue RestClient::Exception => e
110
- print_rest_exception(e, options)
111
- exit 1
159
+ print reset,"\n"
160
+ end
161
+ if deployment_versions.empty?
162
+ return 1, "no versions found"
163
+ else
164
+ return 0, nil
112
165
  end
113
166
  end
114
167
 
115
- def update(args)
116
- deployment_name = args[0]
168
+ def add(args)
117
169
  options = {}
118
- account_name = nil
170
+ params = {}
119
171
  optparse = Morpheus::Cli::OptionParser.new do |opts|
120
172
  opts.banner = subcommand_usage("[name] [options]")
121
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
173
+ build_option_type_options(opts, options, add_deployment_option_types)
174
+ build_option_type_options(opts, options, add_deployment_advanced_option_types)
175
+ build_standard_add_options(opts, options)
176
+ opts.footer = <<-EOT
177
+ Create a new deployment.
178
+ EOT
122
179
  end
123
180
  optparse.parse!(args)
124
- if args.count < 1
125
- puts optparse
126
- exit 1
127
- end
181
+ verify_args!(args:args, optparse:optparse, min:0, max:1)
182
+ options[:options]['name'] = args[0] if args[0]
128
183
  connect(options)
129
- begin
130
- deployment = find_deployment_by_name_or_id(deployment_name)
131
- exit 1 if deployment.nil?
132
-
133
- #params = Morpheus::Cli::OptionTypes.prompt(add_user_option_types, options[:options], @api_client, options[:params]) # options[:params] is mysterious
134
- params = options[:options] || {}
184
+ payload = {}
185
+ if options[:payload]
186
+ payload = options[:payload]
187
+ payload.deep_merge!({'deployment' => parse_passed_options(options)})
188
+ else
189
+ payload.deep_merge!({'deployment' => parse_passed_options(options)})
190
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(add_deployment_option_types, options[:options], @api_client, options[:params])
191
+ params.deep_merge!(v_prompt)
192
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_deployment_advanced_option_types, options[:options], @api_client, options[:params])
193
+ advanced_config.deep_compact!
194
+ params.deep_merge!(advanced_config)
195
+ payload['deployment'].deep_merge!(params)
196
+ end
197
+ @deployments_interface.setopts(options)
198
+ if options[:dry_run]
199
+ print_dry_run @deployments_interface.dry.create(payload)
200
+ return 0, nil
201
+ end
202
+ json_response = @deployments_interface.create(payload)
203
+ deployment = json_response['deployment']
204
+ render_response(json_response, options, 'deployment') do
205
+ print_green_success "Added deployment #{deployment['name']}"
206
+ return _get(deployment["id"], {}, options)
207
+ end
208
+ return 0, nil
209
+ end
135
210
 
136
- if params.empty?
137
- puts optparse
138
- option_lines = update_deployment_option_types().collect {|it| "\t-O #{it['fieldContext'] ? (it['fieldContext'] + '.') : ''}#{it['fieldName']}=\"value\"" }.join("\n")
139
- puts "\nAvailable Options:\n#{option_lines}\n\n"
140
- exit 1
211
+ def update(args)
212
+ options = {}
213
+ params = {}
214
+ payload = {}
215
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
216
+ opts.banner = subcommand_usage("[deployment] [options]")
217
+ build_option_type_options(opts, options, update_deployment_option_types)
218
+ build_option_type_options(opts, options, update_deployment_advanced_option_types)
219
+ build_standard_update_options(opts, options)
220
+ opts.footer = <<-EOT
221
+ Update a deployment.
222
+ [deployment] is required. This is the name or id of a deployment.
223
+ EOT
224
+ end
225
+ optparse.parse!(args)
226
+ verify_args!(args:args, optparse:optparse, count:1)
227
+ connect(options)
228
+ deployment = find_deployment_by_name_or_id(args[0])
229
+ return 1 if deployment.nil?
230
+ payload = {}
231
+ if options[:payload]
232
+ payload = options[:payload]
233
+ payload.deep_merge!({'deployment' => parse_passed_options(options)})
234
+ else
235
+ payload.deep_merge!({'deployment' => parse_passed_options(options)})
236
+ # do not prompt on update
237
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_deployment_option_types, options[:options], @api_client, options[:params])
238
+ v_prompt.deep_compact!
239
+ params.deep_merge!(v_prompt)
240
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_deployment_advanced_option_types, options[:options], @api_client, options[:params])
241
+ advanced_config.deep_compact!
242
+ params.deep_merge!(advanced_config)
243
+ payload.deep_merge!({'deployment' => params})
244
+ if payload['deployment'].empty? # || options[:no_prompt]
245
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
141
246
  end
247
+ end
248
+ @deployments_interface.setopts(options)
249
+ if options[:dry_run]
250
+ print_dry_run @deployments_interface.dry.update(deployment['id'], payload)
251
+ return
252
+ end
253
+ json_response = @deployments_interface.update(deployment['id'], payload)
254
+ deployment = json_response['deployment']
255
+ render_response(json_response, options, 'deployment') do
256
+ print_green_success "Updated deployment #{deployment['name']}"
257
+ return _get(deployment["id"], {}, options)
258
+ end
259
+ return 0, nil
260
+ end
142
261
 
143
- #puts "parsed params is : #{params.inspect}"
144
- deployment_keys = ['name','description']
145
- changes_payload = (params.select {|k,v| deployment_keys.include?(k) })
146
- deployment_payload = deployment
147
- if changes_payload
148
- deployment_payload.merge!(changes_payload)
149
- end
262
+ def remove(args)
263
+ options = {}
264
+ params = {}
265
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
266
+ opts.banner = subcommand_usage("[deployment] [options]")
267
+ build_standard_remove_options(opts, options)
268
+ opts.footer = <<-EOT
269
+ Delete a deployment.
270
+ [deployment] is required. This is the name or id of a deployment.
271
+ EOT
272
+ end
273
+ optparse.parse!(args)
274
+ verify_args!(args:args, optparse:optparse, count:1)
275
+ connect(options)
276
+ deployment = find_deployment_by_name_or_id(args[0])
277
+ return 1 if deployment.nil?
278
+ @deployments_interface.setopts(options)
279
+ if options[:dry_run]
280
+ print_dry_run @deployments_interface.dry.destroy(deployment['id'], params)
281
+ return
282
+ end
283
+ json_response = @deployments_interface.destroy(deployment['id'], params)
284
+ render_response(json_response, options) do
285
+ print_green_success "Removed deployment #{deployment['name']}"
286
+ end
287
+ return 0, nil
288
+ end
150
289
 
290
+ def get_version(args)
291
+ options = {}
292
+ params = {}
293
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
294
+ opts.banner = subcommand_usage("[deployment] [version] [options]")
295
+ build_option_type_options(opts, options, add_deployment_version_option_types)
296
+ build_option_type_options(opts, options, add_deployment_version_advanced_option_types)
297
+ build_standard_add_options(opts, options)
298
+ opts.footer = <<-EOT
299
+ Create a new deployment version.
300
+ [deployment] is required. This is the name or id of a deployment.
301
+ [version] is required. This is the deployment version identifier
302
+ EOT
303
+ end
304
+ optparse.parse!(args)
305
+ verify_args!(args:args, optparse:optparse, count:2)
306
+ connect(options)
151
307
 
152
- payload = {deployment: deployment_payload}
153
- @deployments_interface.setopts(options)
154
- if options[:dry_run]
155
- print_dry_run @deployments_interface.dry.update(deployment['id'], payload)
156
- return
308
+ deployment = find_deployment_by_name_or_id(args[0])
309
+ return 1 if deployment.nil?
310
+ id = args[1]
311
+ if id.to_s =~ /\A\d{1,}\Z/
312
+ id = id.to_i
313
+ else
314
+ deployment_version = find_deployment_version_by_name(deployment['id'], id)
315
+ if deployment_version
316
+ id = deployment_version['id']
317
+ else
318
+ # raise_command_error "deployment not found for name '#{id}'"
319
+ return 1, "deployment version not found for name '#{id}'"
157
320
  end
158
- response = @deployments_interface.update(deployment['id'], payload)
159
- if options[:json]
160
- print JSON.pretty_generate(json_response)
161
- if !response['success']
162
- exit 1
163
- end
321
+ end
322
+ @deployments_interface.setopts(options)
323
+ if options[:dry_run]
324
+ print_dry_run @deployments_interface.dry.get_version(deployment['id'], id, params)
325
+ return
326
+ end
327
+ json_response = @deployments_interface.get_version(deployment['id'], id, params)
328
+ deployment_version = json_response['version']
329
+ render_response(json_response, options, 'version') do
330
+ # print_h1 "Deployment Version Details", [deployment['name']], options
331
+ print_h1 "Deployment Version Details", [], options
332
+ print cyan
333
+ #columns = deployment_version_column_definitions
334
+ columns = {
335
+ "ID" => 'id',
336
+ "Deployment" => lambda {|it| deployment['name'] },
337
+ "Version" => 'userVersion',
338
+ "Deploy Type" => lambda {|it| it['deployType'] },
339
+ "URL" => lambda {|it|
340
+ if it['deployType'] == 'fetch'
341
+ "#{it['fetchUrl']}"
342
+ elsif it['deployType'] == 'git'
343
+ "#{it['gitUrl']}"
344
+ end
345
+ },
346
+ "Ref" => lambda {|it|
347
+ if it['deployType'] == 'git'
348
+ "#{it['gitRef']}"
349
+ end
350
+ },
351
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
352
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
353
+ }
354
+ if deployment_version['deployType'] == 'git'
355
+ columns['Git URL'] = columns['URL']
356
+ elsif deployment_version['deployType'] == 'fetch'
357
+ columns['Fetch URL'] = columns['URL']
358
+ columns.delete('Ref')
164
359
  else
165
- print "\n", cyan, "Deployment #{response['deployment']['name']} updated", reset, "\n\n"
360
+ columns.delete('URL')
361
+ columns.delete('Ref')
166
362
  end
167
- rescue RestClient::Exception => e
168
- print_rest_exception(e, options)
169
- exit 1
363
+ print_description_list(columns, deployment_version)
364
+ print reset,"\n"
170
365
  end
366
+ return 0, nil
171
367
  end
172
368
 
173
- def add(args)
369
+ def add_version(args)
174
370
  options = {}
371
+ params = {}
175
372
  optparse = Morpheus::Cli::OptionParser.new do |opts|
176
- opts.banner = subcommand_usage("[name]")
177
- opts.on( '-d', '--description DESCRIPTION', "Description" ) do |val|
178
- options[:description] = val
179
- end
180
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
373
+ opts.banner = subcommand_usage("[deployment] [version] [options]")
374
+ build_option_type_options(opts, options, add_deployment_version_option_types)
375
+ build_option_type_options(opts, options, add_deployment_version_advanced_option_types)
376
+ build_standard_add_options(opts, options)
377
+ opts.footer = <<-EOT
378
+ Create a new deployment version.
379
+ [deployment] is required. This is the name or id of a deployment.
380
+ [version] is required. This is the deployment version identifier
381
+ EOT
181
382
  end
182
383
  optparse.parse!(args)
183
- if args.count < 1
184
- puts optparse
185
- exit 1
186
- end
187
- deployment_name = args[0]
384
+ verify_args!(args:args, optparse:optparse, min:0, max:2)
188
385
  connect(options)
189
- begin
190
- payload = {deployment: {name: deployment_name, description: options[:description]}}
191
- @deployments_interface.setopts(options)
192
- if options[:dry_run]
193
- print_dry_run @deployments_interface.dry.create(payload)
194
- return
195
- end
196
- json_response = @deployments_interface.create(payload)
197
- if options[:json]
198
- print JSON.pretty_generate(json_response)
199
- else
200
- print "\n", cyan, "Deployment #{json_response['deployment']['name']} created successfully", reset, "\n\n"
201
- end
202
- rescue RestClient::Exception => e
203
- print_rest_exception(e, options)
204
- exit 1
386
+ deployment = nil
387
+ if args[0]
388
+ deployment = find_deployment_by_name_or_id(args[0])
389
+ return 1 if deployment.nil?
390
+ else
391
+ deployment_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'deploymentId', 'fieldLabel' => 'Deployment', 'type' => 'select', 'required' => true, 'description' => 'Deployment to add version to', 'optionSource' => lambda {
392
+ @deployments_interface.list(max:10000)['deployments'].collect {|it|
393
+ {'name' => it['name'], 'value' => it['id']}
394
+ }
395
+ }}], options[:options])['deploymentId']
396
+ deployment = {'id' => deployment_id.to_i}
397
+ end
398
+ options[:options]['userVersion'] = args[1] if args[1]
399
+ payload = {}
400
+ if options[:payload]
401
+ payload = options[:payload]
402
+ payload.deep_merge!({'version' => parse_passed_options(options)})
403
+ else
404
+ payload.deep_merge!({'version' => parse_passed_options(options)})
405
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(add_deployment_version_option_types, options[:options], @api_client, options[:params])
406
+ params.deep_merge!(v_prompt)
407
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_deployment_version_advanced_option_types, options[:options], @api_client, options[:params])
408
+ advanced_config.deep_compact!
409
+ params.deep_merge!(advanced_config)
410
+ payload['version'].deep_merge!(params)
411
+ end
412
+ @deployments_interface.setopts(options)
413
+ if options[:dry_run]
414
+ print_dry_run @deployments_interface.dry.create_version(deployment['id'], payload)
415
+ return 0, nil
416
+ end
417
+ json_response = @deployments_interface.create_version(deployment['id'], payload)
418
+ deployment_version = json_response['version']
419
+ render_response(json_response, options, 'version') do
420
+ print_green_success "Added deployment version #{deployment_version['userVersion']}"
421
+ return get_version([deployment["id"], deployment_version['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
205
422
  end
206
423
  end
207
424
 
208
- def remove(args)
425
+ def update_version(args)
209
426
  options = {}
427
+ params = {}
210
428
  optparse = Morpheus::Cli::OptionParser.new do |opts|
211
- opts.banner = subcommand_usage("[name]")
212
- build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
429
+ opts.banner = subcommand_usage("[deployment] [version] [options]")
430
+ build_option_type_options(opts, options, update_deployment_version_option_types)
431
+ build_option_type_options(opts, options, update_deployment_version_advanced_option_types)
432
+ build_standard_update_options(opts, options)
433
+ opts.footer = <<-EOT
434
+ Update a deployment version.
435
+ [deployment] is required. This is the name or id of a deployment.
436
+ [version] is required. This is the deployment version identifier
437
+ EOT
213
438
  end
214
439
  optparse.parse!(args)
215
- if args.count < 1
216
- puts optparse
217
- exit 1
440
+ verify_args!(args:args, optparse:optparse, min:0, max:2)
441
+ connect(options)
442
+ deployment = find_deployment_by_name_or_id(args[0])
443
+ return 1 if deployment.nil?
444
+ deployment_version = find_deployment_version_by_name_or_id(deployment['id'], args[1])
445
+ return 1 if deployment_version.nil?
446
+ payload = {}
447
+ if options[:payload]
448
+ payload = options[:payload]
449
+ payload.deep_merge!({'version' => parse_passed_options(options)})
450
+ else
451
+ payload.deep_merge!({'version' => parse_passed_options(options)})
452
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_deployment_version_option_types, options[:options], @api_client, options[:params])
453
+ params.deep_merge!(v_prompt)
454
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_deployment_version_advanced_option_types, options[:options], @api_client, options[:params])
455
+ advanced_config.deep_compact!
456
+ params.deep_merge!(advanced_config)
457
+ payload['version'].deep_merge!(params)
458
+ end
459
+ @deployments_interface.setopts(options)
460
+ if options[:dry_run]
461
+ print_dry_run @deployments_interface.dry.update_version(deployment['id'], deployment_version['id'], payload)
462
+ return 0, nil
463
+ end
464
+ json_response = @deployments_interface.update_version(deployment['id'], deployment_version['id'], payload)
465
+ deployment_version = json_response['version']
466
+ render_response(json_response, options, 'version') do
467
+ print_green_success "Updated deployment version #{deployment_version['userVersion']}"
468
+ return get_version([deployment["id"], deployment_version['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
469
+ end
470
+ end
471
+
472
+ def remove_version(args)
473
+ options = {}
474
+ params = {}
475
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
476
+ opts.banner = subcommand_usage("[deployment] [version] [options]")
477
+ build_standard_remove_options(opts, options)
478
+ opts.footer = <<-EOT
479
+ Delete a deployment version.
480
+ [deployment] is required. This is the name or id of a deployment.
481
+ [version] is required. This is the version identifier of a deployment version.
482
+ EOT
218
483
  end
219
- deployment_name = args[0]
484
+ optparse.parse!(args)
485
+ verify_args!(args:args, optparse:optparse, count:2)
220
486
  connect(options)
221
- begin
222
- deployment = find_deployment_by_name_or_id(deployment_name)
223
- exit 1 if deployment.nil?
224
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the deployment #{deployment['name']}?")
225
- exit
226
- end
227
- @deployments_interface.setopts(options)
228
- if options[:dry_run]
229
- print_dry_run @deployments_interface.dry.destroy(deployment['id'])
230
- return
231
- end
232
- json_response = @deployments_interface.destroy(deployment['id'])
233
- if options[:json]
234
- print JSON.pretty_generate(json_response)
487
+ deployment = find_deployment_by_name_or_id(args[0])
488
+ return 1 if deployment.nil?
489
+ id = args[1]
490
+
491
+ if id.to_s =~ /\A\d{1,}\Z/
492
+ id = id.to_i
493
+ else
494
+ deployment_version = find_deployment_version_by_name(deployment['id'], id)
495
+ if deployment_version
496
+ id = deployment_version['id']
235
497
  else
236
- print "\n", cyan, "Deployment #{deployment['name']} removed", reset, "\n\n"
498
+ # raise_command_error "deployment not found for '#{id}'"
499
+ return 1, "deployment version not found for '#{id}'"
237
500
  end
238
- rescue RestClient::Exception => e
239
- print_rest_exception(e, options)
240
- exit 1
241
501
  end
502
+ @deployments_interface.setopts(options)
503
+ if options[:dry_run]
504
+ print_dry_run @deployments_interface.dry.destroy(deployment['id'], params)
505
+ return
506
+ end
507
+ json_response = @deployments_interface.destroy(deployment['id'], params)
508
+ render_response(json_response, options) do
509
+ print_green_success "Removed deployment version #{deployment_version['userVersion']}"
510
+ end
511
+ return 0, nil
242
512
  end
243
513
 
244
-
245
514
  private
246
- def find_deployment_by_name_or_id(val)
247
- raise "find_deployment_by_name_or_id passed a bad name: #{val.inspect}" if val.to_s == ''
248
- results = @deployments_interface.get(val)
249
- result = nil
250
- if !results['deployments'].nil? && !results['deployments'].empty?
251
- result = results['deployments'][0]
252
- elsif val.to_i.to_s == val
253
- results = @deployments_interface.get(val.to_i)
254
- result = results['deployment']
255
- end
256
- if result.nil?
257
- print_red_alert "Deployment not found by '#{val}'"
258
- return nil
259
- end
260
- return result
515
+
516
+ def deployment_column_definitions
517
+ {
518
+ "ID" => 'id',
519
+ "Name" => 'name',
520
+ "Description" => 'description',
521
+ "Versions" => lambda {|it| it['versionCount'] },
522
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
523
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
524
+ }
525
+ end
526
+
527
+ # this is not so simple, need to first choose select instance, host or provider
528
+ def add_deployment_option_types
529
+ [
530
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
531
+ {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 1}
532
+ ]
533
+ end
534
+
535
+ def add_deployment_advanced_option_types
536
+ []
261
537
  end
262
538
 
263
- def find_deployment_type_by_name(val)
264
- raise "find_deployment_type_by_name passed a bad name: #{val.inspect}" if val.to_s == ''
265
- results = @deployments_interface.deployment_types(val)
266
- result = nil
267
- if !results['deploymentTypes'].nil? && !results['deploymentTypes'].empty?
268
- result = results['deploymentTypes'][0]
269
- elsif val.to_i.to_s == val
270
- results = @deployments_interface.deployment_types(val.to_i)
271
- result = results['deploymentType']
272
- end
273
- if result.nil?
274
- print_red_alert "Deployment Type not found by '#{val}'"
275
- return nil
276
- end
277
- return result
539
+ def update_deployment_option_types
540
+ add_deployment_option_types.collect {|it|
541
+ it.delete('required')
542
+ it.delete('defaultValue')
543
+ it
544
+ }
278
545
  end
279
546
 
280
- def update_deployment_option_types()
547
+ def update_deployment_advanced_option_types
548
+ add_deployment_advanced_option_types.collect {|it|
549
+ it.delete('required')
550
+ it.delete('defaultValue')
551
+ it
552
+ }
553
+ end
554
+
555
+ ## Deployment Versions
556
+
557
+ def deployment_version_column_definitions
558
+ {
559
+ "ID" => 'id',
560
+ "Version" => 'userVersion',
561
+ "Deploy Type" => lambda {|it| it['deployType'] },
562
+ "URL" => lambda {|it|
563
+ if it['deployType'] == 'fetch'
564
+ "#{it['fetchUrl']}"
565
+ elsif it['deployType'] == 'git'
566
+ "#{it['gitUrl']}"
567
+ end
568
+ },
569
+ "Ref" => lambda {|it|
570
+ if it['deployType'] == 'git'
571
+ "#{it['gitRef']}"
572
+ end
573
+ },
574
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
575
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
576
+ }
577
+ end
578
+
579
+ # this is not so simple, need to first choose select instance, host or provider
580
+ def add_deployment_version_option_types
281
581
  [
282
- {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 0},
283
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false, 'displayOrder' => 1}
582
+ {'fieldName' => 'userVersion', 'fieldLabel' => 'Version', 'type' => 'text', 'required' => true, 'displayOrder' => 1, 'description' => 'This is the deployment version identifier (userVersion)'},
583
+ {'fieldName' => 'deployType', 'fieldLabel' => 'Deploy Type', 'type' => 'select', 'optionSource' => 'deployTypes', 'required' => true, 'displayOrder' => 1, 'description' => 'This is the deployment version identifier (userVersion)', 'defaultValue' => 'file', 'code' => 'deployment.deployType'},
584
+ {'fieldName' => 'fetchUrl', 'fieldLabel' => 'Fetch URL', 'type' => 'select', 'optionSource' => 'deployTypes', 'required' => true, 'displayOrder' => 1, 'description' => 'The URL to fetch the deployment file(s) from.', 'dependsOnCode' => 'deployment.deployType:fetch'},
585
+ {'fieldName' => 'gitUrl', 'fieldLabel' => 'Git URL', 'type' => 'string', 'required' => true, 'displayOrder' => 1, 'description' => 'The URL to fetch the deployment file(s) from.', 'dependsOnCode' => 'deployment.deployType:git'},
586
+ {'fieldName' => 'gitRef', 'fieldLabel' => 'Git Ref', 'type' => 'string', 'displayOrder' => 1, 'description' => 'The Git Reference to use, this the branch or tag name, defaults to master.', 'dependsOnCode' => 'deployment.deployType:git'}
284
587
  ]
285
588
  end
589
+
590
+ def add_deployment_version_advanced_option_types
591
+ []
592
+ end
593
+
594
+ def update_deployment_version_option_types
595
+ add_deployment_version_option_types.collect {|it|
596
+ it.delete('required')
597
+ it.delete('defaultValue')
598
+ it
599
+ }
600
+ end
601
+
602
+ def update_deployment_version_advanced_option_types
603
+ add_deployment_version_advanced_option_types.collect {|it|
604
+ it.delete('required')
605
+ it.delete('defaultValue')
606
+ it
607
+ }
608
+ end
609
+
286
610
  end