morpheus-cli 4.1.6 → 4.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c550fa0412be48d0457ca10f54822e7b77e25bb515e6c5cb6092d43f9aee66a6
4
- data.tar.gz: a8949f6a0ace1bc99f6a327ebe30e8f9678c9922c9a3d8a776543475c94141f0
3
+ metadata.gz: e55c3726ed7947b5d691c9027193844361880ca143f493aa886ece9423bb45a1
4
+ data.tar.gz: a6e90dac8b23e38762565259def0bddead03a57d38c9f4f691c39032ed6d6431
5
5
  SHA512:
6
- metadata.gz: 46e33763b7980a60312a7479d0104dab355e34c8a01e7a561b98a18468360a975dbbc26fabc2f61ac7f0506be8e8c4f3dbc8fc998d23cd6b1481cdedbb341d1a
7
- data.tar.gz: 6e64c4f697547bbad0fcba6e9aeb6ec218daf37491d5b0ebb4b309ac523a3389aeb621e6c9265035c6233bc3b0b7189d36d5ba9c08133d2d104430135802d598
6
+ metadata.gz: 910f2ccd9bd70988654f744a47a4633baa8b525a7054b961ee62600691c36d9706303b134c37b01c1584b29d87e7cb958fab237f721467966b12aa355e7d7ad7
7
+ data.tar.gz: 8c14cf726ac4ca45aa716b590b56d46a1043f5ac2d9d668f5de4234aea48f9955aac2d79ebd43851f0ea9f652192794f329fe9afe4bd77c09e5821e97d69d0dc
@@ -607,6 +607,14 @@ class Morpheus::APIClient
607
607
  Morpheus::EnvironmentsInterface.new(@access_token, @refresh_token, @expires_at, @base_url).setopts(@options)
608
608
  end
609
609
 
610
+ def backup_settings
611
+ Morpheus::BackupSettingsInterface.new(@access_token, @refresh_token, @expires_at, @base_url).setopts(@options)
612
+ end
613
+
614
+ def log_settings
615
+ Morpheus::LogSettingsInterface.new(@access_token, @refresh_token, @expires_at, @base_url).setopts(@options)
616
+ end
617
+
610
618
  def whitelabel_settings
611
619
  Morpheus::WhitelabelSettingsInterface.new(@access_token, @refresh_token, @expires_at, @base_url).setopts(@options)
612
620
  end
