forked from splunk/slack-alerts
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
4,145 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
presets: ['@splunk/babel-preset'], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,13 +10,32 @@ | |
"repository": "[email protected]:ziegfried/splunk-slack-alerts.git", | ||
"author": "Siegfried Puchbauer <[email protected]>", | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"@splunk/react-page": "^3.0.0", | ||
"@splunk/react-toast-notifications": "^0.7.0", | ||
"@splunk/react-ui": "^2", | ||
"react": "^16", | ||
"react-dom": "^16", | ||
"styled-components": "^4" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7", | ||
"@splunk/babel-preset": "^3.0.0", | ||
"@splunk/webpack-configs": "^5.0.0", | ||
"babel-loader": "^8.0.4", | ||
"onchange": "^3.2.1", | ||
"splunk-slap": "^0.0.6" | ||
"prettier": "^2.0.5", | ||
"splunk-slap": "^0.0.6", | ||
"webpack": "^4.16.2", | ||
"webpack-cli": "^3.1.0", | ||
"webpack-livereload-plugin": "^2.1.1", | ||
"webpack-merge": "^4.1.3" | ||
}, | ||
"scripts": { | ||
"setup": "yarn install && yarn build && yarn symlink", | ||
"build": "slap stage", | ||
"build:pages": "webpack --config=src/ui/webpack.config.js --bail", | ||
"slap:post-stage": "yarn build:pages", | ||
"symlink": "slap symlink", | ||
"package": "slap package --prod", | ||
"pkg": "yarn package", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<!doctype html> | ||
<html class="no-js" lang=""> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="x-ua-compatible" content="ie=edge"> | ||
<title> | ||
Slack Alerts Setup | ||
</title> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<link rel="apple-touch-icon" href="apple-touch-icon.png"> | ||
</head> | ||
<body> | ||
<script src="${make_url('/config?autoload=1')}" crossorigin="use-credentials"></script> | ||
<script src="${make_url('/static/js/i18n.js')}"></script> | ||
<script src="${make_url('/i18ncatalog?autoload=1')}"></script> | ||
<% | ||
page_path = "/static/app/slack_alerts/pages/slack_alerts_setup.js" | ||
common_path = "/static/app/slack_alerts/pages/common.js" | ||
%> | ||
<script src="${make_url(common_path)}"></script> | ||
<script src="${make_url(page_path)}"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0"?> | ||
<view template="slack_alerts:/templates/setup.html" type="html"> | ||
<label>Slack Alerts Setup</label> | ||
</view> |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { useState, useEffect, useCallback } from 'react'; | ||
import { makeUrl } from './utils'; | ||
import Toaster, { makeCreateToast } from '@splunk/react-toast-notifications/Toaster'; | ||
|
||
const createToast = makeCreateToast(Toaster); | ||
|
||
function getFormKey() { | ||
const prefix = `splunkweb_csrf_token_${window.$C.MRSPARKLE_PORT_NUMBER}=`; | ||
if (document.cookie) { | ||
for (const chunk of document.cookie.split(';')) { | ||
const cookie = String(chunk).trim(); | ||
if (cookie.startsWith(prefix)) { | ||
return decodeURIComponent(cookie.slice(prefix.length)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
export function loadConfig() { | ||
return fetch( | ||
makeUrl('/splunkd/__raw/servicesNS/-/-/alerts/alert_actions/slack?output_mode=json&_=' + Date.now()) | ||
) | ||
.then((res) => { | ||
if (!res.ok) { | ||
throw new Error(`Failed to fetch config: HTTP status ${res.status}`); | ||
} | ||
return res.json(); | ||
}) | ||
.then((data) => { | ||
const d = data.entry[0].content; | ||
return { | ||
webhook_url: d['param.webhook_url'], | ||
from_user: d['param.from_user'], | ||
from_user_icon: d['param.from_user_icon'], | ||
}; | ||
}); | ||
} | ||
|
||
export function updateConfig(data) { | ||
return fetch( | ||
makeUrl(`/splunkd/__raw/servicesNS/-/slack_alerts/alerts/alert_actions/slack?output_mode=json`), | ||
{ | ||
method: 'POST', | ||
body: [ | ||
`param.webhook_url=${encodeURIComponent(data.webhook_url)}`, | ||
`param.from_user=${encodeURIComponent(data.from_user)}`, | ||
`param.from_user_icon=${encodeURIComponent(data.from_user_icon)}`, | ||
].join('&'), | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
'X-Requested-With': 'XMLHttpRequest', | ||
'X-Splunk-Form-Key': getFormKey(), | ||
}, | ||
} | ||
).then((res) => { | ||
if (!res.ok) { | ||
throw new Error(`Failed to save: HTTP status ${res.status}`); | ||
} | ||
}); | ||
} | ||
|
||
const eq = (a, b) => { | ||
const ka = Object.keys(a); | ||
const kb = Object.keys(b); | ||
return ka.length === kb.length && ka.every((k) => k in b && a[k] === b[k]); | ||
}; | ||
|
||
export function useSlackConfig() { | ||
const [loading, setLoading] = useState(true); | ||
const [error, setError] = useState(null); | ||
const [savedData, setSavedData] = useState({}); | ||
const [data, setData] = useState({}); | ||
|
||
useEffect(() => { | ||
loadConfig().then( | ||
(cfg) => { | ||
setSavedData(cfg); | ||
setData(cfg); | ||
setLoading(false); | ||
}, | ||
(e) => { | ||
setError(`Error: ${e.message}`); | ||
setLoading(false); | ||
} | ||
); | ||
}, [setLoading, setError]); | ||
|
||
const update = useCallback( | ||
(data) => { | ||
setData(data); | ||
}, | ||
[setData] | ||
); | ||
|
||
const save = useCallback(() => { | ||
if (!eq(savedData, data)) { | ||
updateConfig(data).then( | ||
() => { | ||
setSavedData(data); | ||
createToast({ | ||
message: 'Successfully updated Slack alert action', | ||
type: 'success', | ||
}); | ||
}, | ||
(e) => { | ||
setError(`Error: ${e.message}`); | ||
createToast({ | ||
message: `Failed to save changes: ${e.message}`, | ||
type: 'error', | ||
autoDismiss: false, | ||
}); | ||
} | ||
); | ||
} | ||
}, [data, savedData, setSavedData, setError]); | ||
|
||
return [{ loading, error, data, isDirty: !eq(savedData, data) }, update, save]; | ||
} | ||
|
||
export function redirectToAlertListingPage() { | ||
window.location = makeUrl('/manager/slack_alerts/alert_actions'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import Button from '@splunk/react-ui/Button'; | ||
import ControlGroup from '@splunk/react-ui/ControlGroup'; | ||
import Heading from '@splunk/react-ui/Heading'; | ||
import Link from '@splunk/react-ui/Link'; | ||
import Paragraph from '@splunk/react-ui/Paragraph'; | ||
import Text from '@splunk/react-ui/Text'; | ||
import React, { useCallback } from 'react'; | ||
import { useSlackConfig, redirectToAlertListingPage } from './config'; | ||
import { openSlackMessagePreview } from './preview'; | ||
import { ButtonGroup, FormWrapper } from './styles'; | ||
|
||
export function SetupForm() { | ||
const [{ loading, error, data, isDirty }, update, save] = useSlackConfig(); | ||
|
||
const updateUrl = useCallback((e, { value }) => update({ ...data, webhook_url: value })); | ||
const updateUser = useCallback((e, { value }) => update({ ...data, from_user: value })); | ||
const updateUserIcon = useCallback((e, { value }) => update({ ...data, from_user_icon: value })); | ||
|
||
const webhookUrl = loading ? '' : data.webhook_url; | ||
const fromUserName = loading ? '' : data.from_user; | ||
const fromUserIcon = loading ? '' : data.from_user_icon; | ||
|
||
return ( | ||
<> | ||
<Heading level={3}>Slack Incoming Webhook</Heading> | ||
<Paragraph> | ||
This alert action uses Slack's{' '} | ||
<Link to="https://slack.com/apps/A0F7XDUAZ-incoming-webhooks" openInNewContext> | ||
Incoming Webhooks | ||
</Link>{' '} | ||
to post messages from Splunk into Slack channels. You can set a default webhook URL here, | ||
which will be used for all alerts be default. Each alert can override and use a different | ||
webhook URL that has different permissions or can send to a different Slack workspace. | ||
</Paragraph> | ||
<FormWrapper> | ||
<ControlGroup | ||
label="Webhook URL" | ||
help={ | ||
<Link to="https://slack.com/apps/A0F7XDUAZ-incoming-webhooks" openInNewContext> | ||
Configure Slack incoming webhook | ||
</Link> | ||
} | ||
> | ||
<Text | ||
value={webhookUrl} | ||
onChange={updateUrl} | ||
disabled={loading} | ||
placeholder="https://hooks.slack.com/services/XXXXX/YYYY/ZZZZZ" | ||
/> | ||
</ControlGroup> | ||
</FormWrapper> | ||
<Heading level={3}>Message Appearance</Heading> | ||
<Paragraph> | ||
The following settings will influence how messages will show up in Slack.{' '} | ||
<Link onClick={() => openSlackMessagePreview(data)} openInNewContext> | ||
Show Preview | ||
</Link> | ||
. | ||
</Paragraph> | ||
<FormWrapper> | ||
<ControlGroup | ||
label="Sender Name" | ||
help="This name will appear in slack as the user sending the message." | ||
> | ||
<Text value={fromUserName} onChange={updateUser} disabled={loading} /> | ||
</ControlGroup> | ||
<ControlGroup | ||
label="Sender Icon" | ||
help="The avatar/icon shown by the sender of the slack message. This URL needs to be accessible from the internet." | ||
> | ||
<Text value={fromUserIcon} onChange={updateUserIcon} disabled={loading} /> | ||
</ControlGroup> | ||
</FormWrapper> | ||
<ButtonGroup> | ||
<div> | ||
<Button label="Cancel" appearance="secondary" onClick={redirectToAlertListingPage} /> | ||
</div> | ||
<div> | ||
<Button label="Save" appearance="primary" disabled={loading || !isDirty} onClick={save} /> | ||
</div> | ||
</ButtonGroup> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import layout from '@splunk/react-page'; | ||
import Heading from '@splunk/react-ui/Heading'; | ||
import React from 'react'; | ||
import { SetupForm } from './form'; | ||
import { BodyWrapper, Dialog, DialogWrapper, TitleWrapper } from './styles'; | ||
import ToastMessages from '@splunk/react-toast-notifications/ToastMessages'; | ||
|
||
function SlackSetupPage() { | ||
return ( | ||
<BodyWrapper> | ||
<TitleWrapper> | ||
<Heading level={1}>Slack Alerts Setup</Heading> | ||
</TitleWrapper> | ||
<DialogWrapper> | ||
<Dialog> | ||
<SetupForm /> | ||
</Dialog> | ||
</DialogWrapper> | ||
<ToastMessages /> | ||
</BodyWrapper> | ||
); | ||
} | ||
|
||
layout(<SlackSetupPage />, { pageTitle: 'Slack Alert setup', hideAppBar: true }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export function generateMessageJSON({ from_user, from_user_icon, message = 'Lorem ipsum dolor sit amet.' }) { | ||
return { | ||
text: message, | ||
username: from_user, | ||
icon_url: from_user_icon, | ||
}; | ||
} | ||
|
||
export function openSlackMessagePreview(data) { | ||
const url = `https://api.slack.com/docs/messages/builder?msg=${encodeURIComponent( | ||
JSON.stringify(generateMessageJSON(data)) | ||
)}`; | ||
window.open(url); | ||
} |
Oops, something went wrong.