morpheus-cli 4.1.6 → 4.1.7

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: 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