morpheus-cli 3.5.3 → 3.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23cf1069887e9d9fc379bb4c5d542ffaf746fb045ba394b281f1bcbe2f6979e0
4
- data.tar.gz: 544bb68d0fc395fa8d6a76391028641e564d37f9f6f82c515d763420e83230bb
3
+ metadata.gz: b8bc4a83d010a1cdbb2fc481c135ebf974d81e68f5805a34fcac5cfce5f8d601
4
+ data.tar.gz: 964c7254ac780580a9597e904b72f9453c30d181f56738daa254876310dbd58c
5
5
  SHA512:
6
- metadata.gz: '09147a460130571ad8a3f30e5e7062b290425d11c9dbf30f14ae5dedf4e99cd821b5fde46b6c3f69c1bd4eb3d2c4477a9df2ae5f766164fda7e99173bb9d877f'
7
- data.tar.gz: 0d0775dd6ff2b7e9e670a295d44b2fe60e68095cc74df2b6cbd75d5dca3e2ea40e9378f5129fdf86bedae1ec9a1d0d667732ea50eaf03caf45d8c31837c0dc7d
6
+ metadata.gz: ccc67373869029704d83ceca978898b3e02ca2236f2697c654d7dd43227a08157b1a1a41d26e81228ce8dff1d4da88ed491dbd7a7e514f6785f4b4013a27aff7
7
+ data.tar.gz: bc2377f5c747c0ee19c6a71a8104af9e52a73eadc1f55de05d0cbdb7a5f0320c17a370e06e86c85d60d6ff6533f130a16e7acbbd52f21c503dfa6e1a8aa6854f
@@ -315,6 +315,10 @@ class Morpheus::APIClient
315
315
  Morpheus::ExecutionRequestInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
316
316
  end
317
317
 
318
+ def file_copy_request
319
+ Morpheus::FileCopyRequestInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
320
+ end
321
+
318
322
  def processes
319
323
  Morpheus::ProcessesInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
320
324
  end
@@ -0,0 +1,76 @@
1
+ require 'morpheus/api/api_client'
2
+ require 'uri'
3
+
4
+ class Morpheus::FileCopyRequestInterface < Morpheus::APIClient
5
+ def initialize(access_token, refresh_token, expires_at = nil, base_url=nil)
6
+ @access_token = access_token
7
+ @refresh_token = refresh_token
8
+ @base_url = base_url
9
+ @expires_at = expires_at
10
+ end
11
+
12
+ def get(id, params={})
13
+ raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
14
+ url = "#{@base_url}/api/file-copy-request/#{id}"
15
+ headers = { :params => params, authorization: "Bearer #{@access_token}"}
16
+ opts = {method: :get, url: url, headers: headers}
17
+ execute(opts)
18
+ end
19
+
20
+ def create(local_file, params={})
21
+ # puts "upload_file #{local_file} to destination #{destination}"
22
+ if !local_file.kind_of?(File)
23
+ local_file = File.new(local_file, 'rb')
24
+ end
25
+ url = "#{@base_url}/api/file-copy-request/execute"
26
+ headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/octet-stream'}
27
+ headers[:params][:filename] = File.basename(local_file)
28
+ payload = local_file
29
+ headers['Content-Length'] = local_file.size # File.size(local_file)
30
+ execute(method: :post, url: url, headers: headers, payload: payload)
31
+ end
32
+
33
+ def execute_against_lease(id, local_file, params)
34
+ # puts "upload_file #{local_file} to destination #{destination}"
35
+ if !local_file.kind_of?(File)
36
+ local_file = File.new(local_file, 'rb')
37
+ end
38
+ url = "#{@base_url}/api/file-copy-request/lease/#{URI.escape(id)}"
39
+ headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/octet-stream'}
40
+ headers[:params][:filename] = File.basename(local_file)
41
+ payload = local_file
42
+ headers['Content-Length'] = local_file.size # File.size(local_file)
43
+ execute(method: :post, url: url, headers: headers, payload: payload)
44
+ end
45
+
46
+ def download_file_chunked(id, outfile, params={})
47
+ raise "#{self.class}.download_file() passed a blank id!" if id.to_s == ''
48
+ url = "#{@base_url}/api/file-copy-request/download/#{URI.escape(id)}"
49
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
50
+ opts = {method: :get, url: url, headers: headers}
51
+ # execute(opts, false)
52
+ if Dir.exists?(outfile)
53
+ raise "outfile is invalid. It is the name of an existing directory: #{outfile}"
54
+ end
55
+ # if @verify_ssl == false
56
+ # opts[:verify_ssl] = OpenSSL::SSL::VERIFY_NONE
57
+ # end
58
+ if @dry_run
59
+ return opts
60
+ end
61
+ http_response = nil
62
+ File.open(outfile, 'w') {|f|
63
+ block = proc { |response|
64
+ response.read_body do |chunk|
65
+ # writing to #{outfile} ..."
66
+ f.write chunk
67
+ end
68
+ }
69
+ opts[:block_response] = block
70
+ http_response = RestClient::Request.new(opts).execute
71
+ # RestClient::Request.execute(opts)
72
+ }
73
+ return http_response
74
+ end
75
+
76
+ end
@@ -51,6 +51,13 @@ class Morpheus::MonitoringAppsInterface < Morpheus::APIClient
51
51
  execute(opts)
