mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
feat(cloudwatch): add mute and unmute alarm operations (#4602)
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { CloudWatchClient, DisableAlarmActionsCommand } from '@aws-sdk/client-cloudwatch'
|
||||
import { createLogger } from '@sim/logger'
|
||||
import { toError } from '@sim/utils/errors'
|
||||
import { type NextRequest, NextResponse } from 'next/server'
|
||||
import { awsCloudwatchMuteAlarmContract } from '@/lib/api/contracts/tools/aws/cloudwatch-mute-alarm'
|
||||
import { parseToolRequest } from '@/lib/api/server'
|
||||
import { checkInternalAuth } from '@/lib/auth/hybrid'
|
||||
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
|
||||
|
||||
const logger = createLogger('CloudWatchMuteAlarm')
|
||||
|
||||
export const POST = withRouteHandler(async (request: NextRequest) => {
|
||||
try {
|
||||
const auth = await checkInternalAuth(request)
|
||||
if (!auth.success || !auth.userId) {
|
||||
return NextResponse.json({ error: auth.error || 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
|
||||
const parsed = await parseToolRequest(awsCloudwatchMuteAlarmContract, request, {
|
||||
errorFormat: 'details',
|
||||
logger,
|
||||
})
|
||||
if (!parsed.success) return parsed.response
|
||||
const validatedData = parsed.data.body
|
||||
|
||||
logger.info(`Muting ${validatedData.alarmNames.length} CloudWatch alarm(s)`)
|
||||
|
||||
const client = new CloudWatchClient({
|
||||
region: validatedData.region,
|
||||
credentials: {
|
||||
accessKeyId: validatedData.accessKeyId,
|
||||
secretAccessKey: validatedData.secretAccessKey,
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
const command = new DisableAlarmActionsCommand({
|
||||
AlarmNames: validatedData.alarmNames,
|
||||
})
|
||||
|
||||
await client.send(command)
|
||||
|
||||
logger.info(`Successfully muted ${validatedData.alarmNames.length} alarm(s)`)
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
output: {
|
||||
success: true,
|
||||
alarmNames: validatedData.alarmNames,
|
||||
},
|
||||
})
|
||||
} finally {
|
||||
client.destroy()
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('MuteAlarm failed', { error: toError(error).message })
|
||||
return NextResponse.json(
|
||||
{ error: `Failed to mute CloudWatch alarm: ${toError(error).message}` },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,62 @@
|
||||
import { CloudWatchClient, EnableAlarmActionsCommand } from '@aws-sdk/client-cloudwatch'
|
||||
import { createLogger } from '@sim/logger'
|
||||
import { toError } from '@sim/utils/errors'
|
||||
import { type NextRequest, NextResponse } from 'next/server'
|
||||
import { awsCloudwatchUnmuteAlarmContract } from '@/lib/api/contracts/tools/aws/cloudwatch-unmute-alarm'
|
||||
import { parseToolRequest } from '@/lib/api/server'
|
||||
import { checkInternalAuth } from '@/lib/auth/hybrid'
|
||||
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
|
||||
|
||||
const logger = createLogger('CloudWatchUnmuteAlarm')
|
||||
|
||||
export const POST = withRouteHandler(async (request: NextRequest) => {
|
||||
try {
|
||||
const auth = await checkInternalAuth(request)
|
||||
if (!auth.success || !auth.userId) {
|
||||
return NextResponse.json({ error: auth.error || 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
|
||||
const parsed = await parseToolRequest(awsCloudwatchUnmuteAlarmContract, request, {
|
||||
errorFormat: 'details',
|
||||
logger,
|
||||
})
|
||||
if (!parsed.success) return parsed.response
|
||||
const validatedData = parsed.data.body
|
||||
|
||||
logger.info(`Unmuting ${validatedData.alarmNames.length} CloudWatch alarm(s)`)
|
||||
|
||||
const client = new CloudWatchClient({
|
||||
region: validatedData.region,
|
||||
credentials: {
|
||||
accessKeyId: validatedData.accessKeyId,
|
||||
secretAccessKey: validatedData.secretAccessKey,
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
const command = new EnableAlarmActionsCommand({
|
||||
AlarmNames: validatedData.alarmNames,
|
||||
})
|
||||
|
||||
await client.send(command)
|
||||
|
||||
logger.info(`Successfully unmuted ${validatedData.alarmNames.length} alarm(s)`)
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
output: {
|
||||
success: true,
|
||||
alarmNames: validatedData.alarmNames,
|
||||
},
|
||||
})
|
||||
} finally {
|
||||
client.destroy()
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('UnmuteAlarm failed', { error: toError(error).message })
|
||||
return NextResponse.json(
|
||||
{ error: `Failed to unmute CloudWatch alarm: ${toError(error).message}` },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -8,8 +8,10 @@ import type {
|
||||
CloudWatchGetLogEventsResponse,
|
||||
CloudWatchGetMetricStatisticsResponse,
|
||||
CloudWatchListMetricsResponse,
|
||||
CloudWatchMuteAlarmResponse,
|
||||
CloudWatchPutMetricDataResponse,
|
||||
CloudWatchQueryLogsResponse,
|
||||
CloudWatchUnmuteAlarmResponse,
|
||||
} from '@/tools/cloudwatch/types'
|
||||
|
||||
export const CloudWatchBlock: BlockConfig<
|
||||
@@ -21,6 +23,8 @@ export const CloudWatchBlock: BlockConfig<
|
||||
| CloudWatchListMetricsResponse
|
||||
| CloudWatchGetMetricStatisticsResponse
|
||||
| CloudWatchPutMetricDataResponse
|
||||
| CloudWatchMuteAlarmResponse
|
||||
| CloudWatchUnmuteAlarmResponse
|
||||
> = {
|
||||
type: 'cloudwatch',
|
||||
name: 'CloudWatch',
|
||||
@@ -47,6 +51,8 @@ export const CloudWatchBlock: BlockConfig<
|
||||
{ label: 'Get Metric Statistics', id: 'get_metric_statistics' },
|
||||
{ label: 'Publish Metric', id: 'put_metric_data' },
|
||||
{ label: 'Describe Alarms', id: 'describe_alarms' },
|
||||
{ label: 'Mute Alarm', id: 'mute_alarm' },
|
||||
{ label: 'Unmute Alarm', id: 'unmute_alarm' },
|
||||
],
|
||||
value: () => 'query_logs',
|
||||
},
|
||||
@@ -360,6 +366,14 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
|
||||
value: () => '',
|
||||
condition: { field: 'operation', value: 'describe_alarms' },
|
||||
},
|
||||
{
|
||||
id: 'alarmNames',
|
||||
title: 'Alarm Names',
|
||||
type: 'short-input',
|
||||
placeholder: 'my-alarm-1, my-alarm-2',
|
||||
condition: { field: 'operation', value: ['mute_alarm', 'unmute_alarm'] },
|
||||
required: { field: 'operation', value: ['mute_alarm', 'unmute_alarm'] },
|
||||
},
|
||||
{
|
||||
id: 'limit',
|
||||
title: 'Limit',
|
||||
@@ -389,6 +403,8 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
|
||||
'cloudwatch_get_metric_statistics',
|
||||
'cloudwatch_put_metric_data',
|
||||
'cloudwatch_describe_alarms',
|
||||
'cloudwatch_mute_alarm',
|
||||
'cloudwatch_unmute_alarm',
|
||||
],
|
||||
config: {
|
||||
tool: (params) => {
|
||||
@@ -409,6 +425,10 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
|
||||
return 'cloudwatch_put_metric_data'
|
||||
case 'describe_alarms':
|
||||
return 'cloudwatch_describe_alarms'
|
||||
case 'mute_alarm':
|
||||
return 'cloudwatch_mute_alarm'
|
||||
case 'unmute_alarm':
|
||||
return 'cloudwatch_unmute_alarm'
|
||||
default:
|
||||
throw new Error(`Invalid CloudWatch operation: ${params.operation}`)
|
||||
}
|
||||
@@ -613,6 +633,33 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
|
||||
...(parsedLimit !== undefined && { limit: parsedLimit }),
|
||||
}
|
||||
|
||||
case 'mute_alarm':
|
||||
case 'unmute_alarm': {
|
||||
const alarmNames = rest.alarmNames
|
||||
if (!alarmNames) {
|
||||
throw new Error('Alarm names are required')
|
||||
}
|
||||
|
||||
const names =
|
||||
typeof alarmNames === 'string'
|
||||
? alarmNames
|
||||
.split(',')
|
||||
.map((n: string) => n.trim())
|
||||
.filter(Boolean)
|
||||
: alarmNames
|
||||
|
||||
if (!Array.isArray(names) || names.length === 0) {
|
||||
throw new Error('At least one alarm name is required')
|
||||
}
|
||||
|
||||
return {
|
||||
awsRegion,
|
||||
awsAccessKeyId,
|
||||
awsSecretAccessKey,
|
||||
alarmNames: names,
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid CloudWatch operation: ${operation}`)
|
||||
}
|
||||
@@ -653,6 +700,7 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
|
||||
description: 'Alarm state filter (OK, ALARM, INSUFFICIENT_DATA)',
|
||||
},
|
||||
alarmType: { type: 'string', description: 'Alarm type filter (MetricAlarm, CompositeAlarm)' },
|
||||
alarmNames: { type: 'string', description: 'Comma-separated alarm names to mute or unmute' },
|
||||
limit: { type: 'number', description: 'Maximum number of results' },
|
||||
},
|
||||
outputs: {
|
||||
@@ -696,9 +744,13 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
|
||||
type: 'array',
|
||||
description: 'CloudWatch alarms with state and configuration',
|
||||
},
|
||||
alarmNames: {
|
||||
type: 'array',
|
||||
description: 'Names of the alarms that were muted or unmuted',
|
||||
},
|
||||
success: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the published metric was successful',
|
||||
description: 'Whether the operation completed successfully',
|
||||
},
|
||||
namespace: {
|
||||
type: 'string',
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { z } from 'zod'
|
||||
import type {
|
||||
ContractBody,
|
||||
ContractBodyInput,
|
||||
ContractJsonResponse,
|
||||
} from '@/lib/api/contracts/types'
|
||||
import { defineRouteContract } from '@/lib/api/contracts/types'
|
||||
import { validateAwsRegion } from '@/lib/core/security/input-validation'
|
||||
|
||||
const MuteAlarmSchema = z.object({
|
||||
region: z
|
||||
.string()
|
||||
.min(1, 'AWS region is required')
|
||||
.refine((v) => validateAwsRegion(v).isValid, {
|
||||
message: 'Invalid AWS region format (e.g., us-east-1, eu-west-2)',
|
||||
}),
|
||||
accessKeyId: z.string().min(1, 'AWS access key ID is required'),
|
||||
secretAccessKey: z.string().min(1, 'AWS secret access key is required'),
|
||||
alarmNames: z
|
||||
.array(z.string().min(1, 'Alarm name cannot be empty'))
|
||||
.min(1, 'At least one alarm name is required')
|
||||
.max(100, 'At most 100 alarm names are allowed per request'),
|
||||
})
|
||||
|
||||
const MuteAlarmResponseSchema = z.object({
|
||||
success: z.literal(true),
|
||||
output: z.object({
|
||||
success: z.literal(true),
|
||||
alarmNames: z.array(z.string()),
|
||||
}),
|
||||
})
|
||||
|
||||
export const awsCloudwatchMuteAlarmContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/cloudwatch/mute-alarm',
|
||||
body: MuteAlarmSchema,
|
||||
response: { mode: 'json', schema: MuteAlarmResponseSchema },
|
||||
})
|
||||
export type AwsCloudwatchMuteAlarmRequest = ContractBodyInput<typeof awsCloudwatchMuteAlarmContract>
|
||||
export type AwsCloudwatchMuteAlarmBody = ContractBody<typeof awsCloudwatchMuteAlarmContract>
|
||||
export type AwsCloudwatchMuteAlarmResponse = ContractJsonResponse<
|
||||
typeof awsCloudwatchMuteAlarmContract
|
||||
>
|
||||
@@ -0,0 +1,45 @@
|
||||
import { z } from 'zod'
|
||||
import type {
|
||||
ContractBody,
|
||||
ContractBodyInput,
|
||||
ContractJsonResponse,
|
||||
} from '@/lib/api/contracts/types'
|
||||
import { defineRouteContract } from '@/lib/api/contracts/types'
|
||||
import { validateAwsRegion } from '@/lib/core/security/input-validation'
|
||||
|
||||
const UnmuteAlarmSchema = z.object({
|
||||
region: z
|
||||
.string()
|
||||
.min(1, 'AWS region is required')
|
||||
.refine((v) => validateAwsRegion(v).isValid, {
|
||||
message: 'Invalid AWS region format (e.g., us-east-1, eu-west-2)',
|
||||
}),
|
||||
accessKeyId: z.string().min(1, 'AWS access key ID is required'),
|
||||
secretAccessKey: z.string().min(1, 'AWS secret access key is required'),
|
||||
alarmNames: z
|
||||
.array(z.string().min(1, 'Alarm name cannot be empty'))
|
||||
.min(1, 'At least one alarm name is required')
|
||||
.max(100, 'At most 100 alarm names are allowed per request'),
|
||||
})
|
||||
|
||||
const UnmuteAlarmResponseSchema = z.object({
|
||||
success: z.literal(true),
|
||||
output: z.object({
|
||||
success: z.literal(true),
|
||||
alarmNames: z.array(z.string()),
|
||||
}),
|
||||
})
|
||||
|
||||
export const awsCloudwatchUnmuteAlarmContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/cloudwatch/unmute-alarm',
|
||||
body: UnmuteAlarmSchema,
|
||||
response: { mode: 'json', schema: UnmuteAlarmResponseSchema },
|
||||
})
|
||||
export type AwsCloudwatchUnmuteAlarmRequest = ContractBodyInput<
|
||||
typeof awsCloudwatchUnmuteAlarmContract
|
||||
>
|
||||
export type AwsCloudwatchUnmuteAlarmBody = ContractBody<typeof awsCloudwatchUnmuteAlarmContract>
|
||||
export type AwsCloudwatchUnmuteAlarmResponse = ContractJsonResponse<
|
||||
typeof awsCloudwatchUnmuteAlarmContract
|
||||
>
|
||||
@@ -4,8 +4,10 @@ import { describeLogStreamsTool } from '@/tools/cloudwatch/describe_log_streams'
|
||||
import { getLogEventsTool } from '@/tools/cloudwatch/get_log_events'
|
||||
import { getMetricStatisticsTool } from '@/tools/cloudwatch/get_metric_statistics'
|
||||
import { listMetricsTool } from '@/tools/cloudwatch/list_metrics'
|
||||
import { muteAlarmTool } from '@/tools/cloudwatch/mute_alarm'
|
||||
import { putMetricDataTool } from '@/tools/cloudwatch/put_metric_data'
|
||||
import { queryLogsTool } from '@/tools/cloudwatch/query_logs'
|
||||
import { unmuteAlarmTool } from '@/tools/cloudwatch/unmute_alarm'
|
||||
|
||||
export * from './types'
|
||||
|
||||
@@ -15,5 +17,7 @@ export const cloudwatchDescribeLogStreamsTool = describeLogStreamsTool
|
||||
export const cloudwatchGetLogEventsTool = getLogEventsTool
|
||||
export const cloudwatchGetMetricStatisticsTool = getMetricStatisticsTool
|
||||
export const cloudwatchListMetricsTool = listMetricsTool
|
||||
export const cloudwatchMuteAlarmTool = muteAlarmTool
|
||||
export const cloudwatchPutMetricDataTool = putMetricDataTool
|
||||
export const cloudwatchQueryLogsTool = queryLogsTool
|
||||
export const cloudwatchUnmuteAlarmTool = unmuteAlarmTool
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import type {
|
||||
CloudWatchMuteAlarmParams,
|
||||
CloudWatchMuteAlarmResponse,
|
||||
} from '@/tools/cloudwatch/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const muteAlarmTool: ToolConfig<CloudWatchMuteAlarmParams, CloudWatchMuteAlarmResponse> = {
|
||||
id: 'cloudwatch_mute_alarm',
|
||||
name: 'CloudWatch Mute Alarm',
|
||||
description: 'Disable notification actions on one or more CloudWatch alarms',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
awsRegion: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
awsAccessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
awsSecretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
alarmNames: {
|
||||
type: 'array',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Names of the CloudWatch alarms to mute',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/cloudwatch/mute-alarm',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
region: params.awsRegion,
|
||||
accessKeyId: params.awsAccessKeyId,
|
||||
secretAccessKey: params.awsSecretAccessKey,
|
||||
alarmNames: params.alarmNames,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to mute CloudWatch alarm')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: data.output,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Whether the alarms were muted successfully' },
|
||||
alarmNames: {
|
||||
type: 'array',
|
||||
description: 'Names of the alarms that were muted',
|
||||
items: { type: 'string' },
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -163,3 +163,25 @@ export interface CloudWatchPutMetricDataResponse extends ToolResponse {
|
||||
timestamp: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface CloudWatchMuteAlarmParams extends CloudWatchConnectionConfig {
|
||||
alarmNames: string[]
|
||||
}
|
||||
|
||||
export interface CloudWatchMuteAlarmResponse extends ToolResponse {
|
||||
output: {
|
||||
success: boolean
|
||||
alarmNames: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface CloudWatchUnmuteAlarmParams extends CloudWatchConnectionConfig {
|
||||
alarmNames: string[]
|
||||
}
|
||||
|
||||
export interface CloudWatchUnmuteAlarmResponse extends ToolResponse {
|
||||
output: {
|
||||
success: boolean
|
||||
alarmNames: string[]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import type {
|
||||
CloudWatchUnmuteAlarmParams,
|
||||
CloudWatchUnmuteAlarmResponse,
|
||||
} from '@/tools/cloudwatch/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const unmuteAlarmTool: ToolConfig<
|
||||
CloudWatchUnmuteAlarmParams,
|
||||
CloudWatchUnmuteAlarmResponse
|
||||
> = {
|
||||
id: 'cloudwatch_unmute_alarm',
|
||||
name: 'CloudWatch Unmute Alarm',
|
||||
description: 'Re-enable notification actions on one or more CloudWatch alarms',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
awsRegion: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
awsAccessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
awsSecretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
alarmNames: {
|
||||
type: 'array',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Names of the CloudWatch alarms to unmute',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/cloudwatch/unmute-alarm',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
region: params.awsRegion,
|
||||
accessKeyId: params.awsAccessKeyId,
|
||||
secretAccessKey: params.awsSecretAccessKey,
|
||||
alarmNames: params.alarmNames,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to unmute CloudWatch alarm')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: data.output,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Whether the alarms were unmuted successfully' },
|
||||
alarmNames: {
|
||||
type: 'array',
|
||||
description: 'Names of the alarms that were unmuted',
|
||||
items: { type: 'string' },
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -350,8 +350,10 @@ import {
|
||||
cloudwatchGetLogEventsTool,
|
||||
cloudwatchGetMetricStatisticsTool,
|
||||
cloudwatchListMetricsTool,
|
||||
cloudwatchMuteAlarmTool,
|
||||
cloudwatchPutMetricDataTool,
|
||||
cloudwatchQueryLogsTool,
|
||||
cloudwatchUnmuteAlarmTool,
|
||||
} from '@/tools/cloudwatch'
|
||||
import {
|
||||
confluenceAddLabelTool,
|
||||
@@ -3813,8 +3815,10 @@ export const tools: Record<string, ToolConfig> = {
|
||||
cloudwatch_get_log_events: cloudwatchGetLogEventsTool,
|
||||
cloudwatch_get_metric_statistics: cloudwatchGetMetricStatisticsTool,
|
||||
cloudwatch_list_metrics: cloudwatchListMetricsTool,
|
||||
cloudwatch_mute_alarm: cloudwatchMuteAlarmTool,
|
||||
cloudwatch_put_metric_data: cloudwatchPutMetricDataTool,
|
||||
cloudwatch_query_logs: cloudwatchQueryLogsTool,
|
||||
cloudwatch_unmute_alarm: cloudwatchUnmuteAlarmTool,
|
||||
crowdstrike_get_sensor_aggregates: crowdstrikeGetSensorAggregatesTool,
|
||||
crowdstrike_get_sensor_details: crowdstrikeGetSensorDetailsTool,
|
||||
crowdstrike_query_sensors: crowdstrikeQuerySensorsTool,
|
||||
|
||||
@@ -9,8 +9,8 @@ const QUERY_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/queries')
|
||||
const SELECTOR_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/selectors')
|
||||
|
||||
const BASELINE = {
|
||||
totalRoutes: 736,
|
||||
zodRoutes: 736,
|
||||
totalRoutes: 738,
|
||||
zodRoutes: 738,
|
||||
nonZodRoutes: 0,
|
||||
} as const
|
||||
|
||||
|
||||
Reference in New Issue
Block a user