Skip to content

Commit

Permalink
feat(cdevents-notification): CDEvents notification to produce CDEvents (
Browse files Browse the repository at this point in the history
#9997)

* feat(cdevents-notification): CDEvents notification to produce CDEvents

* fix: linter issue Sort the import statements

* fix: cdevents files formatting

* adding validations for URL and cdevents type

* fix prettier formatting issue

* update regex for URL validation

* review comments on placeholder/regex configurable

* lint issue with order import

* lint issue Prettier
  • Loading branch information
rjalander authored Dec 22, 2023
1 parent 20d6ca8 commit fc96adb
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 2 deletions.
3 changes: 3 additions & 0 deletions halconfig/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ window.spinnakerSettings = {
pubsub: {
enabled: true,
},
cdevents: {
enabled: true,
},
slack: slack,
sms: sms,
},
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ window.spinnakerSettings = {
sms: {
enabled: true,
},
cdevents: {
enabled: true,
},
},
onDemandClusterThreshold: Number(onDemandClusterThreshold),
pollSchedule: 30000,
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface INotificationSettings {
pubsub: { enabled: boolean };
slack: { botName: string; enabled: boolean };
sms: { enabled: boolean };
cdevents: { enabled: boolean };
}

export interface IFeatures {
Expand Down Expand Up @@ -152,6 +153,10 @@ export interface ISpinnakerSettings {
useClassicFirewallLabels: boolean;
kubernetesAdHocInfraWritesEnabled: boolean;
changelogUrl: string;
cdevents?: {
validUrlPattern: string;
validCDEvent: string;
};
}

export const SETTINGS: ISpinnakerSettings = (window as any).spinnakerSettings || {};
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/notification/modal/NotificationDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ export class NotificationDetails extends React.Component<INotificationDetailsPro
}

private renderCustomMessage = (type: string, whenOption: string): React.ReactNode => {
if (whenOption !== 'manualJudgment' && ['email', 'slack', 'googlechat', 'microsoftteams'].includes(type)) {
if (
whenOption !== 'manualJudgment' &&
['email', 'slack', 'googlechat', 'microsoftteams', 'cdevents'].includes(type)
) {
return (
<FormikFormField
name={`message["${whenOption}"].text`}
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/notification/notification.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { INotificationTypeConfig } from '../domain';
import { Registry } from '../registry';

import { bearyChatNotification } from './selector/types/bearychat/beary.notification';
import { cdEventsNotification } from './selector/types/cdevents/cdevents.notification';
import { emailNotification } from './selector/types/email/email.notification';
import { githubstatusNotification } from './selector/types/githubstatus/githubstatus.notification';
import { googlechatNotification } from './selector/types/googlechat/googlechat.notification';
Expand All @@ -23,6 +24,7 @@ import { smsNotification } from './selector/types/sms/sms.notification';
pubsubNotification,
slackNotification,
smsNotification,
cdEventsNotification,
].forEach((config: INotificationTypeConfig) => {
if (SETTINGS.notifications) {
const notificationSetting: { enabled: boolean; botName?: string } =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';

import type { INotificationTypeCustomConfig } from '../../../../domain';
import { FormikFormField, TextInput, Validators } from '../../../../presentation';

export class CDEventsNotificationType extends React.Component<INotificationTypeCustomConfig> {
public render() {
const { fieldName } = this.props;
return (
<>
<FormikFormField
label="Events Broker URL"
name={fieldName ? `${fieldName}.address` : 'address'}
validate={Validators.skipIfSpel(Validators.urlValue('Please enter a valid URL'))}
input={(props) => (
<TextInput
inputClassName={'form-control input-sm'}
{...props}
placeholder="Enter an events message broker URL"
/>
)}
required={true}
/>
<FormikFormField
label="CDEvents Type"
name={fieldName ? `${fieldName}.cdEventsType` : 'cdEventsType'}
validate={Validators.skipIfSpel(Validators.cdeventsTypeValue('Please enter a valid CDEvents Type'))}
input={(props) => (
<TextInput inputClassName={'form-control input-sm'} {...props} placeholder="Enter a CDEvents type" />
)}
required={true}
/>
</>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { CDEventsNotificationType } from './CDEventsNotificationType';
import type { INotificationTypeConfig } from '../../../../domain';

export const cdEventsNotification: INotificationTypeConfig = {
component: CDEventsNotificationType,
key: 'cdevents',
label: 'CDEvents',
};
1 change: 1 addition & 0 deletions packages/core/src/notification/selector/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './microsoftteams/MicrosoftTeamsNotificationType';
export * from './pubsub/PubsubNotificationType';
export * from './slack/SlackNotificationType';
export * from './sms/SmsNotificationType';
export * from './cdevents/CDEventsNotificationType';
25 changes: 24 additions & 1 deletion packages/core/src/presentation/forms/validation/validators.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { isNumber } from 'lodash';
import { robotToHuman } from '../../robotToHumanFilter/robotToHuman.filter';

import { SETTINGS } from '../../../config/settings';
import { robotToHuman } from '../../robotToHumanFilter/robotToHuman.filter';
import type { IValidator } from './validation';

const THIS_FIELD = 'This field';
Expand All @@ -9,13 +10,33 @@ const VALID_EMAIL_REGEX = new RegExp(
'^(([^<>()\\[\\]\\\\.,;:\\s@"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$',
);

const urlPattern = SETTINGS.cdevents?.validUrlPattern ?? '^https?://.+$';
const VALID_URL = new RegExp(urlPattern);

const cdeventPattern = SETTINGS.cdevents?.validCDEvent ?? '^dev\\.cdevents\\.[^.]+\\.[^.]+$';
const VALID_CDEVENT_REGEX = new RegExp(cdeventPattern);

const emailValue = (message?: string): IValidator => {
return function emailValue(val: string, label = THIS_FIELD) {
message = message || `${label} is not a valid email address.`;
return val && !VALID_EMAIL_REGEX.test(val) && message;
};
};

const urlValue = (message?: string): IValidator => {
return function urlValue(val: string, label = THIS_FIELD) {
message = message || `${label} is not a valid URL.`;
return val && !VALID_URL.test(val) && message;
};
};

const cdeventsTypeValue = (message?: string): IValidator => {
return function cdeventsTypeValue(val: string, label = THIS_FIELD) {
message = message || `${label} is not a valid CDEvents Type.`;
return val && !VALID_CDEVENT_REGEX.test(val) && message;
};
};

const isRequired = (message?: string): IValidator => {
return function isRequired(val: any, label = THIS_FIELD) {
message = message || `${label} is required.`;
Expand Down Expand Up @@ -138,6 +159,8 @@ export const Validators = {
arrayNotEmpty,
checkBetween,
emailValue,
cdeventsTypeValue,
urlValue,
isNum,
isRequired,
isValidJson,
Expand Down

0 comments on commit fc96adb

Please sign in to comment.