52
52
  end
53
53
 
54
+ def quarantine_all(payload={})
55
+ url = "#{@base_url}/api/monitoring/apps/quarantine-all"
56
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
57
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
58
+ execute(opts)
59
+ end
60
+
54
61
  def statistics(id, params={})
55
62
  url = "#{@base_url}/api/monitoring/apps/#{id}/statistics"
56
63
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -53,6 +53,14 @@ class Morpheus::MonitoringChecksInterface < Morpheus::APIClient
53
53
  execute(opts)
54
54
  end
55
55
 
56
+ def quarantine_all(options={})
57
+ url = "#{@base_url}/api/monitoring/checks/quarantine-all"
58
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
59
+ payload = options
60
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
61
+ execute(opts)
62
+ end
63
+
56
64
  def history(id, params={})
57
65
  url = "#{@base_url}/api/monitoring/checks/#{id}/history"
58
66
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -51,6 +51,13 @@ class Morpheus::MonitoringGroupsInterface < Morpheus::APIClient
51
51
  execute(opts)
52
52
  end
53
53
 
54
+ def quarantine_all(payload={})
55
+ url = "#{@base_url}/api/monitoring/groups/quarantine-all"
56
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
57
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
58
+ execute(opts)
59
+ end
60
+
54
61
  def history(id, params={})
55
62
  url = "#{@base_url}/api/monitoring/groups/#{id}/history"
56
63
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -72,8 +72,11 @@ class Morpheus::MonitoringIncidentsInterface < Morpheus::APIClient
72
72
  execute(opts)
73
73
  end
74
74
 
75
- def mute(id, payload={})
76
- quarantine(id, payload)
75
+ def quarantine_all(payload={})
76
+ url = "#{@base_url}/api/monitoring/incidents/quarantine-all"
77
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
78
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
79
+ execute(opts)
77
80
  end
78
81
 
79
82
  def history(id, params={})
data/lib/morpheus/cli.rb CHANGED
@@ -148,6 +148,7 @@ module Morpheus
148
148
  load 'morpheus/cli/archives_command.rb'
149
149
  load 'morpheus/cli/storage_providers_command.rb'
150
150
  load 'morpheus/cli/execution_request_command.rb'
151
+ load 'morpheus/cli/file_copy_request_command.rb'
151
152
  load 'morpheus/cli/processes_command.rb'
152
153
 
153
154
  # nice to have commands
@@ -100,7 +100,9 @@ module Morpheus
100
100
  rescue ::RestClient::Exception => e
101
101
  #raise e
102
102
  if (e.response && e.response.code == 400)
103
- print_red_alert "Credentials not verified."
103
+ json_response = JSON.parse(e.response.to_s)
104
+ error_msg = json_response['error_description'] || "Credentials not verified."
105
+ print_red_alert error_msg
104
106
  if opts[:json]
105
107
  json_response = JSON.parse(e.response.to_s)
106
108
  print JSON.pretty_generate(json_response)
