Skip to content

Commit dbbb3b0

Browse files
committed
new actions
1 parent c0edb4b commit dbbb3b0

File tree

8 files changed

+785
-6
lines changed

8 files changed

+785
-6
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import splunk from "../../splunk.app.mjs";
2+
3+
export default {
4+
key: "splunk-create-event",
5+
name: "Create Event",
6+
description: "Sends a new event to a specified Splunk index. [See the documentation](https://docs.splunk.com/Documentation/Splunk/9.4.1/RESTREF/RESTinput#receivers.2Fsimple)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
splunk,
11+
selfSigned: {
12+
propDefinition: [
13+
splunk,
14+
"selfSigned",
15+
],
16+
},
17+
indexName: {
18+
propDefinition: [
19+
splunk,
20+
"indexName",
21+
(c) => ({
22+
selfSigned: c.selfSigned,
23+
}),
24+
],
25+
},
26+
eventData: {
27+
type: "string",
28+
label: "Event Data",
29+
description: "The data of the event to send to the Splunk index. Raw event text. This is the entirety of the HTTP request body",
30+
},
31+
source: {
32+
type: "string",
33+
label: "Source",
34+
description: "The source value to fill in the metadata for this input's events",
35+
optional: true,
36+
},
37+
sourcetype: {
38+
type: "string",
39+
label: "Sourcetype",
40+
description: "The sourcetype to apply to events from this input",
41+
optional: true,
42+
},
43+
},
44+
async run({ $ }) {
45+
const response = await this.splunk.sendEvent({
46+
$,
47+
selfSigned: this.selfSigned,
48+
params: {
49+
index: this.indexName,
50+
source: this.source,
51+
sourcetype: this.sourcetype,
52+
},
53+
data: this.eventData,
54+
});
55+
$.export("$summary", `Event sent to index ${this.indexName} successfully`);
56+
return response;
57+
},
58+
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import splunk from "../../splunk.app.mjs";
2+
3+
export default {
4+
key: "splunk-get-search-job-status",
5+
name: "Get Search Job Status",
6+
description: "Retrieve the status of a previously executed Splunk search job. [See the documentation](https://docs.splunk.com/Documentation/Splunk/9.4.1/RESTREF/RESTsearch#search.2Fjobs)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
splunk,
11+
selfSigned: {
12+
propDefinition: [
13+
splunk,
14+
"selfSigned",
15+
],
16+
},
17+
searchId: {
18+
propDefinition: [
19+
splunk,
20+
"searchId",
21+
(c) => ({
22+
selfSigned: c.selfSigned,
23+
}),
24+
],
25+
},
26+
},
27+
async run({ $ }) {
28+
const response = await this.splunk.getSearchJobStatus({
29+
$,
30+
selfSigned: this.selfSigned,
31+
searchId: this.searchId,
32+
});
33+
$.export("$summary", `Successfully retrieved status for job ID ${this.searchId}`);
34+
return response;
35+
},
36+
};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import splunk from "../../splunk.app.mjs";
2+
3+
export default {
4+
key: "splunk-run-search",
5+
name: "Run Search",
6+
description: "Executes a Splunk search query and returns the results. [See the documentation](https://docs.splunk.com/Documentation/Splunk/9.4.1/RESTREF/RESTsearch#search.2Fjobs)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
splunk,
11+
selfSigned: {
12+
propDefinition: [
13+
splunk,
14+
"selfSigned",
15+
],
16+
},
17+
query: {
18+
type: "string",
19+
label: "Search Query",
20+
description: "The Splunk search query. Example: `search *`. [See the documentation](https://docs.splunk.com/Documentation/Splunk/9.4.1/SearchReference/Search) for more information about search command sytax.",
21+
},
22+
earliestTime: {
23+
type: "string",
24+
label: "Earliest Time",
25+
description: "Specify a time string. Sets the earliest (inclusive), respectively, time bounds for the search. The time string can be either a UTC time (with fractional seconds), a relative time specifier (to now) or a formatted time string. Refer to [Time modifiers](https://docs.splunk.com/Documentation/Splunk/9.4.1/SearchReference/SearchTimeModifiers) for search for information and examples of specifying a time string.",
26+
optional: true,
27+
},
28+
latestTime: {
29+
type: "string",
30+
label: "Latest Time",
31+
description: " Specify a time string. Sets the latest (exclusive), respectively, time bounds for the search. The time string can be either a UTC time (with fractional seconds), a relative time specifier (to now) or a formatted time string. Refer to [Time modifiers](https://docs.splunk.com/Documentation/Splunk/9.4.1/SearchReference/SearchTimeModifiers) for search for information and examples of specifying a time string.",
32+
optional: true,
33+
},
34+
},
35+
async run({ $ }) {
36+
const response = await this.splunk.executeSearchQuery({
37+
$,
38+
selfSigned: this.selfSigned,
39+
data: {
40+
search: this.query,
41+
earliest_time: this.earliestTime,
42+
latest_time: this.latestTime,
43+
},
44+
});
45+
$.export("$summary", `Executed Splunk search query: ${this.query}`);
46+
return response;
47+
},
48+
};

