Skip to content

Commit

Permalink
Merge pull request #1752 from RoadieHQ/sc-24202-wiz-snags
Browse files Browse the repository at this point in the history
Improve error handling
  • Loading branch information
Irma12 authored Dec 9, 2024
2 parents 2e3cbf3 + 0f076ce commit 3136a49
Show file tree
Hide file tree
Showing 16 changed files with 85 additions and 73 deletions.
7 changes: 7 additions & 0 deletions .changeset/breezy-pigs-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@roadiehq/backstage-plugin-wiz': patch
'@roadiehq/plugin-wiz-backend': patch
'backend': patch
---

Handle missing parameters message, remove uneeded config property. Improve description in WIZ graphs
3 changes: 0 additions & 3 deletions app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,3 @@ bugsnag:

iframe:
allowList: ['example.com']

wiz:
enabled: false
20 changes: 1 addition & 19 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,6 @@ async function main() {
const argocdEnv = useHotMemoize(module, () => createEnv('argocd'));
const wizEnv = useHotMemoize(module, () => createEnv('wiz'));

const wizConfig = {
enabled: config.getOptionalBoolean('wiz.enabled'),
clientId: config.getOptionalString('wiz.clientId'),
clientSecret: config.getOptionalString('wiz.clientSecret'),
tokenUrl: config.getOptionalString('wiz.tokenUrl'),
apiUrl: config.getOptionalString('wiz.wizAPIUrl'),
};

const apiRouter = Router();
apiRouter.use('/catalog', await catalog(catalogEnv));
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
Expand All @@ -115,17 +107,7 @@ async function main() {
apiRouter.use('/proxy', await proxy(proxyEnv));
apiRouter.use('/aws', await aws(awsEnv));
apiRouter.use('/argocd', await argocd(argocdEnv));

if (
wizConfig.enabled &&
wizConfig.clientId &&
wizConfig.clientSecret &&
wizConfig.tokenUrl &&
wizConfig.apiUrl
) {
apiRouter.use('/wiz-backend', await wiz(wizEnv));
}

apiRouter.use('/wiz-backend', await wiz(wizEnv));
apiRouter.use(notFoundHandler());

const service = createServiceBuilder(module)
Expand Down
3 changes: 1 addition & 2 deletions plugins/backend/wiz-backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ After obtaining all of the above, add wiz configuration in your app-config.yaml

```yaml
wiz:
enabled: true
clientId: <Client ID>
clientSecret: <Client Secret>
tokenUrl: <Wiz token URL>
wizAPIUrl: <API Endpoint URL>
dashboardLink: <your-wiz-url>
```
Create a file in `packages/backend/src/plugins/wiz.ts`
Expand All @@ -54,7 +54,6 @@ async function main() {
const wizEnv = useHotMemoize(module, () => createEnv('wiz'));
const wizConfig = {
enabled: config.getOptionalBoolean('wiz.enabled'),
clientId: config.getOptionalString('wiz.clientId'),
clientSecret: config.getOptionalString('wiz.clientSecret'),
tokenUrl: config.getOptionalString('wiz.tokenUrl'),
Expand Down
4 changes: 0 additions & 4 deletions plugins/backend/wiz-backend/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
*/
export interface Config {
wiz?: {
/**
* @visibility frontend
*/
enabled?: boolean;
/**
* @visibility frontend
*/
Expand Down
4 changes: 0 additions & 4 deletions plugins/backend/wiz-backend/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ export const wizBackendPlugin = createBackendPlugin({
config,
}),
);
httpRouter.addAuthPolicy({
path: '/health',
allow: 'unauthenticated',
});
},
});
},
Expand Down
9 changes: 5 additions & 4 deletions plugins/backend/wiz-backend/src/service/WizClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ export class WizClient {
private tokenExpiresAt: number | null = null;

constructor(config: Config) {
this.clientId = config.getString('wiz.clientId');
this.clientSecret = config.getString('wiz.clientSecret');
this.tokenUrl = config.getString('wiz.tokenUrl');
this.wizAPIUrl = config.getString('wiz.wizAPIUrl');
this.clientId = config.getOptionalString('wiz.clientId') ?? 'clientId';
this.clientSecret =
config.getOptionalString('wiz.clientSecret') ?? 'clientSecret';
this.tokenUrl = config.getOptionalString('wiz.tokenUrl') ?? 'tokenUrl';
this.wizAPIUrl = config.getOptionalString('wiz.wizAPIUrl') ?? 'wizAPIUrl';
}

async fetchAccessToken() {
Expand Down
45 changes: 41 additions & 4 deletions plugins/backend/wiz-backend/src/service/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
LoggerService,
RootConfigService,
} from '@backstage/backend-plugin-api';
import express from 'express';
import express, { Request, Response, NextFunction } from 'express';
import Router from 'express-promise-router';
import { WizClient } from './WizClient';

Expand All @@ -26,6 +26,40 @@ export interface RouterOptions {
config: RootConfigService;
}

function validateWizConfig(config: any) {
return (_req: Request, res: Response, next: NextFunction): void => {
const wizConfig = {
clientId: config.getOptionalString('wiz.clientId'),
clientSecret: config.getOptionalString('wiz.clientSecret'),
tokenUrl: config.getOptionalString('wiz.tokenUrl'),
apiUrl: config.getOptionalString('wiz.wizAPIUrl'),
};

if (!wizConfig.clientId || !wizConfig.clientSecret) {
res.status(401).send({
error: 'Not authenticated, missing Client Secret or Client ID.',
});
return;
}

if (!wizConfig.tokenUrl) {
res.status(400).send({
error: 'Missing token URL.',
});
return;
}

if (!wizConfig.apiUrl) {
res.status(400).send({
error: 'Missing API endpoint URL',
});
return;
}

next();
};
}

export async function createRouter(
options: RouterOptions,
): Promise<express.Router> {
Expand All @@ -34,10 +68,11 @@ export async function createRouter(
const router = Router();
const wizAuthClient = new WizClient(config);

await wizAuthClient.fetchAccessToken();
router.use(validateWizConfig(config));

router.get('/wiz-issues/:projectId', async (req, res) => {
try {
await wizAuthClient.fetchAccessToken();
const data = await wizAuthClient.getIssuesForProject(
req.params.projectId,
);
Expand All @@ -53,8 +88,10 @@ export async function createRouter(
error: error.message,
});
}
return res.status(500).send({
error: 'Failed to fetch issues for project',
return res.status(error.statusCode).send({
error:
error.message ??
'There was an error fetching issues for this project',
});
}
});
Expand Down
1 change: 0 additions & 1 deletion plugins/frontend/backstage-plugin-wiz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ In order to add correct url which will lead to WIZ dashboard for your organisati

```yaml
wiz:
enabled: true
dashboardLink: <your-wiz-url>
clientId: <Client ID>
clientSecret: <Client Secret>
Expand Down
Binary file modified plugins/frontend/backstage-plugin-wiz/docs/issues-chart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plugins/frontend/backstage-plugin-wiz/docs/issues-widget.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plugins/frontend/backstage-plugin-wiz/docs/severity-graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const IssuesChart = () => {
return (
<InfoCard
title="Issues status graph"
subheader="Status (resolved vs. open) of the last 500 issues created within the past 6 months."
headerProps={{
action: <WizIcon />,
classes: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,24 @@ import { ResponsiveLine } from '@nivo/line';
import { WizIssue } from '../Issues/types';
import { useTheme } from '@material-ui/core';

const issueStatusFilters = {
openIssues: 'OPEN',
resolvedIssues: 'RESOLVED',
};

export const LineChart = ({ issues }: { issues: WizIssue[] }) => {
const theme = useTheme();

const transformIssuesForChart = () => {
const monthMap: Record<string, { open: number; resolved: number }> = {};

const sixMonthsAgo = new Date();
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);

issues?.forEach(
(issue: {
createdAt: string | number | Date;
resolvedAt: string | number | Date;
}) => {
(issue: { status: string; createdAt: string | number | Date }) => {
const createdAtDate = new Date(issue.createdAt);
const resolvedAtDate = issue.resolvedAt
? new Date(issue.resolvedAt)
: null;

// Filter based on createdAt
if (createdAtDate >= sixMonthsAgo) {
const createdAtMonth = createdAtDate.toLocaleString('default', {
month: 'short',
Expand All @@ -47,19 +46,12 @@ export const LineChart = ({ issues }: { issues: WizIssue[] }) => {
if (!monthMap[createdAtMonth]) {
monthMap[createdAtMonth] = { open: 0, resolved: 0 };
}
monthMap[createdAtMonth].open += 1;
}

if (resolvedAtDate && resolvedAtDate >= sixMonthsAgo) {
const resolvedAtMonth = resolvedAtDate.toLocaleString('default', {
month: 'short',
year: 'numeric',
});

if (!monthMap[resolvedAtMonth]) {
monthMap[resolvedAtMonth] = { open: 0, resolved: 0 };
if (issue.status === issueStatusFilters.openIssues) {
monthMap[createdAtMonth].open += 1;
} else if (issue.status === issueStatusFilters.resolvedIssues) {
monthMap[createdAtMonth].resolved += 1;
}
monthMap[resolvedAtMonth].resolved += 1;
}
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export const SeverityChart = () => {

return (
<InfoCard
title="Severity graph"
title="Severity Graph"
subheader="Severity status of the last 500 issues created within the past 6 months."
headerProps={{
action: <WizIcon />,
classes: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,18 @@ export const IssuesWidget = () => {
root: classes.card,
},
}}
deepLink={{
link: `https://${dashboardLink}`,
title: 'Go to WIZ',
onClick: e => {
e.preventDefault();
window.open(`https://${dashboardLink}`);
},
}}
deepLink={
dashboardLink
? {
link: `https://${dashboardLink}`,
title: 'Go to your WIZ dashboard',
onClick: e => {
e.preventDefault();
window.open(`https://${dashboardLink}`);
},
}
: undefined
}
>
{' '}
{value && value.length > 0 ? (
Expand All @@ -131,7 +135,7 @@ export const IssuesWidget = () => {
display="flex"
mt={2}
flexDirection="column"
width="9vw"
width="8.5vw"
style={{
backgroundColor: theme.palette.background.default,
}}
Expand Down Expand Up @@ -186,7 +190,7 @@ export const IssuesWidget = () => {
display="flex"
mt={2}
flexDirection="column"
width="9vw"
width="8.5vw"
style={{
backgroundColor: theme.palette.background.default,
}}
Expand Down Expand Up @@ -241,7 +245,7 @@ export const IssuesWidget = () => {
display="flex"
mt={2}
flexDirection="column"
width="9vw"
width="8.5vw"
style={{
backgroundColor: theme.palette.background.default,
}}
Expand Down Expand Up @@ -296,7 +300,7 @@ export const IssuesWidget = () => {
display="flex"
mt={2}
flexDirection="column"
width="9vw"
width="8.5vw"
style={{
backgroundColor: theme.palette.background.default,
}}
Expand Down

0 comments on commit 3136a49

Please sign in to comment.