@@ -0,0 +1,354 @@
1
+ require 'morpheus/cli/cli_command'
2
+ # require 'morpheus/cli/mixins/provisioning_helper'
3
+ # require 'morpheus/cli/mixins/infrastructure_helper'
4
+
5
+ class Morpheus::Cli::FileCopyRequestCommand
6
+ include Morpheus::Cli::CliCommand
7
+ # include Morpheus::Cli::InfrastructureHelper
8
+ # include Morpheus::Cli::ProvisioningHelper
9
+
10
+ set_command_name :'file-copy-request'
11
+
12
+ register_subcommands :get, :execute, :download
13
+ #register_subcommands :'execute-against-lease' => :execute_against_lease
14
+
15
+ # set_default_subcommand :list
16
+
17
+ def initialize()
18
+ # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
19
+ end
20
+
21
+ def connect(opts)
22
+ @api_client = establish_remote_appliance_connection(opts)
23
+ # @instances_interface = @api_client.instances
24
+ # @containers_interface = @api_client.containers
25
+ # @servers_interface = @api_client.servers
26
+ @file_copy_request_interface = @api_client.file_copy_request
27
+ end
28
+
29
+ def handle(args)
30
+ handle_subcommand(args)
31
+ end
32
+
33
+ def get(args)
34
+ raw_args = args
35
+ options = {}
36
+ params = {}
37
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
38
+ opts.banner = subcommand_usage("[uid]")
39
+ build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
40
+ opts.on('--refresh', String, "Refresh until file copy is finished.") do |val|
41
+ options[:refresh_until_finished] = true
42
+ end
43
+ opts.on('--refresh-interval seconds', String, "Refresh interval. Default is 5 seconds.") do |val|
44
+ options[:refresh_interval] = val.to_f
45
+ end
46
+ opts.footer = "Get details about a file copy request." + "\n" +
47
+ "[uid] is required. This is the unique id of a file copy request."
48
+ end
49
+ optparse.parse!(args)
50
+ connect(options)
51
+ if args.count != 1
52
+ print_error Morpheus::Terminal.angry_prompt
53
+ puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
54
+ return 1
55
+ end
56
+ file_copy_request_id = args[0]
57
+ begin
58
+ params.merge!(parse_list_options(options))
59
+ if options[:dry_run]
60
+ print_dry_run @file_copy_request_interface.dry.get(file_copy_request_id, params)
61
+ return
62
+ end
63
+ json_response = @file_copy_request_interface.get(file_copy_request_id, params)
64
+ if options[:json]
65
+ puts as_json(json_response, options, "fileCopyRequest")
66
+ return 0
67
+ elsif options[:yaml]
68
+ puts as_yaml(json_response, options, "fileCopyRequest")
69
+ return 0
70
+ elsif options[:csv]
71
+ puts records_as_csv([json_response['fileCopyRequest']], options)
72
+ return 0
73
+ end
74
+
75
+ file_copy_request = json_response['fileCopyRequest']
76
+
77
+ # refresh until a status is reached
78
+ if options[:refresh_until_finished]
79
+ if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
80
+ options[:refresh_interval] = 5
81
+ end
82
+ if ['complete','failed','expired'].include?(file_copy_request['status'])
83
+ # it is finished
84
+ else
85
+ print cyan
86
+ print "File copy request has not yet finished. Refreshing every #{options[:refresh_interval]} seconds"
87
+ while !['complete','failed','expired'].include?(file_copy_request['status']) do
88
+ sleep(options[:refresh_interval])
89
+ print cyan,".",reset
90
+ json_response = @file_copy_request_interface.get(file_copy_request_id, params)
91
+ file_copy_request = json_response['fileCopyRequest']
92
+ end
93
+ #sleep_with_dots(options[:refresh_interval])
94
+ print "\n", reset
95
+ # get(raw_args)
96
+ end
97
+ end
98
+
99
+ print_h1 "File Copy Request Details"
100
+ print cyan
101
+ description_cols = {
102
+ #"ID" => lambda {|it| it['id'] },
103
+ "Unique ID" => lambda {|it| it['uniqueId'] },
104
+ "Server ID" => lambda {|it| it['serverId'] },
105
+ "Instance ID" => lambda {|it| it['instanceId'] },
106
+ "Container ID" => lambda {|it| it['containerId'] },
107
+ "Expires At" => lambda {|it| format_local_dt it['expiresAt'] },
108
+ #"Exit Code" => lambda {|it| it['exitCode'] },
109
+ "Status" => lambda {|it| format_file_copy_request_status(it) },
110
+ #"Created By" => lambda {|it| it['createdById'] },
111
+ #"Subdomain" => lambda {|it| it['subdomain'] },
112
+ }
113
+ print_description_list(description_cols, file_copy_request)
114
+
115
+ if file_copy_request['stdErr']
116
+ print_h2 "Error"
117
+ puts file_copy_request['stdErr'].to_s.strip
118
+ end
119
+ if file_copy_request['stdOut']
120
+ print_h2 "Output"
121
+ puts file_copy_request['stdOut'].to_s.strip
122
+ end
123
+ print reset, "\n"
124
+ return 0
125
+ rescue RestClient::Exception => e
126
+ print_rest_exception(e, options)
127
+ return 1
128
+ end
129
+ end
130
+
131
+ def execute(args)
132
+ options = {}
133
+ params = {}
134
+ script_content = nil
135
+ do_refresh = true
136
+ filename = nil
137
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
138
+ opts.banner = subcommand_usage("[options]")
139
+ opts.on('--server ID', String, "Server ID") do |val|
140
+ params['serverId'] = val
141
+ end
142
+ opts.on('--instance ID', String, "Instance ID") do |val|
143
+ params['instanceId'] = val
144
+ end
145
+ opts.on('--container ID', String, "Container ID") do |val|
146
+ params['containerId'] = val
147
+ end
148
+ opts.on('--request ID', String, "File Copy Request ID") do |val|
149
+ params['requestId'] = val
150
+ end
151
+ opts.on('--file FILE', "Local file to be copied." ) do |val|
152
+ filename = val
153
+ end
154
+ opts.on('--target-path PATH', "Target path for file on destination host." ) do |val|
155
+ params['targetPath'] = val
156
+ end
157
+ opts.on(nil, '--no-refresh', "Do not refresh until finished" ) do
158
+ do_refresh = false
159
+ end
160
+ #build_option_type_options(opts, options, add_user_source_option_types())
161
+ build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
162
+ opts.footer = "Copy a file to a remote host(s)." + "\n" +
163
+ "[server] or [instance] or [container] is required. This is the id of a server, instance or container." + "\n" +
164
+ "[file] is required. This is the local filename that is to be copied." + "\n" +
165
+ "[target-path] is required. This is the target path for the file on the destination host."
166
+ end
167
+ optparse.parse!(args)
168
+ connect(options)
169
+ if args.count != 0
170
+ print_error Morpheus::Terminal.angry_prompt
171
+ puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
172
+ return 1
173
+ end
174
+ if params['serverId'].nil? && params['instanceId'].nil? && params['containerId'].nil? && params['requestId'].nil?
175
+ puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: --server or --instance or --container\n#{optparse}"
176
+ return 1
177
+ end
178
+ # if filename.nil?
179
+ # puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: --file\n#{optparse}"
180
+ # return 1
181
+ # end
182
+ # if params['targetPath'].nil?
183
+ # puts_error "#{Morpheus::Terminal.angry_prompt}missing required option: --target-path\n#{optparse}"
184
+ # return 1
185
+ # end
186
+ begin
187
+ # construct payload
188
+ params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
189
+ full_filename = nil
190
+ if filename.nil?
191
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'file', 'type' => 'file', 'fieldLabel' => 'File', 'required' => true, 'description' => 'The local file to be copied'}], options[:options])
192
+ filename = v_prompt['file']
193
+ end
194
+ full_filename = File.expand_path(filename)
195
+ if !File.exists?(full_filename)
196
+ print_red_alert "File not found: #{full_filename}"
197
+ return 1
198
+ end
199
+ local_file = File.new(full_filename, 'rb')
200
+
201
+ if params['targetPath'].nil?
202
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'targetPath', 'type' => 'text', 'fieldLabel' => 'Target Path', 'required' => true, 'description' => 'The target path for the file on the destination host.'}], options[:options])
203
+ params['targetPath'] = v_prompt['targetPath']
204
+ end
205
+
206
+ # dry run?
207
+ if options[:dry_run]
208
+ print_dry_run @file_copy_request_interface.dry.create(local_file, params)
209
+ return 0
210
+ end
211
+ # do it
212
+ json_response = @file_copy_request_interface.create(local_file, params)
213
+ # print and return result
214
+ if options[:quiet]
215
+ return 0
216
+ elsif options[:json]
217
+ puts as_json(json_response, options)
218
+ return 0
219
+ end
220
+ file_copy_request = json_response['fileCopyRequest']
221
+ print_green_success "Executing file copy request #{file_copy_request['uniqueId']}"
222
+ if do_refresh
223
+ get([file_copy_request['uniqueId'], "--refresh"])
224
+ else
225
+ get([file_copy_request['uniqueId']])
226
+ end
227
+ return 0
228
+ rescue RestClient::Exception => e
229
+ print_rest_exception(e, options)
230
+ exit 1
231
+ end
232
+ end
233
+
234
+ def download(args)
235
+ options = {}
236
+ params = {}
237
+ script_content = nil
238
+ filename = nil
239
+ do_overwrite = false
240
+ do_mkdir = false
241
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
242
+ opts.banner = subcommand_usage("[uid] [file]")
243
+ opts.on('--file FILE', "Local file destination for the downloaded file." ) do |val|
244
+ filename = val
245
+ end
246
+ opts.on( '-f', '--force', "Overwrite existing [file] if it exists." ) do
247
+ do_overwrite = true
248
+ # do_mkdir = true
249
+ end
250
+ opts.on( '-p', '--mkdir', "Create missing directories for [file] if they do not exist." ) do
251
+ do_mkdir = true
252
+ end
253
+ #build_option_type_options(opts, options, add_user_source_option_types())
254
+ build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
255
+ opts.footer = "Download a file associated with a file copy request." + "\n" +
256
+ "[uid] is required. This is the unique id of a file copy request." + "\n" +
257
+ "[file] is required. This is the full local filepath for the downloaded file."
258
+ end
259
+ optparse.parse!(args)
260
+ connect(options)
261
+ if args.count < 1 || args.count > 2
262
+ print_error Morpheus::Terminal.angry_prompt
263
+ puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
264
+ return 1
265
+ end
266
+ file_copy_request_id = args[0]
267
+ if args[1]
268
+ filename = args[1]
269
+ end
270
+ outfile = File.expand_path(filename)
271
+ if Dir.exists?(outfile)
272
+ print_red_alert "[file] is invalid. It is the name of an existing directory: #{outfile}"
273
+ return 1
274
+ end
275
+ destination_dir = File.dirname(outfile)
276
+ if !Dir.exists?(destination_dir)
277
+ if do_mkdir
278
+ print cyan,"Creating local directory #{destination_dir}",reset,"\n"
279
+ FileUtils.mkdir_p(destination_dir)
280
+ else
281
+ print_red_alert "[file] is invalid. Directory not found: #{destination_dir}"
282
+ return 1
283
+ end
284
+ end
285
+ if File.exists?(outfile)
286
+ if do_overwrite
287
+ # uhh need to be careful wih the passed filepath here..
288
+ # don't delete, just overwrite.
289
+ # File.delete(outfile)
290
+ else
291
+ print_error Morpheus::Terminal.angry_prompt
292
+ puts_error "[file] is invalid. File already exists: #{outfile}", "Use -f to overwrite the existing file."
293
+ # puts_error optparse
294
+ return 1
295
+ end
296
+ end
297
+ begin
298
+ # construct payload
299
+
300
+ # dry run?
301
+ if options[:dry_run]
302
+ print_dry_run @file_copy_request_interface.dry.download_file_chunked(file_copy_request_id, outfile, params)
303
+ return 0
304
+ end
305
+ # do it
306
+
307
+ if !options[:quiet]
308
+ print cyan + "Downloading file copy request #{file_copy_request_id} to #{outfile} ... "
309
+ end
310
+
311
+ http_response = @file_copy_request_interface.download_file_chunked(file_copy_request_id, outfile, params)
312
+
313
+ # FileUtils.chmod(0600, outfile)
314
+ success = http_response.code.to_i == 200
315
+ if success
316
+ if !options[:quiet]
317
+ print green + "SUCCESS" + reset + "\n"
318
+ end
319
+ return 0
320
+ else
321
+ if !options[:quiet]
322
+ print red + "ERROR" + reset + " HTTP #{http_response.code}" + "\n"
323
+ end
324
+ # F it, just remove a bad result
325
+ if File.exists?(outfile) && File.file?(outfile)
326
+ Morpheus::Logging::DarkPrinter.puts "Deleting bad file download: #{outfile}" if Morpheus::Logging.debug?
327
+ File.delete(outfile)
328
+ end
329
+ if options[:debug]
330
+ puts_error http_response.inspect
331
+ end
332
+ return 1
333
+ end
334
+
335
+ rescue RestClient::Exception => e
336
+ print_rest_exception(e, options)
337
+ exit 1
338
+ end
339
+ end
340
+
341
+ def format_file_copy_request_status(file_copy_request, return_color=cyan)
342
+ out = ""
343
+ status_str = file_copy_request['status']
344
+ if status_str == 'complete'
345
+ out << "#{green}#{status_str.upcase}#{return_color}"
346
+ elsif status_str == 'failed' || status_str == 'expired'
347
+ out << "#{red}#{status_str.upcase}#{return_color}"
348
+ else
349
+ out << "#{cyan}#{status_str.upcase}#{return_color}"
350
+ end
351
+ out
352
+ end
353
+
354
+ end
@@ -9,6 +9,8 @@ class Morpheus::Cli::MonitoringAppsCommand
9
9
 
