lita-alertlogic 0.0.1
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 +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.rubocop.yml +18 -0
- data/.travis.yml +8 -0
- data/Gemfile +6 -0
- data/LICENSE +19 -0
- data/README.md +100 -0
- data/Rakefile +6 -0
- data/lib/alertlogic_helper/agents.rb +107 -0
- data/lib/alertlogic_helper/api.rb +53 -0
- data/lib/alertlogic_helper/appliances.rb +27 -0
- data/lib/alertlogic_helper/common.rb +33 -0
- data/lib/alertlogic_helper/customer.rb +78 -0
- data/lib/alertlogic_helper/incidents.rb +29 -0
- data/lib/alertlogic_helper/log_manager.rb +121 -0
- data/lib/alertlogic_helper/threat_manager.rb +173 -0
- data/lib/lita-alertlogic.rb +20 -0
- data/lib/lita/handlers/alertlogic_customer.rb +60 -0
- data/lib/lita/handlers/alertlogic_incidents.rb +43 -0
- data/lib/lita/handlers/alertlogic_log_manager.rb +197 -0
- data/lib/lita/handlers/alertlogic_monitoring.rb +79 -0
- data/lib/lita/handlers/alertlogic_threat_manager.rb +264 -0
- data/lita-alertlogic.gemspec +26 -0
- data/locales/en.yml +69 -0
- data/spec/lita/handlers/alertlogic_customer_spec.rb +7 -0
- data/spec/lita/handlers/alertlogic_incidents_spec.rb +7 -0
- data/spec/lita/handlers/alertlogic_log_manager_spec.rb +11 -0
- data/spec/lita/handlers/alertlogic_monitoring_spec.rb +9 -0
- data/spec/lita/handlers/alertlogic_threat_manager_spec.rb +13 -0
- data/spec/spec_helper.rb +38 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 33f770a03b17649cee43382f7ebdc99703b21367
|
4
|
+
data.tar.gz: e7dd0d0a2336402d40a2f1fada7f3a7b71713e9b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6cd08c2a809b420cef9307bf722eaedfb660b147f36f0bcba615ec45801cb0684e43ce5d711cb75f1edd8946f5a0a0050f56bddec609d883473880aa5cb03e97
|
7
|
+
data.tar.gz: 36d9a795bc4a8f2042111acc5bc8d7d1a1e9b8c242af9fc8201f3b7ca81abee833553a2735a94f816d2ad0fb84e741cda5a40aafa2503e3f1891465c83d4ff48
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --profile 5
|
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2016 Alert Logic Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# lita-alertlogic
|
2
|
+
|
3
|
+
[](https://travis-ci.org/alertlogic/lita-alertlogic)
|
4
|
+
|
5
|
+
**lita-alertlogic** is a handler for [Lita](https://github.com/jimmycuadra/lita). It can be used to pull various data points about Alert Logic customers directly from Hipchat.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add lita-alertlogic to your Lita instance's Gemfile:
|
10
|
+
|
11
|
+
``` ruby
|
12
|
+
gem 'lita-alertlogic'
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
Run 'lita help alertlogic' to get detailed usage:
|
18
|
+
|
19
|
+
```
|
20
|
+
[You] lita help alertlogic
|
21
|
+
[Lita Bot]
|
22
|
+
Lita: alertlogic customerinfo <customer_id or customer_name> - Displays customer and child list.
|
23
|
+
Lita: alertlogic appliance agent counts <customer_id> - Displays count of agents assigned to each appliance
|
24
|
+
Lita: alertlogic policies agent counts <customer_id> - Displays count of agents assigned to each policy
|
25
|
+
Lita: alertlogic agent ip counts <customer_id> - Display count of IP's assigned to agents
|
26
|
+
Lita: alertlogic lm appliances <customer_id> - Displays customer LM appliance list.
|
27
|
+
Lita: alertlogic lm applianceinfo <customer_id> <applaince_uuid> - Displays LM appliance details.
|
28
|
+
Lita: alertlogic lm policies <customer_id> - Displays customer log assignment policies.
|
29
|
+
Lita: alertlogic lm sources <customer_id> - Displays customer log sources.
|
30
|
+
Lita: alertlogic lm hosts <customer_id> - Displays customer log hosts.
|
31
|
+
Lita: alertlogic tm appliances <customer_id> - Displays customer TM appliance list.
|
32
|
+
Lita: alertlogic tm applianceinfo <customer_id> <applaince_uuid> - Displays TM appliance details.
|
33
|
+
Lita: alertlogic tm policies <customer_id> - Displays customer threat assignment policies.
|
34
|
+
Lita: alertlogic tm hosts <customer_id> - Displays customer threat hosts hosts.
|
35
|
+
Lita: alertlogic protectedhosts status <customer_id> - Displays protected hosts summary.
|
36
|
+
Lita: alertlogic protectedhosts list <customer_id> - Displays complete protected hosts lists.
|
37
|
+
Lita: alertlogic protectedhosts search <customer_id> <protected host name or uuid>- Search protected hosts by name or uuid.
|
38
|
+
```
|
39
|
+
|
40
|
+
Example:
|
41
|
+
|
42
|
+
```
|
43
|
+
[You] lita alertlogic customerinfo Alert
|
44
|
+
[Lita Bot]
|
45
|
+
Information for parent customer: Alert Logic Inc.
|
46
|
+
Customer ID | Customer Name
|
47
|
+
------------+----------------
|
48
|
+
XXXXX | Alert Logic
|
49
|
+
```
|
50
|
+
|
51
|
+
## Config
|
52
|
+
|
53
|
+
```
|
54
|
+
Lita.configure do |config|
|
55
|
+
# Alert Logic API Settings
|
56
|
+
config.handlers.alertlogic.customer_id = 'your-alertlogic-customer-id'
|
57
|
+
config.handlers.alertlogic.api_auth = 'your-api-key-obtained-from-alert-logic:'
|
58
|
+
config.handlers.alertlogic.lm_api_url = 'https://publicapi.alertlogic.net/api/lm/v1'
|
59
|
+
config.handlers.alertlogic.tm_api_url = 'https://publicapi.alertlogic.net/api/tm/v1'
|
60
|
+
config.handlers.alertlogic.customer_api_url = 'https://api.alertlogic.net/api/customer/v1'
|
61
|
+
config.handlers.alertlogic.monitoring_api_url = 'https://api.alertlogic.net/api/monitoring/v1'
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
## Sample config with Hipchat plugin
|
66
|
+
|
67
|
+
```
|
68
|
+
Lita.configure do |config|
|
69
|
+
# Logging level
|
70
|
+
config.robot.log_level = :info
|
71
|
+
|
72
|
+
# Hipchat adapter
|
73
|
+
config.robot.adapter = :hipchat
|
74
|
+
|
75
|
+
# Bot name
|
76
|
+
config.robot.name = "Lita Bot"
|
77
|
+
|
78
|
+
# Bot admins Type: String or Array of Jabber ID(s)
|
79
|
+
config.robot.admins = ['some_jabber_id@chat.hipchat.com']
|
80
|
+
config.adapters.hipchat.jid = 'bots-hipchat-jabber-id@chat.hipchat.com'
|
81
|
+
config.adapters.hipchat.password = 'bots-password'
|
82
|
+
|
83
|
+
# Hipchat room(s) Type: String or Array
|
84
|
+
config.adapters.hipchat.rooms = :all
|
85
|
+
|
86
|
+
# Debugging mode
|
87
|
+
#config.adapters.hipchat.debug = false
|
88
|
+
|
89
|
+
# Alert Logic Settings
|
90
|
+
config.handlers.alertlogic.customer_id = 'your-alertlogic-customer-id'
|
91
|
+
config.handlers.alertlogic.api_auth = 'your-api-key-obtained-from-alert-logic:'
|
92
|
+
config.handlers.alertlogic.lm_api_url = 'https://publicapi.alertlogic.net/api/lm/v1'
|
93
|
+
config.handlers.alertlogic.tm_api_url = 'https://publicapi.alertlogic.net/api/tm/v1'
|
94
|
+
config.handlers.alertlogic.customer_api_url = 'https://api.alertlogic.net/api/customer/v1'
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
## License
|
99
|
+
|
100
|
+
[MIT](http://opensource.org/licenses/MIT)
|
data/Rakefile
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# Alertlogic Helper
|
2
|
+
module AlertlogicHelper
|
3
|
+
# Agents Helper
|
4
|
+
module Agents
|
5
|
+
# rubocop:disable MethodLength
|
6
|
+
def agent_appliance_summary(customer_id)
|
7
|
+
data = []
|
8
|
+
reply = "/code Appliance/Agents counts for customer: #{customer_id} \n"
|
9
|
+
headers = [
|
10
|
+
'Appliance Name',
|
11
|
+
'Appliance IP',
|
12
|
+
'Agents Count',
|
13
|
+
'Overall Collection Status'
|
14
|
+
]
|
15
|
+
|
16
|
+
params = {
|
17
|
+
customer_id: customer_id,
|
18
|
+
type: 'monitoring',
|
19
|
+
source: 'tmc-appliances'
|
20
|
+
}
|
21
|
+
assignment_info = parse_json(
|
22
|
+
api_call(params)
|
23
|
+
)
|
24
|
+
assignment_info['sources'].each do |source|
|
25
|
+
data << [
|
26
|
+
source['source']['name'],
|
27
|
+
source['source']['metadata']['local_ipv4'],
|
28
|
+
source['source']['agents_count'],
|
29
|
+
source['source']['status']['status']
|
30
|
+
]
|
31
|
+
end
|
32
|
+
reply << build_table(data, headers)
|
33
|
+
reply
|
34
|
+
end
|
35
|
+
# rubocop:enable MethodLength
|
36
|
+
|
37
|
+
# rubocop:disable MethodLength
|
38
|
+
def agent_policy_summary(customer_id)
|
39
|
+
data = []
|
40
|
+
reply = "/code Policy/Agents counts for customer: #{customer_id} \n"
|
41
|
+
headers = [
|
42
|
+
'Policy Name',
|
43
|
+
'Policy ID',
|
44
|
+
'Agents Count'
|
45
|
+
]
|
46
|
+
|
47
|
+
params = {
|
48
|
+
customer_id: customer_id,
|
49
|
+
type: 'tm',
|
50
|
+
source: 'policies'
|
51
|
+
}
|
52
|
+
policies = parse_json(api_call(params))['policies']
|
53
|
+
policies.each do |policy|
|
54
|
+
policy_id = policy['policy']['id']
|
55
|
+
policy_name = policy['policy']['name']
|
56
|
+
params = {
|
57
|
+
customer_id: customer_id,
|
58
|
+
api_type: 'tm',
|
59
|
+
source_type: 'protectedhosts'
|
60
|
+
}
|
61
|
+
base_url = construct_api_url(params)
|
62
|
+
url = "#{base_url}?appliance.policy.id=#{policy_id}"
|
63
|
+
params = {
|
64
|
+
customer_id: customer_id,
|
65
|
+
url: url
|
66
|
+
}
|
67
|
+
agents_count = parse_json(api_call(params))['total_count']
|
68
|
+
data << [
|
69
|
+
policy_name,
|
70
|
+
policy_id,
|
71
|
+
agents_count
|
72
|
+
]
|
73
|
+
end
|
74
|
+
reply << build_table(data, headers)
|
75
|
+
reply
|
76
|
+
end
|
77
|
+
# rubocop:enable MethodLength
|
78
|
+
|
79
|
+
def agent_ip_summary(customer_id)
|
80
|
+
data = []
|
81
|
+
headers = [
|
82
|
+
'IP Count/Agent',
|
83
|
+
'Agents Count'
|
84
|
+
]
|
85
|
+
reply = "/code Agents/IP summary for customer: #{customer_id} \n"
|
86
|
+
ip_count = []
|
87
|
+
summary = Hash.new 0
|
88
|
+
params = {
|
89
|
+
customer_id: customer_id,
|
90
|
+
type: 'tm',
|
91
|
+
source: 'protectedhosts'
|
92
|
+
}
|
93
|
+
agents = parse_json(api_call(params))['protectedhosts']
|
94
|
+
agents.each do |agent|
|
95
|
+
ip_count << agent['protectedhost']['metadata']['local_ipv4'].length unless !agent['protectedhost']['metadata']
|
96
|
+
end
|
97
|
+
ip_count.each do |count|
|
98
|
+
summary[count] += 1
|
99
|
+
end
|
100
|
+
summary.each do |agents_list, count|
|
101
|
+
data << [agents_list, count]
|
102
|
+
end
|
103
|
+
reply << build_table(data, headers)
|
104
|
+
reply
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Alertlogic Helper
|
2
|
+
module AlertlogicHelper
|
3
|
+
# Api Helper
|
4
|
+
module Api
|
5
|
+
def api_call(options = {})
|
6
|
+
customer_id = options[:customer_id]
|
7
|
+
type = options[:type] || nil
|
8
|
+
source = options[:source] || nil
|
9
|
+
url = options[:url] || nil
|
10
|
+
|
11
|
+
url_options = {
|
12
|
+
customer_id: customer_id,
|
13
|
+
api_type: type,
|
14
|
+
source_type: source
|
15
|
+
}
|
16
|
+
|
17
|
+
# Construct URL if url not provided
|
18
|
+
url = construct_api_url(url_options) if url.nil?
|
19
|
+
http_resp = http(config.http_options).get(url) do |req|
|
20
|
+
req.headers = headers
|
21
|
+
req.options.timeout = 90
|
22
|
+
end
|
23
|
+
http_resp.body.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def construct_api_url(options = {})
|
27
|
+
customer_id = options[:customer_id]
|
28
|
+
api_type = options[:api_type]
|
29
|
+
source_type = options[:source_type] || nil
|
30
|
+
|
31
|
+
case api_type
|
32
|
+
when 'customer'
|
33
|
+
return "#{config.customer_api_url}/#{customer_id}"
|
34
|
+
when 'monitoring'
|
35
|
+
return "#{config.monitoring_api_url}/#{source_type}/#{customer_id}"
|
36
|
+
when 'lm'
|
37
|
+
return "#{config.lm_api_url}/#{customer_id}/#{source_type}"
|
38
|
+
when 'tm'
|
39
|
+
return "#{config.tm_api_url}/#{customer_id}//#{source_type}"
|
40
|
+
else
|
41
|
+
return t('error.generic')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def headers
|
46
|
+
{}.tap do |headers|
|
47
|
+
headers['Authorization'] = "Basic #{Base64.encode64(config.api_auth).chomp.gsub(/\n/, '')}" if config.api_auth
|
48
|
+
headers['Content-Type'] = 'application/json'
|
49
|
+
headers['Accept'] = 'application/json'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Alertlogic Helper
|
2
|
+
module AlertlogicHelper
|
3
|
+
# Appliances Helper
|
4
|
+
module Appliances
|
5
|
+
def process_appliances(appliance_list, customer_id)
|
6
|
+
data = []
|
7
|
+
reply = "/code Customer appliances for ID: #{customer_id} \n"
|
8
|
+
headers = ['Appliance Type', 'UUID', 'Name', 'Status']
|
9
|
+
|
10
|
+
parse_json(appliance_list)['appliances'].each do |appliance|
|
11
|
+
appliance.each do |type, details|
|
12
|
+
data << [
|
13
|
+
type,
|
14
|
+
details['id'],
|
15
|
+
details['name'],
|
16
|
+
details['status']['status']
|
17
|
+
]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
count = parse_json(appliance_list)['total_count']
|
22
|
+
reply << build_table(data, headers)
|
23
|
+
reply << "Total Appliances: #{count}\n"
|
24
|
+
reply
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'pretty_table'
|
3
|
+
# Alertlogic Helper
|
4
|
+
module AlertlogicHelper
|
5
|
+
# Common Helper
|
6
|
+
module Common
|
7
|
+
def parse_json(json)
|
8
|
+
return JSON.parse(json)
|
9
|
+
rescue TypeError, JSON::ParserError
|
10
|
+
return t('error.json_parse')
|
11
|
+
end
|
12
|
+
|
13
|
+
def pretty_json(json)
|
14
|
+
JSON.pretty_generate(json)
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_table(data, headers)
|
18
|
+
PrettyTable.new(data, headers).to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def check_msg_size?(string)
|
22
|
+
string.length >= 9_500 && string.length <= 10_000
|
23
|
+
end
|
24
|
+
|
25
|
+
def search?(key, name, hash)
|
26
|
+
hash[key].downcase.include? name.downcase
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid_uuid?(string)
|
30
|
+
UUID.validate(string)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Alertlogic Helper
|
2
|
+
module AlertlogicHelper
|
3
|
+
# Customer Helper
|
4
|
+
module Customer
|
5
|
+
def find_cid_by_name(customer_name)
|
6
|
+
customer_ids = []
|
7
|
+
customer_list = all_customers
|
8
|
+
customer_list['child_chain'].each do |customer|
|
9
|
+
if customer['customer_name'].downcase.include? customer_name.downcase
|
10
|
+
customer_ids << customer['customer_id']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
customer_ids
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_customer_ids(parent)
|
17
|
+
params = {
|
18
|
+
customer_id: parent,
|
19
|
+
type: 'customer'
|
20
|
+
}
|
21
|
+
resp = api_call(params)
|
22
|
+
cids = []
|
23
|
+
return t('error.customer_not_found') if parse_json(resp)['error']
|
24
|
+
parse_json(resp)['child_chain'].each do |customer|
|
25
|
+
cids << customer['customer_id'].to_i
|
26
|
+
end
|
27
|
+
cids
|
28
|
+
end
|
29
|
+
|
30
|
+
def all_customers
|
31
|
+
params = {
|
32
|
+
customer_id: config.customer_id,
|
33
|
+
type: 'customer'
|
34
|
+
}
|
35
|
+
resp = api_call(params)
|
36
|
+
parse_json(resp)
|
37
|
+
end
|
38
|
+
|
39
|
+
def process_customer_id(customer)
|
40
|
+
if /\A[-+]?\d+\z/ === customer
|
41
|
+
return customer.to_i
|
42
|
+
else
|
43
|
+
return find_cid_by_name(customer)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid_cid(customer_id)
|
48
|
+
customer_id.to_i if /\A[-+]?\d+\z/ === customer_id.strip
|
49
|
+
end
|
50
|
+
|
51
|
+
def process_customers(customer_list)
|
52
|
+
reply_text = '/code '
|
53
|
+
headers = ['Customer ID', 'Customer Name']
|
54
|
+
data = []
|
55
|
+
if customer_list.is_a? Array
|
56
|
+
customer_list.each do |customer|
|
57
|
+
cust = parse_json(customer)
|
58
|
+
data << [
|
59
|
+
"#{cust['customer_id']}",
|
60
|
+
cust['customer_name'].strip
|
61
|
+
]
|
62
|
+
end
|
63
|
+
reply_text << build_table(data, headers)
|
64
|
+
else
|
65
|
+
if parse_json(customer_list)['error']
|
66
|
+
return t('error.customer_not_found')
|
67
|
+
end
|
68
|
+
parse_json(customer_list)['child_chain'].each do |customer|
|
69
|
+
data << [
|
70
|
+
"#{customer['customer_id']}",
|
71
|
+
customer['customer_name'].strip
|
72
|
+
]
|
73
|
+
end
|
74
|
+
reply_text << build_table(data, headers)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|