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.
Files changed (76) 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/budgets_command.rb +4 -4
  24. data/lib/morpheus/cli/cli_command.rb +99 -41
  25. data/lib/morpheus/cli/cloud_resource_pools_command.rb +16 -0
  26. data/lib/morpheus/cli/clouds.rb +7 -10
  27. data/lib/morpheus/cli/clusters.rb +0 -18
  28. data/lib/morpheus/cli/commands/standard/benchmark_command.rb +7 -7
  29. data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
  30. data/lib/morpheus/cli/credentials.rb +13 -9
  31. data/lib/morpheus/cli/deploy.rb +374 -0
  32. data/lib/morpheus/cli/deployments.rb +521 -197
  33. data/lib/morpheus/cli/deploys.rb +271 -126
  34. data/lib/morpheus/cli/doc.rb +182 -0
  35. data/lib/morpheus/cli/error_handler.rb +23 -8
  36. data/lib/morpheus/cli/errors.rb +3 -2
  37. data/lib/morpheus/cli/image_builder_command.rb +2 -2
  38. data/lib/morpheus/cli/instances.rb +136 -17
  39. data/lib/morpheus/cli/invoices_command.rb +59 -47
  40. data/lib/morpheus/cli/jobs_command.rb +2 -2
  41. data/lib/morpheus/cli/library_instance_types_command.rb +17 -3
  42. data/lib/morpheus/cli/library_layouts_command.rb +1 -1
  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/option_source_helper.rb +1 -1
  48. data/lib/morpheus/cli/mixins/print_helper.rb +110 -74
  49. data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -2
  50. data/lib/morpheus/cli/mixins/whoami_helper.rb +19 -6
  51. data/lib/morpheus/cli/network_routers_command.rb +1 -1
  52. data/lib/morpheus/cli/option_parser.rb +48 -5
  53. data/lib/morpheus/cli/option_types.rb +1 -1
  54. data/lib/morpheus/cli/projects_command.rb +7 -7
  55. data/lib/morpheus/cli/provisioning_licenses_command.rb +2 -2
  56. data/lib/morpheus/cli/remote.rb +3 -2
  57. data/lib/morpheus/cli/roles.rb +49 -92
  58. data/lib/morpheus/cli/security_groups.rb +7 -1
  59. data/lib/morpheus/cli/service_plans_command.rb +10 -10
  60. data/lib/morpheus/cli/setup.rb +1 -1
  61. data/lib/morpheus/cli/shell.rb +7 -6
  62. data/lib/morpheus/cli/subnets_command.rb +1 -1
  63. data/lib/morpheus/cli/tasks.rb +24 -10
  64. data/lib/morpheus/cli/tenants_command.rb +133 -163
  65. data/lib/morpheus/cli/user_groups_command.rb +20 -65
  66. data/lib/morpheus/cli/user_settings_command.rb +115 -13
  67. data/lib/morpheus/cli/user_sources_command.rb +57 -24
  68. data/lib/morpheus/cli/users.rb +210 -186
  69. data/lib/morpheus/cli/version.rb +1 -1
  70. data/lib/morpheus/cli/whitelabel_settings_command.rb +29 -5
  71. data/lib/morpheus/cli/whoami.rb +113 -6
  72. data/lib/morpheus/cli/workflows.rb +11 -8
  73. data/lib/morpheus/ext/hash.rb +21 -0
  74. data/lib/morpheus/terminal.rb +1 -0
  75. metadata +12 -3
  76. data/lib/morpheus/cli/auth_command.rb +0 -105