10
10
  register_subcommands :list, :get, :add, :update, :remove
11
11
  register_subcommands :mute, :unmute #, :history, :statistics
12
+ register_subcommands :'mute-all' => :mute_all
13
+ register_subcommands :'unmute-all' => :unmute_all
12
14
 
13
15
  def connect(opts)
14
16
  @api_client = establish_remote_appliance_connection(opts)
@@ -524,6 +526,94 @@ class Morpheus::Cli::MonitoringAppsCommand
524
526
  end
525
527
  end
526
528
 
529
+ def mute_all(args)
530
+ options = {}
531
+ params = {'enabled' => true}
532
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
533
+ opts.banner = subcommand_usage()
534
+ opts.on(nil, "--disable", "Unmute instead, the same as the unmute-all command") do
535
+ params['enabled'] = false
536
+ end
537
+ opts.footer = "Mute all monitoring apps. This prevents the creation of new incidents."
538
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote, :quiet])
539
+ end
540
+ optparse.parse!(args)
541
+ if args.count != 0
542
+ puts optparse
543
+ return 1
544
+ end
545
+ connect(options)
546
+ begin
547
+ # construct payload
548
+ payload = nil
549
+ if options[:payload]
550
+ payload = options[:payload]
551
+ else
552
+ payload = params
553
+ end
554
+ if options[:dry_run]
555
+ print_dry_run @monitoring_interface.apps.dry.quarantine_all(payload)
556
+ return 0
557
+ end
558
+ json_response = @monitoring_interface.apps.quarantine_all(payload)
559
+ if options[:json]
560
+ puts as_json(json_response, options)
561
+ elsif !options[:quiet]
562
+ num_updated = json_response['updated']
563
+ if params['enabled']
564
+ print_green_success "Muted #{num_updated} apps"
565
+ else
566
+ print_green_success "Unmuted #{num_updated} apps"
567
+ end
568
+ end
569
+ return 0
570
+ rescue RestClient::Exception => e
571
+ print_rest_exception(e, options)
572
+ exit 1
573
+ end
574
+ end
575
+
576
+ def unmute_all(args)
577
+ options = {}
578
+ params = {'enabled' => false}
579
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
580
+ opts.banner = subcommand_usage()
581
+ build_common_options(opts, options, [:payload, :json, :dry_run, :remote, :quiet])
582
+ opts.footer = "Unmute all monitoring apps."
583
+ end
584
+ optparse.parse!(args)
585
+ if args.count != 0
586
+ puts optparse
587
+ return 1
588
+ end
589
+ connect(options)
590
+
591
+ begin
592
+ # construct payload
593
+ payload = nil
594
+ if options[:payload]
595
+ payload = options[:payload]
596
+ else
597
+ payload = params
598
+ end
599
+ if options[:dry_run]
600
+ print_dry_run @monitoring_interface.apps.dry.quarantine_all(payload)
601
+ return 0
602
+ end
603
+ json_response = @monitoring_interface.apps.quarantine_all(payload)
604
+ if options[:json]
605
+ puts as_json(json_response, options)
606
+ elsif !options[:quiet]
607
+ num_updated = json_response['updated']
608
+ print_green_success "Unmuted #{num_updated} apps"
609
+ end
610
+ return 0
611
+ rescue RestClient::Exception => e
612
+ print_rest_exception(e, options)
613
+ exit 1
614
+ end
615
+ end
616
+
527
617
  def remove(args)
