mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: implement optional json payload and template (#4752)
## About the changes Adds optional support for specifying JSON templates for datadog message payload  ### Important files <!-- PRs can contain a lot of changes, but not all changes are equally important. Where should a reviewer start looking to get an overview of the changes? Are any files particularly important? --> `frontend/src/component/integrations/IntegrationForm/IntegrationParameters/IntegrationParameter/IntegrationParameterEnableWithDropdown.tsx` - a new component comprising of a text field and a dropdown menu `src/lib/addons/datadog.ts` - Where the integration is taking place ## Discussion points <!-- Anything about the PR you'd like to discuss before it gets merged? Got any questions or doubts? --> - Should I have implemented the new component type as a specifiable addon parameter type in definitions? Felt a bit YAGNI/Premature - Would like input on naming and the new component etc
This commit is contained in:
		
							parent
							
								
									be7f0d8b4e
								
							
						
					
					
						commit
						bff1bd1026
					
				| @ -1,19 +1,8 @@ | |||||||
| import { TextField, Typography } from '@mui/material'; |  | ||||||
| import { ChangeEventHandler } from 'react'; | import { ChangeEventHandler } from 'react'; | ||||||
| import { StyledAddonParameterContainer } from '../../IntegrationForm.styles'; | import { StyledAddonParameterContainer } from '../../IntegrationForm.styles'; | ||||||
| import type { AddonParameterSchema, AddonSchema } from 'openapi'; | import type { AddonParameterSchema, AddonSchema } from 'openapi'; | ||||||
| 
 | import { IntegrationParameterTextField } from './IntegrationParameterTextField'; | ||||||
| const resolveType = ({ type = 'text', sensitive = false }, value: string) => { | import { useUiFlag } from 'hooks/useUiFlag'; | ||||||
|     if (sensitive && value === MASKED_VALUE) { |  | ||||||
|         return 'text'; |  | ||||||
|     } |  | ||||||
|     if (type === 'textfield') { |  | ||||||
|         return 'text'; |  | ||||||
|     } |  | ||||||
|     return type; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const MASKED_VALUE = '*****'; |  | ||||||
| 
 | 
 | ||||||
| export interface IIntegrationParameterProps { | export interface IIntegrationParameterProps { | ||||||
|     parametersErrors: Record<string, string>; |     parametersErrors: Record<string, string>; | ||||||
| @ -28,41 +17,22 @@ export const IntegrationParameter = ({ | |||||||
|     parametersErrors, |     parametersErrors, | ||||||
|     setParameterValue, |     setParameterValue, | ||||||
| }: IIntegrationParameterProps) => { | }: IIntegrationParameterProps) => { | ||||||
|     const value = config.parameters[definition?.name] || ''; |     const datadogJson = useUiFlag('datadogJsonTemplate'); | ||||||
|     const type = resolveType( |     if ( | ||||||
|         definition, |         config.provider === 'datadog' && | ||||||
|         typeof value === 'string' ? value : '' |         definition.name === 'bodyTemplate' && | ||||||
|     ); |         !datadogJson | ||||||
|     const error = parametersErrors[definition.name]; |     ) { | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|         <StyledAddonParameterContainer> |         <StyledAddonParameterContainer> | ||||||
|             <TextField |             <IntegrationParameterTextField | ||||||
|                 size="small" |                 config={config} | ||||||
|                 style={{ width: '100%' }} |                 definition={definition} | ||||||
|                 minRows={definition.type === 'textfield' ? 5 : 0} |                 parametersErrors={parametersErrors} | ||||||
|                 multiline={definition.type === 'textfield'} |                 setParameterValue={setParameterValue} | ||||||
|                 type={type} |  | ||||||
|                 label={ |  | ||||||
|                     <> |  | ||||||
|                         {definition.displayName} |  | ||||||
|                         {definition.required ? ( |  | ||||||
|                             <Typography component="span" color="error"> |  | ||||||
|                                 * |  | ||||||
|                             </Typography> |  | ||||||
|                         ) : null} |  | ||||||
|                     </> |  | ||||||
|                 } |  | ||||||
|                 name={definition.name} |  | ||||||
|                 placeholder={definition.placeholder || ''} |  | ||||||
|                 InputLabelProps={{ |  | ||||||
|                     shrink: true, |  | ||||||
|                 }} |  | ||||||
|                 value={value} |  | ||||||
|                 error={Boolean(error)} |  | ||||||
|                 onChange={setParameterValue(definition.name)} |  | ||||||
|                 variant="outlined" |  | ||||||
|                 helperText={definition.description} |  | ||||||
|             /> |             /> | ||||||
|         </StyledAddonParameterContainer> |         </StyledAddonParameterContainer> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -0,0 +1,70 @@ | |||||||
|  | import { TextField, Typography } from '@mui/material'; | ||||||
|  | import { AddonParameterSchema, AddonSchema } from 'openapi'; | ||||||
|  | import { ChangeEventHandler } from 'react'; | ||||||
|  | import { styled } from '@mui/material'; | ||||||
|  | 
 | ||||||
|  | const MASKED_VALUE = '*****'; | ||||||
|  | 
 | ||||||
|  | const resolveType = ({ type = 'text', sensitive = false }, value: string) => { | ||||||
|  |     if (sensitive && value === MASKED_VALUE) { | ||||||
|  |         return 'text'; | ||||||
|  |     } | ||||||
|  |     if (type === 'textfield') { | ||||||
|  |         return 'text'; | ||||||
|  |     } | ||||||
|  |     return type; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export interface IIntegrationParameterTextFieldProps { | ||||||
|  |     parametersErrors: Record<string, string>; | ||||||
|  |     definition: AddonParameterSchema; | ||||||
|  |     setParameterValue: (param: string) => ChangeEventHandler<HTMLInputElement>; | ||||||
|  |     config: AddonSchema; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const StyledTextField = styled(TextField)({ | ||||||
|  |     width: '100%', | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | export const IntegrationParameterTextField = ({ | ||||||
|  |     definition, | ||||||
|  |     config, | ||||||
|  |     parametersErrors, | ||||||
|  |     setParameterValue, | ||||||
|  | }: IIntegrationParameterTextFieldProps) => { | ||||||
|  |     const value = config.parameters[definition?.name] || ''; | ||||||
|  |     const type = resolveType( | ||||||
|  |         definition, | ||||||
|  |         typeof value === 'string' ? value : '' | ||||||
|  |     ); | ||||||
|  |     const error = parametersErrors[definition.name]; | ||||||
|  | 
 | ||||||
|  |     return ( | ||||||
|  |         <StyledTextField | ||||||
|  |             size="small" | ||||||
|  |             minRows={definition.type === 'textfield' ? 5 : 0} | ||||||
|  |             multiline={definition.type === 'textfield'} | ||||||
|  |             type={type} | ||||||
|  |             label={ | ||||||
|  |                 <> | ||||||
|  |                     {definition.displayName} | ||||||
|  |                     {definition.required ? ( | ||||||
|  |                         <Typography component="span" color="error"> | ||||||
|  |                             * | ||||||
|  |                         </Typography> | ||||||
|  |                     ) : null} | ||||||
|  |                 </> | ||||||
|  |             } | ||||||
|  |             name={definition.name} | ||||||
|  |             placeholder={definition.placeholder || ''} | ||||||
|  |             InputLabelProps={{ | ||||||
|  |                 shrink: true, | ||||||
|  |             }} | ||||||
|  |             value={value} | ||||||
|  |             error={Boolean(error)} | ||||||
|  |             onChange={setParameterValue(definition.name)} | ||||||
|  |             variant="outlined" | ||||||
|  |             helperText={definition.description} | ||||||
|  |         /> | ||||||
|  |     ); | ||||||
|  | }; | ||||||
| @ -75,6 +75,7 @@ exports[`should create default config 1`] = ` | |||||||
|       "anonymiseEventLog": false, |       "anonymiseEventLog": false, | ||||||
|       "caseInsensitiveInOperators": false, |       "caseInsensitiveInOperators": false, | ||||||
|       "customRootRolesKillSwitch": false, |       "customRootRolesKillSwitch": false, | ||||||
|  |       "datadogJsonTemplate": false, | ||||||
|       "demo": false, |       "demo": false, | ||||||
|       "dependentFeatures": false, |       "dependentFeatures": false, | ||||||
|       "disableBulkToggle": false, |       "disableBulkToggle": false, | ||||||
| @ -114,6 +115,7 @@ exports[`should create default config 1`] = ` | |||||||
|       "anonymiseEventLog": false, |       "anonymiseEventLog": false, | ||||||
|       "caseInsensitiveInOperators": false, |       "caseInsensitiveInOperators": false, | ||||||
|       "customRootRolesKillSwitch": false, |       "customRootRolesKillSwitch": false, | ||||||
|  |       "datadogJsonTemplate": false, | ||||||
|       "demo": false, |       "demo": false, | ||||||
|       "dependentFeatures": false, |       "dependentFeatures": false, | ||||||
|       "disableBulkToggle": false, |       "disableBulkToggle": false, | ||||||
|  | |||||||
| @ -8,6 +8,8 @@ exports[`Should call datadog webhook 1`] = `"{"text":"%%% \\n some@user.com crea | |||||||
| 
 | 
 | ||||||
| exports[`Should call datadog webhook for toggled environment 1`] = `"{"text":"%%% \\n some@user.com *disabled* [some-toggle](http://some-url.com/projects/default/features/some-toggle) in *development* environment in project *default* \\n %%% ","title":"Unleash notification update"}"`; | exports[`Should call datadog webhook for toggled environment 1`] = `"{"text":"%%% \\n some@user.com *disabled* [some-toggle](http://some-url.com/projects/default/features/some-toggle) in *development* environment in project *default* \\n %%% ","title":"Unleash notification update"}"`; | ||||||
| 
 | 
 | ||||||
|  | exports[`Should call datadog webhook with JSON when template set 1`] = `"{"text":"{\\n  \\"event\\": \\"feature-created\\",\\n  \\"createdBy\\": \\"some@user.com\\"\\n}","title":"Unleash notification update"}"`; | ||||||
|  | 
 | ||||||
| exports[`Should include customHeaders in headers when calling service 1`] = `"{"text":"%%% \\n some@user.com *disabled* [some-toggle](http://some-url.com/projects/default/features/some-toggle) in *development* environment in project *default* \\n %%% ","title":"Unleash notification update"}"`; | exports[`Should include customHeaders in headers when calling service 1`] = `"{"text":"%%% \\n some@user.com *disabled* [some-toggle](http://some-url.com/projects/default/features/some-toggle) in *development* environment in project *default* \\n %%% ","title":"Unleash notification update"}"`; | ||||||
| 
 | 
 | ||||||
| exports[`Should include customHeaders in headers when calling service 2`] = ` | exports[`Should include customHeaders in headers when calling service 2`] = ` | ||||||
|  | |||||||
| @ -62,6 +62,21 @@ const dataDogDefinition: IAddonDefinition = { | |||||||
|             sensitive: true, |             sensitive: true, | ||||||
|             type: 'textfield', |             type: 'textfield', | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |             name: 'bodyTemplate', | ||||||
|  |             displayName: 'Body template', | ||||||
|  |             placeholder: `{
 | ||||||
|  |   "event": "{{event.type}}", | ||||||
|  |   "createdBy": "{{event.createdBy}}", | ||||||
|  |   "featureToggle": "{{event.data.name}}", | ||||||
|  |   "timestamp": "{{event.data.createdAt}}" | ||||||
|  | }`,
 | ||||||
|  |             description: | ||||||
|  |                 '(Optional) The default format is a markdown string formatted by Unleash. You may override the format of the body using a mustache template.', | ||||||
|  |             required: false, | ||||||
|  |             sensitive: false, | ||||||
|  |             type: 'textfield', | ||||||
|  |         }, | ||||||
|     ], |     ], | ||||||
|     events: [ |     events: [ | ||||||
|         FEATURE_CREATED, |         FEATURE_CREATED, | ||||||
|  | |||||||
| @ -39,6 +39,11 @@ test('Should call datadog webhook', async () => { | |||||||
|     const addon = new DatadogAddon({ |     const addon = new DatadogAddon({ | ||||||
|         getLogger: noLogger, |         getLogger: noLogger, | ||||||
|         unleashUrl: 'http://some-url.com', |         unleashUrl: 'http://some-url.com', | ||||||
|  |         flagResolver: { | ||||||
|  |             getAll: jest.fn().mockReturnValue([]), | ||||||
|  |             getVariant: jest.fn(), | ||||||
|  |             isEnabled: jest.fn().mockReturnValue(false), | ||||||
|  |         }, | ||||||
|     }); |     }); | ||||||
|     const event: IEvent = { |     const event: IEvent = { | ||||||
|         id: 1, |         id: 1, | ||||||
| @ -68,6 +73,11 @@ test('Should call datadog webhook  for archived toggle', async () => { | |||||||
|     const addon = new DatadogAddon({ |     const addon = new DatadogAddon({ | ||||||
|         getLogger: noLogger, |         getLogger: noLogger, | ||||||
|         unleashUrl: 'http://some-url.com', |         unleashUrl: 'http://some-url.com', | ||||||
|  |         flagResolver: { | ||||||
|  |             getAll: jest.fn().mockReturnValue([]), | ||||||
|  |             getVariant: jest.fn(), | ||||||
|  |             isEnabled: jest.fn().mockReturnValue(false), | ||||||
|  |         }, | ||||||
|     }); |     }); | ||||||
|     const event: IEvent = { |     const event: IEvent = { | ||||||
|         id: 2, |         id: 2, | ||||||
| @ -95,6 +105,11 @@ test('Should call datadog webhook  for archived toggle with project info', async | |||||||
|     const addon = new DatadogAddon({ |     const addon = new DatadogAddon({ | ||||||
|         getLogger: noLogger, |         getLogger: noLogger, | ||||||
|         unleashUrl: 'http://some-url.com', |         unleashUrl: 'http://some-url.com', | ||||||
|  |         flagResolver: { | ||||||
|  |             getAll: jest.fn().mockReturnValue([]), | ||||||
|  |             getVariant: jest.fn(), | ||||||
|  |             isEnabled: jest.fn().mockReturnValue(false), | ||||||
|  |         }, | ||||||
|     }); |     }); | ||||||
|     const event: IEvent = { |     const event: IEvent = { | ||||||
|         id: 2, |         id: 2, | ||||||
| @ -123,6 +138,11 @@ test(`Should call datadog webhook for toggled environment`, async () => { | |||||||
|     const addon = new DatadogAddon({ |     const addon = new DatadogAddon({ | ||||||
|         getLogger: noLogger, |         getLogger: noLogger, | ||||||
|         unleashUrl: 'http://some-url.com', |         unleashUrl: 'http://some-url.com', | ||||||
|  |         flagResolver: { | ||||||
|  |             getAll: jest.fn().mockReturnValue([]), | ||||||
|  |             getVariant: jest.fn(), | ||||||
|  |             isEnabled: jest.fn().mockReturnValue(false), | ||||||
|  |         }, | ||||||
|     }); |     }); | ||||||
|     const event: IEvent = { |     const event: IEvent = { | ||||||
|         id: 2, |         id: 2, | ||||||
| @ -153,6 +173,11 @@ test(`Should include customHeaders in headers when calling service`, async () => | |||||||
|     const addon = new DatadogAddon({ |     const addon = new DatadogAddon({ | ||||||
|         getLogger: noLogger, |         getLogger: noLogger, | ||||||
|         unleashUrl: 'http://some-url.com', |         unleashUrl: 'http://some-url.com', | ||||||
|  |         flagResolver: { | ||||||
|  |             getAll: jest.fn().mockReturnValue([]), | ||||||
|  |             getVariant: jest.fn(), | ||||||
|  |             isEnabled: jest.fn().mockReturnValue(false), | ||||||
|  |         }, | ||||||
|     }); |     }); | ||||||
|     const event: IEvent = { |     const event: IEvent = { | ||||||
|         id: 2, |         id: 2, | ||||||
| @ -184,6 +209,11 @@ test(`Should not include source_type_name when included in the config`, async () | |||||||
|     const addon = new DatadogAddon({ |     const addon = new DatadogAddon({ | ||||||
|         getLogger: noLogger, |         getLogger: noLogger, | ||||||
|         unleashUrl: 'http://some-url.com', |         unleashUrl: 'http://some-url.com', | ||||||
|  |         flagResolver: { | ||||||
|  |             getAll: jest.fn().mockReturnValue([]), | ||||||
|  |             getVariant: jest.fn(), | ||||||
|  |             isEnabled: jest.fn().mockReturnValue(false), | ||||||
|  |         }, | ||||||
|     }); |     }); | ||||||
|     const event: IEvent = { |     const event: IEvent = { | ||||||
|         id: 2, |         id: 2, | ||||||
| @ -213,3 +243,39 @@ test(`Should not include source_type_name when included in the config`, async () | |||||||
|     expect(fetchRetryCalls[0].options.body).toMatchSnapshot(); |     expect(fetchRetryCalls[0].options.body).toMatchSnapshot(); | ||||||
|     expect(fetchRetryCalls[0].options.headers).toMatchSnapshot(); |     expect(fetchRetryCalls[0].options.headers).toMatchSnapshot(); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | test('Should call datadog webhook with JSON when template set', async () => { | ||||||
|  |     const addon = new DatadogAddon({ | ||||||
|  |         getLogger: noLogger, | ||||||
|  |         unleashUrl: 'http://some-url.com', | ||||||
|  |         flagResolver: { | ||||||
|  |             getAll: jest.fn().mockReturnValue([]), | ||||||
|  |             getVariant: jest.fn(), | ||||||
|  |             isEnabled: jest.fn().mockReturnValue(true), | ||||||
|  |         }, | ||||||
|  |     }); | ||||||
|  |     const event: IEvent = { | ||||||
|  |         id: 1, | ||||||
|  |         createdAt: new Date(), | ||||||
|  |         type: FEATURE_CREATED, | ||||||
|  |         createdBy: 'some@user.com', | ||||||
|  |         featureName: 'some-toggle', | ||||||
|  |         data: { | ||||||
|  |             name: 'some-toggle', | ||||||
|  |             enabled: false, | ||||||
|  |             strategies: [{ name: 'default' }], | ||||||
|  |         }, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const parameters = { | ||||||
|  |         url: 'http://api.datadoghq.com/api/v1/events', | ||||||
|  |         apiKey: 'fakeKey', | ||||||
|  |         bodyTemplate: | ||||||
|  |             '{\n  "event": "{{event.type}}",\n  "createdBy": "{{event.createdBy}}"\n}', | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     await addon.handleEvent(event, parameters); | ||||||
|  |     expect(fetchRetryCalls.length).toBe(1); | ||||||
|  |     expect(fetchRetryCalls[0].url).toBe(parameters.url); | ||||||
|  |     expect(fetchRetryCalls[0].options.body).toMatchSnapshot(); | ||||||
|  | }); | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| import Addon from './addon'; | import Addon from './addon'; | ||||||
| 
 | 
 | ||||||
| import definition from './datadog-definition'; | import definition from './datadog-definition'; | ||||||
|  | import Mustache from 'mustache'; | ||||||
|  | import { IFlagResolver } from '../types/experimental'; | ||||||
| import { IAddonConfig } from '../types/model'; | import { IAddonConfig } from '../types/model'; | ||||||
| import { | import { | ||||||
|     FeatureEventFormatter, |     FeatureEventFormatter, | ||||||
| @ -14,6 +16,7 @@ interface IDatadogParameters { | |||||||
|     apiKey: string; |     apiKey: string; | ||||||
|     sourceTypeName?: string; |     sourceTypeName?: string; | ||||||
|     customHeaders?: string; |     customHeaders?: string; | ||||||
|  |     bodyTemplate?: string; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface DDRequestBody { | interface DDRequestBody { | ||||||
| @ -23,15 +26,22 @@ interface DDRequestBody { | |||||||
|     source_type_name?: string; |     source_type_name?: string; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export interface IDatadogAddonConfig extends IAddonConfig { | ||||||
|  |     flagResolver: IFlagResolver; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export default class DatadogAddon extends Addon { | export default class DatadogAddon extends Addon { | ||||||
|     private msgFormatter: FeatureEventFormatter; |     private msgFormatter: FeatureEventFormatter; | ||||||
| 
 | 
 | ||||||
|     constructor(config: IAddonConfig) { |     private flagResolver: IFlagResolver; | ||||||
|  | 
 | ||||||
|  |     constructor(config: IDatadogAddonConfig) { | ||||||
|         super(definition, config); |         super(definition, config); | ||||||
|         this.msgFormatter = new FeatureEventFormatterMd( |         this.msgFormatter = new FeatureEventFormatterMd( | ||||||
|             config.unleashUrl, |             config.unleashUrl, | ||||||
|             LinkStyle.MD, |             LinkStyle.MD, | ||||||
|         ); |         ); | ||||||
|  |         this.flagResolver = config.flagResolver; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async handleEvent( |     async handleEvent( | ||||||
| @ -43,15 +53,29 @@ export default class DatadogAddon extends Addon { | |||||||
|             apiKey, |             apiKey, | ||||||
|             sourceTypeName, |             sourceTypeName, | ||||||
|             customHeaders, |             customHeaders, | ||||||
|  |             bodyTemplate, | ||||||
|         } = parameters; |         } = parameters; | ||||||
| 
 | 
 | ||||||
|         const text = this.msgFormatter.format(event); |         const context = { | ||||||
|  |             event, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let text; | ||||||
|  |         if ( | ||||||
|  |             this.flagResolver.isEnabled('datadogJsonTemplate') && | ||||||
|  |             typeof bodyTemplate === 'string' && | ||||||
|  |             bodyTemplate.length > 1 | ||||||
|  |         ) { | ||||||
|  |             text = Mustache.render(bodyTemplate, context); | ||||||
|  |         } else { | ||||||
|  |             text = `%%% \n ${this.msgFormatter.format(event)} \n %%% `; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         const { tags: eventTags } = event; |         const { tags: eventTags } = event; | ||||||
|         const tags = |         const tags = | ||||||
|             eventTags && eventTags.map((tag) => `${tag.type}:${tag.value}`); |             eventTags && eventTags.map((tag) => `${tag.type}:${tag.value}`); | ||||||
|         const body: DDRequestBody = { |         const body: DDRequestBody = { | ||||||
|             text: `%%% \n ${text} \n %%% `, |             text: text, | ||||||
|             title: 'Unleash notification update', |             title: 'Unleash notification update', | ||||||
|             tags, |             tags, | ||||||
|         }; |         }; | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ export const getAddons: (args: { | |||||||
|         new Webhook({ getLogger }), |         new Webhook({ getLogger }), | ||||||
|         slackAddon, |         slackAddon, | ||||||
|         new TeamsAddon({ getLogger, unleashUrl }), |         new TeamsAddon({ getLogger, unleashUrl }), | ||||||
|         new DatadogAddon({ getLogger, unleashUrl }), |         new DatadogAddon({ getLogger, unleashUrl, flagResolver }), | ||||||
|     ]; |     ]; | ||||||
| 
 | 
 | ||||||
|     if (slackAppAddonEnabled) { |     if (slackAppAddonEnabled) { | ||||||
|  | |||||||
| @ -65,6 +65,16 @@ const webhookDefinition: IAddonDefinition = { | |||||||
|             required: false, |             required: false, | ||||||
|             sensitive: true, |             sensitive: true, | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |             name: 'customHeaders', | ||||||
|  |             displayName: 'Extra HTTP Headers', | ||||||
|  |             placeholder: | ||||||
|  |                 '{\n"ISTIO_USER_KEY": "hunter2",\n"SOME_OTHER_CUSTOM_HTTP_HEADER": "SOMEVALUE"\n}', | ||||||
|  |             description: `(Optional) Used to add extra HTTP Headers to the request the plugin fires off. This must be a valid json object of key-value pairs where both the key and the value are strings`, | ||||||
|  |             required: false, | ||||||
|  |             sensitive: true, | ||||||
|  |             type: 'textfield', | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|             name: 'bodyTemplate', |             name: 'bodyTemplate', | ||||||
|             displayName: 'Body template', |             displayName: 'Body template', | ||||||
| @ -80,16 +90,6 @@ const webhookDefinition: IAddonDefinition = { | |||||||
|             required: false, |             required: false, | ||||||
|             sensitive: false, |             sensitive: false, | ||||||
|         }, |         }, | ||||||
|         { |  | ||||||
|             name: 'customHeaders', |  | ||||||
|             displayName: 'Extra HTTP Headers', |  | ||||||
|             placeholder: |  | ||||||
|                 '{\n"ISTIO_USER_KEY": "hunter2",\n"SOME_OTHER_CUSTOM_HTTP_HEADER": "SOMEVALUE"\n}', |  | ||||||
|             description: `(Optional) Used to add extra HTTP Headers to the request the plugin fires off. This must be a valid json object of key-value pairs where both the key and the value are strings`, |  | ||||||
|             required: false, |  | ||||||
|             sensitive: true, |  | ||||||
|             type: 'textfield', |  | ||||||
|         }, |  | ||||||
|     ], |     ], | ||||||
|     events: [ |     events: [ | ||||||
|         FEATURE_CREATED, |         FEATURE_CREATED, | ||||||
|  | |||||||
| @ -31,7 +31,8 @@ export type IFlagKey = | |||||||
|     | 'variantTypeNumber' |     | 'variantTypeNumber' | ||||||
|     | 'accessOverview' |     | 'accessOverview' | ||||||
|     | 'privateProjects' |     | 'privateProjects' | ||||||
|     | 'dependentFeatures'; |     | 'dependentFeatures' | ||||||
|  |     | 'datadogJsonTemplate'; | ||||||
| 
 | 
 | ||||||
| export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; | export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; | ||||||
| 
 | 
 | ||||||
| @ -147,6 +148,10 @@ const flags: IFlags = { | |||||||
|         process.env.UNLEASH_EXPERIMENTAL_ACCESS_OVERVIEW, |         process.env.UNLEASH_EXPERIMENTAL_ACCESS_OVERVIEW, | ||||||
|         false, |         false, | ||||||
|     ), |     ), | ||||||
|  |     datadogJsonTemplate: parseEnvVarBoolean( | ||||||
|  |         process.env.UNLEASH_EXPERIMENTAL_DATADOG_JSON_TEMPLATE, | ||||||
|  |         false, | ||||||
|  |     ), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const defaultExperimentalOptions: IExperimentalOptions = { | export const defaultExperimentalOptions: IExperimentalOptions = { | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ process.nextTick(async () => { | |||||||
|                         variantTypeNumber: true, |                         variantTypeNumber: true, | ||||||
|                         privateProjects: false, |                         privateProjects: false, | ||||||
|                         accessOverview: true, |                         accessOverview: true, | ||||||
|  |                         datadogJsonTemplate: true, | ||||||
|                     }, |                     }, | ||||||
|                 }, |                 }, | ||||||
|                 authentication: { |                 authentication: { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user