From 3f2f2424794ac0f2fecd94cd4a3a12477eea46fc Mon Sep 17 00:00:00 2001 From: Remi Date: Sun, 7 Feb 2021 15:02:21 +0100 Subject: [PATCH] feat(splunk-on-call-plugin): edge cases --- app-config.yaml | 2 +- plugins/splunk-on-call/README.md | 2 +- plugins/splunk-on-call/src/api/client.ts | 12 +-- plugins/splunk-on-call/src/api/types.ts | 6 -- .../components/Incident/IncidentListItem.tsx | 19 +---- .../src/components/SplunkOnCallCard.test.tsx | 2 +- .../src/components/SplunkOnCallCard.tsx | 73 +++++++++++++++---- .../TriggerDialog/TriggerDialog.tsx | 15 ++-- 8 files changed, 75 insertions(+), 56 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index de5bec1f54..7cc194d06b 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -394,5 +394,5 @@ homepage: timezone: 'Asia/Tokyo' pagerduty: eventsBaseUrl: 'https://events.pagerduty.com/v2' -splunkoncall: +splunkOnCall: username: 'guest' diff --git a/plugins/splunk-on-call/README.md b/plugins/splunk-on-call/README.md index cc32735164..50fefb5255 100644 --- a/plugins/splunk-on-call/README.md +++ b/plugins/splunk-on-call/README.md @@ -54,7 +54,7 @@ The user supplied must be a valid Splunk On-Call user and a member of your organ In `app-config.yaml`: ```yaml -splunkoncall: +splunkOnCall: username: ``` diff --git a/plugins/splunk-on-call/src/api/client.ts b/plugins/splunk-on-call/src/api/client.ts index e974f27b83..955192e241 100644 --- a/plugins/splunk-on-call/src/api/client.ts +++ b/plugins/splunk-on-call/src/api/client.ts @@ -44,7 +44,7 @@ export const splunkOnCallApiRef = createApiRef({ export class SplunkOnCallClient implements SplunkOnCallApi { static fromConfig(configApi: ConfigApi, discoveryApi: DiscoveryApi) { const usernameFromConfig: string | null = - configApi.getOptionalString('splunkoncall.username') || 'ayshiff'; + configApi.getOptionalString('splunkoncall.username') || null; return new SplunkOnCallClient({ username: usernameFromConfig, discoveryApi, @@ -52,10 +52,6 @@ export class SplunkOnCallClient implements SplunkOnCallApi { } constructor(private readonly config: ClientApiConfig) {} - getUsername(): string | undefined { - return this.config.username as string; - } - async getIncidents(): Promise { const url = `${await this.config.discoveryApi.getBaseUrl( 'proxy', @@ -85,7 +81,6 @@ export class SplunkOnCallClient implements SplunkOnCallApi { } async acknowledgeIncident({ - userName, incidentNames, }: PatchIncidentRequest): Promise { const options = { @@ -95,7 +90,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { 'Content-Type': 'application/json', }, body: JSON.stringify({ - userName: this.config.username || userName, + userName: this.config.username, incidentNames, }), }; @@ -108,7 +103,6 @@ export class SplunkOnCallClient implements SplunkOnCallApi { } async resolveIncident({ - userName, incidentNames, }: PatchIncidentRequest): Promise { const options = { @@ -118,7 +112,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { 'Content-Type': 'application/json', }, body: JSON.stringify({ - userName: this.config.username || userName, + userName: this.config.username, incidentNames, }), }; diff --git a/plugins/splunk-on-call/src/api/types.ts b/plugins/splunk-on-call/src/api/types.ts index 4cfa5037f1..bce42d35d2 100644 --- a/plugins/splunk-on-call/src/api/types.ts +++ b/plugins/splunk-on-call/src/api/types.ts @@ -83,15 +83,9 @@ export interface SplunkOnCallApi { * Get a list of escalation policies for your organization. */ getEscalationPolicies(): Promise; - - /** - * Get the current user username. - */ - getUsername(): string | undefined; } export type PatchIncidentRequest = { - userName: string; incidentNames: string[]; message?: string; }; diff --git a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx index eb29bc2aad..beaf1b4848 100644 --- a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx +++ b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx @@ -94,13 +94,11 @@ const incidentPhaseTooltip = (currentPhase: IncidentPhase) => { const IncidentAction = ({ currentPhase, - userName, incidentNames, resolveAction, aknowledgeAction, }: { currentPhase: string; - userName: string; incidentNames: string[]; resolveAction: (args: PatchIncidentRequest) => void; aknowledgeAction: (args: PatchIncidentRequest) => void; @@ -109,9 +107,7 @@ const IncidentAction = ({ case 'UNACKED': return ( - aknowledgeAction({ userName, incidentNames })} - > + aknowledgeAction({ incidentNames })}> @@ -119,9 +115,7 @@ const IncidentAction = ({ case 'ACKED': return ( - resolveAction({ userName, incidentNames })} - > + resolveAction({ incidentNames })}> @@ -135,8 +129,6 @@ export const IncidentListItem = ({ incident, onIncidentAction }: Props) => { const classes = useStyles(); const createdAt = formatDistanceToNowStrict(new Date(incident.startTime!)); const alertApi = useApi(alertApiRef); - const identityApi = useApi(identityApiRef); - const userName = identityApi.getUserId(); const api = useApi(splunkOnCallApiRef); const hasBeenManuallyTriggered = incident.monitorName?.includes('vouser-'); @@ -149,9 +141,8 @@ export const IncidentListItem = ({ incident, onIncidentAction }: Props) => { { value: resolveValue, loading: _resolveLoading, error: resolveError }, handleResolveIncident, ] = useAsyncFn( - async ({ userName, incidentNames }: PatchIncidentRequest) => + async ({ incidentNames }: PatchIncidentRequest) => await api.resolveIncident({ - userName, incidentNames, }), ); @@ -164,9 +155,8 @@ export const IncidentListItem = ({ incident, onIncidentAction }: Props) => { }, handleAcknowledgeIncident, ] = useAsyncFn( - async ({ userName, incidentNames }: PatchIncidentRequest) => + async ({ incidentNames }: PatchIncidentRequest) => await api.acknowledgeIncident({ - userName, incidentNames, }), ); @@ -230,7 +220,6 @@ export const IncidentListItem = ({ incident, onIncidentAction }: Props) => { {incident.incidentLink && incident.incidentNumber && ( ( + +); + +export const MissingUsername = () => ( + + + +); + export const isPluginApplicableToEntity = (entity: Entity) => Boolean(entity.metadata.annotations?.[SPLUNK_ON_CALL_TEAM]); @@ -62,11 +83,14 @@ type Props = { export const SplunkOnCallCard = ({ entity }: Props) => { const classes = useStyles(); + const config = useApi(configApiRef); const api = useApi(splunkOnCallApiRef); const [showDialog, setShowDialog] = useState(false); const [refreshIncidents, setRefreshIncidents] = useState(false); const team = entity.metadata.annotations![SPLUNK_ON_CALL_TEAM]; + const username = config.getOptionalString('splunkOnCall.username'); + const handleRefresh = useCallback(() => { setRefreshIncidents(x => !x); }, []); @@ -89,6 +113,9 @@ export const SplunkOnCallCard = ({ entity }: Props) => { return { usersHashMap, userList: users }; }); + const incidentCreator = + username && users?.userList.find(user => user.username === username); + if (error instanceof UnauthorizedError) { return ; } @@ -105,6 +132,33 @@ export const SplunkOnCallCard = ({ entity }: Props) => { return ; } + const Content = () => { + if (!team) { + return ; + } + if (!username) { + return ; + } + + return ( + <> + + {users?.usersHashMap && team && ( + + )} + {users && incidentCreator && ( + + )} + + ); + }; + const triggerLink = { label: 'Create Incident', action: ( @@ -126,23 +180,14 @@ export const SplunkOnCallCard = ({ entity }: Props) => { title="Splunk On-Call" subheader={[ Team: {team}, - , + username && ( + + ), ]} /> - - {users?.usersHashMap && ( - - )} - {users && ( - - )} + ); diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx index b2bc50cf33..3b84052aa7 100644 --- a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx +++ b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx @@ -34,8 +34,6 @@ import { FormControl, InputLabel, } from '@material-ui/core'; -import Card from '@material-ui/core/Card'; -import CardContent from '@material-ui/core/CardContent'; import { useApi, alertApiRef, identityApiRef } from '@backstage/core'; import { useAsync, useAsyncFn } from 'react-use'; import { splunkOnCallApiRef } from '../../api'; @@ -52,8 +50,8 @@ const MenuProps = { }; type Props = { - // name: string; users: User[]; + incidentCreator: User; showDialog: boolean; handleDialog: () => void; onIncidentCreated: () => void; @@ -82,6 +80,7 @@ const useStyles = makeStyles((theme: Theme) => export const TriggerDialog = ({ users, + incidentCreator, showDialog, handleDialog, onIncidentCreated: onIncidentCreated, @@ -118,10 +117,6 @@ export const TriggerDialog = ({ }), ); - const username = api.getUsername(); - - const currentUser = users.find(user => user.username === username); - const { value: policies, loading: policiesLoaading, @@ -187,7 +182,7 @@ export const TriggerDialog = ({ Created by:{' '} - {currentUser?.firstName} {currentUser?.lastName} + {incidentCreator?.firstName} {incidentCreator?.lastName} @@ -257,7 +252,9 @@ export const TriggerDialog = ({ value={policyTargets} onChange={handlePolicyTargets} input={} - inputProps={{ 'data-testid': 'trigger-select-policies-target' }} + inputProps={{ + 'data-testid': 'trigger-select-policies-target', + }} renderValue={selected => (
{(selected as string[]).map(value => {