528
618
  options = {}
529
619
  params = {}
@@ -8,6 +8,8 @@ class Morpheus::Cli::MonitoringChecksCommand
8
8
  set_command_name :'monitor-checks'
9
9
  register_subcommands :list, :get, :add, :update, :remove
10
10
  register_subcommands :mute, :unmute, :history #, :statistics
11
+ register_subcommands :'mute-all' => :mute_all
12
+ register_subcommands :'unmute-all' => :unmute_all
11
13
  register_subcommands :'list-types' => :list_types
12
14
 
13
15
  def connect(opts)
@@ -531,8 +533,97 @@ class Morpheus::Cli::MonitoringChecksCommand
531
533
  end
532
534
  end
533
535
 
536
+ def mute_all(args)
537
+ options = {}
538
+ params = {'enabled' => true}
539
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
540
+ opts.banner = subcommand_usage()
541
+ opts.on(nil, "--disable", "Disable mute state instead, the same as unmute-all") do
542
+ params['enabled'] = false
543
+ end
544
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
545
+ opts.footer = "Mute all checks. This prevents the creation new incidents."
546
+ end
547
+ optparse.parse!(args)
548
+ if args.count != 0
549
+ puts optparse
550
+ return 1
551
+ end
552
+ connect(options)
553
+ begin
554
+ # construct payload
555
+ payload = nil
556
+ if options[:payload]
557
+ payload = options[:payload]
558
+ else
559
+ payload = params
560
+ end
561
+ if options[:dry_run]
562
+ print_dry_run @monitoring_interface.checks.dry.quarantine_all(payload)
563
+ return 0
564
+ end
565
+ json_response = @monitoring_interface.checks.quarantine_all(payload)
566
+ if options[:json]
567
+ puts as_json(json_response, options)
568
+ elsif !options[:quiet]
569
+ num_updated = json_response['updated']
570
+ if params['enabled']
571
+ print_green_success "Muted #{num_updated} checks"
572
+ else
573
+ print_green_success "Unmuted #{num_updated} checks"
574
+ end
575
+ end
576
+ return 0
577
+ rescue RestClient::Exception => e
578
+ print_rest_exception(e, options)
579
+ exit 1
580
+ end
581
+ end
582
+
583
+ def unmute_all(args)
584
+ options = {}
585
+ params = {'enabled' => false}
586
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
587
+ opts.banner = subcommand_usage()
588
+ build_common_options(opts, options, [:payload, :json, :dry_run, :quiet, :remote])
589
+ opts.footer = "Unmute all checks."
590
+ end
591
+ optparse.parse!(args)
592
+ if args.count != 0
593
+ puts optparse
594
+ return 1
595
+ end
596
+ connect(options)
597
+
598
+ begin
599
+ # construct payload
600
+ payload = nil
601
+ if options[:payload]
602
+ payload = options[:payload]
603
+ else
604
+ payload = params
605
+ end
606
+ if options[:dry_run]
607
+ print_dry_run @monitoring_interface.checks.dry.quarantine_all(payload)
608
+ return 0
609
+ end
610
+ json_response = @monitoring_interface.checks.quarantine_all(payload)
611
+ if options[:json]
612
+ puts as_json(json_response, options)
613
+ elsif !options[:quiet]
614
+ num_updated = json_response['updated']
615
+ print_green_success "Unmuted #{num_updated} checks"
616
+ end
617
+ return 0
618
+ rescue RestClient::Exception => e
619
+ print_rest_exception(e, options)
620
+ exit 1
621
+ end
622
+ end
623
+
534
624
  def remove(args)