@@ -0,0 +1,374 @@
1
+ require 'morpheus/cli/cli_command'
2
+ require 'yaml'
3
+
4
+ class Morpheus::Cli::Deploy
5
+ include Morpheus::Cli::CliCommand
6
+ include Morpheus::Cli::DeploymentsHelper
7
+
8
+ set_command_name :deploy
9
+
10
+ def connect(opts)
11
+ @api_client = establish_remote_appliance_connection(opts)
12
+ @instances_interface = @api_client.instances
13
+ @deploy_interface = @api_client.deploy
14
+ @deployments_interface = @api_client.deployments
15
+ end
16
+
17
+ def handle(args)
18
+ options={}
19
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
20
+ opts.banner = "Usage: morpheus deploy [environment]"
21
+ build_common_options(opts, options, [:auto_confirm, :remote, :dry_run])
22
+ opts.footer = <<-EOT
23
+ Deploy to an instance using the morpheus.yml file, located in the working directory.
24
+ [environment] is optional. Merge settings under environments.{environment}. Default is no environment.
25
+
26
+ First this parses the morpheus.yml file and merges the specified environment settings.
27
+ The specified instance must exist and the specified version must not exist.
28
+ If the settings are valid, the new deployment version will be created and
29
+ all the specified files are uploaded to the new deployment version.
30
+ Finally, it deploys the new version to the instance.
31
+
32
+ The morpheus.yml should be located in the working directory.
33
+ This file contains the information necessary to perform a deployment via the cli.
34
+
35
+ File Settings
36
+ ==================
37
+
38
+ * name - (required) The instance name we are deploying to and, by default, name of the deployment being created.
39
+ * version - (required) The version identifier of the deployment being created (userVersion)
40
+ * deployment - The name of the deployment being created, name is used by default
41
+ * script - The initial script to run before looking for files to upload.
42
+ * files - List of file patterns to use for uploading files and their target destination.
43
+ Each item should contain path and pattern, path may be relative to the working directory, default pattern is: '**/*'
44
+ * options - Map of deployment options depending on deployment type
45
+ * post_script - A post operation script to be run on the local machine
46
+ * stage_only - If set to true the deploy will only be staged and not actually run
47
+ * environments - Map of objects that contain nested properties for each environment name
48
+
49
+ It is possible to nest these properties in an "environments" map to override based on a passed environment.
50
+
51
+ Example
52
+ ==================
53
+
54
+ name: neatsite
55
+ version: 5.0
56
+ script: "rake build"
57
+ files:
58
+ - path: build
59
+ environments:
60
+ production:
61
+ files:
62
+ - path: production-build
63
+ EOT
64
+ end
65
+ optparse.parse!(args)
66
+ verify_args!(args:args, optparse:optparse, min:0, max:1)
67
+ options[:options]['name'] = args[0] if args[0]
68
+ connect(options)
69
+ payload = {}
70
+
71
+ environment = default_deploy_environment
72
+ if args.count > 0
73
+ environment = args[0]
74
+ end
75
+ if load_deploy_file().nil?
76
+ raise_command_error "Morpheus Deploy File `morpheus.yml` not detected. Please create one and try again."
77
+ end
78
+
79
+ # Parse and validate config, need instance + deployment + version + files
80
+ # name can be specified as a single value for both instance and deployment
81
+
82
+ deploy_args = merged_deploy_args(environment)
83
+
84
+ instance_name = deploy_args['name']
85
+ if deploy_args['instance'].is_a?(String)
86
+ instance_name = deploy_args['instance']
87
+ end
88
+ if instance_name.nil?
89
+ raise_command_error "Instance not specified. Please specify the instance name and try again."
90
+ end
91
+
92
+ deployment_name = deploy_args['name'] || instance_name
93
+ if deploy_args['deployment'].is_a?(String)
94
+ deployment_name = deploy_args['deployment']
95
+ end
96
+
97
+ version_number = deploy_args['version']
98
+ if version_number.nil?
99
+ raise_command_error "Version not specified. Please specify the version and try again."
100
+ end
101
+
102
+ instance_results = @instances_interface.list(name: instance_name)
103
+ if instance_results['instances'].empty?
104
+ raise_command_error "Instance not found by name '#{instance_name}'"
105
+ end
106
+ instance = instance_results['instances'][0]
107
+ instance_id = instance['id']
108
+
109
+ # ok do it
110
+ # fetch/create deployment, create deployment version, upload files, and deploy it to instance.
111
+
112
+ print_h1 "Morpheus Deployment"
113
+
114
+ columns = {
115
+ "Instance" => :name,
116
+ "Deployment" => :deployment,
117
+ "Version" => :version,
118
+ "Script" => :script,
119
+ "Post Script" => :post_script,
120
+ "Files" => :files,
121
+ "Environment" => :environment,
122
+ }
123
+ pretty_file_config = deploy_args['files'].collect {|it|
124
+ [(it['path'] ? "path: #{it['path']}" : nil), (it['pattern'] ? "pattern: #{it['pattern']}" : nil)].compact.join(", ")
125
+ }.join(", ")
126
+ deploy_settings = {
127
+ :name => instance_name,
128
+ :deployment => deployment_name,
129
+ :version => version_number,
130
+ :script => deploy_args['script'],
131
+ :post_script => deploy_args['post_script'],
132
+ :files => pretty_file_config,
133
+ # :files => deploy_args['files'],
134
+ # :files => deploy_files.size,
135
+ # :file_config => (deploy_files.size == 1 ? deploy_files[0][:destination] : deploy_args['files'])
136
+ :environment => environment
137
+ }
138
+ columns.delete("Script") if deploy_settings[:script].nil?
139
+ columns.delete("Post Script") if deploy_settings[:post_script].nil?
140
+ columns.delete("Environment") if deploy_settings[:environment].nil?
141
+ print_description_list(columns, deploy_settings)
142
+ print reset, "\n"
143
+
144
+ if !deploy_args['script'].nil?
145
+ # do this for dry run too since this is usually what creates the files to be uploaded
146
+ print cyan, "Executing Pre Deploy Script...", reset, "\n"
147
+ puts "running command: #{deploy_args['script']}"
148
+ if !system(deploy_args['script'])
149
+ raise_command_error "Error executing pre script..."
150
+ end
151
+ end
152
+
153
+ # Find Files to Upload
154
+ deploy_files = []
155
+ if deploy_args['files'].nil? || deploy_args['files'].empty? || !deploy_args['files'].is_a?(Array)
156
+ raise_command_error "Files not specified. Please specify files array, each item may specify a path or pattern of file(s) to upload"
157
+ else
158
+ #print "\n",cyan, "Finding Files...", reset, "\n"
159
+ current_working_dir = Dir.pwd
160
+ deploy_args['files'].each do |fmap|
161
+ Dir.chdir(fmap['path'] || current_working_dir)
162
+ files = Dir.glob(fmap['pattern'] || '**/*')
163
+ files.each do |file|
164
+ if File.file?(file)
165
+ destination = file.split("/")[0..-2].join("/")
166
+ # deploy_files << {filepath: File.expand_path(file), destination: destination}
167
+ deploy_files << {filepath: File.expand_path(file), destination: file}
168
+ end
169
+ end
170
+ end
171
+ #print cyan, "Found #{deploy_files.size} Files to Upload!", reset, "\n"
172
+ Dir.chdir(current_working_dir)
173
+ end
174
+
175
+ if deploy_files.empty?
176
+ raise_command_error "0 files found for: #{deploy_args['files'].inspect}"
177
+ else
178
+ print cyan, "Found #{deploy_files.size} Files to Upload!", reset, "\n"
179
+ end
180
+
181
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to create deployment version #{version_number} (#{deploy_files.size} #{deploy_files.size == 1 ? 'file' : 'files'}) and deploy it to instance #{instance['name']}?")
182
+ return 9, "aborted command"
183
+ end
184
+
185
+ # Find or Create Deployment
186
+ deployment = nil
187
+ deployments = @deployments_interface.list(name: deployment_name)['deployments']
188
+
189
+ @instances_interface.setopts(options)
190
+ @deploy_interface.setopts(options)
191
+ @deployments_interface.setopts(options)
192
+
193
+ if deployments.size > 1
194
+ raise_command_error "#{deployments.size} deployment versions found by deployment '#{name}'"
195
+ elsif deployments.size == 1
196
+ deployment = deployments[0]
197
+ # should update here, eg description
198
+ else
199
+ # create it
200
+ payload = {
201
+ 'deployment' => {
202
+ 'name' => deployment_name
203
+ }
204
+ }
205
+ payload['deployment']['description'] = deploy_args['description'] if deploy_args['description']
206
+
207
+ if options[:dry_run]
208
+ print_dry_run @deployments_interface.dry.create(payload)
209
+ # return 0, nil
210
+ deployment = {'id' => ':deploymentId', 'name' => deployment_name}
211
+ else
212
+ json_response = @deployments_interface.create(payload)
213
+ deployment = json_response['deployment']
214
+ end
215
+ end
216
+
217
+ # Find or Create Deployment Version
218
+ # Actually, for now this this errors if the version already exists, but it should update it.
219
+
220
+ @deployments_interface = @api_client.deployments
221
+ deployment_version = nil
222
+ if options[:dry_run]
223
+ print_dry_run @deployments_interface.dry.list_versions(deployment['id'], {userVersion: version_number})
224
+ # return 0, nil
225
+ #deployment_versions =[{'id' => ':versionId', 'version' => version_number}]
226
+ deployment_versions = []
227
+ else
228
+ deployment_versions = @deployments_interface.list_versions(deployment['id'], {userVersion: version_number})['versions']
229
+ @deployments_interface.setopts(options)
230
+ end
231
+
232
+
233
+ if deployment_versions.size > 0
234
+ raise_command_error "Deployment '#{deployment['name']}' version '#{version_number}' already exists. Specify a new version or delete the existing version."
235
+ # if deployment_versions.size > 1
236
+ # raise_command_error "#{deployment_versions.size} versions found by version '#{name}'"
237
+ # elsif deployment_versions.size == 1
238
+ # deployment_version = deployment_versions[0]
239
+ # # should update here, eg description
240
+ else
241
+ # create it
242
+ payload = {
243
+ 'version' => {
244
+ 'userVersion' => version_number,
245
+ 'deployType' => (deploy_args['type'] || deploy_args['deployType'] || 'file')
246
+ }
247
+ }
248
+ payload['version']['fetchUrl'] = deploy_args['fetchUrl'] if deploy_args['fetchUrl']
249
+ payload['version']['gitUrl'] = deploy_args['gitUrl'] if deploy_args['gitUrl']
250
+ payload['version']['gitRef'] = deploy_args['gitRef'] if deploy_args['gitRef']
251
+
252
+ if options[:dry_run]
253
+ print_dry_run @deployments_interface.dry.create_version(deployment['id'], payload)
254
+ # return 0, nil
255
+ deployment_version = {'id' => ':versionId', 'version' => version_number}
256
+ else
257
+ json_response = @deployments_interface.create_version(deployment['id'], payload)
258
+ deployment_version = json_response['version']
259
+ end
260
+ end
261
+
262
+
263
+ # Upload Files
264
+ if deploy_files && !deploy_files.empty?
265
+ print "\n",cyan, "Uploading #{deploy_files.size} Files...", reset, "\n"
266
+ current_working_dir = Dir.pwd
267
+ deploy_files.each do |f|
268
+ destination = f[:destination]
269
+ if options[:dry_run]
270
+ print_dry_run @deployments_interface.upload_file(deployment['id'], deployment_version['id'], f[:filepath], f[:destination])
271
+ else
272
+ print cyan," - Uploading #{f[:destination]} ...", reset if !options[:quiet]
273
+ upload_result = @deployments_interface.upload_file(deployment['id'], deployment_version['id'], f[:filepath], f[:destination])
274
+ #print green + "SUCCESS" + reset + "\n" if !options[:quiet]
275
+ print reset, "\n" if !options[:quiet]
276
+ end
277
+ end
278
+ print cyan, "Upload Complete!", reset, "\n"
279
+ Dir.chdir(current_working_dir)
280
+ else
281
+ print "\n",cyan, "0 files to upload", reset, "\n"
282
+ end
283
+
284
+ # TODO: support deploying other deployTypes too, git and fetch
285
+
286
+ if !deploy_args['post_script'].nil?
287
+ print cyan, "Executing Post Script...", reset, "\n"
288
+ puts "running command: #{deploy_args['post_script']}"
289
+ if !system(deploy_args['post_script'])
290
+ raise_command_error "Error executing post script..."
291
+ end
292
+ end
293
+
294
+ # JD: restart for evars eh?
295
+ if deploy_args['env']
296
+ evars = []
297
+ deploy_args['env'].each_pair do |key, value|
298
+ evars << {name: key, value: value, export: false}
299
+ end
300
+ payload = {envs: evars}
301
+ if options[:dry_run]
302
+ print_dry_run @instances_interface.dry.create_env(instance_id, payload)
303
+ print_dry_run @instances_interface.dry.restart(instance_id)
304
+ else
305
+ @instances_interface.create_env(instance_id, payload)
306
+ @instances_interface.restart(instance_id)
307
+ end
308
+ end
309
+ # Create the AppDeploy, this does the deploy async (as of 4.2.2-3)
310
+ payload = {'appDeploy' => {} }
311
+ payload['appDeploy']['versionId'] = deployment_version['id']
312
+ if deploy_args['options']
313
+ payload['appDeploy']['config'] = deploy_args['options']
314
+ end
315
+ # stageOnly means do not actually deploy yet, can invoke @deploy_interface.deploy(deployment['id']) later
316
+ # there is no cli command for that yet though..
317
+ stage_only = deploy_args['stage_deploy'] || deploy_args['stage_only'] || deploy_args['stageOnly']
318
+ if stage_only
319
+ payload['appDeploy']['stageOnly'] = true
320
+ end
321
+ app_deploy_id = nil
322
+ if options[:dry_run]
323
+ print_dry_run @deploy_interface.dry.create(instance_id, payload)
324
+ # return 0, nil
325
+ app_deploy_id = ':appDeployId'
326
+ else
327
+ # Create a new appDeploy record, without stageOnly, this actually does the deployment
328
+ print cyan, "Deploying #{deployment_name} version #{version_number} to instance #{instance_name} ...", reset, "\n"
329
+ deploy_result = @deploy_interface.create(instance_id, payload)
330
+ app_deploy = deploy_result['appDeploy']
331
+ app_deploy_id = app_deploy['id']
332
+ print_green_success "Deploy Successful!"
333
+ end
334
+ return 0, nil
335
+ end
336
+
337
+ protected
338
+
339
+ # Loads a morpheus.yml file from within the current working directory.
340
+ # This file contains information necessary to perform a deployment via the cli.
341
+ #
342
+ # === Example File Attributes
343
+ # * +script+ - The initial script to run before uploading files
344
+ # * +name+ - The instance name we are deploying to (can be overridden in CLI)
345
+ # * +files+ - List of file patterns to use for uploading files and their target destination
346
+ # * +options+ - Map of deployment options depending on deployment type
347
+ # * +post_script+ - A post operation script to be run on the local machine
348
+ # * +stage_deploy+ - If set to true the deploy will only be staged and not actually run
349
+ #
350
+ # +NOTE: + It is also possible to nest these properties in an "environments" map to override based on a passed environment deploy name
351
+ #
352
+ def load_deploy_file
353
+ if !File.exist? "morpheus.yml"
354
+ puts "No morpheus.yml file detected in the current directory. Nothing to do."
355
+ return nil
356
+ end
357
+
358
+ @deploy_file = YAML.load_file("morpheus.yml")
359
+ return @deploy_file
360
+ end
361
+
362
+ def merged_deploy_args(environment)
363
+ deploy_args = @deploy_file.reject { |key,value| key == 'environment'}
364
+ if environment && !@deploy_file['environment'].nil? && !@deploy_file['environment'][environment].nil?
365
+ deploy_args = deploy_args.merge(@deploy_file['environment'][environment])
366
+ end
367
+ return deploy_args
368
+ end
369
+
370
+ def default_deploy_environment
371
+ nil
372
+ end
373
+
374
+ end
@@ -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 { |api_client, api_params|
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