mirror of
https://github.com/SigNoz/signoz.git
synced 2026-05-29 13:20:28 +01:00
Compare commits
5 Commits
fix/diff-c
...
custom-rec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cab33095e | ||
|
|
78d0c65736 | ||
|
|
3ea759a4b3 | ||
|
|
081fdd318b | ||
|
|
d99ac9c9d7 |
@@ -96,6 +96,19 @@ components:
|
||||
- createdAt
|
||||
- updatedAt
|
||||
type: object
|
||||
AlertmanagertypesGoogleChatReceiverConfig:
|
||||
properties:
|
||||
http_config:
|
||||
$ref: '#/components/schemas/ConfigHTTPClientConfig'
|
||||
send_resolved:
|
||||
type: boolean
|
||||
text:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
webhook_url:
|
||||
$ref: '#/components/schemas/ConfigSecretURL'
|
||||
type: object
|
||||
AlertmanagertypesMaintenanceKind:
|
||||
enum:
|
||||
- fixed
|
||||
@@ -147,6 +160,8 @@ components:
|
||||
type: object
|
||||
AlertmanagertypesPostableChannel:
|
||||
oneOf:
|
||||
- required:
|
||||
- googlechat_configs
|
||||
- required:
|
||||
- discord_configs
|
||||
- required:
|
||||
@@ -192,6 +207,10 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigEmailConfig'
|
||||
type: array
|
||||
googlechat_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/AlertmanagertypesGoogleChatReceiverConfig'
|
||||
type: array
|
||||
incidentio_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigIncidentioConfig'
|
||||
@@ -305,6 +324,87 @@ components:
|
||||
- channels
|
||||
- name
|
||||
type: object
|
||||
AlertmanagertypesReceiver:
|
||||
properties:
|
||||
discord_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigDiscordConfig'
|
||||
type: array
|
||||
email_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigEmailConfig'
|
||||
type: array
|
||||
googlechat_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/AlertmanagertypesGoogleChatReceiverConfig'
|
||||
type: array
|
||||
incidentio_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigIncidentioConfig'
|
||||
type: array
|
||||
jira_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigJiraConfig'
|
||||
type: array
|
||||
mattermost_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigMattermostConfig'
|
||||
type: array
|
||||
msteams_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigMSTeamsConfig'
|
||||
type: array
|
||||
msteamsv2_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigMSTeamsV2Config'
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
opsgenie_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigOpsGenieConfig'
|
||||
type: array
|
||||
pagerduty_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigPagerdutyConfig'
|
||||
type: array
|
||||
pushover_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigPushoverConfig'
|
||||
type: array
|
||||
rocketchat_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigRocketchatConfig'
|
||||
type: array
|
||||
slack_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigSlackConfig'
|
||||
type: array
|
||||
sns_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigSNSConfig'
|
||||
type: array
|
||||
telegram_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigTelegramConfig'
|
||||
type: array
|
||||
victorops_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigVictorOpsConfig'
|
||||
type: array
|
||||
webex_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigWebexConfig'
|
||||
type: array
|
||||
webhook_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigWebhookConfig'
|
||||
type: array
|
||||
wechat_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigWechatConfig'
|
||||
type: array
|
||||
type: object
|
||||
AlertmanagertypesRecurrence:
|
||||
properties:
|
||||
duration:
|
||||
@@ -1849,83 +1949,6 @@ components:
|
||||
user_key_file:
|
||||
type: string
|
||||
type: object
|
||||
ConfigReceiver:
|
||||
properties:
|
||||
discord_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigDiscordConfig'
|
||||
type: array
|
||||
email_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigEmailConfig'
|
||||
type: array
|
||||
incidentio_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigIncidentioConfig'
|
||||
type: array
|
||||
jira_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigJiraConfig'
|
||||
type: array
|
||||
mattermost_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigMattermostConfig'
|
||||
type: array
|
||||
msteams_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigMSTeamsConfig'
|
||||
type: array
|
||||
msteamsv2_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigMSTeamsV2Config'
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
opsgenie_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigOpsGenieConfig'
|
||||
type: array
|
||||
pagerduty_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigPagerdutyConfig'
|
||||
type: array
|
||||
pushover_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigPushoverConfig'
|
||||
type: array
|
||||
rocketchat_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigRocketchatConfig'
|
||||
type: array
|
||||
slack_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigSlackConfig'
|
||||
type: array
|
||||
sns_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigSNSConfig'
|
||||
type: array
|
||||
telegram_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigTelegramConfig'
|
||||
type: array
|
||||
victorops_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigVictorOpsConfig'
|
||||
type: array
|
||||
webex_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigWebexConfig'
|
||||
type: array
|
||||
webhook_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigWebhookConfig'
|
||||
type: array
|
||||
wechat_configs:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigWechatConfig'
|
||||
type: array
|
||||
type: object
|
||||
ConfigRocketchatAttachmentAction:
|
||||
properties:
|
||||
image_url:
|
||||
@@ -7548,7 +7571,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConfigReceiver'
|
||||
$ref: '#/components/schemas/AlertmanagertypesReceiver'
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
@@ -7599,7 +7622,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConfigReceiver'
|
||||
$ref: '#/components/schemas/AlertmanagertypesReceiver'
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
@@ -12205,7 +12228,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConfigReceiver'
|
||||
$ref: '#/components/schemas/AlertmanagertypesReceiver'
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
|
||||
@@ -19,7 +19,7 @@ import type {
|
||||
|
||||
import type {
|
||||
AlertmanagertypesPostableChannelDTO,
|
||||
ConfigReceiverDTO,
|
||||
AlertmanagertypesReceiverDTO,
|
||||
CreateChannel201,
|
||||
DeleteChannelByIDPathParameters,
|
||||
GetChannelByID200,
|
||||
@@ -385,14 +385,14 @@ export const invalidateGetChannelByID = async (
|
||||
*/
|
||||
export const updateChannelByID = (
|
||||
{ id }: UpdateChannelByIDPathParameters,
|
||||
configReceiverDTO?: BodyType<ConfigReceiverDTO>,
|
||||
alertmanagertypesReceiverDTO?: BodyType<AlertmanagertypesReceiverDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/channels/${id}`,
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: configReceiverDTO,
|
||||
data: alertmanagertypesReceiverDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
@@ -406,7 +406,7 @@ export const getUpdateChannelByIDMutationOptions = <
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateChannelByIDPathParameters;
|
||||
data?: BodyType<ConfigReceiverDTO>;
|
||||
data?: BodyType<AlertmanagertypesReceiverDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
@@ -415,7 +415,7 @@ export const getUpdateChannelByIDMutationOptions = <
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateChannelByIDPathParameters;
|
||||
data?: BodyType<ConfigReceiverDTO>;
|
||||
data?: BodyType<AlertmanagertypesReceiverDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
@@ -432,7 +432,7 @@ export const getUpdateChannelByIDMutationOptions = <
|
||||
Awaited<ReturnType<typeof updateChannelByID>>,
|
||||
{
|
||||
pathParams: UpdateChannelByIDPathParameters;
|
||||
data?: BodyType<ConfigReceiverDTO>;
|
||||
data?: BodyType<AlertmanagertypesReceiverDTO>;
|
||||
}
|
||||
> = (props) => {
|
||||
const { pathParams, data } = props ?? {};
|
||||
@@ -447,7 +447,7 @@ export type UpdateChannelByIDMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateChannelByID>>
|
||||
>;
|
||||
export type UpdateChannelByIDMutationBody =
|
||||
| BodyType<ConfigReceiverDTO>
|
||||
| BodyType<AlertmanagertypesReceiverDTO>
|
||||
| undefined;
|
||||
export type UpdateChannelByIDMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
@@ -463,7 +463,7 @@ export const useUpdateChannelByID = <
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateChannelByIDPathParameters;
|
||||
data?: BodyType<ConfigReceiverDTO>;
|
||||
data?: BodyType<AlertmanagertypesReceiverDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
@@ -472,7 +472,7 @@ export const useUpdateChannelByID = <
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateChannelByIDPathParameters;
|
||||
data?: BodyType<ConfigReceiverDTO>;
|
||||
data?: BodyType<AlertmanagertypesReceiverDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
@@ -483,14 +483,14 @@ export const useUpdateChannelByID = <
|
||||
* @summary Test notification channel
|
||||
*/
|
||||
export const testChannel = (
|
||||
configReceiverDTO?: BodyType<ConfigReceiverDTO>,
|
||||
alertmanagertypesReceiverDTO?: BodyType<AlertmanagertypesReceiverDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/channels/test`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: configReceiverDTO,
|
||||
data: alertmanagertypesReceiverDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
@@ -502,13 +502,13 @@ export const getTestChannelMutationOptions = <
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof testChannel>>,
|
||||
TError,
|
||||
{ data?: BodyType<ConfigReceiverDTO> },
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof testChannel>>,
|
||||
TError,
|
||||
{ data?: BodyType<ConfigReceiverDTO> },
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['testChannel'];
|
||||
@@ -522,7 +522,7 @@ export const getTestChannelMutationOptions = <
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof testChannel>>,
|
||||
{ data?: BodyType<ConfigReceiverDTO> }
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
@@ -535,7 +535,9 @@ export const getTestChannelMutationOptions = <
|
||||
export type TestChannelMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof testChannel>>
|
||||
>;
|
||||
export type TestChannelMutationBody = BodyType<ConfigReceiverDTO> | undefined;
|
||||
export type TestChannelMutationBody =
|
||||
| BodyType<AlertmanagertypesReceiverDTO>
|
||||
| undefined;
|
||||
export type TestChannelMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
@@ -548,13 +550,13 @@ export const useTestChannel = <
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof testChannel>>,
|
||||
TError,
|
||||
{ data?: BodyType<ConfigReceiverDTO> },
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof testChannel>>,
|
||||
TError,
|
||||
{ data?: BodyType<ConfigReceiverDTO> },
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getTestChannelMutationOptions(options));
|
||||
@@ -565,14 +567,14 @@ export const useTestChannel = <
|
||||
* @summary Test notification channel (deprecated)
|
||||
*/
|
||||
export const testChannelDeprecated = (
|
||||
configReceiverDTO?: BodyType<ConfigReceiverDTO>,
|
||||
alertmanagertypesReceiverDTO?: BodyType<AlertmanagertypesReceiverDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/testChannel`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: configReceiverDTO,
|
||||
data: alertmanagertypesReceiverDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
@@ -584,13 +586,13 @@ export const getTestChannelDeprecatedMutationOptions = <
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof testChannelDeprecated>>,
|
||||
TError,
|
||||
{ data?: BodyType<ConfigReceiverDTO> },
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof testChannelDeprecated>>,
|
||||
TError,
|
||||
{ data?: BodyType<ConfigReceiverDTO> },
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['testChannelDeprecated'];
|
||||
@@ -604,7 +606,7 @@ export const getTestChannelDeprecatedMutationOptions = <
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof testChannelDeprecated>>,
|
||||
{ data?: BodyType<ConfigReceiverDTO> }
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
@@ -618,7 +620,7 @@ export type TestChannelDeprecatedMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof testChannelDeprecated>>
|
||||
>;
|
||||
export type TestChannelDeprecatedMutationBody =
|
||||
| BodyType<ConfigReceiverDTO>
|
||||
| BodyType<AlertmanagertypesReceiverDTO>
|
||||
| undefined;
|
||||
export type TestChannelDeprecatedMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
@@ -634,13 +636,13 @@ export const useTestChannelDeprecated = <
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof testChannelDeprecated>>,
|
||||
TError,
|
||||
{ data?: BodyType<ConfigReceiverDTO> },
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof testChannelDeprecated>>,
|
||||
TError,
|
||||
{ data?: BodyType<ConfigReceiverDTO> },
|
||||
{ data?: BodyType<AlertmanagertypesReceiverDTO> },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getTestChannelDeprecatedMutationOptions(options));
|
||||
|
||||
@@ -134,113 +134,6 @@ export interface AlertmanagertypesGettableRoutePolicyDTO {
|
||||
updatedBy?: string | null;
|
||||
}
|
||||
|
||||
export enum AlertmanagertypesMaintenanceKindDTO {
|
||||
fixed = 'fixed',
|
||||
recurring = 'recurring',
|
||||
}
|
||||
export enum AlertmanagertypesMaintenanceStatusDTO {
|
||||
active = 'active',
|
||||
upcoming = 'upcoming',
|
||||
expired = 'expired',
|
||||
}
|
||||
export enum AlertmanagertypesRepeatOnDTO {
|
||||
sunday = 'sunday',
|
||||
monday = 'monday',
|
||||
tuesday = 'tuesday',
|
||||
wednesday = 'wednesday',
|
||||
thursday = 'thursday',
|
||||
friday = 'friday',
|
||||
saturday = 'saturday',
|
||||
}
|
||||
export enum AlertmanagertypesRepeatTypeDTO {
|
||||
daily = 'daily',
|
||||
weekly = 'weekly',
|
||||
monthly = 'monthly',
|
||||
}
|
||||
export interface AlertmanagertypesRecurrenceDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
duration: string;
|
||||
/**
|
||||
* @type string,null
|
||||
* @format date-time
|
||||
*/
|
||||
endTime?: string | null;
|
||||
/**
|
||||
* @type array,null
|
||||
*/
|
||||
repeatOn?: AlertmanagertypesRepeatOnDTO[] | null;
|
||||
repeatType: AlertmanagertypesRepeatTypeDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
startTime: string;
|
||||
}
|
||||
|
||||
export interface AlertmanagertypesScheduleDTO {
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
endTime?: string;
|
||||
recurrence?: AlertmanagertypesRecurrenceDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
startTime?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
timezone: string;
|
||||
}
|
||||
|
||||
export interface AlertmanagertypesPlannedMaintenanceDTO {
|
||||
/**
|
||||
* @type array,null
|
||||
*/
|
||||
alertIds?: string[] | null;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
createdAt?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
createdBy?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
id: string;
|
||||
kind: AlertmanagertypesMaintenanceKindDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name: string;
|
||||
schedule: AlertmanagertypesScheduleDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
scope?: string;
|
||||
status: AlertmanagertypesMaintenanceStatusDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
updatedAt?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
updatedBy?: string;
|
||||
}
|
||||
|
||||
export interface ConfigAuthorizationDTO {
|
||||
/**
|
||||
* @type string
|
||||
@@ -475,6 +368,130 @@ export interface ConfigSecretURLDTO {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface AlertmanagertypesGoogleChatReceiverConfigDTO {
|
||||
http_config?: ConfigHTTPClientConfigDTO;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
send_resolved?: boolean;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
text?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
title?: string;
|
||||
webhook_url?: ConfigSecretURLDTO;
|
||||
}
|
||||
|
||||
export enum AlertmanagertypesMaintenanceKindDTO {
|
||||
fixed = 'fixed',
|
||||
recurring = 'recurring',
|
||||
}
|
||||
export enum AlertmanagertypesMaintenanceStatusDTO {
|
||||
active = 'active',
|
||||
upcoming = 'upcoming',
|
||||
expired = 'expired',
|
||||
}
|
||||
export enum AlertmanagertypesRepeatOnDTO {
|
||||
sunday = 'sunday',
|
||||
monday = 'monday',
|
||||
tuesday = 'tuesday',
|
||||
wednesday = 'wednesday',
|
||||
thursday = 'thursday',
|
||||
friday = 'friday',
|
||||
saturday = 'saturday',
|
||||
}
|
||||
export enum AlertmanagertypesRepeatTypeDTO {
|
||||
daily = 'daily',
|
||||
weekly = 'weekly',
|
||||
monthly = 'monthly',
|
||||
}
|
||||
export interface AlertmanagertypesRecurrenceDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
duration: string;
|
||||
/**
|
||||
* @type string,null
|
||||
* @format date-time
|
||||
*/
|
||||
endTime?: string | null;
|
||||
/**
|
||||
* @type array,null
|
||||
*/
|
||||
repeatOn?: AlertmanagertypesRepeatOnDTO[] | null;
|
||||
repeatType: AlertmanagertypesRepeatTypeDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
startTime: string;
|
||||
}
|
||||
|
||||
export interface AlertmanagertypesScheduleDTO {
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
endTime?: string;
|
||||
recurrence?: AlertmanagertypesRecurrenceDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
startTime?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
timezone: string;
|
||||
}
|
||||
|
||||
export interface AlertmanagertypesPlannedMaintenanceDTO {
|
||||
/**
|
||||
* @type array,null
|
||||
*/
|
||||
alertIds?: string[] | null;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
createdAt?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
createdBy?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
id: string;
|
||||
kind: AlertmanagertypesMaintenanceKindDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name: string;
|
||||
schedule: AlertmanagertypesScheduleDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
scope?: string;
|
||||
status: AlertmanagertypesMaintenanceStatusDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
updatedAt?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
updatedBy?: string;
|
||||
}
|
||||
|
||||
export interface ConfigDiscordConfigDTO {
|
||||
/**
|
||||
* @type string
|
||||
@@ -1634,6 +1651,10 @@ export type AlertmanagertypesPostableChannelDTO = unknown & {
|
||||
* @type array
|
||||
*/
|
||||
email_configs?: ConfigEmailConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
googlechat_configs?: AlertmanagertypesGoogleChatReceiverConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
@@ -1748,6 +1769,89 @@ export interface AlertmanagertypesPostableRoutePolicyDTO {
|
||||
tags?: string[] | null;
|
||||
}
|
||||
|
||||
export interface AlertmanagertypesReceiverDTO {
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
discord_configs?: ConfigDiscordConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
email_configs?: ConfigEmailConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
googlechat_configs?: AlertmanagertypesGoogleChatReceiverConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
incidentio_configs?: ConfigIncidentioConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
jira_configs?: ConfigJiraConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
mattermost_configs?: ConfigMattermostConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
msteams_configs?: ConfigMSTeamsConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
msteamsv2_configs?: ConfigMSTeamsV2ConfigDTO[];
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
opsgenie_configs?: ConfigOpsGenieConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
pagerduty_configs?: ConfigPagerdutyConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
pushover_configs?: ConfigPushoverConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
rocketchat_configs?: ConfigRocketchatConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
slack_configs?: ConfigSlackConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
sns_configs?: ConfigSNSConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
telegram_configs?: ConfigTelegramConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
victorops_configs?: ConfigVictorOpsConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
webex_configs?: ConfigWebexConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
webhook_configs?: ConfigWebhookConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
wechat_configs?: ConfigWechatConfigDTO[];
|
||||
}
|
||||
|
||||
export interface AuthtypesAttributeMappingDTO {
|
||||
/**
|
||||
* @type string
|
||||
@@ -2927,85 +3031,6 @@ export interface CommonJSONRefDTO {
|
||||
$ref?: string;
|
||||
}
|
||||
|
||||
export interface ConfigReceiverDTO {
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
discord_configs?: ConfigDiscordConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
email_configs?: ConfigEmailConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
incidentio_configs?: ConfigIncidentioConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
jira_configs?: ConfigJiraConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
mattermost_configs?: ConfigMattermostConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
msteams_configs?: ConfigMSTeamsConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
msteamsv2_configs?: ConfigMSTeamsV2ConfigDTO[];
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
opsgenie_configs?: ConfigOpsGenieConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
pagerduty_configs?: ConfigPagerdutyConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
pushover_configs?: ConfigPushoverConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
rocketchat_configs?: ConfigRocketchatConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
slack_configs?: ConfigSlackConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
sns_configs?: ConfigSNSConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
telegram_configs?: ConfigTelegramConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
victorops_configs?: ConfigVictorOpsConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
webex_configs?: ConfigWebexConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
webhook_configs?: ConfigWebhookConfigDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
wechat_configs?: ConfigWechatConfigDTO[];
|
||||
}
|
||||
|
||||
export interface CoretypesObjectGroupDTO {
|
||||
resource: CoretypesResourceRefDTO;
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ type Alertmanager interface {
|
||||
PutAlerts(context.Context, string, alertmanagertypes.PostableAlerts) error
|
||||
|
||||
// TestReceiver sends a test alert to a receiver.
|
||||
TestReceiver(context.Context, string, alertmanagertypes.Receiver) error
|
||||
TestReceiver(context.Context, string, *alertmanagertypes.Receiver) error
|
||||
|
||||
// TestAlert sends an alert to a list of receivers.
|
||||
TestAlert(ctx context.Context, orgID string, ruleID string, receiversMap map[*alertmanagertypes.PostableAlert][]string) error
|
||||
@@ -41,10 +41,10 @@ type Alertmanager interface {
|
||||
GetChannelByID(context.Context, string, valuer.UUID) (*alertmanagertypes.Channel, error)
|
||||
|
||||
// UpdateChannel updates a channel for the organization.
|
||||
UpdateChannelByReceiverAndID(context.Context, string, alertmanagertypes.Receiver, valuer.UUID) error
|
||||
UpdateChannelByReceiverAndID(context.Context, string, *alertmanagertypes.Receiver, valuer.UUID) error
|
||||
|
||||
// CreateChannel creates a channel for the organization.
|
||||
CreateChannel(context.Context, string, alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error)
|
||||
CreateChannel(context.Context, string, *alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error)
|
||||
|
||||
// DeleteChannelByID deletes a channel for the organization.
|
||||
DeleteChannelByID(context.Context, string, valuer.UUID) error
|
||||
|
||||
@@ -26,8 +26,8 @@ var customNotifierIntegrations = []string{
|
||||
msteamsv2.Integration,
|
||||
}
|
||||
|
||||
func NewReceiverIntegrations(nc alertmanagertypes.Receiver, tmpl *template.Template, logger *slog.Logger, templater alertmanagertypes.Templater) ([]notify.Integration, error) {
|
||||
upstreamIntegrations, err := receiver.BuildReceiverIntegrations(nc, tmpl, logger)
|
||||
func NewReceiverIntegrations(nc *alertmanagertypes.Receiver, tmpl *template.Template, logger *slog.Logger, templater alertmanagertypes.Templater) ([]notify.Integration, error) {
|
||||
upstreamIntegrations, err := receiver.BuildReceiverIntegrations(*nc.Receiver, tmpl, logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -275,7 +275,11 @@ func (server *Server) SetConfig(ctx context.Context, alertmanagerConfig *alertma
|
||||
server.logger.InfoContext(ctx, "skipping creation of receiver not referenced by any route", slog.String("receiver", rcv.Name))
|
||||
continue
|
||||
}
|
||||
integrations, err := alertmanagernotify.NewReceiverIntegrations(rcv, server.tmpl, server.logger, server.templater)
|
||||
extendedRcv, err := alertmanagerConfig.GetReceiver(rcv.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
integrations, err := alertmanagernotify.NewReceiverIntegrations(extendedRcv, server.tmpl, server.logger, server.templater)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -350,7 +354,7 @@ func (server *Server) SetConfig(ctx context.Context, alertmanagerConfig *alertma
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *Server) TestReceiver(ctx context.Context, receiver alertmanagertypes.Receiver) error {
|
||||
func (server *Server) TestReceiver(ctx context.Context, receiver *alertmanagertypes.Receiver) error {
|
||||
testAlert := alertmanagertypes.NewTestAlert(receiver, time.Now(), time.Now())
|
||||
return alertmanagertypes.TestReceiver(ctx, receiver, alertmanagernotify.NewReceiverIntegrations, server.alertmanagerConfig, server.tmpl, server.logger, server.templater, testAlert.Labels, testAlert)
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func TestServerTestReceiverTypeWebhook(t *testing.T) {
|
||||
webhookURL, err := url.Parse("http://" + webhookListener.Addr().String() + "/webhook")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = server.TestReceiver(context.Background(), alertmanagertypes.Receiver{
|
||||
err = server.TestReceiver(context.Background(), &alertmanagertypes.Receiver{Receiver: &config.Receiver{
|
||||
Name: "test-receiver",
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
@@ -83,7 +83,7 @@ func TestServerTestReceiverTypeWebhook(t *testing.T) {
|
||||
URL: config.SecretTemplateURL(webhookURL.String()),
|
||||
},
|
||||
},
|
||||
})
|
||||
}})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, requestBody.String(), "test-receiver")
|
||||
@@ -101,7 +101,7 @@ func TestServerPutAlerts(t *testing.T) {
|
||||
amConfig, err := alertmanagertypes.NewDefaultConfig(srvCfg.Global, srvCfg.Route, "1")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, amConfig.CreateReceiver(alertmanagertypes.Receiver{
|
||||
require.NoError(t, amConfig.CreateReceiver(&alertmanagertypes.Receiver{Receiver: &config.Receiver{
|
||||
Name: "test-receiver",
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
@@ -109,7 +109,7 @@ func TestServerPutAlerts(t *testing.T) {
|
||||
URL: config.SecretTemplateURL("http://localhost/test-receiver"),
|
||||
},
|
||||
},
|
||||
}))
|
||||
}}))
|
||||
|
||||
require.NoError(t, server.SetConfig(context.Background(), amConfig))
|
||||
|
||||
@@ -181,7 +181,7 @@ func TestServerTestAlert(t *testing.T) {
|
||||
webhook2URL, err := url.Parse("http://" + webhook2Listener.Addr().String() + "/webhook")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, amConfig.CreateReceiver(alertmanagertypes.Receiver{
|
||||
require.NoError(t, amConfig.CreateReceiver(&alertmanagertypes.Receiver{Receiver: &config.Receiver{
|
||||
Name: "receiver-1",
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
@@ -189,9 +189,9 @@ func TestServerTestAlert(t *testing.T) {
|
||||
URL: config.SecretTemplateURL(webhook1URL.String()),
|
||||
},
|
||||
},
|
||||
}))
|
||||
}}))
|
||||
|
||||
require.NoError(t, amConfig.CreateReceiver(alertmanagertypes.Receiver{
|
||||
require.NoError(t, amConfig.CreateReceiver(&alertmanagertypes.Receiver{Receiver: &config.Receiver{
|
||||
Name: "receiver-2",
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
@@ -199,7 +199,7 @@ func TestServerTestAlert(t *testing.T) {
|
||||
URL: config.SecretTemplateURL(webhook2URL.String()),
|
||||
},
|
||||
},
|
||||
}))
|
||||
}}))
|
||||
|
||||
require.NoError(t, server.SetConfig(context.Background(), amConfig))
|
||||
defer func() {
|
||||
@@ -273,7 +273,7 @@ func TestServerTestAlertContinuesOnFailure(t *testing.T) {
|
||||
webhookURL, err := url.Parse("http://" + webhookListener.Addr().String() + "/webhook")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, amConfig.CreateReceiver(alertmanagertypes.Receiver{
|
||||
require.NoError(t, amConfig.CreateReceiver(&alertmanagertypes.Receiver{Receiver: &config.Receiver{
|
||||
Name: "working-receiver",
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
@@ -281,9 +281,9 @@ func TestServerTestAlertContinuesOnFailure(t *testing.T) {
|
||||
URL: config.SecretTemplateURL(webhookURL.String()),
|
||||
},
|
||||
},
|
||||
}))
|
||||
}}))
|
||||
|
||||
require.NoError(t, amConfig.CreateReceiver(alertmanagertypes.Receiver{
|
||||
require.NoError(t, amConfig.CreateReceiver(&alertmanagertypes.Receiver{Receiver: &config.Receiver{
|
||||
Name: "failing-receiver",
|
||||
WebhookConfigs: []*config.WebhookConfig{
|
||||
{
|
||||
@@ -291,7 +291,7 @@ func TestServerTestAlertContinuesOnFailure(t *testing.T) {
|
||||
URL: config.SecretTemplateURL("http://localhost:1/webhook"),
|
||||
},
|
||||
},
|
||||
}))
|
||||
}}))
|
||||
|
||||
require.NoError(t, server.SetConfig(context.Background(), amConfig))
|
||||
defer func() {
|
||||
|
||||
@@ -155,7 +155,7 @@ func (_c *MockAlertmanager_Config_Call) RunAndReturn(run func() alertmanagerserv
|
||||
}
|
||||
|
||||
// CreateChannel provides a mock function for the type MockAlertmanager
|
||||
func (_mock *MockAlertmanager) CreateChannel(context1 context.Context, s string, v alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error) {
|
||||
func (_mock *MockAlertmanager) CreateChannel(context1 context.Context, s string, v *alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error) {
|
||||
ret := _mock.Called(context1, s, v)
|
||||
|
||||
if len(ret) == 0 {
|
||||
@@ -164,17 +164,17 @@ func (_mock *MockAlertmanager) CreateChannel(context1 context.Context, s string,
|
||||
|
||||
var r0 *alertmanagertypes.Channel
|
||||
var r1 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, string, alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error)); ok {
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, string, *alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error)); ok {
|
||||
return returnFunc(context1, s, v)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, string, alertmanagertypes.Receiver) *alertmanagertypes.Channel); ok {
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, string, *alertmanagertypes.Receiver) *alertmanagertypes.Channel); ok {
|
||||
r0 = returnFunc(context1, s, v)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*alertmanagertypes.Channel)
|
||||
}
|
||||
}
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, string, alertmanagertypes.Receiver) error); ok {
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, string, *alertmanagertypes.Receiver) error); ok {
|
||||
r1 = returnFunc(context1, s, v)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
@@ -190,12 +190,12 @@ type MockAlertmanager_CreateChannel_Call struct {
|
||||
// CreateChannel is a helper method to define mock.On call
|
||||
// - context1 context.Context
|
||||
// - s string
|
||||
// - v alertmanagertypes.Receiver
|
||||
// - v *alertmanagertypes.Receiver
|
||||
func (_e *MockAlertmanager_Expecter) CreateChannel(context1 interface{}, s interface{}, v interface{}) *MockAlertmanager_CreateChannel_Call {
|
||||
return &MockAlertmanager_CreateChannel_Call{Call: _e.mock.On("CreateChannel", context1, s, v)}
|
||||
}
|
||||
|
||||
func (_c *MockAlertmanager_CreateChannel_Call) Run(run func(context1 context.Context, s string, v alertmanagertypes.Receiver)) *MockAlertmanager_CreateChannel_Call {
|
||||
func (_c *MockAlertmanager_CreateChannel_Call) Run(run func(context1 context.Context, s string, v *alertmanagertypes.Receiver)) *MockAlertmanager_CreateChannel_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 context.Context
|
||||
if args[0] != nil {
|
||||
@@ -205,9 +205,9 @@ func (_c *MockAlertmanager_CreateChannel_Call) Run(run func(context1 context.Con
|
||||
if args[1] != nil {
|
||||
arg1 = args[1].(string)
|
||||
}
|
||||
var arg2 alertmanagertypes.Receiver
|
||||
var arg2 *alertmanagertypes.Receiver
|
||||
if args[2] != nil {
|
||||
arg2 = args[2].(alertmanagertypes.Receiver)
|
||||
arg2 = args[2].(*alertmanagertypes.Receiver)
|
||||
}
|
||||
run(
|
||||
arg0,
|
||||
@@ -223,7 +223,7 @@ func (_c *MockAlertmanager_CreateChannel_Call) Return(channel *alertmanagertypes
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAlertmanager_CreateChannel_Call) RunAndReturn(run func(context1 context.Context, s string, v alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error)) *MockAlertmanager_CreateChannel_Call {
|
||||
func (_c *MockAlertmanager_CreateChannel_Call) RunAndReturn(run func(context1 context.Context, s string, v *alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error)) *MockAlertmanager_CreateChannel_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
@@ -1624,7 +1624,7 @@ func (_c *MockAlertmanager_TestAlert_Call) RunAndReturn(run func(ctx context.Con
|
||||
}
|
||||
|
||||
// TestReceiver provides a mock function for the type MockAlertmanager
|
||||
func (_mock *MockAlertmanager) TestReceiver(context1 context.Context, s string, v alertmanagertypes.Receiver) error {
|
||||
func (_mock *MockAlertmanager) TestReceiver(context1 context.Context, s string, v *alertmanagertypes.Receiver) error {
|
||||
ret := _mock.Called(context1, s, v)
|
||||
|
||||
if len(ret) == 0 {
|
||||
@@ -1632,7 +1632,7 @@ func (_mock *MockAlertmanager) TestReceiver(context1 context.Context, s string,
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, string, alertmanagertypes.Receiver) error); ok {
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, string, *alertmanagertypes.Receiver) error); ok {
|
||||
r0 = returnFunc(context1, s, v)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
@@ -1648,12 +1648,12 @@ type MockAlertmanager_TestReceiver_Call struct {
|
||||
// TestReceiver is a helper method to define mock.On call
|
||||
// - context1 context.Context
|
||||
// - s string
|
||||
// - v alertmanagertypes.Receiver
|
||||
// - v *alertmanagertypes.Receiver
|
||||
func (_e *MockAlertmanager_Expecter) TestReceiver(context1 interface{}, s interface{}, v interface{}) *MockAlertmanager_TestReceiver_Call {
|
||||
return &MockAlertmanager_TestReceiver_Call{Call: _e.mock.On("TestReceiver", context1, s, v)}
|
||||
}
|
||||
|
||||
func (_c *MockAlertmanager_TestReceiver_Call) Run(run func(context1 context.Context, s string, v alertmanagertypes.Receiver)) *MockAlertmanager_TestReceiver_Call {
|
||||
func (_c *MockAlertmanager_TestReceiver_Call) Run(run func(context1 context.Context, s string, v *alertmanagertypes.Receiver)) *MockAlertmanager_TestReceiver_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 context.Context
|
||||
if args[0] != nil {
|
||||
@@ -1663,9 +1663,9 @@ func (_c *MockAlertmanager_TestReceiver_Call) Run(run func(context1 context.Cont
|
||||
if args[1] != nil {
|
||||
arg1 = args[1].(string)
|
||||
}
|
||||
var arg2 alertmanagertypes.Receiver
|
||||
var arg2 *alertmanagertypes.Receiver
|
||||
if args[2] != nil {
|
||||
arg2 = args[2].(alertmanagertypes.Receiver)
|
||||
arg2 = args[2].(*alertmanagertypes.Receiver)
|
||||
}
|
||||
run(
|
||||
arg0,
|
||||
@@ -1681,7 +1681,7 @@ func (_c *MockAlertmanager_TestReceiver_Call) Return(err error) *MockAlertmanage
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAlertmanager_TestReceiver_Call) RunAndReturn(run func(context1 context.Context, s string, v alertmanagertypes.Receiver) error) *MockAlertmanager_TestReceiver_Call {
|
||||
func (_c *MockAlertmanager_TestReceiver_Call) RunAndReturn(run func(context1 context.Context, s string, v *alertmanagertypes.Receiver) error) *MockAlertmanager_TestReceiver_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
@@ -1750,7 +1750,7 @@ func (_c *MockAlertmanager_UpdateAllRoutePoliciesByRuleId_Call) RunAndReturn(run
|
||||
}
|
||||
|
||||
// UpdateChannelByReceiverAndID provides a mock function for the type MockAlertmanager
|
||||
func (_mock *MockAlertmanager) UpdateChannelByReceiverAndID(context1 context.Context, s string, v alertmanagertypes.Receiver, uUID valuer.UUID) error {
|
||||
func (_mock *MockAlertmanager) UpdateChannelByReceiverAndID(context1 context.Context, s string, v *alertmanagertypes.Receiver, uUID valuer.UUID) error {
|
||||
ret := _mock.Called(context1, s, v, uUID)
|
||||
|
||||
if len(ret) == 0 {
|
||||
@@ -1758,7 +1758,7 @@ func (_mock *MockAlertmanager) UpdateChannelByReceiverAndID(context1 context.Con
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, string, alertmanagertypes.Receiver, valuer.UUID) error); ok {
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, string, *alertmanagertypes.Receiver, valuer.UUID) error); ok {
|
||||
r0 = returnFunc(context1, s, v, uUID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
@@ -1774,13 +1774,13 @@ type MockAlertmanager_UpdateChannelByReceiverAndID_Call struct {
|
||||
// UpdateChannelByReceiverAndID is a helper method to define mock.On call
|
||||
// - context1 context.Context
|
||||
// - s string
|
||||
// - v alertmanagertypes.Receiver
|
||||
// - v *alertmanagertypes.Receiver
|
||||
// - uUID valuer.UUID
|
||||
func (_e *MockAlertmanager_Expecter) UpdateChannelByReceiverAndID(context1 interface{}, s interface{}, v interface{}, uUID interface{}) *MockAlertmanager_UpdateChannelByReceiverAndID_Call {
|
||||
return &MockAlertmanager_UpdateChannelByReceiverAndID_Call{Call: _e.mock.On("UpdateChannelByReceiverAndID", context1, s, v, uUID)}
|
||||
}
|
||||
|
||||
func (_c *MockAlertmanager_UpdateChannelByReceiverAndID_Call) Run(run func(context1 context.Context, s string, v alertmanagertypes.Receiver, uUID valuer.UUID)) *MockAlertmanager_UpdateChannelByReceiverAndID_Call {
|
||||
func (_c *MockAlertmanager_UpdateChannelByReceiverAndID_Call) Run(run func(context1 context.Context, s string, v *alertmanagertypes.Receiver, uUID valuer.UUID)) *MockAlertmanager_UpdateChannelByReceiverAndID_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 context.Context
|
||||
if args[0] != nil {
|
||||
@@ -1790,9 +1790,9 @@ func (_c *MockAlertmanager_UpdateChannelByReceiverAndID_Call) Run(run func(conte
|
||||
if args[1] != nil {
|
||||
arg1 = args[1].(string)
|
||||
}
|
||||
var arg2 alertmanagertypes.Receiver
|
||||
var arg2 *alertmanagertypes.Receiver
|
||||
if args[2] != nil {
|
||||
arg2 = args[2].(alertmanagertypes.Receiver)
|
||||
arg2 = args[2].(*alertmanagertypes.Receiver)
|
||||
}
|
||||
var arg3 valuer.UUID
|
||||
if args[3] != nil {
|
||||
@@ -1813,7 +1813,7 @@ func (_c *MockAlertmanager_UpdateChannelByReceiverAndID_Call) Return(err error)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAlertmanager_UpdateChannelByReceiverAndID_Call) RunAndReturn(run func(context1 context.Context, s string, v alertmanagertypes.Receiver, uUID valuer.UUID) error) *MockAlertmanager_UpdateChannelByReceiverAndID_Call {
|
||||
func (_c *MockAlertmanager_UpdateChannelByReceiverAndID_Call) RunAndReturn(run func(context1 context.Context, s string, v *alertmanagertypes.Receiver, uUID valuer.UUID) error) *MockAlertmanager_UpdateChannelByReceiverAndID_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ func (service *Service) PutAlerts(ctx context.Context, orgID string, alerts aler
|
||||
return server.PutAlerts(ctx, alerts)
|
||||
}
|
||||
|
||||
func (service *Service) TestReceiver(ctx context.Context, orgID string, receiver alertmanagertypes.Receiver) error {
|
||||
func (service *Service) TestReceiver(ctx context.Context, orgID string, receiver *alertmanagertypes.Receiver) error {
|
||||
service.serversMtx.RLock()
|
||||
defer service.serversMtx.RUnlock()
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ func (provider *provider) PutAlerts(ctx context.Context, orgID string, alerts al
|
||||
return provider.service.PutAlerts(ctx, orgID, alerts)
|
||||
}
|
||||
|
||||
func (provider *provider) TestReceiver(ctx context.Context, orgID string, receiver alertmanagertypes.Receiver) error {
|
||||
func (provider *provider) TestReceiver(ctx context.Context, orgID string, receiver *alertmanagertypes.Receiver) error {
|
||||
return provider.service.TestReceiver(ctx, orgID, receiver)
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ func (provider *provider) GetChannelByID(ctx context.Context, orgID string, chan
|
||||
return provider.configStore.GetChannelByID(ctx, orgID, channelID)
|
||||
}
|
||||
|
||||
func (provider *provider) UpdateChannelByReceiverAndID(ctx context.Context, orgID string, receiver alertmanagertypes.Receiver, id valuer.UUID) error {
|
||||
func (provider *provider) UpdateChannelByReceiverAndID(ctx context.Context, orgID string, receiver *alertmanagertypes.Receiver, id valuer.UUID) error {
|
||||
channel, err := provider.configStore.GetChannelByID(ctx, orgID, id)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -211,7 +211,7 @@ func (provider *provider) DeleteChannelByID(ctx context.Context, orgID string, c
|
||||
}))
|
||||
}
|
||||
|
||||
func (provider *provider) CreateChannel(ctx context.Context, orgID string, receiver alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error) {
|
||||
func (provider *provider) CreateChannel(ctx context.Context, orgID string, receiver *alertmanagertypes.Receiver) (*alertmanagertypes.Channel, error) {
|
||||
config, err := provider.configStore.Get(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -269,7 +269,7 @@ func (migration *addAlertmanager) msTeamsChannelToMSTeamsV2Channel(c *alertmanag
|
||||
return nil
|
||||
}
|
||||
|
||||
func (migration *addAlertmanager) msTeamsReceiverToMSTeamsV2Receiver(receiver alertmanagertypes.Receiver) alertmanagertypes.Receiver {
|
||||
func (migration *addAlertmanager) msTeamsReceiverToMSTeamsV2Receiver(receiver *alertmanagertypes.Receiver) *alertmanagertypes.Receiver {
|
||||
if receiver.MSTeamsConfigs == nil {
|
||||
return receiver
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ func NewAlertsFromPostableAlerts(ctx context.Context, postableAlerts PostableAle
|
||||
return validAlerts, errs
|
||||
}
|
||||
|
||||
func NewTestAlert(receiver Receiver, startsAt time.Time, updatedAt time.Time) *Alert {
|
||||
func NewTestAlert(receiver *Receiver, startsAt time.Time, updatedAt time.Time) *Alert {
|
||||
return &Alert{
|
||||
Alert: model.Alert{
|
||||
StartsAt: startsAt,
|
||||
|
||||
@@ -56,7 +56,7 @@ type Channel struct {
|
||||
|
||||
// NewChannelFromReceiver creates a new Channel from a Receiver.
|
||||
// It can return nil if the receiver is the default receiver.
|
||||
func NewChannelFromReceiver(receiver config.Receiver, orgID string) (*Channel, error) {
|
||||
func NewChannelFromReceiver(receiver *Receiver, orgID string) (*Channel, error) {
|
||||
if receiver.Name == DefaultReceiverName {
|
||||
return nil, errors.Newf(errors.TypeInvalidInput, ErrCodeAlertmanagerChannelInvalid, "cannot use %s name as a channel name", receiver.Name)
|
||||
}
|
||||
@@ -74,46 +74,13 @@ func NewChannelFromReceiver(receiver config.Receiver, orgID string) (*Channel, e
|
||||
OrgID: orgID,
|
||||
}
|
||||
|
||||
// Use reflection to examine receiver struct fields
|
||||
receiverType := reflect.TypeOf(receiver)
|
||||
receiverVal := reflect.ValueOf(receiver)
|
||||
|
||||
// Iterate through fields looking for *Config fields
|
||||
for i := 0; i < receiverType.NumField(); i++ {
|
||||
field := receiverType.Field(i)
|
||||
fieldVal := receiverVal.Field(i)
|
||||
|
||||
// Skip if not a slice or is empty
|
||||
if fieldVal.Kind() != reflect.Slice || fieldVal.Len() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get channel type from yaml tag
|
||||
yamlTag := field.Tag.Get("yaml")
|
||||
if yamlTag == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Extract the base type name (e.g., "email_configs" -> "email")
|
||||
matches := receiverTypeRegex.FindStringSubmatch(yamlTag)
|
||||
if len(matches) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
channelType := matches[1]
|
||||
|
||||
// Marshal config data to JSON
|
||||
configData, err := json.Marshal(receiver)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
channel.Type = channelType
|
||||
channel.Data = string(configData)
|
||||
break
|
||||
data, err := json.Marshal(receiver)
|
||||
if err != nil {
|
||||
return nil, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "marshal receiver")
|
||||
}
|
||||
channel.Data = string(data)
|
||||
|
||||
// If we were unable to find the channel type, return an error
|
||||
channel.Type = receiverChannelType(receiver)
|
||||
if channel.Type == "" {
|
||||
return nil, errors.Newf(errors.TypeInvalidInput, ErrCodeAlertmanagerChannelInvalid, "channel '%s' must have at least one notification configuration (e.g., email_configs, webhook_configs, slack_configs)", receiver.Name)
|
||||
}
|
||||
@@ -121,6 +88,44 @@ func NewChannelFromReceiver(receiver config.Receiver, orgID string) (*Channel, e
|
||||
return &channel, nil
|
||||
}
|
||||
|
||||
// receiverChannelType returns the channel.Type discriminator. Walks
|
||||
// Receiver's own fields first (native), then the embed (upstream); first
|
||||
// non-empty *_configs slice wins.
|
||||
func receiverChannelType(receiver *Receiver) string {
|
||||
if t := nonEmptyConfigsField(reflect.ValueOf(*receiver)); t != "" {
|
||||
return t
|
||||
}
|
||||
if t := nonEmptyConfigsField(reflect.ValueOf(*receiver.Receiver)); t != "" {
|
||||
return t
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func nonEmptyConfigsField(v reflect.Value) string {
|
||||
t := v.Type()
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
fieldVal := v.Field(i)
|
||||
|
||||
if fieldVal.Kind() != reflect.Slice || fieldVal.Len() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
yamlTag := field.Tag.Get("yaml")
|
||||
if yamlTag == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Extract the base type name (e.g., "email_configs" -> "email").
|
||||
matches := receiverTypeRegex.FindStringSubmatch(yamlTag)
|
||||
if len(matches) != 2 {
|
||||
continue
|
||||
}
|
||||
return matches[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func NewConfigFromChannels(globalConfig GlobalConfig, routeConfig RouteConfig, channels Channels, orgID string) (*Config, error) {
|
||||
cfg, err := NewDefaultConfig(
|
||||
globalConfig,
|
||||
@@ -182,7 +187,7 @@ func NewStatsFromChannels(channels Channels) map[string]any {
|
||||
return stats
|
||||
}
|
||||
|
||||
func (c *Channel) Update(receiver Receiver) error {
|
||||
func (c *Channel) Update(receiver *Receiver) error {
|
||||
channel, err := NewChannelFromReceiver(receiver, c.OrgID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -192,6 +197,7 @@ func (c *Channel) Update(receiver Receiver) error {
|
||||
return errors.Newf(errors.TypeInvalidInput, ErrCodeAlertmanagerChannelNameMismatch, "cannot update channel name")
|
||||
}
|
||||
|
||||
c.Type = channel.Type
|
||||
c.Data = channel.Data
|
||||
c.UpdatedAt = time.Now()
|
||||
|
||||
@@ -210,15 +216,19 @@ func (PostableChannel) JSONSchema() (jsonschema.Schema, error) {
|
||||
schema.WithRequired("name")
|
||||
|
||||
var oneOf []jsonschema.SchemaOrBool
|
||||
receiverType := reflect.TypeOf(Receiver{})
|
||||
for i := 0; i < receiverType.NumField(); i++ {
|
||||
jsonTag := strings.Split(receiverType.Field(i).Tag.Get("json"), ",")[0]
|
||||
if !strings.HasSuffix(jsonTag, "_configs") {
|
||||
continue
|
||||
// Walk both halves: native fields on Receiver, upstream on the embed.
|
||||
collect := func(t reflect.Type) {
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
jsonTag := strings.Split(t.Field(i).Tag.Get("json"), ",")[0]
|
||||
if !strings.HasSuffix(jsonTag, "_configs") {
|
||||
continue
|
||||
}
|
||||
branch := (&jsonschema.Schema{}).WithRequired(jsonTag)
|
||||
oneOf = append(oneOf, branch.ToSchemaOrBool())
|
||||
}
|
||||
branch := (&jsonschema.Schema{}).WithRequired(jsonTag)
|
||||
oneOf = append(oneOf, branch.ToSchemaOrBool())
|
||||
}
|
||||
collect(reflect.TypeOf(Receiver{}))
|
||||
collect(reflect.TypeOf(config.Receiver{}))
|
||||
|
||||
schema.WithOneOf(oneOf...)
|
||||
|
||||
|
||||
@@ -285,7 +285,8 @@ func TestNewChannelFromReceiver(t *testing.T) {
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
channel, err := NewChannelFromReceiver(testCase.receiver, "1")
|
||||
receiver := testCase.receiver
|
||||
channel, err := NewChannelFromReceiver(&Receiver{Receiver: &receiver}, "1")
|
||||
if !testCase.pass {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
@@ -299,3 +300,31 @@ func TestNewChannelFromReceiver(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Type and Data are derived from the native googlechat_configs field.
|
||||
func TestNewChannelFromReceiverGoogleChat(t *testing.T) {
|
||||
webhookURL, err := url.Parse("https://chat.googleapis.com/v1/spaces/test/messages")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
receiver := &Receiver{
|
||||
Receiver: &config.Receiver{Name: "googlechat-receiver"},
|
||||
GoogleChatConfigs: []*GoogleChatReceiverConfig{
|
||||
{
|
||||
WebhookURL: &config.SecretURL{URL: webhookURL},
|
||||
Title: "Alert",
|
||||
Text: "Body",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
channel, err := NewChannelFromReceiver(receiver, "1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "googlechat-receiver", channel.Name)
|
||||
assert.Equal(t, "googlechat", channel.Type)
|
||||
assert.JSONEq(t,
|
||||
`{"name":"googlechat-receiver","googlechat_configs":[{"send_resolved":false,"webhook_url":"https://chat.googleapis.com/v1/spaces/test/messages","title":"Alert","text":"Body"}]}`,
|
||||
channel.Data,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -59,12 +59,43 @@ type Config struct {
|
||||
|
||||
// storeableConfig is the representation of the config in the store
|
||||
storeableConfig *StoreableConfig
|
||||
|
||||
// customConfigs holds the custom notifier configs upstream's
|
||||
// config.Receiver cannot carry, keyed by receiver name.
|
||||
customConfigs map[string]customReceiverConfigs
|
||||
}
|
||||
|
||||
// customReceiverConfigs is the per-receiver custom notifier
|
||||
// configs. To add another, mirror GoogleChat: a field here, a matching field
|
||||
// on Receiver, and extensions to customConfigsOf + isEmpty.
|
||||
type customReceiverConfigs struct {
|
||||
GoogleChat []*GoogleChatReceiverConfig
|
||||
}
|
||||
|
||||
func (c customReceiverConfigs) isEmpty() bool {
|
||||
return len(c.GoogleChat) == 0
|
||||
}
|
||||
|
||||
func customConfigsOf(receiver *Receiver) customReceiverConfigs {
|
||||
return customReceiverConfigs{
|
||||
GoogleChat: receiver.GoogleChatConfigs,
|
||||
}
|
||||
}
|
||||
|
||||
// storedConfig is the persistence unit. The outer Receivers shadows the
|
||||
// embed's so receivers emit as the extended *Receiver (encoding/json:
|
||||
// shallower-field-wins on duplicate JSON names).
|
||||
type storedConfig struct {
|
||||
*config.Config
|
||||
Receivers []*Receiver `json:"receivers"`
|
||||
}
|
||||
|
||||
func NewConfig(c *config.Config, orgID string) *Config {
|
||||
raw := string(newRawFromConfig(c))
|
||||
customConfigs := make(map[string]customReceiverConfigs)
|
||||
raw := string(newRawFromConfig(c, customConfigs))
|
||||
return &Config{
|
||||
alertmanagerConfig: c,
|
||||
customConfigs: customConfigs,
|
||||
storeableConfig: &StoreableConfig{
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
@@ -81,13 +112,14 @@ func NewConfig(c *config.Config, orgID string) *Config {
|
||||
}
|
||||
|
||||
func NewConfigFromStoreableConfig(sc *StoreableConfig) (*Config, error) {
|
||||
alertmanagerConfig, err := newConfigFromString(sc.Config)
|
||||
alertmanagerConfig, customConfigs, err := newConfigFromString(sc.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Config{
|
||||
alertmanagerConfig: alertmanagerConfig,
|
||||
customConfigs: customConfigs,
|
||||
storeableConfig: sc,
|
||||
}, nil
|
||||
}
|
||||
@@ -113,32 +145,47 @@ func NewDefaultConfig(globalConfig GlobalConfig, routeConfig RouteConfig, orgID
|
||||
}, orgID), nil
|
||||
}
|
||||
|
||||
func newConfigFromString(s string) (*config.Config, error) {
|
||||
config := new(config.Config)
|
||||
err := json.Unmarshal([]byte(s), config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func newConfigFromString(s string) (*config.Config, map[string]customReceiverConfigs, error) {
|
||||
stored := storedConfig{Config: new(config.Config)}
|
||||
if err := json.Unmarshal([]byte(s), &stored); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
for i, receiver := range config.Receivers {
|
||||
bytes, err := json.Marshal(receiver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amConfig := stored.Config
|
||||
amConfig.Receivers = make([]config.Receiver, len(stored.Receivers))
|
||||
customConfigs := make(map[string]customReceiverConfigs)
|
||||
|
||||
receiver, err := NewReceiver(string(bytes))
|
||||
// Re-run NewReceiver per receiver so defaults apply (mirrors create path).
|
||||
for i, rcv := range stored.Receivers {
|
||||
rcvJSON, err := json.Marshal(rcv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
parsed, err := NewReceiver(string(rcvJSON))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
amConfig.Receivers[i] = *parsed.Receiver
|
||||
if custom := customConfigsOf(parsed); !custom.isEmpty() {
|
||||
customConfigs[parsed.Name] = custom
|
||||
}
|
||||
|
||||
config.Receivers[i] = receiver
|
||||
}
|
||||
|
||||
return config, nil
|
||||
return amConfig, customConfigs, nil
|
||||
}
|
||||
|
||||
func newRawFromConfig(c *config.Config) []byte {
|
||||
b, err := json.Marshal(c)
|
||||
func newRawFromConfig(c *config.Config, customConfigs map[string]customReceiverConfigs) []byte {
|
||||
receivers := make([]*Receiver, len(c.Receivers))
|
||||
for i := range c.Receivers {
|
||||
base := c.Receivers[i]
|
||||
custom := customConfigs[base.Name]
|
||||
receivers[i] = &Receiver{
|
||||
Receiver: &base,
|
||||
GoogleChatConfigs: custom.GoogleChat,
|
||||
}
|
||||
}
|
||||
|
||||
b, err := json.Marshal(storedConfig{Config: c, Receivers: receivers})
|
||||
if err != nil {
|
||||
// Taking inspiration from the upstream. This is never expected to happen.
|
||||
return []byte(fmt.Sprintf("<error creating config string: %s>", err))
|
||||
@@ -151,6 +198,14 @@ func newConfigHash(s string) [16]byte {
|
||||
return md5.Sum([]byte(s))
|
||||
}
|
||||
|
||||
// flush refreshes the storeable representation. Call after any mutation.
|
||||
func (c *Config) flush() {
|
||||
raw := string(newRawFromConfig(c.alertmanagerConfig, c.customConfigs))
|
||||
c.storeableConfig.Config = raw
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(raw))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
}
|
||||
|
||||
func (c *Config) CopyWithReset() (*Config, error) {
|
||||
newConfig, err := NewDefaultConfig(
|
||||
*c.alertmanagerConfig.Global,
|
||||
@@ -179,9 +234,7 @@ func (c *Config) SetGlobalConfig(globalConfig GlobalConfig) error {
|
||||
globalConfig.SMTPRequireTLS = smtpRequireTLS
|
||||
|
||||
c.alertmanagerConfig.Global = &globalConfig
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
c.flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -193,9 +246,7 @@ func (c *Config) SetRouteConfig(routeConfig RouteConfig) error {
|
||||
}
|
||||
c.alertmanagerConfig.Route = route
|
||||
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
c.flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -207,9 +258,7 @@ func (c *Config) AddInhibitRules(rules []config.InhibitRule) error {
|
||||
|
||||
c.alertmanagerConfig.InhibitRules = append(c.alertmanagerConfig.InhibitRules, rules...)
|
||||
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
c.flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -222,7 +271,7 @@ func (c *Config) StoreableConfig() *StoreableConfig {
|
||||
return c.storeableConfig
|
||||
}
|
||||
|
||||
func (c *Config) CreateReceiver(receiver config.Receiver) error {
|
||||
func (c *Config) CreateReceiver(receiver *Receiver) error {
|
||||
// check that receiver name is not already used
|
||||
for _, existingReceiver := range c.alertmanagerConfig.Receivers {
|
||||
if existingReceiver.Name == receiver.Name {
|
||||
@@ -236,33 +285,39 @@ func (c *Config) CreateReceiver(receiver config.Receiver) error {
|
||||
}
|
||||
|
||||
c.alertmanagerConfig.Route.Routes = append(c.alertmanagerConfig.Route.Routes, route)
|
||||
c.alertmanagerConfig.Receivers = append(c.alertmanagerConfig.Receivers, receiver)
|
||||
c.alertmanagerConfig.Receivers = append(c.alertmanagerConfig.Receivers, *receiver.Receiver)
|
||||
c.setCustomConfigs(receiver)
|
||||
|
||||
if err := c.alertmanagerConfig.UnmarshalYAML(func(i interface{}) error { return nil }); err != nil {
|
||||
return err
|
||||
}
|
||||
c.applyNativeDefaults()
|
||||
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
c.flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) GetReceiver(name string) (Receiver, error) {
|
||||
for _, receiver := range c.alertmanagerConfig.Receivers {
|
||||
if receiver.Name == name {
|
||||
return receiver, nil
|
||||
func (c *Config) GetReceiver(name string) (*Receiver, error) {
|
||||
for i := range c.alertmanagerConfig.Receivers {
|
||||
if c.alertmanagerConfig.Receivers[i].Name == name {
|
||||
base := c.alertmanagerConfig.Receivers[i]
|
||||
custom := c.customConfigs[name]
|
||||
return &Receiver{
|
||||
Receiver: &base,
|
||||
GoogleChatConfigs: custom.GoogleChat,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return Receiver{}, errors.Newf(errors.TypeNotFound, ErrCodeAlertmanagerChannelNotFound, "channel with name %q not found", name)
|
||||
return nil, errors.Newf(errors.TypeNotFound, ErrCodeAlertmanagerChannelNotFound, "channel with name %q not found", name)
|
||||
}
|
||||
|
||||
func (c *Config) UpdateReceiver(receiver config.Receiver) error {
|
||||
func (c *Config) UpdateReceiver(receiver *Receiver) error {
|
||||
// find and update receiver
|
||||
for i, existingReceiver := range c.alertmanagerConfig.Receivers {
|
||||
if existingReceiver.Name == receiver.Name {
|
||||
c.alertmanagerConfig.Receivers[i] = receiver
|
||||
c.alertmanagerConfig.Receivers[i] = *receiver.Receiver
|
||||
c.setCustomConfigs(receiver)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -270,10 +325,9 @@ func (c *Config) UpdateReceiver(receiver config.Receiver) error {
|
||||
if err := c.alertmanagerConfig.UnmarshalYAML(func(i interface{}) error { return nil }); err != nil {
|
||||
return err
|
||||
}
|
||||
c.applyNativeDefaults()
|
||||
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
c.flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -298,13 +352,36 @@ func (c *Config) DeleteReceiver(name string) error {
|
||||
}
|
||||
}
|
||||
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
delete(c.customConfigs, name)
|
||||
|
||||
c.flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) setCustomConfigs(receiver *Receiver) {
|
||||
if custom := customConfigsOf(receiver); !custom.isEmpty() {
|
||||
c.customConfigs[receiver.Name] = custom
|
||||
} else {
|
||||
delete(c.customConfigs, receiver.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) applyNativeDefaults() {
|
||||
if c.alertmanagerConfig.Global == nil {
|
||||
return
|
||||
}
|
||||
httpDefault := c.alertmanagerConfig.Global.HTTPConfig
|
||||
|
||||
for _, custom := range c.customConfigs {
|
||||
for _, gc := range custom.GoogleChat {
|
||||
if gc.HTTPConfig == nil {
|
||||
gc.HTTPConfig = httpDefault
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) CreateRuleIDMatcher(ruleID string, receiverNames []string) error {
|
||||
if c.alertmanagerConfig.Route == nil {
|
||||
return errors.New(errors.TypeInvalidInput, ErrCodeAlertmanagerConfigInvalid, "route is nil")
|
||||
@@ -318,9 +395,7 @@ func (c *Config) CreateRuleIDMatcher(ruleID string, receiverNames []string) erro
|
||||
}
|
||||
}
|
||||
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
c.flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -339,9 +414,7 @@ func (c *Config) DeleteRuleIDInhibitor(ruleID string) error {
|
||||
}
|
||||
}
|
||||
c.alertmanagerConfig.InhibitRules = filteredRules
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
c.flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -362,9 +435,7 @@ func (c *Config) DeleteRuleIDMatcher(ruleID string) error {
|
||||
}
|
||||
}
|
||||
|
||||
c.storeableConfig.Config = string(newRawFromConfig(c.alertmanagerConfig))
|
||||
c.storeableConfig.Hash = fmt.Sprintf("%x", newConfigHash(c.storeableConfig.Config))
|
||||
c.storeableConfig.UpdatedAt = time.Now()
|
||||
c.flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ func TestCreateRuleIDMatcher(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, receiver := range tc.receivers {
|
||||
err := cfg.CreateReceiver(receiver)
|
||||
err := cfg.CreateReceiver(&Receiver{Receiver: &receiver})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ func TestDeleteRuleIDMatcher(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, receiver := range tc.receivers {
|
||||
err := cfg.CreateReceiver(receiver)
|
||||
err := cfg.CreateReceiver(&Receiver{Receiver: &receiver})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -329,3 +329,58 @@ func TestSetGlobalConfigPreservesSMTPRequireTLS(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Round-trip: create → serialize → reload → GetReceiver still has the configs.
|
||||
func TestConfigPreservesGoogleChatConfigs(t *testing.T) {
|
||||
webhookURL, err := url.Parse("https://chat.googleapis.com/v1/spaces/test/messages")
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg, err := NewDefaultConfig(
|
||||
GlobalConfig{SMTPSmarthost: config.HostPort{Host: "localhost", Port: "25"}, SMTPFrom: "test@example.com"},
|
||||
RouteConfig{GroupInterval: time.Minute, GroupWait: time.Minute, RepeatInterval: time.Minute},
|
||||
"1",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
receiver := &Receiver{
|
||||
Receiver: &config.Receiver{Name: "googlechat-receiver"},
|
||||
GoogleChatConfigs: []*GoogleChatReceiverConfig{
|
||||
{
|
||||
WebhookURL: &config.SecretURL{URL: webhookURL},
|
||||
Title: "Alert",
|
||||
Text: "Body",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, cfg.CreateReceiver(receiver))
|
||||
|
||||
got, err := cfg.GetReceiver("googlechat-receiver")
|
||||
require.NoError(t, err)
|
||||
require.Len(t, got.GoogleChatConfigs, 1)
|
||||
assert.Equal(t, "Alert", got.GoogleChatConfigs[0].Title)
|
||||
assert.Equal(t, "Body", got.GoogleChatConfigs[0].Text)
|
||||
|
||||
// HTTPConfig threaded from Global by applyNativeDefaults.
|
||||
require.NotNil(t, got.GoogleChatConfigs[0].HTTPConfig)
|
||||
assert.Same(t, cfg.alertmanagerConfig.Global.HTTPConfig, got.GoogleChatConfigs[0].HTTPConfig)
|
||||
|
||||
reloaded, err := NewConfigFromStoreableConfig(cfg.StoreableConfig())
|
||||
require.NoError(t, err)
|
||||
|
||||
reloadedReceiver, err := reloaded.GetReceiver("googlechat-receiver")
|
||||
require.NoError(t, err)
|
||||
require.Len(t, reloadedReceiver.GoogleChatConfigs, 1)
|
||||
assert.Equal(t, "Alert", reloadedReceiver.GoogleChatConfigs[0].Title)
|
||||
assert.Equal(t, "Body", reloadedReceiver.GoogleChatConfigs[0].Text)
|
||||
assert.Equal(t, "https://chat.googleapis.com/v1/spaces/test/messages", reloadedReceiver.GoogleChatConfigs[0].WebhookURL.String())
|
||||
require.NotNil(t, reloadedReceiver.GoogleChatConfigs[0].HTTPConfig)
|
||||
|
||||
receiver.GoogleChatConfigs[0].Title = "Updated"
|
||||
require.NoError(t, cfg.UpdateReceiver(receiver))
|
||||
|
||||
updated, err := cfg.GetReceiver("googlechat-receiver")
|
||||
require.NoError(t, err)
|
||||
require.Len(t, updated.GoogleChatConfigs, 1)
|
||||
assert.Equal(t, "Updated", updated.GoogleChatConfigs[0].Title)
|
||||
}
|
||||
|
||||
34
pkg/types/alertmanagertypes/googlechat.go
Normal file
34
pkg/types/alertmanagertypes/googlechat.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package alertmanagertypes
|
||||
|
||||
import (
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
commoncfg "github.com/prometheus/common/config"
|
||||
)
|
||||
|
||||
type GoogleChatReceiverConfig struct {
|
||||
config.NotifierConfig `yaml:",inline" json:",inline"`
|
||||
|
||||
HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"`
|
||||
|
||||
WebhookURL *config.SecretURL `yaml:"webhook_url,omitempty" json:"webhook_url,omitempty"`
|
||||
Title string `yaml:"title,omitempty" json:"title,omitempty"`
|
||||
Text string `yaml:"text,omitempty" json:"text,omitempty"`
|
||||
}
|
||||
|
||||
var DefaultGoogleChatReceiverConfig = GoogleChatReceiverConfig{
|
||||
NotifierConfig: config.NotifierConfig{
|
||||
VSendResolved: false,
|
||||
},
|
||||
Title: `[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }}`,
|
||||
Text: `{{ range .Alerts -}}
|
||||
*Alert:* {{ .Labels.alertname }}{{ if .Labels.severity }} ({{ .Labels.severity }}){{ end }}{{ if .Annotations.summary }}
|
||||
*Summary:* {{ .Annotations.summary }}{{ end }}{{ if .Annotations.description }}
|
||||
*Description:* {{ .Annotations.description }}{{ end }}
|
||||
{{ end }}`,
|
||||
}
|
||||
|
||||
func (c *GoogleChatReceiverConfig) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
*c = DefaultGoogleChatReceiverConfig
|
||||
type plain GoogleChatReceiverConfig
|
||||
return unmarshal((*plain)(c))
|
||||
}
|
||||
@@ -22,7 +22,7 @@ func TestAddRuleIDToRoute(t *testing.T) {
|
||||
{
|
||||
name: "Simple",
|
||||
route: func() *config.Route {
|
||||
route, err := NewRouteFromReceiver(Receiver{Name: "test"})
|
||||
route, err := NewRouteFromReceiver(&Receiver{Receiver: &config.Receiver{Name: "test"}})
|
||||
require.NoError(t, err)
|
||||
|
||||
return route
|
||||
@@ -33,7 +33,7 @@ func TestAddRuleIDToRoute(t *testing.T) {
|
||||
{
|
||||
name: "AlreadyExists",
|
||||
route: func() *config.Route {
|
||||
route, err := NewRouteFromReceiver(Receiver{Name: "test"})
|
||||
route, err := NewRouteFromReceiver(&Receiver{Receiver: &config.Receiver{Name: "test"}})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = addRuleIDToRoute(route, "1")
|
||||
@@ -84,7 +84,7 @@ func TestRemoveRuleIDFromRoute(t *testing.T) {
|
||||
{
|
||||
name: "Simple",
|
||||
route: func() *config.Route {
|
||||
route, err := NewRouteFromReceiver(Receiver{Name: "test"})
|
||||
route, err := NewRouteFromReceiver(&Receiver{Receiver: &config.Receiver{Name: "test"}})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = addRuleIDToRoute(route, "1")
|
||||
@@ -98,7 +98,7 @@ func TestRemoveRuleIDFromRoute(t *testing.T) {
|
||||
{
|
||||
name: "DoesNotExist",
|
||||
route: func() *config.Route {
|
||||
route, err := NewRouteFromReceiver(Receiver{Name: "test"})
|
||||
route, err := NewRouteFromReceiver(&Receiver{Receiver: &config.Receiver{Name: "test"}})
|
||||
require.NoError(t, err)
|
||||
|
||||
return route
|
||||
@@ -109,7 +109,7 @@ func TestRemoveRuleIDFromRoute(t *testing.T) {
|
||||
{
|
||||
name: "DeleteMatcher",
|
||||
route: func() *config.Route {
|
||||
route, err := NewRouteFromReceiver(Receiver{Name: "test"})
|
||||
route, err := NewRouteFromReceiver(&Receiver{Receiver: &config.Receiver{Name: "test"}})
|
||||
require.NoError(t, err)
|
||||
|
||||
return route
|
||||
|
||||
@@ -17,4 +17,4 @@ type Templater interface {
|
||||
|
||||
// ReceiverIntegrationsFunc constructs the notify.Integration list for a
|
||||
// configured receiver.
|
||||
type ReceiverIntegrationsFunc = func(nc Receiver, tmpl *template.Template, logger *slog.Logger, templater Templater) ([]notify.Integration, error)
|
||||
type ReceiverIntegrationsFunc = func(nc *Receiver, tmpl *template.Template, logger *slog.Logger, templater Templater) ([]notify.Integration, error)
|
||||
|
||||
@@ -17,40 +17,73 @@ import (
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
)
|
||||
|
||||
type (
|
||||
// Receiver is the type for the receiver configuration.
|
||||
Receiver = config.Receiver
|
||||
)
|
||||
|
||||
// Creates a new receiver from a string. The input is initialized with the default values from the upstream alertmanager.
|
||||
// The only default value which is missed is `send_resolved` (as it is a bool) which if not set in the input will always be set to `false`.
|
||||
func NewReceiver(input string) (Receiver, error) {
|
||||
receiver := Receiver{}
|
||||
err := json.Unmarshal([]byte(input), &receiver)
|
||||
if err != nil {
|
||||
return Receiver{}, err
|
||||
}
|
||||
|
||||
// We marshal and unmarshal the receiver to ensure that the receiver is
|
||||
// initialized with defaults from the upstream alertmanager.
|
||||
bytes, err := yaml.Marshal(receiver)
|
||||
if err != nil {
|
||||
return Receiver{}, err
|
||||
}
|
||||
|
||||
receiverWithDefaults := Receiver{}
|
||||
if err := yaml.Unmarshal(bytes, &receiverWithDefaults); err != nil {
|
||||
return Receiver{}, err
|
||||
}
|
||||
|
||||
if err := receiverWithDefaults.UnmarshalYAML(func(i interface{}) error { return nil }); err != nil {
|
||||
return Receiver{}, err
|
||||
}
|
||||
|
||||
return receiverWithDefaults, nil
|
||||
// Receiver embeds upstream config.Receiver to support custom receivers
|
||||
// To add another native notifier, mirror GoogleChatConfigs here
|
||||
// and extend customReceiverConfigs in config.go.
|
||||
type Receiver struct {
|
||||
*config.Receiver
|
||||
GoogleChatConfigs []*GoogleChatReceiverConfig `json:"googlechat_configs,omitempty" yaml:"googlechat_configs,omitempty"`
|
||||
}
|
||||
|
||||
func TestReceiver(ctx context.Context, receiver Receiver, receiverIntegrationsFunc ReceiverIntegrationsFunc, config *Config, tmpl *template.Template, logger *slog.Logger, templater Templater, lSet model.LabelSet, alert ...*Alert) error {
|
||||
// NewReceiver builds a Receiver from its JSON input, applying each notifier
|
||||
// config's per-config defaults via UnmarshalYAML.
|
||||
func NewReceiver(input string) (*Receiver, error) {
|
||||
receiver := &Receiver{Receiver: &config.Receiver{}}
|
||||
if err := json.Unmarshal([]byte(input), receiver); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
withDefaults, err := defaultedBaseReceiver(receiver.Receiver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
receiver.Receiver = withDefaults
|
||||
|
||||
// Extend this block when adding another native notifier type.
|
||||
for i, gc := range receiver.GoogleChatConfigs {
|
||||
defaulted, err := defaultedNotifierConfig(gc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
receiver.GoogleChatConfigs[i] = defaulted
|
||||
}
|
||||
|
||||
return receiver, nil
|
||||
}
|
||||
|
||||
func defaultedBaseReceiver(base *config.Receiver) (*config.Receiver, error) {
|
||||
bytes, err := yaml.Marshal(base)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
withDefaults := &config.Receiver{}
|
||||
if err := yaml.Unmarshal(bytes, withDefaults); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := withDefaults.UnmarshalYAML(func(i interface{}) error { return nil }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return withDefaults, nil
|
||||
}
|
||||
|
||||
// defaultedNotifierConfig triggers T.UnmarshalYAML via a yaml round-trip,
|
||||
// installing T's DefaultXxxConfig over user values.
|
||||
func defaultedNotifierConfig[T any](cfg *T) (*T, error) {
|
||||
bytes, err := yaml.Marshal(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := new(T)
|
||||
if err := yaml.Unmarshal(bytes, out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func TestReceiver(ctx context.Context, receiver *Receiver, receiverIntegrationsFunc ReceiverIntegrationsFunc, config *Config, tmpl *template.Template, logger *slog.Logger, templater Templater, lSet model.LabelSet, alert ...*Alert) error {
|
||||
ctx = notify.WithGroupKey(ctx, fmt.Sprintf("%s-%s-%d", receiver.Name, lSet.Fingerprint(), time.Now().Unix()))
|
||||
ctx = notify.WithGroupLabels(ctx, lSet)
|
||||
ctx = notify.WithReceiverName(ctx, receiver.Name)
|
||||
@@ -67,12 +100,12 @@ func TestReceiver(ctx context.Context, receiver Receiver, receiverIntegrationsFu
|
||||
return err
|
||||
}
|
||||
|
||||
receiver, err = testConfig.GetReceiver(receiver.Name)
|
||||
defaultedReceiver, err := testConfig.GetReceiver(receiver.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
integrations, err := receiverIntegrationsFunc(receiver, tmpl, logger, templater)
|
||||
integrations, err := receiverIntegrationsFunc(defaultedReceiver, tmpl, logger, templater)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -21,6 +21,12 @@ func TestNewReceiver(t *testing.T) {
|
||||
expected: `{"name":"telegram","telegram_configs":[{"send_resolved":false,"token":"1234567890","chat":12345,"message":"{{ template \"telegram.default.message\" . }}","parse_mode":"HTML"}]}`,
|
||||
pass: true,
|
||||
},
|
||||
{
|
||||
name: "GoogleChatConfig",
|
||||
input: `{"name":"googlechat","googlechat_configs":[{"webhook_url":"https://chat.googleapis.com/v1/spaces/test/messages","title":"Alert","text":"Body"}]}`,
|
||||
expected: `{"name":"googlechat","googlechat_configs":[{"send_resolved":false,"webhook_url":"https://chat.googleapis.com/v1/spaces/test/messages","title":"Alert","text":"Body"}]}`,
|
||||
pass: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -39,3 +45,27 @@ func TestNewReceiver(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Omitted fields fall back to DefaultGoogleChatReceiverConfig.
|
||||
func TestNewReceiverGoogleChatAppliesDefaults(t *testing.T) {
|
||||
receiver, err := NewReceiver(`{"name":"googlechat","googlechat_configs":[{"webhook_url":"https://chat.googleapis.com/v1/spaces/test/messages"}]}`)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, receiver.GoogleChatConfigs, 1)
|
||||
|
||||
got := receiver.GoogleChatConfigs[0]
|
||||
assert.Equal(t, DefaultGoogleChatReceiverConfig.Title, got.Title, "Title should fall back to the default template")
|
||||
assert.Equal(t, DefaultGoogleChatReceiverConfig.Text, got.Text, "Text should fall back to the default template")
|
||||
assert.Equal(t, DefaultGoogleChatReceiverConfig.VSendResolved, got.SendResolved(), "send_resolved should fall back to the default")
|
||||
}
|
||||
|
||||
// User-specified values override defaults.
|
||||
func TestNewReceiverGoogleChatPreservesUserOverrides(t *testing.T) {
|
||||
receiver, err := NewReceiver(`{"name":"googlechat","googlechat_configs":[{"webhook_url":"https://chat.googleapis.com/v1/spaces/test/messages","title":"X","text":"Y","send_resolved":true}]}`)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, receiver.GoogleChatConfigs, 1)
|
||||
|
||||
got := receiver.GoogleChatConfigs[0]
|
||||
assert.Equal(t, "X", got.Title)
|
||||
assert.Equal(t, "Y", got.Text)
|
||||
assert.True(t, got.SendResolved())
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func NewRouteFromRouteConfig(route *config.Route, cfg RouteConfig) (*config.Rout
|
||||
return route, nil
|
||||
}
|
||||
|
||||
func NewRouteFromReceiver(receiver Receiver) (*config.Route, error) {
|
||||
func NewRouteFromReceiver(receiver *Receiver) (*config.Route, error) {
|
||||
route := &config.Route{Receiver: receiver.Name, Continue: true, Matchers: config.Matchers{noRuleIDMatcher}}
|
||||
if err := route.UnmarshalYAML(func(i interface{}) error { return nil }); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user