535
625
  options = {}
626
+ params = {}
536
627
  optparse = Morpheus::Cli::OptionParser.new do |opts|
537
628
  opts.banner = subcommand_usage("[name]")
538
629
  build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
@@ -551,12 +642,6 @@ class Morpheus::Cli::MonitoringChecksCommand
551
642
  return false
552
643
  end
553
644
 
554
- # payload = {
555
- # 'check' => {id: check["id"]}
556
- # }
557
- # payload['check'].merge!(check)
558
- payload = params
559
-
560
645
  if options[:dry_run]
561
646
  print_dry_run @monitoring_interface.checks.dry.destroy(check["id"])
562
647
  return
@@ -8,6 +8,8 @@ class Morpheus::Cli::MonitoringGroupsCommand
8
8
  set_command_name :'monitor-groups'
9
9
  register_subcommands :list, :get, :add, :update, :remove
10
10
  register_subcommands :mute, :unmute, :history #, :statistics
11
+ register_subcommands :'mute-all' => :mute_all
12
+ register_subcommands :'unmute-all' => :unmute_all
11
13
 
12
14
  def connect(opts)
13
15
  @api_client = establish_remote_appliance_connection(opts)
@@ -489,6 +491,94 @@ class Morpheus::Cli::MonitoringGroupsCommand
489
491
  end