components/splunk/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/splunk",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Pipedream Splunk Components",
55
"main": "splunk.app.mjs",
66
"keywords": [
@@ -11,5 +11,9 @@
1111
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
1212
"publishConfig": {
1313
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.3",
17+
"https": "^1.0.0"
1418
}
15-
}
19+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import splunk from "../../splunk.app.mjs";
2+
3+
export default {
4+
key: "splunk-new-alert-instant",
5+
name: "Splunk New Alert (Instant)",
6+
description: "Emit new event when a saved search alert is triggered in Splunk. [See the documentation]()",
7+
version: "0.0.{{ts}}",
8+
type: "source",
9+
dedupe: "unique",
10+
props: {
11+
splunk,
12+
alertName: {
13+
propDefinition: [
14+
"splunk",
15+
"alertName",
16+
],
17+
},
18+
pollingInterval: {
19+
propDefinition: [
20+
"splunk",
21+
"pollingInterval",
22+
],
23+
},
24+
http: {
25+
type: "$.interface.http",
26+
customResponse: false,
27+
},
28+
db: "$.service.db",
29+
},
30+
hooks: {
31+
async deploy() {
32+
const currentTime = Math.floor(Date.now() / 1000);
33+
const lastRunTime = currentTime - (this.pollingInterval || 60);
34+
await this.db.set("lastRunTime", lastRunTime);
35+
},
36+
async activate() {
37+
// No webhook creation needed for polling
38+
},
39+
async deactivate() {
40+
// No webhook deletion needed for polling
41+
},
42+
},
43+
methods: {
44+
async getSearchResults(jobId) {
45+
let results = [];
46+
let offset = 0;
47+
const count = 100;
48+
49+
while (true) {
50+
const response = await this.splunk._makeRequest({
51+
method: "GET",
52+
path: `search/jobs/${jobId}/results`,
53+
params: {
54+
count,
55+
offset,
56+
output_mode: "json",
57+
},
58+
});
59+
60+
if (!response.results || response.results.length === 0) {
61+
break;
62+
}
63+
64+
results = results.concat(response.results);
65+
offset += count;
66+
67+
if (response.results.length < count) {
68+
break;
69+
}
70+
}
71+
72+
return results;
73+
},
74+
},
75+
async run() {
76+
const lastRunTime = (await this.db.get("lastRunTime")) || 0;
77+
const currentTime = Math.floor(Date.now() / 1000);
78+
79+
let query = `_time > ${lastRunTime}`;
80+
if (this.alertName) {
81+
query = `savedsearch="${this.alertName}" AND _time > ${lastRunTime}`;
82+
}
83+
84+
const searchJob = await this.splunk.search({
85+
query,
86+
earliestTime: lastRunTime,
87+
latestTime: currentTime,
88+
});
89+
90+
const jobId = searchJob.sid;
91+
92+
let jobStatus;
93+
do {
94+
jobStatus = await this.splunk.getSearchJobStatus({
95+
jobId,
96+
});
97+
if (jobStatus.status === "DONE") break;
98+
await new Promise((resolve) => setTimeout(resolve, 1000));
99+
} while (true);
100+
101+
const results = await this.methods.getSearchResults(jobId);
102+
103+
for (const result of results) {
104+
const eventData = result;
105+
106+
this.$emit(eventData, {
107+
id: result._raw || JSON.stringify(result),
108+
summary: `Alert "${this.alertName || "All Alerts"}" triggered.`,
109+
ts: result._time
110+
? result._time * 1000
111+
: Date.now(),
112+
});
113+
}
114+
115+
await this.db.set("lastRunTime", currentTime);
116+
},
117+
};

0 commit comments

Comments
 (0)