@@ -0,0 +1,23 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::BackupSettingsInterface < Morpheus::APIClient
4
+ def initialize(access_token, refresh_token,expires_at = nil, base_url=nil, api='backup-settings')
5
+ @access_token = access_token
6
+ @refresh_token = refresh_token
7
+ @base_url = base_url
8
+ @api_url = "#{base_url}/api/#{api}"
9
+ @expires_at = expires_at
10
+ end
11
+
12
+ def get(params={})
13
+ url = @api_url
14
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
15
+ execute(method: :get, url: url, headers: headers)
16
+ end
17
+
18
+ def update(payload, params={})
19
+ url = @api_url
20
+ headers = { params: params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
21
+ execute(method: :put, url: url, headers: headers, payload: payload.to_json)
22
+ end
23
+ end
@@ -0,0 +1,41 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::LogSettingsInterface < Morpheus::APIClient
4
+ def initialize(access_token, refresh_token,expires_at = nil, base_url=nil, api='log-settings')
5
+ @access_token = access_token
6
+ @refresh_token = refresh_token
7
+ @base_url = base_url
8
+ @api_url = "#{base_url}/api/#{api}"
9
+ @expires_at = expires_at
10
+ end
11
+
12
+ def get(params={})
13
+ url = @api_url
14
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
15
+ execute(method: :get, url: url, headers: headers)
16
+ end
17
+
18
+ def update(payload, params={})
19
+ url = @api_url
20
+ headers = { params: params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
21
+ execute(method: :put, url: url, headers: headers, payload: payload.to_json)
22
+ end
23
+
24
+ def update_integration(name, payload, params={})
25
+ url = "#{@api_url}/integrations/#{name}"
26
+ headers = { params: params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
27
+ execute(method: :put, url: url, headers: headers, payload: payload.to_json)
28
+ end
29
+
30
+ def add_syslog_rule(payload, params={})
31
+ url = "#{@api_url}/syslog-rules"
32
+ headers = { params: params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
33
+ execute(method: :post, url: url, headers: headers, payload: payload.to_json)
34
+ end
35
+
36
+ def destroy_syslog_rule(name, params={})
37
+ url = "#{@api_url}/syslog-rules/#{name}"
38
+ headers = { params: params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
39
+ execute(method: :delete, url: url, headers: headers)
40
+ end
41
+ end
@@ -69,8 +69,9 @@ class Morpheus::ServersInterface < Morpheus::APIClient
69
69
  execute(opts)
70
70
  end
71
71
 
72
- def install_agent(serverId,payload = {})
72
+ def make_managed(serverId,payload = {})
73
73
  url = "#{@base_url}/api/servers/#{serverId}/install-agent"
74
+ #url = "#{@base_url}/api/servers/#{serverId}/make-managed" # added in 4.1
74
75
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
75
76
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
76
77
  execute(opts)
data/lib/morpheus/cli.rb CHANGED
@@ -149,6 +149,8 @@ module Morpheus
149
149
  load 'morpheus/cli/packages_command.rb'
150
150
  load 'morpheus/cli/reports_command.rb'
151
151
  load 'morpheus/cli/environments_command.rb'
152
+ load 'morpheus/cli/backup_settings_command.rb'
153
+ load 'morpheus/cli/log_settings_command.rb'
152
154
  load 'morpheus/cli/whitelabel_settings_command.rb'
153
155
  load 'morpheus/cli/wiki_command.rb'
154
156
 
@@ -3,7 +3,7 @@ require 'morpheus/cli/cli_command'
3
3
  class Morpheus::Cli::ApplianceSettingsCommand
4
4
  include Morpheus::Cli::CliCommand
5
5
  include Morpheus::Cli::AccountsHelper
6
- set_command_hidden # hide until 4.2.0
6
+ set_command_hidden
7
7
  set_command_name :'appliance-settings'
8
8
 
9
9
  register_subcommands :get, :update
@@ -207,7 +207,7 @@ class Morpheus::Cli::ApplianceSettingsCommand
207
207
  opts.on("--disable-all-clouds", "Set all cloud types enabled status off, can be used in conjunction with --enable-clouds options") do
208
208
  params['disableAllZoneTypes'] = true
209
209
  end
210
- build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
210
+ build_common_options(opts, options, [:json, :payload, :dry_run, :quiet, :remote])
211
211
  end
212
212
 
213
213
  optparse.parse!(args)
@@ -0,0 +1,181 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::BackupSettingsCommand
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::AccountsHelper
6
+ set_command_hidden
7
+ set_command_name :'backup-settings'
8
+
9
+ register_subcommands :get, :update
10
+ set_default_subcommand :get
11
+
12
+ def connect(opts)
13
+ @api_client = establish_remote_appliance_connection(opts)
14
+ @backup_settings_interface = @api_client.backup_settings
15
+ @options_interface = @api_client.options
16
+ @storage_providers = @api_client.storage_providers
17
+ end
18
+
19
+ def handle(args)
20
+ handle_subcommand(args)
21
+ end
22
+
23
+ def get(args)
24
+ options = {}
25
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
26
+ opts.banner = subcommand_usage()
27
+ build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
28
+ opts.footer = "Get backup settings."
29
+ end
30
+ optparse.parse!(args)
31
+ connect(options)
32
+ if args.count != 0
33
+ raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args}\n#{optparse}"
34
+ return 1
35
+ end
36
+
37
+ begin
38
+ @backup_settings_interface.setopts(options)
39
+
40
+ if options[:dry_run]
41
+ print_dry_run @backup_settings_interface.dry.get(options)
42
+ return
43
+ end
44
+ json_response = @backup_settings_interface.get(options)
45
+ if options[:json]
46
+ puts as_json(json_response, options, "backupSettings")
47
+ return 0
48
+ elsif options[:yaml]
49
+ puts as_yaml(json_response, options, "backupSettings")
50
+ return 0
51
+ elsif options[:csv]
52
+ puts records_as_csv([json_response['backupSettings']], options)
53
+ return 0
54
+ end
55
+
56
+ backup_settings = json_response['backupSettings']
57
+
58
+ print_h1 "Backup Settings"
59
+ print cyan
60
+ description_cols = {
61
+ "Backups Enabled" => lambda {|it| format_boolean(it['enabled']) },
62
+ "Create Backups" => lambda {|it| format_boolean(it['createBackups']) },
63
+ "Backup Appliance" => lambda {|it| format_boolean(it['backupAppliance']) },
64
+ "Default Backup Bucket" => lambda {|it| it['defaultStorageBucket'] ? it['defaultStorageBucket']['name'] : '' },
65
+ "Default Backup Schedule" => lambda {|it| it['defaultSchedule'] ? it['defaultSchedule']['name'] : ''},
66
+ "Backup Retention Count" => lambda {|it| it['retentionCount'] }
67
+ }
68
+ print_description_list(description_cols, backup_settings)
69
+ print reset "\n"
70
+ return 0
71
+ rescue RestClient::Exception => e
72
+ print_rest_exception(e, options)
73
+ return 1
74
+ end
75
+ end
76
+
77
+ def update(args)
78
+ options = {}
79
+ params = {}
80
+
81
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
82
+ opts.banner = opts.banner = subcommand_usage()
83
+ opts.on('-a', '--active [on|off]', String, "Can be used to enable / disable the backups. Default is on") do |val|
84
+ params['enabled'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
85
+ end
86
+ opts.on("--create-backups [on|off]", String, "Can be used to enable / disable create backups. Default is on") do |val|
87
+ params['createBackups'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
88
+ end
89
+ opts.on("--backup-appliance [on|off]", ['on','off'], "Can be use to enable / disable backup appliance. Default is on") do |val|
90
+ params['backupAppliance'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
91
+ end
92
+ opts.on("-b", "--bucket BUCKET", String, "Default storage bucket name or ID") do |val|
93
+ options[:storageBucket] = val
94
+ end
95
+ opts.on("--clear-bucket", "Use this flag to clear default backup bucket") do |val|
96
+ params['clearDefaultStorageBucket'] = true
97
+ end
98
+ opts.on("-u", "--update-existing", "Use this flag to update existing backups with new settings") do |val|
99
+ params['updateExisting'] = true
100
+ end
101
+ opts.on("-s", "--backup-schedule ID", String, "Backup schedule type ID") do |val|
102
+ options[:backupSchedule] = val
103
+ end
104
+ opts.on("--clear-schedule", "Use this flag to clear default backup schedule") do |val|
105
+ params['clearDefaultSchedule'] = true
106
+ end
107
+ opts.on("-R", "--retention NUMBER", Integer, "Maximum number of successful backups to retain") do |val|
108
+ params['retentionCount'] = val.to_i
109
+ end
110
+ build_common_options(opts, options, [:json, :payload, :dry_run, :quiet, :remote])
111
+ opts.footer = "Update your backup settings."
112
+ end
113
+
114
+ optparse.parse!(args)
115
+ connect(options)
116
+ if args.count != 0
117
+ raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args}\n#{optparse}"
118
+ return 1
119
+ end
120
+
121
+ begin
122
+ payload = parse_payload(options)
123
+
124
+ if !payload
125
+ payload = {'backupSettings' => params}
126
+
127
+ if !options[:backupSchedule].nil?
128
+ backup_schedule = @options_interface.options_for_source('executeSchedules', {})['data'].find do |it|
129
+ it['name'] == options[:backupSchedule] || it['value'] == options[:backupSchedule].to_i
130
+ end
131
+
132
+ if backup_schedule.nil?
133
+ print_red_alert "Backup schedule type not found for #{options[:backupSchedule]}"
134
+ return 1
135
+ end
136
+ payload['backupSettings']['defaultSchedule'] = {'id' => backup_schedule['value'].to_i}
137
+ end
138
+
139
+ if !options[:storageBucket].nil?
140
+ storage_bucket = @storage_providers.list['storageBuckets'].find do |it|
141
+ it['name'] == options[:storageBucket].to_s || it['bucketName'] == options[:storageBucket].to_s || it['id'] == options[:storageBucket].to_i
142
+ end
143
+ if storage_bucket.nil?
144
+ print_red_alert "Storage bucket not found for #{options[:storageBucket]}"
145
+ return 1
146
+ end
147
+ payload['backupSettings']['defaultStorageBucket'] = {'id' => storage_bucket['id']}
148
+ end
149
+ end
150
+
151
+ if payload['backupSettings'].empty?
152
+ print_green_success "Nothing to update"
153
+ exit 1
154
+ end
155
+
156
+ @backup_settings_interface.setopts(options)
157
+ if options[:dry_run]
158
+ print_dry_run @backup_settings_interface.dry.update(payload)
159
+ return
160
+ end
161
+ json_response = @backup_settings_interface.update(payload)
162
+
163
+ if options[:json]
164
+ puts as_json(json_response, options)
165
+ elsif !options[:quiet]
166
+ if json_response['success']
167
+ print_green_success "Updated log settings"
168
+ get([] + (options[:remote] ? ["-r",options[:remote]] : []))
169
+ else
170
+ print_red_alert "Error updating log settings: #{json_response['msg'] || json_response['errors']}"
171
+ end
172
+ end
173
+ return 0
174
+
175
+ rescue RestClient::Exception => e
176
+ print_rest_exception(e, options)
177
+ exit 1
178
+ end
179
+ end
180
+
181
+ end
@@ -101,7 +101,7 @@ class Morpheus::Cli::Deployments
101
101
  rows = versions.collect do |version|
102
102
  {version: version['userVersion'], type: version['deployType'], updated: format_local_dt(version['lastUpdated'])}
103
103
  end
104
- coumns = [:version, :type, :updated]
104
+ columns = [:version, :type, :updated]
105
105
  print as_pretty_table(rows, columns, options)
106
106
  end
107
107
  print reset,"\n"
@@ -14,7 +14,7 @@ class Morpheus::Cli::Hosts
14
14
  include Morpheus::Cli::ProvisioningHelper
15
15
  set_command_name :hosts
16
16
  set_command_description "View and manage hosts (servers)."
17
- register_subcommands :list, :count, :get, :view, :stats, :add, :update, :remove, :logs, :start, :stop, :resize, :run_workflow, {:'make-managed' => :install_agent}, :upgrade_agent
17
+ register_subcommands :list, :count, :get, :view, :stats, :add, :update, :remove, :logs, :start, :stop, :resize, :run_workflow, :make_managed, :upgrade_agent
18
18
  register_subcommands :'types' => :list_types
19
19
  register_subcommands :exec => :execution_request
20
20
  register_subcommands :wiki, :update_wiki
@@ -1166,12 +1166,18 @@ class Morpheus::Cli::Hosts
1166
1166
  end
1167
1167
  end
1168
1168
 
1169
- def install_agent(args)
1169
+ def make_managed(args)
1170
1170
  options = {}
1171
1171
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1172
1172
  opts.banner = subcommand_usage("[name]")
1173
- build_option_type_options(opts, options, install_agent_option_types(false))
1174
- build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
1173
+ build_option_type_options(opts, options, make_managed_option_types(false))
1174
+ opts.on('--install-agent [on|off]', String, "Install Agent? Pass false to manually install agent. Default is true.") do |val|
1175
+ options['installAgent'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
1176
+ end
1177
+ # opts.on('--instance-type-id ID', String, "Instance Type ID for the new instance.") do |val|
1178
+ # options['instanceTypeId'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
1179
+ # end
1180
+ build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
1175
1181
  end
1176
1182
  optparse.parse!(args)
1177
1183
  if args.count < 1
@@ -1188,7 +1194,9 @@ class Morpheus::Cli::Hosts
1188
1194
  payload = {
1189
1195
  'server' => {}
1190
1196
  }
1191
- params = Morpheus::Cli::OptionTypes.prompt(install_agent_option_types, options[:options], @api_client, options[:params])
1197
+ passed_options = (options[:options] || {}).reject {|k,v| k.is_a?(Symbol) }
1198
+ payload.deep_merge!(passed_options)
1199
+ params = Morpheus::Cli::OptionTypes.prompt(make_managed_option_types, options[:options], @api_client, options[:params])
1192
1200
  server_os = params.delete('serverOs')
1193
1201
  if server_os
1194
1202
  payload['server']['serverOs'] = {id: server_os}
@@ -1198,12 +1206,17 @@ class Morpheus::Cli::Hosts
1198
1206
  payload['server']['account'] = {id: account}
1199
1207
  end
1200
1208
  payload['server'].merge!(params)
1209
+ ['installAgent','instanceTypeId'].each do |k|
1210
+ if options[k] != nil
1211
+ payload[k] = options[k]
1212
+ end
1213
+ end
1201
1214
  @servers_interface.setopts(options)
1202
1215
  if options[:dry_run]
1203
- print_dry_run @servers_interface.dry.install_agent(host['id'], payload)
1216
+ print_dry_run @servers_interface.dry.make_managed(host['id'], payload)
1204
1217
  return
1205
1218
  end
1206
- json_response = @servers_interface.install_agent(host['id'], payload)
1219
+ json_response = @servers_interface.make_managed(host['id'], payload)
1207
1220
  if options[:json]
1208
1221
  print JSON.pretty_generate(json_response)
1209
1222
  print "\n"
@@ -1882,7 +1895,7 @@ class Morpheus::Cli::Hosts
1882
1895
  out
1883
1896
  end
1884
1897
 
1885
- def install_agent_option_types(connected=true)
1898
+ def make_managed_option_types(connected=true)
1886
1899
  [
1887
1900
  #{'fieldName' => 'account', 'fieldLabel' => 'Account', 'type' => 'select', 'optionSource' => 'accounts', 'required' => true},
1888
1901
  {'fieldName' => 'sshUsername', 'fieldLabel' => 'SSH Username', 'type' => 'text', 'required' => true},
@@ -2347,7 +2347,7 @@ class Morpheus::Cli::Instances
2347
2347
  instance_ids = instances.collect {|instance| instance["id"] }
2348
2348
 
2349
2349
  # figure out what action to run
2350
- available_actions = @instances_interface.available_actions(instance_ids, options)["actions"]
2350
+ available_actions = @instances_interface.available_actions(instance_ids)["actions"]
2351
2351
  if available_actions.empty?
2352
2352
  if instance_ids.size > 1
2353
2353
  print_red_alert "The specified instances have no available actions in common."
@@ -50,7 +50,10 @@ class Morpheus::Cli::License
50
50
  json_response = @license_interface.get()
51
51
  # 200 OK, parse results
52
52
  license = json_response['license']
53
- used_memory = json_response['licenseUsedMemory']
53
+ current_usage = json_response['currentUsage'] || {}
54
+ used_memory = json_response['licenseUsedMemory'] || current_usage['memory']
55
+ used_storage = current_usage['storage']
56
+ used_workloads = current_usage['workloads']
54
57
 
55
58
  # Determine exit status and any error conditions for the command
56
59
  exit_code = 0
@@ -81,6 +84,9 @@ class Morpheus::Cli::License
81
84
  max_memory = Filesize.from("#{license['maxMemory']} B").pretty if license['maxMemory'].to_i != 0
82
85
  max_storage = Filesize.from("#{license['maxStorage']} B").pretty if license['maxStorage'].to_i != 0
83
86
  used_memory = Filesize.from("#{used_memory} B").pretty if used_memory.to_i != 0
87
+ used_storage = Filesize.from("#{used_storage} B").pretty if used_storage.to_i != 0
88
+ #used_workloads = "n/a" if used_workloads.nil?
89
+ max_workloads = license["maxInstances"].to_i == 0 ? 'Unlimited' : license["maxInstances"]
84
90
  print cyan
85
91
  description_cols = {
86
92
  "Account" => 'accountName',
@@ -94,8 +100,8 @@ class Morpheus::Cli::License
94
100
  end
95
101
  },
96
102
  "Memory" => lambda {|it| "#{used_memory} / #{max_memory}" },
97
- "Max Storage" => lambda {|it| "#{max_storage}" },
98
- "Max Instances" => lambda {|it| it["maxInstances"].to_i == 0 ? 'Unlimited' : it["maxInstances"] },
103
+ "Storage" => lambda {|it| "#{used_storage} / #{max_storage}" },
104
+ "Workloads" => lambda {|it| "#{used_workloads} / #{max_workloads}" },
99
105
  "Hard Limit" => lambda {|it| it[""] == false ? 'Yes' : 'No' },
100
106
  }
101
107
  print_description_list(description_cols, license)
@@ -0,0 +1,396 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::LogSettingsCommand
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::AccountsHelper
6
+ set_command_hidden
7
+ set_command_name :'log-settings'
8
+
9
+ register_subcommands :get, :update
10
+ register_subcommands :enable_integration, :disable_integration
11
+ register_subcommands :add_syslog_rule, :remove_syslog_rule
12
+
13
+ set_default_subcommand :get
14
+
15
+ def connect(opts)
16
+ @api_client = establish_remote_appliance_connection(opts)
17
+ @log_settings_interface = @api_client.log_settings
18
+ end
19
+
20
+ def handle(args)
21
+ handle_subcommand(args)
22
+ end
23
+
24
+ def get(args)
25
+ options = {}
26
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
27
+ opts.banner = subcommand_usage()
28
+ build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
29
+ opts.footer = "Get log settings."
30
+ end
31
+ optparse.parse!(args)
32
+ connect(options)
33
+ if args.count != 0
34
+ raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args}\n#{optparse}"
35
+ return 1
36
+ end
37
+
38
+ begin
39
+ @log_settings_interface.setopts(options)
40
+
41
+ if options[:dry_run]
42
+ print_dry_run @log_settings_interface.dry.get()
43
+ return
44
+ end
45
+ json_response = @log_settings_interface.get()
46
+ if options[:json]
47
+ puts as_json(json_response, options, "logSettings")
48
+ return 0
49
+ elsif options[:yaml]
50
+ puts as_yaml(json_response, options, "logSettings")
51
+ return 0
52
+ elsif options[:csv]
53
+ puts records_as_csv([json_response['logSettings']], options)
54
+ return 0
55
+ end
56
+
57
+ log_settings = json_response['logSettings']
58
+
59
+ print_h1 "Log Settings"
60
+ print cyan
61
+ description_cols = {
62
+ "Logs Enabled" => lambda {|it| format_boolean(it['enabled']) },
63
+ "Availability Time Frame" => lambda {|it| it['retentionDays'] }
64
+ }
65
+ print_description_list(description_cols, log_settings)
66
+
67
+ # Syslog Forwarding Rules
68
+ if !log_settings['syslogRules'].empty?
69
+ print_h2 "Syslog Forwarding Rules"
70
+ print cyan
71
+ print as_pretty_table(log_settings['syslogRules'], [:id, :name, :rule])
72
+ end
73
+
74
+ # Integrations
75
+ if !log_settings['integrations'].empty?
76
+ print_h2 "Integrations"
77
+ print cyan
78
+ print as_pretty_table(log_settings['integrations'], [:name, :enabled, :host, :port])
79
+ end
80
+ print reset "\n"
81
+ return 0
82
+ rescue RestClient::Exception => e
83
+ print_rest_exception(e, options)
84
+ return 1
85
+ end
86
+ end
87
+
88
+ def update(args)
89
+ options = {}
90
+ params = {}
91
+
92
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
93
+ opts.banner = opts.banner = subcommand_usage()
94
+ opts.on("--enabled [on|off]", ['on','off'], "Logs enabled") do |val|
95
+ params['enabled'] = ['true','on'].include?(val.to_s.strip)
96
+ end
97
+ opts.on("-R", "--retention NUMBER", Integer, "Availability time frame in days") do |val|
98
+ params['retentionDays'] = val.to_i
99
+ end
100
+ opts.on("-s", "--syslog JSON", String, "Syslog rules JSON") do |val|
101
+ begin
102
+ syslog_rules = JSON.parse(val.to_s)
103
+ options[:syslogRules] = syslog_rules.kind_of?(Array) ? syslog_rules : [syslog_rules]
104
+ rescue JSON::ParserError => e
105
+ print_red_alert "Unable to parse syslog rules JSON"
106
+ exit 1
107
+ end
108
+ end
109
+ opts.on('--syslog-list LIST', Array, "Syslog rules list in form of name value pairs: name1=rule1,name2=rule2") do |val|
110
+ options[:syslogRules] = val.collect { |nv|
111
+ parts = nv.split('=')
112
+ {'name' => parts[0].strip, 'rule' => (parts.count > 1 ? parts[1].strip : '')}
113
+ }
114
+ end
115
+ opts.on( '-i', '--integrations JSON', "Integrations") do |val|
116
+ begin
117
+ ints = JSON.parse(val.to_s)
118
+ options[:integrations] = ints.kind_of?(Array) ? ints : [ints]
119
+ rescue JSON::ParserError => e
120
+ print_red_alert "Unable to parse integrations JSON"
121
+ exit 1
122
+ end
123
+ end
124
+ build_common_options(opts, options, [:json, :payload, :dry_run, :quiet, :remote])
125
+ opts.footer = "Update your log settings."
126
+ end
127
+
128
+ optparse.parse!(args)
129
+ connect(options)
130
+ if args.count != 0
131
+ raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args}\n#{optparse}"
132
+ return 1
133
+ end
134
+
135
+ begin
136
+ payload = parse_payload(options)
137
+
138
+ if !payload
139
+ payload = {'logSettings' => params}
140
+
141
+ if !options[:syslogRules].nil?
142
+ if options[:syslogRules].reject { |rule| rule['name'] }.count > 0
143
+ print_red_alert "Invalid forwarding rule(s), name is required"
144
+ return 1
145
+ end
146
+ payload['logSettings']['syslogRules'] = options[:syslogRules]
147
+ end
148
+
149
+ if !options[:integrations].nil?
150
+ if options[:integrations].reject { |rule| rule['name'] && rule['host'] && rule['port'] }.count > 0
151
+ print_red_alert "Invalid integration: name, host and port are required"
152
+ return 1
153
+ end
154
+ payload['logSettings']['integrations'] = options[:integrations]
155
+ end
156
+ end
157
+
158
+ if payload['logSettings'].empty?
159
+ print_green_success "Nothing to update"
160
+ exit 1
161
+ end
162
+
163
+ @log_settings_interface.setopts(options)
164
+ if options[:dry_run]
165
+ print_dry_run @log_settings_interface.dry.update(payload)
166
+ return
167
+ end
168
+ json_response = @log_settings_interface.update(payload)
169
+
170
+ if options[:json]
171
+ puts as_json(json_response, options)
172
+ elsif !options[:quiet]
173
+ if json_response['success']
174
+ print_green_success "Updated log settings"
175
+ get([] + (options[:remote] ? ["-r",options[:remote]] : []))
176
+ else
177
+ print_red_alert "Error updating log settings: #{json_response['msg'] || json_response['errors']}"
178
+ end
179
+ end
180
+ return 0
181
+
182
+ rescue RestClient::Exception => e
183
+ print_rest_exception(e, options)
184
+ exit 1
185
+ end
186
+ end
187
+
188
+ def enable_integration(args)
189
+ options = {}
190
+
191
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
192
+ opts.banner = opts.banner = subcommand_usage("[name] [host] [port]")
193
+ build_common_options(opts, options, [:json, :payload, :dry_run, :quiet, :remote])
194
+ opts.footer = "Enables specifed integration.\n" +
195
+ "[name] is required. Currently supports splunk and logrhythm integrations.\n" +
196
+ "[host] is required. Host of the integration.\n" +
197
+ "[port] is required. Port of the integration."
198
+ end
199
+
200
+ optparse.parse!(args)
201
+ connect(options)
202
+ if args.count != 3
203
+ raise_command_error "wrong number of arguments, expected 3 and got (#{args.count}) #{args}\n#{optparse}"
204
+ return 1
205
+ end
206
+ if !args[2].to_i
207
+ raise_command_error "port argument must be a number"
208
+ end
209
+
210
+ begin
211
+ payload = parse_payload(options)
212
+
213
+ if !payload
214
+ payload = {'integration' => {'enabled' => true, 'host' => args[1], 'port' => args[2]}}
215
+ end
216
+
217
+ @log_settings_interface.setopts(options)
218
+ if options[:dry_run]
219
+ print_dry_run @log_settings_interface.dry.update_integration(args[0], payload)
220
+ return
221
+ end
222
+ json_response = @log_settings_interface.update_integration(args[0], payload)
223
+
224
+ if options[:json]
225
+ puts as_json(json_response, options)
226
+ elsif !options[:quiet]
227
+ if json_response['success']
228
+ print_green_success "Integration added"
229
+ get([] + (options[:remote] ? ["-r",options[:remote]] : []))
230
+ else
231
+ print_red_alert "Error enabling integration: #{json_response['msg'] || json_response['errors']}"
232
+ end
233
+ end
234
+ return 0
235
+
236
+ rescue RestClient::Exception => e
237
+ print_rest_exception(e, options)
238
+ exit 1
239
+ end
240
+ end
241
+
242
+ def disable_integration(args)
243
+ options = {}
244
+
245
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
246
+ opts.banner = opts.banner = subcommand_usage("[name]")
247
+ build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
248
+ opts.footer = "Disabled specifed integration.\n" +
249
+ "[name] is required. Currently supports splunk and logrhythm integrations."
250
+ end
251
+
252
+ optparse.parse!(args)
253
+ connect(options)
254
+ if args.count != 1
255
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
256
+ return 1
257
+ end
258
+
259
+ begin
260
+ payload = {'integration' => {'enabled' => false}}
261
+
262
+ @log_settings_interface.setopts(options)
263
+ if options[:dry_run]
264
+ print_dry_run @log_settings_interface.dry.update_integration(args[0], payload)
265
+ return
266
+ end
267
+ json_response = @log_settings_interface.update_integration(args[0], payload)
268
+
269
+ if options[:json]
270
+ puts as_json(json_response, options)
271
+ elsif !options[:quiet]
272
+ if json_response['success']
273
+ print_green_success "Integration removed"
274
+ get([] + (options[:remote] ? ["-r",options[:remote]] : []))
275
+ else
276
+ print_red_alert "Error disabling integration: #{json_response['msg'] || json_response['errors']}"
277
+ end
278
+ end
279
+ return 0
280
+
281
+ rescue RestClient::Exception => e
282
+ print_rest_exception(e, options)
283
+ exit 1
284
+ end
285
+ end
286
+
287
+ def add_syslog_rule(args)
288
+ options = {}
289
+
290
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
291
+ opts.banner = opts.banner = subcommand_usage("[name] [rule]")
292
+ build_common_options(opts, options, [:json, :payload, :dry_run, :quiet, :remote])
293
+ opts.footer = "Add syslog rule.\n" +
294
+ "[name] is required. If syslog already exists, the specified rule will be updated\n" +
295
+ "[rule] is required"
296
+ end
297
+
298
+ optparse.parse!(args)
299
+ connect(options)
300
+ if args.count != 2
301
+ raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
302
+ return 1
303
+ end
304
+
305
+ begin
306
+ payload = parse_payload(options)
307
+
308
+ if !payload
309
+ payload = {'syslogRule' => {'name' => args[0], 'rule' => args[1]}}
310
+ end
311
+
312
+ @log_settings_interface.setopts(options)
313
+ if options[:dry_run]
314
+ print_dry_run @log_settings_interface.dry.add_syslog_rule(payload)
315
+ return
316
+ end
317
+ json_response = @log_settings_interface.add_syslog_rule(payload)
318
+
319
+ if options[:json]
320
+ puts as_json(json_response, options)
321
+ elsif !options[:quiet]
322
+ if json_response['success']
323
+ print_green_success "Syslog rule added"
324
+ get([] + (options[:remote] ? ["-r",options[:remote]] : []))
325
+ else
326
+ print_red_alert "Error adding syslog rule: #{json_response['msg'] || json_response['errors']}"
327
+ end
328
+ end
329
+ return 0
330
+
331
+ rescue RestClient::Exception => e
332
+ print_rest_exception(e, options)
333
+ exit 1
334
+ end
335
+ end
336
+
337
+ def remove_syslog_rule(args)
338
+ options = {}
339
+
340
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
341
+ opts.banner = opts.banner = subcommand_usage("[syslog-rule]")
342
+ build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
343
+ opts.footer = "Delete a syslog rule.\n" +
344
+ "[syslog-rule] is required. This is the name or id of an syslog rule."
345
+ end
346
+
347
+ optparse.parse!(args)
348
+ connect(options)
349
+ if args.count != 1
350
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
351
+ return 1
352
+ end
353
+
354
+ begin
355
+ syslog_rule = find_syslog_rule_by_name_or_id(args[0])
356
+
357
+ if syslog_rule.nil?
358
+ print_red_alert "Syslog rule not found for: #{args[0]}"
359
+ return 1
360
+ end
361
+
362
+ @log_settings_interface.setopts(options)
363
+ if options[:dry_run]
364
+ print_dry_run @log_settings_interface.dry.destroy_syslog_rule(syslog_rule['id'])
365
+ return
366
+ end
367
+ json_response = @log_settings_interface.destroy_syslog_rule(syslog_rule['id'])
368
+
369
+ if options[:json]
370
+ puts as_json(json_response, options)
371
+ elsif !options[:quiet]
372
+ if json_response['success']
373
+ print_green_success "Syslog rule removed"
374
+ get([] + (options[:remote] ? ["-r",options[:remote]] : []))
375
+ else
376
+ print_red_alert "Error removing syslog rule: #{json_response['msg'] || json_response['errors']}"
377
+ end
378
+ end
379
+ return 0
380
+
381
+ rescue RestClient::Exception => e
382
+ print_rest_exception(e, options)
383
+ exit 1
384
+ end
385
+ end
386
+
387
+ private
388
+
389
+ def find_syslog_rule_by_name_or_id(val)
390
+ log_settings = @log_settings_interface.get()['logSettings']
391
+ log_settings['syslogRules'].find do |rule|
392
+ val.casecmp(rule['name']) == 0 || rule['id'] == val.to_i
393
+ end
394
+ end
395
+
396
+ end