490
492
  end
491
493
 
494
+ def mute_all(args)
495
+ options = {}
496
+ params = {'enabled' => true}
497
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
498
+ opts.banner = subcommand_usage()
499
+ opts.on(nil, "--disable", "Disable mute, the same as unmute-all") do
500
+ params['enabled'] = false
501
+ end
502
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote, :quiet])
503
+ opts.footer = "Mute all check groups. This prevents the creation of new incidents."
504
+ end
505
+ optparse.parse!(args)
506
+ if args.count != 0
507
+ puts optparse
508
+ return 1
509
+ end
510
+ connect(options)
511
+ begin
512
+ # construct payload
513
+ payload = nil
514
+ if options[:payload]
515
+ payload = options[:payload]
516
+ else
517
+ payload = params
518
+ end
519
+ if options[:dry_run]
520
+ print_dry_run @monitoring_interface.groups.dry.quarantine_all(payload)
521
+ return 0
522
+ end
523
+ json_response = @monitoring_interface.groups.quarantine_all(payload)
524
+ if options[:json]
525
+ puts as_json(json_response, options)
526
+ elsif !options[:quiet]
527
+ num_updated = json_response['updated']
528
+ if params['enabled']
529
+ print_green_success "Muted #{num_updated} check groups"
530
+ else
531
+ print_green_success "Unmuted #{num_updated} check groups"
532
+ end
533
+ end
534
+ return 0
535
+ rescue RestClient::Exception => e
536
+ print_rest_exception(e, options)
537
+ exit 1
538
+ end
539
+ end
540
+
541
+ def unmute_all(args)
542
+ options = {}
543
+ params = {'enabled' => false}
544
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
545
+ opts.banner = subcommand_usage()
546
+ build_common_options(opts, options, [:payload, :json, :dry_run, :remote, :quiet])
547
+ opts.footer = "Unmute all check groups."
548
+ end
549
+ optparse.parse!(args)
550
+ if args.count != 0
551
+ puts optparse
552
+ return 1
553
+ end
554
+ connect(options)
555
+
556
+ begin
557
+ # construct payload
558
+ payload = nil
559
+ if options[:payload]
560
+ payload = options[:payload]
561
+ else
562
+ payload = params
563
+ end
564
+ if options[:dry_run]
565
+ print_dry_run @monitoring_interface.groups.dry.quarantine_all(payload)
566
+ return 0
567
+ end
568
+ json_response = @monitoring_interface.groups.quarantine_all(payload)
569
+ if options[:json]
570
+ puts as_json(json_response, options)
571
+ elsif !options[:quiet]
572
+ num_updated = json_response['updated']
573
+ print_green_success "Unmuted #{num_updated} check groups"
574
+ end
575
+ return 0
576
+ rescue RestClient::Exception => e
577
+ print_rest_exception(e, options)
578
+ exit 1
579
+ end
580
+ end
581
+
492
582
  def remove(args)
493
583
  options = {}
494
584
  params = {}
@@ -7,7 +7,9 @@ class Morpheus::Cli::MonitoringIncidentsCommand
7
7
 
8
8
  set_command_name :'monitor-incidents'
9
9
  register_subcommands :list, :stats, :get, :history, :notifications, :update, :close, :reopen, :mute, :unmute
10
-
10
+ register_subcommands :'mute-all' => :mute_all
11
+ register_subcommands :'unmute-all' => :unmute_all
12
+
11
13
  def connect(opts)
12
14
  @api_client = establish_remote_appliance_connection(opts)
13
15
  @monitoring_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).monitoring
@@ -563,6 +565,94 @@ class Morpheus::Cli::MonitoringIncidentsCommand
563
565
  end
564
566
  end
565
567
 
