Skip to content

Commit

Permalink
feat: Support Cohesity (#1412)
Browse files Browse the repository at this point in the history
fixes #1399
  • Loading branch information
Ryan Faircloth authored Jan 30, 2022
1 parent c07adcd commit b8525fc
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 0 deletions.
49 changes: 49 additions & 0 deletions docs/sources/Cohesity/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Vendor - Cohesity


## Product - Switches

| Ref | Link |
|----------------|---------------------------------------------------------------------------------------------------------|
| Splunk Add-on | None |
| Product Manual | unknown |


### Sourcetypes

| sourcetype | notes |
|----------------|---------------------------------------------------------------------------------------------------------|
| cohesity:cluster:audit | None |
| cohesity:cluster:dataprotection | None |

### Sourcetype and Index Configuration

| key | sourcetype | index | notes |
|----------------|----------------|----------------|----------------|
| cohesity_cluster_audit | cohesity:cluster:audit | infraops | none |
| cohesity_cluster_dataprotection | cohesity:cluster:dataprotection | infraops | none |

### Filter type

MSG Parsing

### Setup and Configuration

Device setup unknown

### Options

| Variable | default | description |
|----------------|----------------|----------------|
| SC4S_LISTEN_COHESITY_CLUSTER_TCP_PORT | empty string | Enable a TCP port for this specific vendor product using a comma-separated list of port numbers |
| SC4S_LISTEN_COHESITY_CLUSTER_UDP_PORT | empty string | Enable a UDP port for this specific vendor product using a comma-separated list of port numbers |
| SC4S_ARCHIVE_COHESITY_CLUSTER | no | Enable archive to disk for this specific source |
| SC4S_DEST_COHESITY_CLUSTER_HEC | no | When Splunk HEC is disabled globally set to yes to enable this specific source |

### Verification

An active device will generate frequent events. Use the following search to validate events are present per source device

```
index=<asconfigured> sourcetype=cohesity:cluster:* | stats count by host
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ nav:
- Checkpoint: sources/Checkpoint/index.md
- Cisco: sources/Cisco/index.md
- Citrix: sources/Citrix/index.md
- Cohesity: sources/Cohesity/index.md
- "Common Event Format": sources/CommonEventFormat/index.md
- CyberArk: sources/CyberArk/index.md
- Cylance: sources/Cylance/index.md
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
block parser app-syslog-cohesity_cluster_audit() {
channel {
parser {
json-parser(
prefix('.values.')
);
date-parser-nofilter(
format(
'%Y-%m-%dT%T.%f%z',
'%Y-%m-%dT%T%z',
)
template("${.values.Timestamp}")
);
};
filter {
"${.values.ClusterInfo}" ne "";
};
rewrite {
r_set_splunk_dest_default(
index('infraops')
sourcetype('cohesity:cluster:audit')
vendor_product("cohesity_cluster_audit")
template('t_msg_only')
);
};

};
};
application app-syslog-cohesity_cluster_audit[sc4s-syslog] {
filter {
"${PROGRAM}" eq "cluster_audit";
};
parser { app-syslog-cohesity_cluster_audit(); };
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
block parser app-syslog-cohesity_cluster_dataprotection() {
channel {
parser {
json-parser(
prefix('.values.')
);
date-parser-nofilter(
format(
'%Y-%m-%dT%T.%f%z',
'%Y-%m-%dT%T%z',
)
template("${.values.Timestamp}")
);
};
filter {
"${.values.EventType}" ne "";
};
rewrite {
r_set_splunk_dest_default(
index('infraops')
sourcetype('cohesity:cluster:dataprotection')
vendor_product("cohesity_cluster_dataprotection")
template('t_msg_only')
);
};

};
};
application app-syslog-cohesity_cluster_dataprotection[sc4s-syslog] {
filter {
"${PROGRAM}" eq "dataprotection_events";
};
parser { app-syslog-cohesity_cluster_dataprotection(); };
};

89 changes: 89 additions & 0 deletions tests/test_cohesity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Copyright 2019 Splunk, Inc.
#
# Use of this source code is governed by a BSD-2-clause-style
# license that can be found in the LICENSE-BSD2 file or at
# https://opensource.org/licenses/BSD-2-Clause

from jinja2 import Environment

from .sendmessage import *
from .splunkutils import *
from .timeutils import *

import pytest

env = Environment()


# <14>Jan 26 14:20:39 host cluster_audit: {"Timestamp" : "2022-01-26T14:19:27.512Z", "AttributeMap" : {}, "EntityType" : "Access Token", "EntityId" : "cohesitysnowdev", "EntityName" : "cohesitysnowdev", "User" : "", "Domain" : "local", "Action" : "Create", "Description" : "@local attempted to generate new access token for user cohesitysnowdev on domain local from 1.1.1.1 failed with error Invalid Username or Password specified.", "ClusterInfo" : "ClusterName: clustername, ClusterId: xxxxxx"}
testdata = [
'{{ mark }}{{ bsd }} {{ host }} cluster_audit: {"Timestamp" : "{{ iso }}", "AttributeMap" : {}, "EntityType" : "Access Token", "EntityId" : "cohesitysnowdev", "EntityName" : "cohesitysnowdev", "User" : "", "Domain" : "local", "Action" : "Create", "Description" : "@local attempted to generate new access token for user cohesitysnowdev on domain local from 1.1.1.1 failed with error Invalid Username or Password specified.", "ClusterInfo" : "ClusterName: clustername, ClusterId: xxxxxx"}',
]


@pytest.mark.parametrize("event", testdata)
def test_cohesity_cluster_audit(
record_property, setup_wordlist, get_host_key, setup_splunk, setup_sc4s, event
):
host = get_host_key

dt = datetime.datetime.now()
iso, bsd, time, date, tzoffset, tzname, epoch = time_operations(dt)

# Tune time functions
epoch = epoch[:-3]

mt = env.from_string(event + "\n")
message = mt.render(mark="<166>", bsd=bsd, host=host, iso=iso)

sendsingle(message, setup_sc4s[0], setup_sc4s[1][514])

st = env.from_string(
'search index=infraops _time={{ epoch }} sourcetype="cohesity:cluster:audit" (host="{{ host }}" OR "{{ host }}")'
)
search = st.render(epoch=epoch, host=host)

resultCount, eventCount = splunk_single(setup_splunk, search)

record_property("host", host)
record_property("resultCount", resultCount)
record_property("message", message)

assert resultCount == 1


# <14>Jan 26 14:20:39 host cluster_audit: {"Timestamp" : "2022-01-26T14:19:27.512Z", "AttributeMap" : {}, "EntityType" : "Access Token", "EntityId" : "cohesitysnowdev", "EntityName" : "cohesitysnowdev", "User" : "", "Domain" : "local", "Action" : "Create", "Description" : "@local attempted to generate new access token for user cohesitysnowdev on domain local from 1.1.1.1 failed with error Invalid Username or Password specified.", "ClusterInfo" : "ClusterName: clustername, ClusterId: xxxxxx"}
testdata2 = [
'{{ mark }}{{ bsd }} {{ host }} dataprotection_events: {"EventMessage" : "Expiring backup run", "Timestamp" : "{{ iso }}", "ClusterInfo" : {"ClusterId" : "1755240360407376", "ClusterName" : "cluster-name"}, "EventType" : "kBackup", "EnvironmentType" : "kVMware", "RegisteredSource" : {"EntityType" : "kVMware", "EntityId" : "1", "EntityName" : "ttllxapp-vc01"}, "BackupJobName" : "test1", "BackupJobId" : "582", "Entities" : [{"EntityType" : "kVMware", "EntityId" : "27", "EntityName" : "xxx-xxx"}, {"EntityType" : "kVMware", "EntityId" : "70", "EntityName" : "ttllxapp-joe01"}], "TaskId" : "509872", "AttributeMap" : {}}',
]


@pytest.mark.parametrize("event", testdata2)
def test_cohesity_dataprotection_events(
record_property, setup_wordlist, get_host_key, setup_splunk, setup_sc4s, event
):
host = get_host_key

dt = datetime.datetime.now()
iso, bsd, time, date, tzoffset, tzname, epoch = time_operations(dt)

# Tune time functions
epoch = epoch[:-3]

mt = env.from_string(event + "\n")
message = mt.render(mark="<166>", bsd=bsd, host=host, iso=iso)

sendsingle(message, setup_sc4s[0], setup_sc4s[1][514])

st = env.from_string(
'search index=infraops _time={{ epoch }} sourcetype="cohesity:cluster:dataprotection" (host="{{ host }}" OR "{{ host }}")'
)
search = st.render(epoch=epoch, host=host)

resultCount, eventCount = splunk_single(setup_splunk, search)

record_property("host", host)
record_property("resultCount", resultCount)
record_property("message", message)

assert resultCount == 1

0 comments on commit b8525fc

Please sign in to comment.