568
+ def mute_all(args)
569
+ options = {}
570
+ params = {'enabled' => true}
571
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
572
+ opts.banner = subcommand_usage()
573
+ opts.on(nil, "--disable", "Disable mute state instead, the same as unmute-all") do
574
+ params['enabled'] = false
575
+ end
576
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
577
+ opts.footer = "Mute all open incidents."
578
+ end
579
+ optparse.parse!(args)
580
+ if args.count != 0
581
+ puts optparse
582
+ return 1
583
+ end
584
+ connect(options)
585
+ begin
586
+ # construct payload
587
+ payload = nil
588
+ if options[:payload]
589
+ payload = options[:payload]
590
+ else
591
+ payload = params
592
+ end
593
+ if options[:dry_run]
594
+ print_dry_run @monitoring_interface.incidents.dry.quarantine_all(payload)
595
+ return 0
596
+ end
597
+ json_response = @monitoring_interface.incidents.quarantine_all(payload)
598
+ if options[:json]
599
+ puts as_json(json_response, options)
600
+ elsif !options[:quiet]
601
+ num_updated = json_response['updated']
602
+ if params['enabled']
603
+ print_green_success "Muted #{num_updated} open incidents"
604
+ else
605
+ print_green_success "Unmuted #{num_updated} open incidents"
606
+ end
607
+ end
608
+ return 0
609
+ rescue RestClient::Exception => e
610
+ print_rest_exception(e, options)
611
+ exit 1
612
+ end
613
+ end
614
+
615
+ def unmute_all(args)
616
+ options = {}
617
+ params = {'enabled' => false}
618
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
619
+ opts.banner = subcommand_usage()
620
+ build_common_options(opts, options, [:payload, :json, :dry_run, :quiet, :remote])
621
+ opts.footer = "Unmute all open incidents."
622
+ end
623
+ optparse.parse!(args)
624
+ if args.count != 0
625
+ puts optparse
626
+ return 1
627
+ end
628
+ connect(options)
629
+
630
+ begin
631
+ # construct payload
632
+ payload = nil
633
+ if options[:payload]
634
+ payload = options[:payload]
635
+ else
636
+ payload = params
637
+ end
638
+ if options[:dry_run]
639
+ print_dry_run @monitoring_interface.incidents.dry.quarantine_all(payload)
640
+ return 0
641
+ end
642
+ json_response = @monitoring_interface.incidents.quarantine_all(payload)
643
+ if options[:json]
644
+ puts as_json(json_response, options)
645
+ elsif !options[:quiet]
646
+ num_updated = json_response['updated']
647
+ print_green_success "Unmuted #{num_updated} open incidents"
648
+ end
649
+ return 0
650
+ rescue RestClient::Exception => e
651
+ print_rest_exception(e, options)
652
+ exit 1
653
+ end
654
+ end
655
+
566
656
  def close(args)
567
657
  options = {}
568
658
  optparse = Morpheus::Cli::OptionParser.new do |opts|
@@ -412,7 +412,7 @@ module Morpheus
412
412
  Readline.completion_append_character = ""
413
413
  Readline.basic_word_break_characters = ''
414
414
  Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
415
- input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
415
+ input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: ", false).to_s
416
416
  input = input.chomp.strip
417
417
  #input = $stdin.gets.chomp!
418
418
  value = input.empty? ? option_type['defaultValue'] : input.to_s
@@ -429,7 +429,7 @@ class Morpheus::Cli::Roles
429
429
  end
430
430
 
431
431
  if params['multitenant'].to_s != ''
432
- role_payload['multitenant'] = ['on','true'].include?(v_prompt['multitenant'].to_s)
432
+ role_payload['multitenant'] = ['on','true'].include?(params['multitenant'].to_s)
433
433
  end
434
434
  payload = {role: role_payload}
435
435
  if options[:dry_run]
@@ -810,7 +810,10 @@ class Morpheus::Cli::Roles
810
810
  if !do_all
811
811
  group_id = nil
812
812
  if !options[:group].nil?
813
- group_id = find_group_id_by_name(options[:group])
813
+ #group_id = find_group_id_by_name(options[:group])
814
+ group = find_group_by_name(options[:group])
815
+ return 1 if group.nil?
816
+ group_id = group['id']
814
817
  else
815
818
  group_id = @active_group_id
816
819
  end
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "3.5.3"
4
+ VERSION = "3.6.0"
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morpheus-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.3
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Estes
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2018-12-13 00:00:00.000000000 Z
14
+ date: 2019-01-04 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -190,6 +190,7 @@ files:
190
190
  - lib/morpheus/api/deployments_interface.rb
191
191
  - lib/morpheus/api/execute_schedules_interface.rb
192
192
  - lib/morpheus/api/execution_request_interface.rb
193
+ - lib/morpheus/api/file_copy_request_interface.rb
193
194
  - lib/morpheus/api/group_policies_interface.rb
194
195
  - lib/morpheus/api/groups_interface.rb
195
196
  - lib/morpheus/api/image_builder_boot_scripts_interface.rb
@@ -274,6 +275,7 @@ files:
274
275
  - lib/morpheus/cli/execute_schedules_command.rb
275
276
  - lib/morpheus/cli/execution_request_command.rb
276
277
  - lib/morpheus/cli/expression_parser.rb
278
+ - lib/morpheus/cli/file_copy_request_command.rb
277
279
  - lib/morpheus/cli/groups.rb
278
280
  - lib/morpheus/cli/hosts.rb
279
281
  - lib/morpheus/cli/image_builder_command.rb