From 2a37ef549265718bf9faf0b91eb739f6af9bbd5a Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Thu, 7 Sep 2023 14:03:08 -0400 Subject: [PATCH 01/27] prelim scheduel in core --- .../aws-cdk-lib/aws-backup/lib/schedule.ts | 0 packages/aws-cdk-lib/core/lib/index.ts | 1 + packages/aws-cdk-lib/core/lib/schedule.ts | 176 ++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 packages/aws-cdk-lib/aws-backup/lib/schedule.ts create mode 100644 packages/aws-cdk-lib/core/lib/schedule.ts diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/aws-cdk-lib/core/lib/index.ts b/packages/aws-cdk-lib/core/lib/index.ts index b35e89c0e59e4..53d5cf9bf63d1 100644 --- a/packages/aws-cdk-lib/core/lib/index.ts +++ b/packages/aws-cdk-lib/core/lib/index.ts @@ -71,3 +71,4 @@ export * from './validation'; export * from './private/intrinsic'; export * from './names'; export * from './time-zone'; +export * from './schedule'; diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts new file mode 100644 index 0000000000000..9ee14ef58ceb4 --- /dev/null +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -0,0 +1,176 @@ +import { Duration } from './duration'; +import { TimeZone } from './time-zone'; + +/** + * Schedule + * + * Note that rates cannot be defined in fractions of minutes. + * + * @see https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html + */ +export abstract class Schedule { + /** + * Construct a one-time schedule from a date. + * + * @param date The date and time to use. The millisecond part will be ignored. + * @param timeZone The time zone to use for interpreting the date. Default: - UTC + */ + public static at(date: Date, timeZone?: TimeZone): Schedule { + try { + const literal = date.toISOString().split('.')[0]; + return new LiteralSchedule(`at(${literal})`, timeZone ?? TimeZone.ETC_UTC); + } catch (e) { + if (e instanceof RangeError) { + throw new Error('Invalid date'); + } + throw e; + } + } + + /** + * Construct a schedule from a literal schedule expression + * + * @param expression The expression to use. Must be in a format that EventBridge will recognize + */ + public static expression(expression: string): Schedule { + return new LiteralSchedule(expression); + } + + /** + * Construct a schedule from an interval and a time unit + * + * Rates may be defined with any unit of time, but when converted into minutes, the duration must be a positive whole number of minutes. + */ + public static rate(duration: Duration): Schedule { + if (duration.isUnresolved()) { + const validDurationUnit = ['minute', 'minutes', 'hour', 'hours', 'day', 'days']; + if (validDurationUnit.indexOf(duration.unitLabel()) === -1) { + throw new Error("Allowed units for scheduling are: 'minute', 'minutes', 'hour', 'hours', 'day', 'days'"); + } + return new LiteralSchedule(`rate(${duration.formatTokenToNumber()})`); + } + if (duration.toMinutes() === 0) { + throw new Error('Duration cannot be 0'); + } + + let rate = maybeRate(duration.toDays({ integral: false }), 'day'); + if (rate === undefined) { rate = maybeRate(duration.toHours({ integral: false }), 'hour'); } + if (rate === undefined) { rate = makeRate(duration.toMinutes({ integral: true }), 'minute'); } + return new LiteralSchedule(rate); + } + + /** + * Create a schedule from a set of cron fields + */ + public static cron(options: CronOptions): Schedule { + if (options.weekDay !== undefined && options.day !== undefined) { + throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); + } + + const minute = fallback(options.minute, '*'); + const hour = fallback(options.hour, '*'); + const month = fallback(options.month, '*'); + const year = fallback(options.year, '*'); + + // Weekday defaults to '?' if not supplied. If it is supplied, day must become '?' + const day = fallback(options.day, options.weekDay !== undefined ? '?' : '*'); + const weekDay = fallback(options.weekDay, '?'); + + const expressionString: string = `cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`; + return new LiteralSchedule(expressionString); + } + + /** + * Retrieve the expression for this schedule + */ + public abstract readonly expressionString: string; + + protected constructor() {} +} + +/** + * Options to configure a cron expression + * + * All fields are strings so you can use complex expressions. Absence of + * a field implies '*' or '?', whichever one is appropriate. + * + * @see https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html#cron-expressions + */ +export interface CronOptions { + /** + * The minute to run this rule at + * + * @default - Every minute + */ + readonly minute?: string; + + /** + * The hour to run this rule at + * + * @default - Every hour + */ + readonly hour?: string; + + /** + * The day of the month to run this rule at + * + * @default - Every day of the month + */ + readonly day?: string; + + /** + * The month to run this rule at + * + * @default - Every month + */ + readonly month?: string; + + /** + * The year to run this rule at + * + * @default - Every year + */ + readonly year?: string; + + /** + * The day of the week to run this rule at + * + * @default - Any day of the week + */ + readonly weekDay?: string; + + /** + * Retrieve the expression for this schedule + */ + readonly timeZone?: TimeZone; +} + +const DEFAULT_TIMEZONE = TimeZone.ETC_UTC; + +class LiteralSchedule extends Schedule { + constructor( + public readonly expressionString: string, + public readonly timeZone: TimeZone = DEFAULT_TIMEZONE, + ) { + super(); + } +} + +function fallback(x: T | undefined, def: T): T { + return x ?? def; +} + +/** + * Return the rate if the rate is whole number + */ +function maybeRate(interval: number, singular: string) { + if (interval === 0 || !Number.isInteger(interval)) { return undefined; } + return makeRate(interval, singular); +} + +/** + * Return 'rate(${interval} ${singular}(s))` for the interval + */ +function makeRate(interval: number, singular: string) { + return interval === 1 ? `rate(1 ${singular})` : `rate(${interval} ${singular}s)`; +} From 1a7848ecb5fd3cc0e83e699dd31f6fc15edbcd90 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 15:42:13 -0400 Subject: [PATCH 02/27] fix schedule --- packages/aws-cdk-lib/core/lib/schedule.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts index 9ee14ef58ceb4..8221f625d03fc 100644 --- a/packages/aws-cdk-lib/core/lib/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -15,7 +15,7 @@ export abstract class Schedule { * @param date The date and time to use. The millisecond part will be ignored. * @param timeZone The time zone to use for interpreting the date. Default: - UTC */ - public static at(date: Date, timeZone?: TimeZone): Schedule { + protected static at(date: Date, timeZone?: TimeZone): Schedule { try { const literal = date.toISOString().split('.')[0]; return new LiteralSchedule(`at(${literal})`, timeZone ?? TimeZone.ETC_UTC); @@ -32,7 +32,7 @@ export abstract class Schedule { * * @param expression The expression to use. Must be in a format that EventBridge will recognize */ - public static expression(expression: string): Schedule { + protected static expression(expression: string): Schedule { return new LiteralSchedule(expression); } @@ -41,7 +41,7 @@ export abstract class Schedule { * * Rates may be defined with any unit of time, but when converted into minutes, the duration must be a positive whole number of minutes. */ - public static rate(duration: Duration): Schedule { + protected static rate(duration: Duration): Schedule { if (duration.isUnresolved()) { const validDurationUnit = ['minute', 'minutes', 'hour', 'hours', 'day', 'days']; if (validDurationUnit.indexOf(duration.unitLabel()) === -1) { @@ -62,7 +62,7 @@ export abstract class Schedule { /** * Create a schedule from a set of cron fields */ - public static cron(options: CronOptions): Schedule { + protected static cron(options: CronOptions): Schedule { if (options.weekDay !== undefined && options.day !== undefined) { throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); } @@ -81,10 +81,15 @@ export abstract class Schedule { } /** - * Retrieve the expression for this schedule + * Retrieve the expression for this schedule. */ public abstract readonly expressionString: string; + /** + * The timezone of the expression, if applicable. + */ + public abstract readonly timeZone?: TimeZone; + protected constructor() {} } @@ -141,6 +146,8 @@ export interface CronOptions { /** * Retrieve the expression for this schedule + * + * @default TimeZone.ETC_UTC */ readonly timeZone?: TimeZone; } From c1d2e2eb4642f27548ba5e85242468f713d59680 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 15:43:02 -0400 Subject: [PATCH 03/27] expose backup.Schedule, create BackupPlanRule.schedule, deprecated BackupPlanRule.scheduleExpression --- packages/aws-cdk-lib/aws-backup/README.md | 18 +++++++++--------- packages/aws-cdk-lib/aws-backup/lib/index.ts | 1 + packages/aws-cdk-lib/aws-backup/lib/plan.ts | 2 +- packages/aws-cdk-lib/aws-backup/lib/rule.ts | 19 +++++++++++++------ .../aws-cdk-lib/aws-backup/lib/schedule.ts | 7 +++++++ .../aws-cdk-lib/aws-backup/test/plan.test.ts | 9 +++++---- .../rosetta/aws_backup/default.ts-fixture | 1 - 7 files changed, 36 insertions(+), 21 deletions(-) diff --git a/packages/aws-cdk-lib/aws-backup/README.md b/packages/aws-cdk-lib/aws-backup/README.md index 27b2fcc3667f1..fe2abaae5608d 100644 --- a/packages/aws-cdk-lib/aws-backup/README.md +++ b/packages/aws-cdk-lib/aws-backup/README.md @@ -8,10 +8,10 @@ configure backup policies and monitor backup activity for your AWS resources in ## Backup plan and selection In AWS Backup, a *backup plan* is a policy expression that defines when and how you want to back up - your AWS resources, such as Amazon DynamoDB tables or Amazon Elastic File System (Amazon EFS) file - systems. You can assign resources to backup plans, and AWS Backup automatically backs up and retains - backups for those resources according to the backup plan. You can create multiple backup plans if you - have workloads with different backup requirements. +your AWS resources, such as Amazon DynamoDB tables or Amazon Elastic File System (Amazon EFS) file +systems. You can assign resources to backup plans, and AWS Backup automatically backs up and retains +backups for those resources according to the backup plan. You can create multiple backup plans if you +have workloads with different backup requirements. This module provides ready-made backup plans (similar to the console experience): @@ -52,8 +52,8 @@ plan.addSelection('Selection', { backup.BackupResource.fromRdsServerlessCluster(myServerlessCluster), // An Aurora Serverless cluster backup.BackupResource.fromTag('stage', 'prod'), // All resources that are tagged stage=prod in the region/account backup.BackupResource.fromConstruct(myCoolConstruct), // All backupable resources in `myCoolConstruct` - ] -}) + ], +}); ``` If not specified, a new IAM role with a managed policy for backup will be @@ -66,7 +66,7 @@ declare const plan: backup.BackupPlan; plan.addRule(new backup.BackupPlanRule({ completionWindow: Duration.hours(2), startWindow: Duration.hours(1), - scheduleExpression: events.Schedule.cron({ // Only cron expressions are supported + schedule: backup.Schedule.cron({ // Only cron expressions are supported day: '15', hour: '3', minute: '30', @@ -100,7 +100,7 @@ plan.addRule(new backup.BackupPlanRule({ destinationBackupVault: secondaryVault, moveToColdStorageAfter: Duration.days(30), deleteAfter: Duration.days(120), - }] + }], })); ``` @@ -193,7 +193,7 @@ const vault = new backup.BackupVault(this, 'Vault', { }), ], }), -}) +}); ``` Alternativately statements can be added to the vault policy using `addToAccessPolicy()`. diff --git a/packages/aws-cdk-lib/aws-backup/lib/index.ts b/packages/aws-cdk-lib/aws-backup/lib/index.ts index 7b34df14d75df..2e6094022a9e1 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/index.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/index.ts @@ -3,6 +3,7 @@ export * from './plan'; export * from './rule'; export * from './selection'; export * from './resource'; +export * from './schedule'; // AWS::Backup CloudFormation Resources: export * from './backup.generated'; diff --git a/packages/aws-cdk-lib/aws-backup/lib/plan.ts b/packages/aws-cdk-lib/aws-backup/lib/plan.ts index a7ce167ac92ea..f9d8a915f1f23 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/plan.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/plan.ts @@ -187,7 +187,7 @@ export class BackupPlan extends Resource implements IBackupPlan { moveToColdStorageAfterDays: rule.props.moveToColdStorageAfter?.toDays(), }, ruleName: rule.props.ruleName ?? `${this.node.id}Rule${this.rules.length}`, - scheduleExpression: rule.props.scheduleExpression?.expressionString, + scheduleExpression: rule.props.schedule?.expressionString ?? rule.props.scheduleExpression?.expressionString, startWindowMinutes: rule.props.startWindow?.toMinutes(), enableContinuousBackup: rule.props.enableContinuousBackup, targetBackupVault: vault.backupVaultName, diff --git a/packages/aws-cdk-lib/aws-backup/lib/rule.ts b/packages/aws-cdk-lib/aws-backup/lib/rule.ts index fe546619bddb3..cf306b3e7b18d 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/rule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/rule.ts @@ -1,6 +1,7 @@ import { IBackupVault } from './vault'; import * as events from '../../aws-events'; import { Duration, Token } from '../../core'; +import { Schedule } from './schedule'; /** * Properties for a BackupPlanRule @@ -41,9 +42,15 @@ export interface BackupPlanRuleProps { * A CRON expression specifying when AWS Backup initiates a backup job. * * @default - no schedule + * @deprecated use schedule prop instead */ readonly scheduleExpression?: events.Schedule; + /** + * A CRON expression specifying when AWS Backup initiates a backup job. + */ + readonly schedule?: Schedule; + /** * The duration after a backup is scheduled before a job is canceled if it doesn't start successfully. * @@ -122,7 +129,7 @@ export class BackupPlanRule { return new BackupPlanRule({ backupVault, ruleName: 'Daily', - scheduleExpression: events.Schedule.cron({ + schedule: Schedule.cron({ hour: '5', minute: '0', }), @@ -137,7 +144,7 @@ export class BackupPlanRule { return new BackupPlanRule({ backupVault, ruleName: 'Weekly', - scheduleExpression: events.Schedule.cron({ + schedule: Schedule.cron({ hour: '5', minute: '0', weekDay: 'SAT', @@ -153,7 +160,7 @@ export class BackupPlanRule { return new BackupPlanRule({ backupVault, ruleName: 'Monthly1Year', - scheduleExpression: events.Schedule.cron({ + schedule: Schedule.cron({ day: '1', hour: '5', minute: '0', @@ -170,7 +177,7 @@ export class BackupPlanRule { return new BackupPlanRule({ backupVault, ruleName: 'Monthly5Year', - scheduleExpression: events.Schedule.cron({ + schedule: Schedule.cron({ day: '1', hour: '5', minute: '0', @@ -187,7 +194,7 @@ export class BackupPlanRule { return new BackupPlanRule({ backupVault, ruleName: 'Monthly7Year', - scheduleExpression: events.Schedule.cron({ + schedule: Schedule.cron({ day: '1', hour: '5', minute: '0', @@ -200,7 +207,7 @@ export class BackupPlanRule { /** * Properties of BackupPlanRule */ - public readonly props: BackupPlanRuleProps + public readonly props: BackupPlanRuleProps; /** @param props Rule properties */ constructor(props: BackupPlanRuleProps) { diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts index e69de29bb2d1d..b5c8fbdcdd41d 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts @@ -0,0 +1,7 @@ +import { CronOptions, Schedule as ScheduleExpression } from '../../core'; + +export abstract class Schedule extends ScheduleExpression { + public static cron(options: CronOptions): Schedule { + return super.cron(options); + } +} diff --git a/packages/aws-cdk-lib/aws-backup/test/plan.test.ts b/packages/aws-cdk-lib/aws-backup/test/plan.test.ts index 4d9c23700d651..007f1c062797e 100644 --- a/packages/aws-cdk-lib/aws-backup/test/plan.test.ts +++ b/packages/aws-cdk-lib/aws-backup/test/plan.test.ts @@ -1,7 +1,8 @@ import { Template } from '../../assertions'; import * as events from '../../aws-events'; +import { testDeprecated } from '@aws-cdk/cdk-build-tools'; import { App, Duration, Stack } from '../../core'; -import { BackupPlan, BackupPlanRule, BackupVault } from '../lib'; +import { BackupPlan, BackupPlanRule, BackupVault, Schedule } from '../lib'; let stack: Stack; beforeEach(() => { @@ -20,7 +21,7 @@ test('create a plan and add rules', () => { new BackupPlanRule({ completionWindow: Duration.hours(2), startWindow: Duration.hours(1), - scheduleExpression: events.Schedule.cron({ + schedule: Schedule.cron({ day: '15', hour: '3', minute: '30', @@ -157,7 +158,7 @@ test('create a plan and add rules - add BackupPlan.AdvancedBackupSettings.Backup new BackupPlanRule({ completionWindow: Duration.hours(2), startWindow: Duration.hours(1), - scheduleExpression: events.Schedule.cron({ + schedule: Schedule.cron({ day: '15', hour: '3', minute: '30', @@ -380,7 +381,7 @@ test('throws when deleteAfter is not greater than moveToColdStorageAfter', () => })).toThrow(/`deleteAfter` must be greater than `moveToColdStorageAfter`/); }); -test('throws when scheduleExpression is not of type cron', () => { +testDeprecated('throws when scheduleExpression is not of type cron', () => { expect(() => new BackupPlanRule({ scheduleExpression: events.Schedule.rate(Duration.hours(5)), })).toThrow(/`scheduleExpression` must be of type `cron`/); diff --git a/packages/aws-cdk-lib/rosetta/aws_backup/default.ts-fixture b/packages/aws-cdk-lib/rosetta/aws_backup/default.ts-fixture index 997a397e1ad70..012bd4f3fdbbd 100644 --- a/packages/aws-cdk-lib/rosetta/aws_backup/default.ts-fixture +++ b/packages/aws-cdk-lib/rosetta/aws_backup/default.ts-fixture @@ -4,7 +4,6 @@ import { Construct } from 'constructs'; import * as backup from 'aws-cdk-lib/aws-backup'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; -import * as events from 'aws-cdk-lib/aws-events'; import * as kms from 'aws-cdk-lib/aws-kms'; import * as sns from 'aws-cdk-lib/aws-sns'; import * as rds from 'aws-cdk-lib/aws-rds'; From 9597cd8bde4ba457d1319212c0787a9bed09a76f Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 15:48:44 -0400 Subject: [PATCH 04/27] add timezone to at expression --- packages/aws-cdk-lib/core/lib/schedule.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts index 8221f625d03fc..ee9ce78b240bc 100644 --- a/packages/aws-cdk-lib/core/lib/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -31,9 +31,10 @@ export abstract class Schedule { * Construct a schedule from a literal schedule expression * * @param expression The expression to use. Must be in a format that EventBridge will recognize + * @param timeZone The time zone, if applicable. This is only valid for 'at' and 'cron' expressions */ - protected static expression(expression: string): Schedule { - return new LiteralSchedule(expression); + protected static expression(expression: string, timeZone?: TimeZone): Schedule { + return new LiteralSchedule(expression, timeZone); } /** From e72f216062cc35d22574f7a242318c70c80a7848 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 16:38:47 -0400 Subject: [PATCH 05/27] add bind to core.Schedule, rename protected methods as protectedXxx cuz of jsii limitation --- .../aws-cdk-lib/aws-backup/lib/schedule.ts | 2 +- .../aws-cdk-lib/aws-events/lib/schedule.ts | 86 ++----------------- packages/aws-cdk-lib/core/lib/schedule.ts | 30 +++++-- 3 files changed, 29 insertions(+), 89 deletions(-) diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts index b5c8fbdcdd41d..35ee7539a9c33 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts @@ -2,6 +2,6 @@ import { CronOptions, Schedule as ScheduleExpression } from '../../core'; export abstract class Schedule extends ScheduleExpression { public static cron(options: CronOptions): Schedule { - return super.cron(options); + return super.protectedCron(options); } } diff --git a/packages/aws-cdk-lib/aws-events/lib/schedule.ts b/packages/aws-cdk-lib/aws-events/lib/schedule.ts index 94b3ecbf7f1e0..97e1ceb1efcd1 100644 --- a/packages/aws-cdk-lib/aws-events/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-events/lib/schedule.ts @@ -1,5 +1,4 @@ -import { Construct } from 'constructs'; -import { Annotations, Duration } from '../../core'; +import { Duration, Schedule as ScheduleExpression } from '../../core'; /** * Schedule for scheduled event rules @@ -8,14 +7,14 @@ import { Annotations, Duration } from '../../core'; * * @see https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html */ -export abstract class Schedule { +export abstract class Schedule extends ScheduleExpression { /** * Construct a schedule from a literal schedule expression * * @param expression The expression to use. Must be in a format that EventBridge will recognize */ public static expression(expression: string): Schedule { - return new LiteralSchedule(expression); + return super.protectedExpression(expression) as Schedule; } /** @@ -24,63 +23,15 @@ export abstract class Schedule { * Rates may be defined with any unit of time, but when converted into minutes, the duration must be a positive whole number of minutes. */ public static rate(duration: Duration): Schedule { - if (duration.isUnresolved()) { - const validDurationUnit = ['minute', 'minutes', 'hour', 'hours', 'day', 'days']; - if (validDurationUnit.indexOf(duration.unitLabel()) === -1) { - throw new Error("Allowed units for scheduling are: 'minute', 'minutes', 'hour', 'hours', 'day', 'days'"); - } - return new LiteralSchedule(`rate(${duration.formatTokenToNumber()})`); - } - if (duration.toMinutes() === 0) { - throw new Error('Duration cannot be 0'); - } - - let rate = maybeRate(duration.toDays({ integral: false }), 'day'); - if (rate === undefined) { rate = maybeRate(duration.toHours({ integral: false }), 'hour'); } - if (rate === undefined) { rate = makeRate(duration.toMinutes({ integral: true }), 'minute'); } - return new LiteralSchedule(rate); + return super.protectedRate(duration) as Schedule; } /** * Create a schedule from a set of cron fields */ public static cron(options: CronOptions): Schedule { - if (options.weekDay !== undefined && options.day !== undefined) { - throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); - } - - const minute = fallback(options.minute, '*'); - const hour = fallback(options.hour, '*'); - const month = fallback(options.month, '*'); - const year = fallback(options.year, '*'); - - // Weekday defaults to '?' if not supplied. If it is supplied, day must become '?' - const day = fallback(options.day, options.weekDay !== undefined ? '?' : '*'); - const weekDay = fallback(options.weekDay, '?'); - - return new class extends Schedule { - public readonly expressionString: string = `cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`; - public _bind(scope: Construct) { - if (!options.minute) { - Annotations.of(scope).addWarningV2('@aws-cdk/aws-events:scheduleWillRunEveryMinute', 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); - } - return new LiteralSchedule(this.expressionString); - } - }; + return super.protectedCron(options) as Schedule; } - - /** - * Retrieve the expression for this schedule - */ - public abstract readonly expressionString: string; - - protected constructor() {} - - /** - * - * @internal - */ - public abstract _bind(scope: Construct): void; } /** @@ -134,30 +85,3 @@ export interface CronOptions { */ readonly weekDay?: string; } - -class LiteralSchedule extends Schedule { - constructor(public readonly expressionString: string) { - super(); - } - - public _bind() {} -} - -function fallback(x: T | undefined, def: T): T { - return x ?? def; -} - -/** - * Return the rate if the rate is whole number - */ -function maybeRate(interval: number, singular: string) { - if (interval === 0 || !Number.isInteger(interval)) { return undefined; } - return makeRate(interval, singular); -} - -/** - * Return 'rate(${interval} ${singular}(s))` for the interval - */ -function makeRate(interval: number, singular: string) { - return interval === 1 ? `rate(1 ${singular})` : `rate(${interval} ${singular}s)`; -} diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts index ee9ce78b240bc..211893b18f0c3 100644 --- a/packages/aws-cdk-lib/core/lib/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -1,5 +1,7 @@ +import { Construct } from 'constructs'; import { Duration } from './duration'; import { TimeZone } from './time-zone'; +import { Annotations } from './annotations'; /** * Schedule @@ -15,7 +17,7 @@ export abstract class Schedule { * @param date The date and time to use. The millisecond part will be ignored. * @param timeZone The time zone to use for interpreting the date. Default: - UTC */ - protected static at(date: Date, timeZone?: TimeZone): Schedule { + protected static protectedAt(date: Date, timeZone?: TimeZone): Schedule { try { const literal = date.toISOString().split('.')[0]; return new LiteralSchedule(`at(${literal})`, timeZone ?? TimeZone.ETC_UTC); @@ -33,7 +35,7 @@ export abstract class Schedule { * @param expression The expression to use. Must be in a format that EventBridge will recognize * @param timeZone The time zone, if applicable. This is only valid for 'at' and 'cron' expressions */ - protected static expression(expression: string, timeZone?: TimeZone): Schedule { + protected static protectedExpression(expression: string, timeZone?: TimeZone): Schedule { return new LiteralSchedule(expression, timeZone); } @@ -42,7 +44,7 @@ export abstract class Schedule { * * Rates may be defined with any unit of time, but when converted into minutes, the duration must be a positive whole number of minutes. */ - protected static rate(duration: Duration): Schedule { + protected static protectedRate(duration: Duration): Schedule { if (duration.isUnresolved()) { const validDurationUnit = ['minute', 'minutes', 'hour', 'hours', 'day', 'days']; if (validDurationUnit.indexOf(duration.unitLabel()) === -1) { @@ -63,7 +65,7 @@ export abstract class Schedule { /** * Create a schedule from a set of cron fields */ - protected static cron(options: CronOptions): Schedule { + protected static protectedCron(options: CronOptions): Schedule { if (options.weekDay !== undefined && options.day !== undefined) { throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); } @@ -77,8 +79,15 @@ export abstract class Schedule { const day = fallback(options.day, options.weekDay !== undefined ? '?' : '*'); const weekDay = fallback(options.weekDay, '?'); - const expressionString: string = `cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`; - return new LiteralSchedule(expressionString); + return new class extends Schedule { + public readonly expressionString = `cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`; + public _bind(scope: Construct) { + if (!options.minute) { + Annotations.of(scope).addWarning('cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); + } + return new LiteralSchedule(this.expressionString, options.timeZone); + } + }; } /** @@ -89,9 +98,14 @@ export abstract class Schedule { /** * The timezone of the expression, if applicable. */ - public abstract readonly timeZone?: TimeZone; + public readonly timeZone?: TimeZone = undefined; protected constructor() {} + + /** + * @internal + */ + public abstract _bind(scope: Construct): void; } /** @@ -162,6 +176,8 @@ class LiteralSchedule extends Schedule { ) { super(); } + + public _bind() {} } function fallback(x: T | undefined, def: T): T { From 89e235547dcfcb9a0008519121fefdcc35f87e00 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 17:19:41 -0400 Subject: [PATCH 06/27] move schedule.ts to helpers-internal --- packages/aws-cdk-lib/aws-backup/lib/schedule.ts | 2 +- packages/aws-cdk-lib/aws-events/lib/schedule.ts | 3 ++- packages/aws-cdk-lib/core/lib/helpers-internal/index.ts | 3 ++- .../aws-cdk-lib/core/lib/{ => helpers-internal}/schedule.ts | 6 +++--- packages/aws-cdk-lib/core/lib/index.ts | 1 - 5 files changed, 8 insertions(+), 7 deletions(-) rename packages/aws-cdk-lib/core/lib/{ => helpers-internal}/schedule.ts (97%) diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts index 35ee7539a9c33..c65d56b08d9c6 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts @@ -1,4 +1,4 @@ -import { CronOptions, Schedule as ScheduleExpression } from '../../core'; +import { CronOptions, Schedule as ScheduleExpression } from '../../core/lib/helpers-internal'; export abstract class Schedule extends ScheduleExpression { public static cron(options: CronOptions): Schedule { diff --git a/packages/aws-cdk-lib/aws-events/lib/schedule.ts b/packages/aws-cdk-lib/aws-events/lib/schedule.ts index 97e1ceb1efcd1..3b4877f50752e 100644 --- a/packages/aws-cdk-lib/aws-events/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-events/lib/schedule.ts @@ -1,4 +1,5 @@ -import { Duration, Schedule as ScheduleExpression } from '../../core'; +import { Duration } from '../../core'; +import { Schedule as ScheduleExpression } from '../../core/lib/helpers-internal'; /** * Schedule for scheduled event rules diff --git a/packages/aws-cdk-lib/core/lib/helpers-internal/index.ts b/packages/aws-cdk-lib/core/lib/helpers-internal/index.ts index 03a39234e8d52..1575518a52e86 100644 --- a/packages/aws-cdk-lib/core/lib/helpers-internal/index.ts +++ b/packages/aws-cdk-lib/core/lib/helpers-internal/index.ts @@ -3,4 +3,5 @@ export * from './cfn-parse'; export { md5hash } from '../private/md5'; export * from './customize-roles'; export * from './string-specializer'; -export { constructInfoFromConstruct, constructInfoFromStack } from '../private/runtime-info'; \ No newline at end of file +export { constructInfoFromConstruct, constructInfoFromStack } from '../private/runtime-info'; +export * from './schedule'; \ No newline at end of file diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/helpers-internal/schedule.ts similarity index 97% rename from packages/aws-cdk-lib/core/lib/schedule.ts rename to packages/aws-cdk-lib/core/lib/helpers-internal/schedule.ts index 211893b18f0c3..0a4e15add0312 100644 --- a/packages/aws-cdk-lib/core/lib/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/helpers-internal/schedule.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; -import { Duration } from './duration'; -import { TimeZone } from './time-zone'; -import { Annotations } from './annotations'; +import { Duration } from '../duration'; +import { TimeZone } from '../time-zone'; +import { Annotations } from '../annotations'; /** * Schedule diff --git a/packages/aws-cdk-lib/core/lib/index.ts b/packages/aws-cdk-lib/core/lib/index.ts index 53d5cf9bf63d1..b35e89c0e59e4 100644 --- a/packages/aws-cdk-lib/core/lib/index.ts +++ b/packages/aws-cdk-lib/core/lib/index.ts @@ -71,4 +71,3 @@ export * from './validation'; export * from './private/intrinsic'; export * from './names'; export * from './time-zone'; -export * from './schedule'; From 8645d078391a5d5eaf43b74777c5b543a1216315 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 17:32:35 -0400 Subject: [PATCH 07/27] move schedule back tto main --- .../lib/schedule.ts | 111 ++---------------- .../aws-cdk-lib/aws-backup/lib/schedule.ts | 2 +- .../aws-cdk-lib/aws-events/lib/schedule.ts | 3 +- .../core/lib/helpers-internal/index.ts | 1 - .../lib/{helpers-internal => }/schedule.ts | 6 +- 5 files changed, 14 insertions(+), 109 deletions(-) rename packages/aws-cdk-lib/core/lib/{helpers-internal => }/schedule.ts (97%) diff --git a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts index 82c73291993ed..184de63e15988 100644 --- a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts @@ -1,87 +1,38 @@ -import { Construct } from 'constructs'; -import { Annotations, Duration } from '../../core'; +import { Duration, TimeZone, CronOptions as CoreCronOptions, Schedule as ScheduleExpression } from '../../core'; /** * Schedule for scheduled scaling actions */ -export abstract class Schedule { +export abstract class Schedule extends ScheduleExpression { /** * Construct a schedule from a literal schedule expression * * @param expression The expression to use. Must be in a format that Application AutoScaling will recognize */ public static expression(expression: string): Schedule { - return new LiteralSchedule(expression); + return super.protectedExpression(expression); } /** * Construct a schedule from an interval and a time unit */ public static rate(duration: Duration): Schedule { - if (duration.isUnresolved()) { - const validDurationUnit = ['minute', 'minutes', 'hour', 'hours', 'day', 'days']; - if (!validDurationUnit.includes(duration.unitLabel())) { - throw new Error("Allowed units for scheduling are: 'minute', 'minutes', 'hour', 'hours', 'day' or 'days'"); - } - return new LiteralSchedule(`rate(${duration.formatTokenToNumber()})`); - } - if (duration.toSeconds() === 0) { - throw new Error('Duration cannot be 0'); - } - - let rate = maybeRate(duration.toDays({ integral: false }), 'day'); - if (rate === undefined) { rate = maybeRate(duration.toHours({ integral: false }), 'hour'); } - if (rate === undefined) { rate = makeRate(duration.toMinutes({ integral: true }), 'minute'); } - return new LiteralSchedule(rate); + return super.protectedRate(duration); } /** * Construct a Schedule from a moment in time */ - public static at(moment: Date): Schedule { - return new LiteralSchedule(`at(${formatISO(moment)})`); + public static at(moment: Date, timeZone?: TimeZone): Schedule { + return super.protectedAt(moment, timeZone); } /** * Create a schedule from a set of cron fields */ - public static cron(options: CronOptions): Schedule { - if (options.weekDay !== undefined && options.day !== undefined) { - throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); - } - - const minute = fallback(options.minute, '*'); - const hour = fallback(options.hour, '*'); - const month = fallback(options.month, '*'); - const year = fallback(options.year, '*'); - - // Weekday defaults to '?' if not supplied. If it is supplied, day must become '?' - const day = fallback(options.day, options.weekDay !== undefined ? '?' : '*'); - const weekDay = fallback(options.weekDay, '?'); - - return new class extends Schedule { - public readonly expressionString: string = `cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`; - public _bind(scope: Construct) { - if (!options.minute) { - Annotations.of(scope).addWarningV2('@aws-cdk/aws-applicationautoscaling:defaultRunEveryMinute', 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); - } - return new LiteralSchedule(this.expressionString); - } - }; + public static cron(options: CoreCronOptions): Schedule { + return super.protectedCron(options); } - - /** - * Retrieve the expression for this schedule - */ - public abstract readonly expressionString: string; - - protected constructor() {} - - /** - * - * @internal - */ - public abstract _bind(scope: Construct): void; } /** @@ -91,6 +42,7 @@ export abstract class Schedule { * a field implies '*' or '?', whichever one is appropriate. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html#CronExpressions + * @deprecated use core.CronOptions instead */ export interface CronOptions { /** @@ -135,48 +87,3 @@ export interface CronOptions { */ readonly weekDay?: string; } - -class LiteralSchedule extends Schedule { - constructor(public readonly expressionString: string) { - super(); - } - - public _bind() {} -} - -function fallback(x: T | undefined, def: T): T { - return x === undefined ? def : x; -} - -function formatISO(date?: Date) { - if (!date) { return undefined; } - - return date.getUTCFullYear() + - '-' + pad(date.getUTCMonth() + 1) + - '-' + pad(date.getUTCDate()) + - 'T' + pad(date.getUTCHours()) + - ':' + pad(date.getUTCMinutes()) + - ':' + pad(date.getUTCSeconds()); - - function pad(num: number) { - if (num < 10) { - return '0' + num; - } - return num; - } -} - -/** - * Return the rate if the rate is whole number - */ -function maybeRate(interval: number, singular: string) { - if (interval === 0 || !Number.isInteger(interval)) { return undefined; } - return makeRate(interval, singular); -} - -/** - * Return 'rate(${interval} ${singular}(s))` for the interval - */ -function makeRate(interval: number, singular: string) { - return interval === 1 ? `rate(1 ${singular})` : `rate(${interval} ${singular}s)`; -} diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts index c65d56b08d9c6..35ee7539a9c33 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts @@ -1,4 +1,4 @@ -import { CronOptions, Schedule as ScheduleExpression } from '../../core/lib/helpers-internal'; +import { CronOptions, Schedule as ScheduleExpression } from '../../core'; export abstract class Schedule extends ScheduleExpression { public static cron(options: CronOptions): Schedule { diff --git a/packages/aws-cdk-lib/aws-events/lib/schedule.ts b/packages/aws-cdk-lib/aws-events/lib/schedule.ts index 3b4877f50752e..97e1ceb1efcd1 100644 --- a/packages/aws-cdk-lib/aws-events/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-events/lib/schedule.ts @@ -1,5 +1,4 @@ -import { Duration } from '../../core'; -import { Schedule as ScheduleExpression } from '../../core/lib/helpers-internal'; +import { Duration, Schedule as ScheduleExpression } from '../../core'; /** * Schedule for scheduled event rules diff --git a/packages/aws-cdk-lib/core/lib/helpers-internal/index.ts b/packages/aws-cdk-lib/core/lib/helpers-internal/index.ts index 1575518a52e86..50003af38ab8f 100644 --- a/packages/aws-cdk-lib/core/lib/helpers-internal/index.ts +++ b/packages/aws-cdk-lib/core/lib/helpers-internal/index.ts @@ -4,4 +4,3 @@ export { md5hash } from '../private/md5'; export * from './customize-roles'; export * from './string-specializer'; export { constructInfoFromConstruct, constructInfoFromStack } from '../private/runtime-info'; -export * from './schedule'; \ No newline at end of file diff --git a/packages/aws-cdk-lib/core/lib/helpers-internal/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts similarity index 97% rename from packages/aws-cdk-lib/core/lib/helpers-internal/schedule.ts rename to packages/aws-cdk-lib/core/lib/schedule.ts index 0a4e15add0312..211893b18f0c3 100644 --- a/packages/aws-cdk-lib/core/lib/helpers-internal/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; -import { Duration } from '../duration'; -import { TimeZone } from '../time-zone'; -import { Annotations } from '../annotations'; +import { Duration } from './duration'; +import { TimeZone } from './time-zone'; +import { Annotations } from './annotations'; /** * Schedule From 72ec383acfdda1fe92348aac0ec14723fbf1fc07 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 17:33:11 -0400 Subject: [PATCH 08/27] export --- packages/aws-cdk-lib/core/lib/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/aws-cdk-lib/core/lib/index.ts b/packages/aws-cdk-lib/core/lib/index.ts index b35e89c0e59e4..b84f63ce14592 100644 --- a/packages/aws-cdk-lib/core/lib/index.ts +++ b/packages/aws-cdk-lib/core/lib/index.ts @@ -71,3 +71,4 @@ export * from './validation'; export * from './private/intrinsic'; export * from './names'; export * from './time-zone'; +export * from './schedule'; \ No newline at end of file From f59f47545a4cd561f42bc0cea768260651f4c179 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 17:54:24 -0400 Subject: [PATCH 09/27] synthetics --- .../aws-synthetics-alpha/lib/schedule.ts | 39 ++++++------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts index 7be04de89fab3..26d219611e34e 100644 --- a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts +++ b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts @@ -1,9 +1,10 @@ -import { Duration } from 'aws-cdk-lib/core'; +import { Duration, Schedule as ScheduleExpression } from 'aws-cdk-lib/core'; +import { Construct } from 'constructs'; /** * Schedule for canary runs */ -export class Schedule { +export class Schedule extends ScheduleExpression { /** * The canary will be executed once. @@ -39,36 +40,24 @@ export class Schedule { if (minutes === 1) { return new Schedule('rate(1 minute)'); } - return new Schedule(`rate(${minutes} minutes)`); + return super.protectedRate(interval); } /** * Create a schedule from a set of cron fields */ public static cron(options: CronOptions): Schedule { - if (options.weekDay !== undefined && options.day !== undefined) { - throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); - } - - const minute = fallback(options.minute, '*'); - const hour = fallback(options.hour, '*'); - const month = fallback(options.month, '*'); - - // Weekday defaults to '?' if not supplied. If it is supplied, day must become '?' - const day = fallback(options.day, options.weekDay !== undefined ? '?' : '*'); - const weekDay = fallback(options.weekDay, '?'); - - // '*' is only allowed in the year field - const year = '*'; + return super.protectedCron({ + ...options, + year: '*', // '*' is the only allowed value in the year field + }); + } - return new Schedule(`cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`); + private constructor(public readonly expressionString: string) { + super(); } - private constructor( - /** - * The Schedule expression - */ - public readonly expressionString: string) {} + public _bind(_scope: Construct) {} } /** @@ -115,7 +104,3 @@ export interface CronOptions { */ readonly weekDay?: string; } - -function fallback(x: string | undefined, def: string): string { - return x ?? def; -} From 2c04d3064b4c74843909baba59a5daf0cd19a786 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 17:54:40 -0400 Subject: [PATCH 10/27] scheduler --- .../lib/schedule-expression.ts | 62 +++---------------- .../aws-scheduler-alpha/lib/target.ts | 2 +- 2 files changed, 8 insertions(+), 56 deletions(-) diff --git a/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts b/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts index 477eee7b20659..9e79b6af766ef 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts @@ -1,5 +1,4 @@ -import * as events from 'aws-cdk-lib/aws-events'; -import { Duration, TimeZone } from 'aws-cdk-lib/core'; +import { Duration, TimeZone, Schedule, CronOptions } from 'aws-cdk-lib/core'; /** * ScheduleExpression for EventBridge Schedule @@ -9,7 +8,7 @@ import { Duration, TimeZone } from 'aws-cdk-lib/core'; * * @see https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html */ -export abstract class ScheduleExpression { +export abstract class ScheduleExpression extends Schedule { /** * Construct a one-time schedule from a date. * @@ -17,15 +16,7 @@ export abstract class ScheduleExpression { * @param timeZone The time zone to use for interpreting the date. Default: - UTC */ public static at(date: Date, timeZone?: TimeZone): ScheduleExpression { - try { - const literal = date.toISOString().split('.')[0]; - return new LiteralScheduleExpression(`at(${literal})`, timeZone ?? TimeZone.ETC_UTC); - } catch (e) { - if (e instanceof RangeError) { - throw new Error('Invalid date'); - } - throw e; - } + return super.protectedAt(date, timeZone); } /** @@ -34,7 +25,7 @@ export abstract class ScheduleExpression { * @param timeZone The time zone to use for interpreting the expression. Default: - UTC */ public static expression(expression: string, timeZone?: TimeZone): ScheduleExpression { - return new LiteralScheduleExpression(expression, timeZone ?? TimeZone.ETC_UTC); + return super.protectedExpression(expression, timeZone); } /** @@ -43,53 +34,14 @@ export abstract class ScheduleExpression { * Rates may be defined with any unit of time, but when converted into minutes, the duration must be a positive whole number of minutes. */ public static rate(duration: Duration): ScheduleExpression { - const schedule = events.Schedule.rate(duration); - return new LiteralScheduleExpression(schedule.expressionString); + return super.protectedRate(duration); } /** * Create a recurring schedule from a set of cron fields and time zone. */ - public static cron(options: CronOptionsWithTimezone): ScheduleExpression { - const { timeZone, ...cronOptions } = options; - const schedule = events.Schedule.cron(cronOptions); - return new LiteralScheduleExpression(schedule.expressionString, timeZone); + public static cron(options: CronOptions): ScheduleExpression { + return super.protectedCron(options); } - - /** - * Retrieve the expression for this schedule - */ - public abstract readonly expressionString: string; - - /** - * Retrieve the expression for this schedule - */ - public abstract readonly timeZone?: TimeZone; - - protected constructor() {} } -/** - * Options to configure a cron expression - * - * All fields are strings so you can use complex expressions. Absence of - * a field implies '*' or '?', whichever one is appropriate. - * - * @see https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html#cron-expressions - */ -export interface CronOptionsWithTimezone extends events.CronOptions { - /** - * The timezone to run the schedule in - * - * @default - TimeZone.ETC_UTC - */ - readonly timeZone?: TimeZone; -} - -const DEFAULT_TIMEZONE = TimeZone.ETC_UTC; - -class LiteralScheduleExpression extends ScheduleExpression { - constructor(public readonly expressionString: string, public readonly timeZone: TimeZone = DEFAULT_TIMEZONE) { - super(); - } -} diff --git a/packages/@aws-cdk/aws-scheduler-alpha/lib/target.ts b/packages/@aws-cdk/aws-scheduler-alpha/lib/target.ts index e15b635f7ae08..3850f095ea04e 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/lib/target.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/lib/target.ts @@ -30,7 +30,7 @@ export interface ScheduleTargetConfig { readonly role: iam.IRole; /** - * What input to pass to the tatget + * What input to pass to the target */ readonly input?: ScheduleTargetInput; From 404ab4ca5609942a793a0f2813ff2793dade9719 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 17:55:01 -0400 Subject: [PATCH 11/27] touchups --- .../aws-applicationautoscaling/README.md | 6 +- .../lib/schedule.ts | 4 +- .../aws-cdk-lib/aws-autoscaling/README.md | 2 +- .../aws-autoscaling/lib/schedule.ts | 57 +++---------------- .../aws-cdk-lib/aws-backup/lib/schedule.ts | 14 ++++- .../aws-cdk-lib/aws-events/lib/schedule.ts | 6 +- 6 files changed, 29 insertions(+), 60 deletions(-) diff --git a/packages/aws-cdk-lib/aws-applicationautoscaling/README.md b/packages/aws-cdk-lib/aws-applicationautoscaling/README.md index 6bc05ee9882f2..c729bd27b704e 100644 --- a/packages/aws-cdk-lib/aws-applicationautoscaling/README.md +++ b/packages/aws-cdk-lib/aws-applicationautoscaling/README.md @@ -191,7 +191,7 @@ capacity.scaleOnSchedule('PrescaleInTheMorning', { capacity.scaleOnSchedule('AllowDownscalingAtNight', { schedule: appscaling.Schedule.cron({ hour: '20', minute: '0' }), - minCapacity: 1 + minCapacity: 1, }); ``` @@ -220,12 +220,12 @@ const target = new appscaling.ScalableTarget(this, 'ScalableTarget', { minCapacity: 10, resourceId: `function:${handler.functionName}:${fnVer.version}`, scalableDimension: 'lambda:function:ProvisionedConcurrency', -}) +}); target.scaleToTrackMetric('PceTracking', { targetValue: 0.9, predefinedMetric: appscaling.PredefinedMetric.LAMBDA_PROVISIONED_CONCURRENCY_UTILIZATION, -}) +}); ``` ### ElastiCache Redis shards scaling with target value diff --git a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts index 184de63e15988..2dc6c698a5ac4 100644 --- a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts @@ -9,8 +9,8 @@ export abstract class Schedule extends ScheduleExpression { * * @param expression The expression to use. Must be in a format that Application AutoScaling will recognize */ - public static expression(expression: string): Schedule { - return super.protectedExpression(expression); + public static expression(expression: string, timeZone?: TimeZone): Schedule { + return super.protectedExpression(expression, timeZone); } /** diff --git a/packages/aws-cdk-lib/aws-autoscaling/README.md b/packages/aws-cdk-lib/aws-autoscaling/README.md index 9fb6dd8c8d81f..2ff0df4646877 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/README.md +++ b/packages/aws-cdk-lib/aws-autoscaling/README.md @@ -288,7 +288,7 @@ autoScalingGroup.scaleOnSchedule('PrescaleInTheMorning', { autoScalingGroup.scaleOnSchedule('AllowDownscalingAtNight', { schedule: autoscaling.Schedule.cron({ hour: '20', minute: '0' }), - minCapacity: 1 + minCapacity: 1, }); ``` diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts index 7f532e65ac62a..1a4fd11fbc29a 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts @@ -1,57 +1,25 @@ -import { Construct } from 'constructs'; -import { Annotations } from '../../core'; +import { CronOptions as CoreCronOptions, Schedule as ScheduleExpression, TimeZone } from '../../core'; /** * Schedule for scheduled scaling actions */ -export abstract class Schedule { +export abstract class Schedule extends ScheduleExpression { /** * Construct a schedule from a literal schedule expression * * @param expression The expression to use. Must be in a format that AutoScaling will recognize * @see http://crontab.org/ */ - public static expression(expression: string): Schedule { - return new LiteralSchedule(expression); + public static expression(expression: string, timeZone?: TimeZone): Schedule { + return super.protectedExpression(expression, timeZone); } /** * Create a schedule from a set of cron fields */ - public static cron(options: CronOptions): Schedule { - if (options.weekDay !== undefined && options.day !== undefined) { - throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); - } - - const minute = fallback(options.minute, '*'); - const hour = fallback(options.hour, '*'); - const month = fallback(options.month, '*'); - const day = fallback(options.day, '*'); - const weekDay = fallback(options.weekDay, '*'); - - return new class extends Schedule { - public readonly expressionString: string = `${minute} ${hour} ${day} ${month} ${weekDay}`; - public _bind(scope: Construct) { - if (!options.minute) { - Annotations.of(scope).addWarningV2('@aws-cdk/aws-autoscaling:scheduleDefaultRunsEveryMinute', 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); - } - return new LiteralSchedule(this.expressionString); - } - }; + public static cron(options: CoreCronOptions): Schedule { + return super.protectedCron(options); } - - /** - * Retrieve the expression for this schedule - */ - public abstract readonly expressionString: string; - - protected constructor() {} - - /** - * - * @internal - */ - public abstract _bind(scope: Construct): void; } /** @@ -61,6 +29,7 @@ export abstract class Schedule { * a field implies '*' or '?', whichever one is appropriate. * * @see http://crontab.org/ + * @deprecated use core.CronOptions */ export interface CronOptions { /** @@ -98,15 +67,3 @@ export interface CronOptions { */ readonly weekDay?: string; } - -class LiteralSchedule extends Schedule { - constructor(public readonly expressionString: string) { - super(); - } - - public _bind(): void {} -} - -function fallback(x: T | undefined, def: T): T { - return x === undefined ? def : x; -} diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts index 35ee7539a9c33..3ab0b6ff30b30 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts @@ -1,6 +1,18 @@ -import { CronOptions, Schedule as ScheduleExpression } from '../../core'; +import { CronOptions, Schedule as ScheduleExpression, TimeZone } from '../../core'; export abstract class Schedule extends ScheduleExpression { + /** + * Construct a schedule from a literal schedule expression + * + * @param expression The expression to use. Must be in a format that Application AutoScaling will recognize + */ + public static expression(expression: string, timeZone?: TimeZone): Schedule { + return super.protectedExpression(expression, timeZone); + } + + /** + * Construct a schedule from cron options + */ public static cron(options: CronOptions): Schedule { return super.protectedCron(options); } diff --git a/packages/aws-cdk-lib/aws-events/lib/schedule.ts b/packages/aws-cdk-lib/aws-events/lib/schedule.ts index 97e1ceb1efcd1..f1958868f59dd 100644 --- a/packages/aws-cdk-lib/aws-events/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-events/lib/schedule.ts @@ -14,7 +14,7 @@ export abstract class Schedule extends ScheduleExpression { * @param expression The expression to use. Must be in a format that EventBridge will recognize */ public static expression(expression: string): Schedule { - return super.protectedExpression(expression) as Schedule; + return super.protectedExpression(expression); } /** @@ -23,14 +23,14 @@ export abstract class Schedule extends ScheduleExpression { * Rates may be defined with any unit of time, but when converted into minutes, the duration must be a positive whole number of minutes. */ public static rate(duration: Duration): Schedule { - return super.protectedRate(duration) as Schedule; + return super.protectedRate(duration); } /** * Create a schedule from a set of cron fields */ public static cron(options: CronOptions): Schedule { - return super.protectedCron(options) as Schedule; + return super.protectedCron(options); } } From 97e492e877d15073136feae220cd3a93df0e1228 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Mon, 11 Sep 2023 19:48:04 -0400 Subject: [PATCH 12/27] add annotations and fix some tests --- .../aws-synthetics-alpha/lib/schedule.ts | 3 --- .../lib/scalable-target.ts | 1 + .../aws-autoscaling/lib/schedule.ts | 22 +++++++++++++++++-- .../aws-autoscaling/lib/scheduled-action.ts | 4 +++- packages/aws-cdk-lib/aws-backup/lib/plan.ts | 1 + packages/aws-cdk-lib/aws-backup/lib/rule.ts | 4 +++- .../aws-cdk-lib/aws-backup/test/plan.test.ts | 2 +- packages/aws-cdk-lib/core/lib/schedule.ts | 8 ++++--- 8 files changed, 34 insertions(+), 11 deletions(-) diff --git a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts index 26d219611e34e..478389ab7ebd5 100644 --- a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts +++ b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts @@ -37,9 +37,6 @@ export class Schedule extends ScheduleExpression { if (minutes === 0) { return Schedule.once(); } - if (minutes === 1) { - return new Schedule('rate(1 minute)'); - } return super.protectedRate(interval); } diff --git a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/scalable-target.ts b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/scalable-target.ts index 0e825bce03d19..4f4dee7696fc8 100644 --- a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/scalable-target.ts +++ b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/scalable-target.ts @@ -155,6 +155,7 @@ export class ScalableTarget extends Resource implements IScalableTarget { this.actions.push({ scheduledActionName: id, schedule: action.schedule.expressionString, + timezone: action.schedule.timeZone?.timezoneName, startTime: action.startTime, endTime: action.endTime, scalableTargetAction: { diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts index 1a4fd11fbc29a..f0203db91c25f 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts @@ -1,4 +1,5 @@ -import { CronOptions as CoreCronOptions, Schedule as ScheduleExpression, TimeZone } from '../../core'; +import { Construct } from 'constructs'; +import { Annotations, CronOptions as CoreCronOptions, Schedule as ScheduleExpression, TimeZone } from '../../core'; /** * Schedule for scheduled scaling actions @@ -18,7 +19,24 @@ export abstract class Schedule extends ScheduleExpression { * Create a schedule from a set of cron fields */ public static cron(options: CoreCronOptions): Schedule { - return super.protectedCron(options); + const cron = super.protectedCron({ + weekDay: '*', // to override core.Schedule's default + day: '*', // to override core.Schedule's default + ...options, + }); + const cronSplit = cron.expressionString.slice(5).split(' '); // remove "cron(" from start + cronSplit.pop(); // remove year, since autoscaling does not accept it + const autoscalingCron = cronSplit.join(' '); + + return new class extends Schedule { + public readonly expressionString = autoscalingCron; + public _bind(scope: Construct) { + if (!options.minute) { + Annotations.of(scope).addWarningV2('@aws-cdk/aws-autoscaling:scheduleDefaultRunsEveryMinute', 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); + } + return Schedule.expression(this.expressionString, options.timeZone); + } + }; } } diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts index 84b2d55f63b1d..05a9c5db98b5b 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts @@ -16,9 +16,11 @@ export interface BasicScheduledActionProps { * For more information, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. * * @default - UTC + * @deprecated use time zones as part of the schedule prop * */ readonly timeZone?: string; + /** * When to perform this action. * @@ -115,7 +117,7 @@ export class ScheduledAction extends Resource { maxSize: props.maxCapacity, desiredCapacity: props.desiredCapacity, recurrence: props.schedule.expressionString, - timeZone: props.timeZone, + timeZone: props.timeZone ?? props.schedule.timeZone?.timezoneName, }); this.scheduledActionName = resource.attrScheduledActionName; diff --git a/packages/aws-cdk-lib/aws-backup/lib/plan.ts b/packages/aws-cdk-lib/aws-backup/lib/plan.ts index f9d8a915f1f23..96789462488c5 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/plan.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/plan.ts @@ -188,6 +188,7 @@ export class BackupPlan extends Resource implements IBackupPlan { }, ruleName: rule.props.ruleName ?? `${this.node.id}Rule${this.rules.length}`, scheduleExpression: rule.props.schedule?.expressionString ?? rule.props.scheduleExpression?.expressionString, + scheduleExpressionTimezone: rule.props.schedule?.timeZone?.timezoneName, startWindowMinutes: rule.props.startWindow?.toMinutes(), enableContinuousBackup: rule.props.enableContinuousBackup, targetBackupVault: vault.backupVaultName, diff --git a/packages/aws-cdk-lib/aws-backup/lib/rule.ts b/packages/aws-cdk-lib/aws-backup/lib/rule.ts index f326cdd80597b..9520c40f4cc8e 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/rule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/rule.ts @@ -1,7 +1,7 @@ +import { Schedule } from './schedule'; import { IBackupVault } from './vault'; import * as events from '../../aws-events'; import { Duration, Token } from '../../core'; -import { Schedule } from './schedule'; /** * Properties for a BackupPlanRule @@ -48,6 +48,8 @@ export interface BackupPlanRuleProps { /** * A CRON expression specifying when AWS Backup initiates a backup job. + * + * @default - no schedule */ readonly schedule?: Schedule; diff --git a/packages/aws-cdk-lib/aws-backup/test/plan.test.ts b/packages/aws-cdk-lib/aws-backup/test/plan.test.ts index 007f1c062797e..5cef7b1c4fdb7 100644 --- a/packages/aws-cdk-lib/aws-backup/test/plan.test.ts +++ b/packages/aws-cdk-lib/aws-backup/test/plan.test.ts @@ -1,6 +1,6 @@ +import { testDeprecated } from '@aws-cdk/cdk-build-tools'; import { Template } from '../../assertions'; import * as events from '../../aws-events'; -import { testDeprecated } from '@aws-cdk/cdk-build-tools'; import { App, Duration, Stack } from '../../core'; import { BackupPlan, BackupPlanRule, BackupVault, Schedule } from '../lib'; diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts index 211893b18f0c3..34dfb64d00aee 100644 --- a/packages/aws-cdk-lib/core/lib/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; +import { Annotations } from './annotations'; import { Duration } from './duration'; import { TimeZone } from './time-zone'; -import { Annotations } from './annotations'; /** * Schedule @@ -66,7 +66,9 @@ export abstract class Schedule { * Create a schedule from a set of cron fields */ protected static protectedCron(options: CronOptions): Schedule { - if (options.weekDay !== undefined && options.day !== undefined) { + if (options.weekDay !== undefined && options.day !== undefined && + !(options.weekDay === '*' && options.day === '*') // special case for aws-autoscaling + ) { throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); } @@ -83,7 +85,7 @@ export abstract class Schedule { public readonly expressionString = `cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`; public _bind(scope: Construct) { if (!options.minute) { - Annotations.of(scope).addWarning('cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); + Annotations.of(scope).addWarningV2('@aws-cdk/core:scheduleDefaultRunsEveryMinute', 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); } return new LiteralSchedule(this.expressionString, options.timeZone); } From 83991123ffe98eb56bc47e27a981d70729c08eff Mon Sep 17 00:00:00 2001 From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com> Date: Wed, 13 Sep 2023 17:44:49 -0400 Subject: [PATCH 13/27] Update packages/aws-cdk-lib/aws-backup/lib/schedule.ts Co-authored-by: Jonathan Goldwasser --- packages/aws-cdk-lib/aws-backup/lib/schedule.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts index 3ab0b6ff30b30..c2d3fa2f3a9e5 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts @@ -4,7 +4,7 @@ export abstract class Schedule extends ScheduleExpression { /** * Construct a schedule from a literal schedule expression * - * @param expression The expression to use. Must be in a format that Application AutoScaling will recognize + * @param expression The expression to use. Must be in a format that AWS Backup will recognize */ public static expression(expression: string, timeZone?: TimeZone): Schedule { return super.protectedExpression(expression, timeZone); From 20cb33982d57f03e0dc1943a48d4ee1b1faa198f Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Wed, 13 Sep 2023 17:59:16 -0400 Subject: [PATCH 14/27] rename to CoreSchedule --- packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts | 4 ++-- .../aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts | 4 ++-- packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts | 4 ++-- packages/aws-cdk-lib/aws-backup/lib/schedule.ts | 4 ++-- packages/aws-cdk-lib/aws-events/lib/schedule.ts | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts index 478389ab7ebd5..4e8a2640f3930 100644 --- a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts +++ b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts @@ -1,10 +1,10 @@ -import { Duration, Schedule as ScheduleExpression } from 'aws-cdk-lib/core'; +import { Duration, Schedule as CoreSchedule } from 'aws-cdk-lib/core'; import { Construct } from 'constructs'; /** * Schedule for canary runs */ -export class Schedule extends ScheduleExpression { +export class Schedule extends CoreSchedule { /** * The canary will be executed once. diff --git a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts index 2dc6c698a5ac4..3cc37f54665d6 100644 --- a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts @@ -1,9 +1,9 @@ -import { Duration, TimeZone, CronOptions as CoreCronOptions, Schedule as ScheduleExpression } from '../../core'; +import { Duration, TimeZone, CronOptions as CoreCronOptions, Schedule as CoreSchedule } from '../../core'; /** * Schedule for scheduled scaling actions */ -export abstract class Schedule extends ScheduleExpression { +export abstract class Schedule extends CoreSchedule { /** * Construct a schedule from a literal schedule expression * diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts index f0203db91c25f..7d4df3a8facab 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts @@ -1,10 +1,10 @@ import { Construct } from 'constructs'; -import { Annotations, CronOptions as CoreCronOptions, Schedule as ScheduleExpression, TimeZone } from '../../core'; +import { Annotations, CronOptions as CoreCronOptions, Schedule as CoreSchedule, TimeZone } from '../../core'; /** * Schedule for scheduled scaling actions */ -export abstract class Schedule extends ScheduleExpression { +export abstract class Schedule extends CoreSchedule { /** * Construct a schedule from a literal schedule expression * diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts index c2d3fa2f3a9e5..b8080c921c660 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts @@ -1,6 +1,6 @@ -import { CronOptions, Schedule as ScheduleExpression, TimeZone } from '../../core'; +import { CronOptions, Schedule as CoreSchedule, TimeZone } from '../../core'; -export abstract class Schedule extends ScheduleExpression { +export abstract class Schedule extends CoreSchedule { /** * Construct a schedule from a literal schedule expression * diff --git a/packages/aws-cdk-lib/aws-events/lib/schedule.ts b/packages/aws-cdk-lib/aws-events/lib/schedule.ts index f1958868f59dd..d45c3a17d045b 100644 --- a/packages/aws-cdk-lib/aws-events/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-events/lib/schedule.ts @@ -1,4 +1,4 @@ -import { Duration, Schedule as ScheduleExpression } from '../../core'; +import { Duration, Schedule as CoreSchedule } from '../../core'; /** * Schedule for scheduled event rules @@ -7,7 +7,7 @@ import { Duration, Schedule as ScheduleExpression } from '../../core'; * * @see https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html */ -export abstract class Schedule extends ScheduleExpression { +export abstract class Schedule extends CoreSchedule { /** * Construct a schedule from a literal schedule expression * From 223070ea84abbe76a22478a71a153268bb6d62f1 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Wed, 13 Sep 2023 18:03:24 -0400 Subject: [PATCH 15/27] backup synth check --- packages/aws-cdk-lib/aws-backup/lib/rule.ts | 4 ++++ packages/aws-cdk-lib/aws-backup/test/plan.test.ts | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/packages/aws-cdk-lib/aws-backup/lib/rule.ts b/packages/aws-cdk-lib/aws-backup/lib/rule.ts index 9520c40f4cc8e..30591c29735c3 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/rule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/rule.ts @@ -222,6 +222,10 @@ export class BackupPlanRule { throw new Error('`scheduleExpression` must be of type `cron`'); } + if (props.schedule && props.scheduleExpression) { + throw new Error('Cannot specify `schedule` and `scheduleExpression` together. Please use `schedule` only.'); + } + const deleteAfter = (props.enableContinuousBackup && !props.deleteAfter) ? Duration.days(35) : props.deleteAfter; if (props.enableContinuousBackup && props.moveToColdStorageAfter) { diff --git a/packages/aws-cdk-lib/aws-backup/test/plan.test.ts b/packages/aws-cdk-lib/aws-backup/test/plan.test.ts index 5cef7b1c4fdb7..3adb1b5e50c2b 100644 --- a/packages/aws-cdk-lib/aws-backup/test/plan.test.ts +++ b/packages/aws-cdk-lib/aws-backup/test/plan.test.ts @@ -387,6 +387,13 @@ testDeprecated('throws when scheduleExpression is not of type cron', () => { })).toThrow(/`scheduleExpression` must be of type `cron`/); }); +testDeprecated('throws when schedule and scheduleExpression are both set', () => { + expect(() => new BackupPlanRule({ + schedule: Schedule.cron({ day: '* ' }), + scheduleExpression: events.Schedule.cron({ day: '?' }), + })).toThrow(/Please use `schedule` only./); +}); + test('synth fails when plan has no rules', () => { // GIVEN const app = new App(); From b1940c7f38f0b2eb8a70c4940c1b0500b402e0d8 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Wed, 13 Sep 2023 18:11:04 -0400 Subject: [PATCH 16/27] autoscaling timezone test --- .../aws-autoscaling/lib/scheduled-action.ts | 6 +++- .../test/scheduled-action.test.ts | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts index 05a9c5db98b5b..468b4027dcd20 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts @@ -106,6 +106,10 @@ export class ScheduledAction extends Resource { throw new Error('At least one of minCapacity, maxCapacity, or desiredCapacity is required'); } + if (props.timeZone && props.schedule.timeZone) { + throw new Error('Cannot set `timeZone` property and `schedule` property with time zone defined. Please remove the deprecated `timeZone` property.'); + } + // add a warning on synth when minute is not defined in a cron schedule props.schedule._bind(this); @@ -117,7 +121,7 @@ export class ScheduledAction extends Resource { maxSize: props.maxCapacity, desiredCapacity: props.desiredCapacity, recurrence: props.schedule.expressionString, - timeZone: props.timeZone ?? props.schedule.timeZone?.timezoneName, + timeZone: props.schedule.timeZone?.timezoneName ?? props.timeZone, }); this.scheduledActionName = resource.attrScheduledActionName; diff --git a/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts b/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts index 943939c09febb..c5944b1bbbf2d 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts @@ -62,6 +62,42 @@ describeDeprecated('scheduled action', () => { }); }); + test('set timezone as part of schedule', () => { + // GIVEN + const stack = new cdk.Stack(); + const asg = makeAutoScalingGroup(stack); + + // WHEN + asg.scaleOnSchedule('ScaleOutAtMiddaySeoul', { + schedule: autoscaling.Schedule.cron({ hour: '12', minute: '0', timeZone: cdk.TimeZone.ASIA_SEOUL }), + minCapacity: 12, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AutoScaling::ScheduledAction', { + MinSize: 12, + Recurrence: '0 12 * * *', + TimeZone: 'Asia/Seoul', + }); + }); + + test('throws when timezone and scheduled timezone set together', () => { + // GIVEN + const stack = new cdk.Stack(); + const asg = makeAutoScalingGroup(stack); + + // THEN + expect(asg.scaleOnSchedule('ScaleOutAtMiddaySeoul', { + schedule: autoscaling.Schedule.cron({ + hour: '12', + minute: '0', + timeZone: cdk.TimeZone.ASIA_SEOUL, + }), + minCapacity: 12, + timeZone: 'Asia/Seoul', + })).toThrowError(/Please remove the deprecated `timeZone` property./); + }); + test('autoscaling group has recommended updatepolicy for scheduled actions', () => { // GIVEN const stack = new cdk.Stack(); From 380bf5f748aedebcc1d39155efbff5c886b19eca Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Thu, 14 Sep 2023 09:27:04 -0400 Subject: [PATCH 17/27] finally fixed nuance in autoscaling.Schedule --- packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts | 3 ++- .../aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts index 7d4df3a8facab..f1ea53b43a5eb 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts @@ -30,11 +30,12 @@ export abstract class Schedule extends CoreSchedule { return new class extends Schedule { public readonly expressionString = autoscalingCron; + public readonly timeZone = options.timeZone; public _bind(scope: Construct) { if (!options.minute) { Annotations.of(scope).addWarningV2('@aws-cdk/aws-autoscaling:scheduleDefaultRunsEveryMinute', 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); } - return Schedule.expression(this.expressionString, options.timeZone); + return Schedule.expression(this.expressionString, this.timeZone); } }; } diff --git a/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts b/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts index c5944b1bbbf2d..33fb769a47d15 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts @@ -69,7 +69,7 @@ describeDeprecated('scheduled action', () => { // WHEN asg.scaleOnSchedule('ScaleOutAtMiddaySeoul', { - schedule: autoscaling.Schedule.cron({ hour: '12', minute: '0', timeZone: cdk.TimeZone.ASIA_SEOUL }), + schedule: autoscaling.Schedule.expression('0 12 * * *', cdk.TimeZone.ASIA_SEOUL), minCapacity: 12, }); @@ -87,7 +87,7 @@ describeDeprecated('scheduled action', () => { const asg = makeAutoScalingGroup(stack); // THEN - expect(asg.scaleOnSchedule('ScaleOutAtMiddaySeoul', { + expect(() => asg.scaleOnSchedule('ScaleOutAtMiddaySeoul', { schedule: autoscaling.Schedule.cron({ hour: '12', minute: '0', From acd58a22ec21635e992027251491acc631cedb71 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Thu, 14 Sep 2023 10:37:16 -0400 Subject: [PATCH 18/27] add documentation --- packages/aws-cdk-lib/core/lib/schedule.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts index 34dfb64d00aee..4a07327e97cd2 100644 --- a/packages/aws-cdk-lib/core/lib/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -4,7 +4,9 @@ import { Duration } from './duration'; import { TimeZone } from './time-zone'; /** - * Schedule + * A Core Schedule. This construct is not meant to be used as is or exposed to consumers in other modules. + * It is meant to be extended by other modules that require some sort of schedule implementation. All + * methods in `core.Schedule` are protected, so that construct authors can decide which APIs to expose. * * Note that rates cannot be defined in fractions of minutes. * From c64a3ca84617dce560ee3aa1f7624de2e9a39dfc Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 19 Sep 2023 10:34:03 -0400 Subject: [PATCH 19/27] fix bugs and tests in scheduler --- .../lib/schedule-expression.ts | 2 +- .../aws-scheduler-alpha/lib/schedule.ts | 1 + .../test/schedule-expression.test.ts | 28 +++++++++++-------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts b/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts index 9e79b6af766ef..9fa2c5165a6e9 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts @@ -41,7 +41,7 @@ export abstract class ScheduleExpression extends Schedule { * Create a recurring schedule from a set of cron fields and time zone. */ public static cron(options: CronOptions): ScheduleExpression { - return super.protectedCron(options); + return super.protectedCron(options, 'aws-scheduler'); } } diff --git a/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule.ts b/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule.ts index 343acc398324f..e349ebb31e2ac 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule.ts @@ -87,6 +87,7 @@ export class Schedule extends Resource implements ISchedule { this.group = props.group; const targetConfig = props.target.bind(this); + props.schedule._bind(this); const resource = new CfnSchedule(this, 'Resource', { name: this.physicalName, diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts b/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts index d12ca608820d3..aeee9d5410443 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts @@ -28,20 +28,26 @@ describe('schedule expression', () => { }); test('cron expressions saves timezone', () => { - expect(TimeZone.EUROPE_LONDON).toEqual(ScheduleExpression.cron( - { - minute: '0', - hour: '10', - timeZone: TimeZone.EUROPE_LONDON, - }).timeZone); + // GIVEN + const cron = ScheduleExpression.cron({ + minute: '0', + hour: '10', + timeZone: TimeZone.EUROPE_LONDON, + }); + cron._bind(new Stack()); + + // eslint-disable-next-line no-console + console.log(cron.expressionString, cron.timeZone); + + // THEN + expect(cron.timeZone).toEqual(TimeZone.EUROPE_LONDON); }); test('cron expressions timezone is UTC if not specified', () => { - expect(TimeZone.ETC_UTC).toEqual(ScheduleExpression.cron( - { - minute: '0', - hour: '10', - }).timeZone); + expect(ScheduleExpression.cron({ + minute: '0', + hour: '10', + }).timeZone).toEqual(TimeZone.ETC_UTC); }); test('rate cannot be 0', () => { From 66d1df76423891750f6bf443bbd73e139236adde Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 19 Sep 2023 10:34:17 -0400 Subject: [PATCH 20/27] finalize schedule class --- packages/aws-cdk-lib/core/lib/schedule.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts index 4a07327e97cd2..c34c81c30f5ad 100644 --- a/packages/aws-cdk-lib/core/lib/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -8,8 +8,6 @@ import { TimeZone } from './time-zone'; * It is meant to be extended by other modules that require some sort of schedule implementation. All * methods in `core.Schedule` are protected, so that construct authors can decide which APIs to expose. * - * Note that rates cannot be defined in fractions of minutes. - * * @see https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html */ export abstract class Schedule { @@ -22,7 +20,7 @@ export abstract class Schedule { protected static protectedAt(date: Date, timeZone?: TimeZone): Schedule { try { const literal = date.toISOString().split('.')[0]; - return new LiteralSchedule(`at(${literal})`, timeZone ?? TimeZone.ETC_UTC); + return new LiteralSchedule(`at(${literal})`, timeZone); } catch (e) { if (e instanceof RangeError) { throw new Error('Invalid date'); @@ -65,9 +63,11 @@ export abstract class Schedule { } /** - * Create a schedule from a set of cron fields + * Create a schedule from a set of cron fields. + * + * @param module the module calling protectedCron, if you want module-specific warnings (i.e. aws-applicationautoscaling) */ - protected static protectedCron(options: CronOptions): Schedule { + protected static protectedCron(options: CronOptions, module?: string): Schedule { if (options.weekDay !== undefined && options.day !== undefined && !(options.weekDay === '*' && options.day === '*') // special case for aws-autoscaling ) { @@ -85,11 +85,12 @@ export abstract class Schedule { return new class extends Schedule { public readonly expressionString = `cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`; + public readonly timeZone = options.timeZone ?? DEFAULT_TIMEZONE; public _bind(scope: Construct) { if (!options.minute) { - Annotations.of(scope).addWarningV2('@aws-cdk/core:scheduleDefaultRunsEveryMinute', 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); + Annotations.of(scope).addWarningV2(`@aws-cdk/${module ?? 'core'}:scheduleDefaultRunsEveryMinute`, 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.'); } - return new LiteralSchedule(this.expressionString, options.timeZone); + return new LiteralSchedule(this.expressionString, this.timeZone); } }; } From 70ac3bfa25787c907afcc53360e3fa4e5c74ccae Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 19 Sep 2023 10:35:09 -0400 Subject: [PATCH 21/27] minor test fixes --- .../@aws-cdk/aws-synthetics-alpha/lib/schedule.ts | 2 +- .../aws-applicationautoscaling/lib/schedule.ts | 4 ++-- .../test/schedule.test.ts | 15 +++++---------- packages/aws-cdk-lib/aws-backup/lib/schedule.ts | 2 +- .../test/ec2/scheduled-ecs-task.test.ts | 2 +- .../test/fargate/scheduled-fargate-task.test.ts | 2 +- packages/aws-cdk-lib/aws-events/lib/schedule.ts | 2 +- packages/aws-cdk-lib/aws-events/test/rule.test.ts | 2 +- 8 files changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts index 4e8a2640f3930..2e412ea20e3f9 100644 --- a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts +++ b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts @@ -47,7 +47,7 @@ export class Schedule extends CoreSchedule { return super.protectedCron({ ...options, year: '*', // '*' is the only allowed value in the year field - }); + }, 'aws-synthetics'); } private constructor(public readonly expressionString: string) { diff --git a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts index 3cc37f54665d6..ef5c562d8dcf9 100644 --- a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts @@ -14,7 +14,7 @@ export abstract class Schedule extends CoreSchedule { } /** - * Construct a schedule from an interval and a time unit + * Construct a schedule from an interval and a time unit. Must be a whole number of seconds. */ public static rate(duration: Duration): Schedule { return super.protectedRate(duration); @@ -31,7 +31,7 @@ export abstract class Schedule extends CoreSchedule { * Create a schedule from a set of cron fields */ public static cron(options: CoreCronOptions): Schedule { - return super.protectedCron(options); + return super.protectedCron(options, 'aws-applicationautoscaling'); } } diff --git a/packages/aws-cdk-lib/aws-applicationautoscaling/test/schedule.test.ts b/packages/aws-cdk-lib/aws-applicationautoscaling/test/schedule.test.ts index 86d4d06c8cae6..59e597522f007 100644 --- a/packages/aws-cdk-lib/aws-applicationautoscaling/test/schedule.test.ts +++ b/packages/aws-cdk-lib/aws-applicationautoscaling/test/schedule.test.ts @@ -1,15 +1,17 @@ -import { Duration, Stack, Lazy } from '../../core'; +import { Duration, Stack, Lazy, TimeZone } from '../../core'; import * as appscaling from '../lib'; describe('cron', () => { test('test utc cron, hour only', () => { expect(appscaling.Schedule.cron({ hour: '18', minute: '0' }).expressionString).toEqual('cron(0 18 * * ? *)'); - }); test('test utc cron, hour and minute', () => { expect(appscaling.Schedule.cron({ hour: '18', minute: '24' }).expressionString).toEqual('cron(24 18 * * ? *)'); + }); + test('test europe/london cron', () => { + expect(appscaling.Schedule.cron({ hour: '18', minute: '0', timeZone: TimeZone.EUROPE_LONDON }).timeZone?.timezoneName).toEqual('Europe/London'); }); }); @@ -17,28 +19,24 @@ describe('rate', () => { test('rate must be whole number of minutes', () => { expect(() => { appscaling.Schedule.rate(Duration.minutes(0.13456)); - }).toThrow(/'0.13456 minutes' cannot be converted into a whole number of seconds/); - + }).toThrow(/0.13456 must be a whole number of minutes/); }); test('rate can be in seconds', () => { const duration = appscaling.Schedule.rate(Duration.seconds(120)); expect('rate(2 minutes)').toEqual(duration.expressionString); - }); test('rate must not be in seconds when specified as a token', () => { expect(() => { appscaling.Schedule.rate(Duration.seconds(Lazy.number({ produce: () => 5 }))); }).toThrow(/Allowed units for scheduling/); - }); test('rate cannot be 0', () => { expect(() => { appscaling.Schedule.rate(Duration.days(0)); }).toThrow(/Duration cannot be 0/); - }); test('rate can be token', () => { @@ -46,20 +44,17 @@ describe('rate', () => { const lazyDuration = Duration.minutes(Lazy.number({ produce: () => 5 })); const rate = appscaling.Schedule.rate(lazyDuration); expect('rate(5 minutes)').toEqual(stack.resolve(rate).expressionString); - }); test('rate can be in allowed type hours', () => { expect('rate(1 hour)').toEqual(appscaling.Schedule.rate(Duration.hours(1)) .expressionString); - }); }); describe('expression', () => { test('test using a literal schedule expression', () => { expect(appscaling.Schedule.expression('cron(0 18 * * ? *)').expressionString).toEqual('cron(0 18 * * ? *)'); - }); }); diff --git a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts index b8080c921c660..25c38df03b52e 100644 --- a/packages/aws-cdk-lib/aws-backup/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-backup/lib/schedule.ts @@ -14,6 +14,6 @@ export abstract class Schedule extends CoreSchedule { * Construct a schedule from cron options */ public static cron(options: CronOptions): Schedule { - return super.protectedCron(options); + return super.protectedCron(options, 'aws-backup'); } } diff --git a/packages/aws-cdk-lib/aws-ecs-patterns/test/ec2/scheduled-ecs-task.test.ts b/packages/aws-cdk-lib/aws-ecs-patterns/test/ec2/scheduled-ecs-task.test.ts index 764d99d4216c0..2d9704e419923 100644 --- a/packages/aws-cdk-lib/aws-ecs-patterns/test/ec2/scheduled-ecs-task.test.ts +++ b/packages/aws-cdk-lib/aws-ecs-patterns/test/ec2/scheduled-ecs-task.test.ts @@ -364,7 +364,7 @@ test('Scheduled Ec2 Task shows warning when minute is not defined in cron', () = }); // THEN - Annotations.fromStack(stack).hasWarning('/Default', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-events:scheduleWillRunEveryMinute]"); + Annotations.fromStack(stack).hasWarning('/Default', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-events:scheduleDefaultRunsEveryMinute]"); }); test('Scheduled Ec2 Task shows no warning when minute is * in cron', () => { diff --git a/packages/aws-cdk-lib/aws-ecs-patterns/test/fargate/scheduled-fargate-task.test.ts b/packages/aws-cdk-lib/aws-ecs-patterns/test/fargate/scheduled-fargate-task.test.ts index 8b318fd8b1167..8e425b9230542 100644 --- a/packages/aws-cdk-lib/aws-ecs-patterns/test/fargate/scheduled-fargate-task.test.ts +++ b/packages/aws-cdk-lib/aws-ecs-patterns/test/fargate/scheduled-fargate-task.test.ts @@ -451,7 +451,7 @@ test('Scheduled Fargate Task shows warning when minute is not defined in cron', }); // THEN - Annotations.fromStack(stack).hasWarning('/Default', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-events:scheduleWillRunEveryMinute]"); + Annotations.fromStack(stack).hasWarning('/Default', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-events:scheduleDefaultRunsEveryMinute]"); }); test('Scheduled Fargate Task shows no warning when minute is * in cron', () => { diff --git a/packages/aws-cdk-lib/aws-events/lib/schedule.ts b/packages/aws-cdk-lib/aws-events/lib/schedule.ts index d45c3a17d045b..d4d6549e8b611 100644 --- a/packages/aws-cdk-lib/aws-events/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-events/lib/schedule.ts @@ -30,7 +30,7 @@ export abstract class Schedule extends CoreSchedule { * Create a schedule from a set of cron fields */ public static cron(options: CronOptions): Schedule { - return super.protectedCron(options); + return super.protectedCron(options, 'aws-events'); } } diff --git a/packages/aws-cdk-lib/aws-events/test/rule.test.ts b/packages/aws-cdk-lib/aws-events/test/rule.test.ts index 6cca0b11ba804..f31f7dd5b7ea8 100644 --- a/packages/aws-cdk-lib/aws-events/test/rule.test.ts +++ b/packages/aws-cdk-lib/aws-events/test/rule.test.ts @@ -38,7 +38,7 @@ describe('rule', () => { }), }); - Annotations.fromStack(stack).hasWarning('/Default/MyRule', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-events:scheduleWillRunEveryMinute]"); + Annotations.fromStack(stack).hasWarning('/Default/MyRule', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-events:scheduleDefaultRunsEveryMinute]"); }); test('rule does not display warning when minute is set to * in cron', () => { From 40f4078ba51fb9c33e00fe5ab394d2885f1deddf Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 19 Sep 2023 10:49:48 -0400 Subject: [PATCH 22/27] test schedule in core --- packages/aws-cdk-lib/core/lib/schedule.ts | 6 +- .../aws-cdk-lib/core/test/schedule.test.ts | 84 +++++++++++++++++++ 2 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 packages/aws-cdk-lib/core/test/schedule.test.ts diff --git a/packages/aws-cdk-lib/core/lib/schedule.ts b/packages/aws-cdk-lib/core/lib/schedule.ts index c34c81c30f5ad..4c30eb3a86a96 100644 --- a/packages/aws-cdk-lib/core/lib/schedule.ts +++ b/packages/aws-cdk-lib/core/lib/schedule.ts @@ -20,7 +20,7 @@ export abstract class Schedule { protected static protectedAt(date: Date, timeZone?: TimeZone): Schedule { try { const literal = date.toISOString().split('.')[0]; - return new LiteralSchedule(`at(${literal})`, timeZone); + return new LiteralSchedule(`at(${literal})`, timeZone ?? DEFAULT_TIMEZONE); } catch (e) { if (e instanceof RangeError) { throw new Error('Invalid date'); @@ -36,7 +36,7 @@ export abstract class Schedule { * @param timeZone The time zone, if applicable. This is only valid for 'at' and 'cron' expressions */ protected static protectedExpression(expression: string, timeZone?: TimeZone): Schedule { - return new LiteralSchedule(expression, timeZone); + return new LiteralSchedule(expression, timeZone ?? DEFAULT_TIMEZONE); } /** @@ -177,7 +177,7 @@ const DEFAULT_TIMEZONE = TimeZone.ETC_UTC; class LiteralSchedule extends Schedule { constructor( public readonly expressionString: string, - public readonly timeZone: TimeZone = DEFAULT_TIMEZONE, + public readonly timeZone?: TimeZone, ) { super(); } diff --git a/packages/aws-cdk-lib/core/test/schedule.test.ts b/packages/aws-cdk-lib/core/test/schedule.test.ts new file mode 100644 index 0000000000000..e238fa6dbdfe9 --- /dev/null +++ b/packages/aws-cdk-lib/core/test/schedule.test.ts @@ -0,0 +1,84 @@ +import { Annotations } from '../../assertions'; +import { Stack } from '../lib/stack'; +import { Duration } from '../lib/duration'; +import { CronOptions, Schedule } from '../lib/schedule'; +import { TimeZone } from '../lib/time-zone'; + +/** + * Basic example of extending core.Schedule for testing purposes. + */ +abstract class TestSchedule extends Schedule { + public static at(date: Date, timeZone?: TimeZone): Schedule { + return Schedule.protectedAt(date, timeZone); + } + + public static rate(duration: Duration): Schedule { + return Schedule.protectedRate(duration); + } + + public static expression(expression: string, timeZone?: TimeZone): Schedule { + return Schedule.protectedExpression(expression, timeZone); + } + + public static cron(options: CronOptions): Schedule { + return Schedule.protectedCron(options); + } +} + +describe('schedules', () => { + test('at - with default timezone', () => { + const schedule = TestSchedule.at(new Date(Date.UTC(1969, 10, 20, 0, 0, 0))); + expectSchedule(schedule, 'at(1969-11-20T00:00:00)', TimeZone.ETC_UTC); + }); + + test('at - with timezone', () => { + const schedule = TestSchedule.at(new Date(Date.UTC(1969, 10, 20, 0, 0, 0)), TimeZone.ASIA_TOKYO ); + expectSchedule(schedule, 'at(1969-11-20T00:00:00)', TimeZone.ASIA_TOKYO); + }); + + test('rate', () => { + const schedule = TestSchedule.rate(Duration.days(1)); + expectSchedule(schedule, 'rate(1 day)', undefined); + }); + + test('expression - with default timezone', () => { + const schedule = TestSchedule.expression('at(1969-11-20T00:00:00)'); + expectSchedule(schedule, 'at(1969-11-20T00:00:00)', TimeZone.ETC_UTC); + }); + + test('expression - with timezone', () => { + const schedule = TestSchedule.expression('at(1969-11-20T00:00:00)', TimeZone.ASIA_SEOUL); + expectSchedule(schedule, 'at(1969-11-20T00:00:00)', TimeZone.ASIA_SEOUL); + }); + + test('cron - with default timezone', () => { + const schedule = TestSchedule.cron({ + minute: '0/10', + weekDay: 'MON-FRI', + }); + expectSchedule(schedule, 'cron(0/10 * ? * MON-FRI *)', TimeZone.ETC_UTC); + }); + + test('cron - with timezone', () => { + const schedule = TestSchedule.cron({ + minute: '0/10', + weekDay: 'MON-FRI', + timeZone: TimeZone.ANTARCTICA_TROLL, + }); + expectSchedule(schedule, 'cron(0/10 * ? * MON-FRI *)', TimeZone.ANTARCTICA_TROLL); + }); + + test('cron warning when minute not supplied', () => { + const stack = new Stack(); + const schedule = TestSchedule.cron({ + weekDay: 'MON-FRI', + }); + schedule._bind(stack); + Annotations.fromStack(stack).hasWarning('/Default', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/core:scheduleDefaultRunsEveryMinute]"); + }); +}); + +function expectSchedule(schedule: Schedule, expectedExpression: string, expectedTimeZone?: TimeZone) { + expect(schedule.expressionString).toEqual(expectedExpression); + expect(schedule.timeZone).toEqual(expectedTimeZone); +} From 1e444c84a5037fc8a630cb8843d6afdf3acbba5d Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 19 Sep 2023 10:53:24 -0400 Subject: [PATCH 23/27] fix tests --- packages/aws-cdk-lib/aws-dynamodb/test/dynamodb.test.ts | 2 +- .../aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts | 2 +- packages/aws-cdk-lib/aws-lambda/test/alias.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/aws-cdk-lib/aws-dynamodb/test/dynamodb.test.ts b/packages/aws-cdk-lib/aws-dynamodb/test/dynamodb.test.ts index edab404c22f61..a92ccb0473df4 100644 --- a/packages/aws-cdk-lib/aws-dynamodb/test/dynamodb.test.ts +++ b/packages/aws-cdk-lib/aws-dynamodb/test/dynamodb.test.ts @@ -1548,7 +1548,7 @@ test('scheduled scaling shows warning when minute is not defined in cron', () => }); // THEN - Annotations.fromStack(stack).hasWarning('/Default/MyTable/ReadScaling/Target', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-applicationautoscaling:defaultRunEveryMinute]"); + Annotations.fromStack(stack).hasWarning('/Default/MyTable/ReadScaling/Target', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-applicationautoscaling:scheduleDefaultRunsEveryMinute]"); }); test('scheduled scaling shows no warning when minute is * in cron', () => { diff --git a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts index aec9f09bff889..d85edf4e940b3 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts @@ -2493,7 +2493,7 @@ describe('fargate service', () => { }); // THEN - Annotations.fromStack(stack).hasWarning('/Default/Service/TaskCount/Target', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-applicationautoscaling:defaultRunEveryMinute]"); + Annotations.fromStack(stack).hasWarning('/Default/Service/TaskCount/Target', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-applicationautoscaling:scheduleDefaultRunsEveryMinute]"); }); test('scheduled scaling shows no warning when minute is * in cron', () => { diff --git a/packages/aws-cdk-lib/aws-lambda/test/alias.test.ts b/packages/aws-cdk-lib/aws-lambda/test/alias.test.ts index 34ee5d33c52bd..a5081ea79593a 100644 --- a/packages/aws-cdk-lib/aws-lambda/test/alias.test.ts +++ b/packages/aws-cdk-lib/aws-lambda/test/alias.test.ts @@ -602,7 +602,7 @@ describe('alias', () => { }); // THEN - Annotations.fromStack(stack).hasWarning('/Default/Alias/AliasScaling/Target', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-applicationautoscaling:defaultRunEveryMinute]"); + Annotations.fromStack(stack).hasWarning('/Default/Alias/AliasScaling/Target', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead. [ack: @aws-cdk/aws-applicationautoscaling:scheduleDefaultRunsEveryMinute]"); }); test('scheduled scaling shows no warning when minute is * in cron', () => { From 44b535e46c9b432d85edba97e943ab3c2cf7e2b4 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 19 Sep 2023 11:06:14 -0400 Subject: [PATCH 24/27] lint --- packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts | 3 +++ packages/aws-cdk-lib/core/test/schedule.test.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts index 2e412ea20e3f9..1d2aa9b88ea67 100644 --- a/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts +++ b/packages/@aws-cdk/aws-synthetics-alpha/lib/schedule.ts @@ -54,6 +54,9 @@ export class Schedule extends CoreSchedule { super(); } + /** + * @internal + */ public _bind(_scope: Construct) {} } diff --git a/packages/aws-cdk-lib/core/test/schedule.test.ts b/packages/aws-cdk-lib/core/test/schedule.test.ts index e238fa6dbdfe9..34723010a9592 100644 --- a/packages/aws-cdk-lib/core/test/schedule.test.ts +++ b/packages/aws-cdk-lib/core/test/schedule.test.ts @@ -1,7 +1,7 @@ import { Annotations } from '../../assertions'; -import { Stack } from '../lib/stack'; import { Duration } from '../lib/duration'; import { CronOptions, Schedule } from '../lib/schedule'; +import { Stack } from '../lib/stack'; import { TimeZone } from '../lib/time-zone'; /** From a530f35eddd7b4b75a017af53b20aa0525e9683d Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 19 Sep 2023 13:55:49 -0400 Subject: [PATCH 25/27] snappies --- .../cdk-backup.assets.json | 6 +- .../cdk-backup.template.json | 3 + .../test/integ.backup.js.snapshot/cdk.out | 2 +- .../test/integ.backup.js.snapshot/integ.json | 2 +- .../integ.backup.js.snapshot/manifest.json | 5 +- .../test/integ.backup.js.snapshot/tree.json | 93 ++++++++++--------- .../aws-cdk-dynamodb.assets.json | 6 +- .../aws-cdk-dynamodb.template.json | 18 ++-- .../integ.autoscaling.lit.js.snapshot/cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 17 ++-- .../tree.json | 70 ++++++++------ .../aws-lambda-autoscaling.assets.json | 4 +- .../aws-lambda-autoscaling.template.json | 6 +- .../manifest.json | 12 +-- .../tree.json | 2 + 16 files changed, 137 insertions(+), 113 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk-backup.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk-backup.assets.json index 19ddf51ac30c3..967f653a106aa 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk-backup.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk-backup.assets.json @@ -1,7 +1,7 @@ { - "version": "32.0.0", + "version": "34.0.0", "files": { - "0c52c355c71ac95690274d7987110017ff9cd1a1bc79fa4206fda2f55d6b62d5": { + "7617f116cb014747232d2ebeb42fb3e22242c4b0987526daf7a033aba236d976": { "source": { "path": "cdk-backup.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "0c52c355c71ac95690274d7987110017ff9cd1a1bc79fa4206fda2f55d6b62d5.json", + "objectKey": "7617f116cb014747232d2ebeb42fb3e22242c4b0987526daf7a033aba236d976.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk-backup.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk-backup.template.json index 2722b98da789d..e1d8a605c90e0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk-backup.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk-backup.template.json @@ -83,6 +83,7 @@ }, "RuleName": "Daily", "ScheduleExpression": "cron(0 5 * * ? *)", + "ScheduleExpressionTimezone": "Etc/UTC", "TargetBackupVault": { "Fn::GetAtt": [ "Vault23237E5B", @@ -96,6 +97,7 @@ }, "RuleName": "Weekly", "ScheduleExpression": "cron(0 5 ? * SAT *)", + "ScheduleExpressionTimezone": "Etc/UTC", "TargetBackupVault": { "Fn::GetAtt": [ "Vault23237E5B", @@ -110,6 +112,7 @@ }, "RuleName": "Monthly5Year", "ScheduleExpression": "cron(0 5 1 * ? *)", + "ScheduleExpressionTimezone": "Etc/UTC", "TargetBackupVault": { "Fn::GetAtt": [ "Vault23237E5B", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk.out index f0b901e7c06e5..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"32.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/integ.json index 266124ac58c12..b044eefcaffbb 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "33.0.0", + "version": "34.0.0", "testCases": { "integ.backup": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/manifest.json index aa4d73d1faac8..85402b8c54933 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "33.0.0", + "version": "34.0.0", "artifacts": { "cdk-backup.assets": { "type": "cdk:asset-manifest", @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "cdk-backup.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/0c52c355c71ac95690274d7987110017ff9cd1a1bc79fa4206fda2f55d6b62d5.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/7617f116cb014747232d2ebeb42fb3e22242c4b0987526daf7a033aba236d976.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/tree.json index 3728b496ca8cf..9120c3a2895c6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-backup/test/integ.backup.js.snapshot/tree.json @@ -37,22 +37,22 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_dynamodb.CfnTable", + "version": "0.0.0" } }, "ScalingRole": { "id": "ScalingRole", "path": "cdk-backup/Table/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_dynamodb.Table", + "version": "0.0.0" } }, "FileSystem": { @@ -63,8 +63,8 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_efs.CfnFileSystem", + "version": "0.0.0" } }, "Vault": { @@ -84,14 +84,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.CfnBackupVault", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.BackupVault", + "version": "0.0.0" } }, "SecondaryVault": { @@ -111,22 +111,22 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.CfnBackupVault", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.BackupVault", + "version": "0.0.0" } }, "Env": { "id": "Env", "path": "cdk-backup/Env", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" } }, "ThirdVault": { @@ -156,14 +156,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.CfnBackupVault", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.BackupVault", + "version": "0.0.0" } }, "Plan": { @@ -185,6 +185,7 @@ }, "ruleName": "Daily", "scheduleExpression": "cron(0 5 * * ? *)", + "scheduleExpressionTimezone": "Etc/UTC", "targetBackupVault": { "Fn::GetAtt": [ "Vault23237E5B", @@ -198,6 +199,7 @@ }, "ruleName": "Weekly", "scheduleExpression": "cron(0 5 ? * SAT *)", + "scheduleExpressionTimezone": "Etc/UTC", "targetBackupVault": { "Fn::GetAtt": [ "Vault23237E5B", @@ -212,6 +214,7 @@ }, "ruleName": "Monthly5Year", "scheduleExpression": "cron(0 5 1 * ? *)", + "scheduleExpressionTimezone": "Etc/UTC", "targetBackupVault": { "Fn::GetAtt": [ "Vault23237E5B", @@ -250,8 +253,8 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.CfnBackupPlan", + "version": "0.0.0" } }, "Selection": { @@ -266,8 +269,8 @@ "id": "ImportRole", "path": "cdk-backup/Plan/Selection/Role/ImportRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "Resource": { @@ -305,14 +308,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" } }, "Resource": { @@ -394,42 +397,42 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.CfnBackupSelection", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.BackupSelection", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.aws_backup.BackupPlan", + "version": "0.0.0" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "cdk-backup/BootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "cdk-backup/CheckBootstrapVersion", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" } }, "Tree": { @@ -437,13 +440,13 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.2.69" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/aws-cdk-dynamodb.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/aws-cdk-dynamodb.assets.json index 354247134c202..30904fa397fe7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/aws-cdk-dynamodb.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/aws-cdk-dynamodb.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "34.0.0", "files": { - "619c64c0f19a7d78d759641bfba47f06ebbd7ffb42aae71ec695a6777a534d01": { + "865151155140d0ba599d3522f659db77ada497ea1a763cf11c3fb58d017a3082": { "source": { "path": "aws-cdk-dynamodb.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "619c64c0f19a7d78d759641bfba47f06ebbd7ffb42aae71ec695a6777a534d01.json", + "objectKey": "865151155140d0ba599d3522f659db77ada497ea1a763cf11c3fb58d017a3082.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/aws-cdk-dynamodb.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/aws-cdk-dynamodb.template.json index 72046e5747d8d..bd730b9100e98 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/aws-cdk-dynamodb.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/aws-cdk-dynamodb.template.json @@ -3,16 +3,16 @@ "TableCD117FA1": { "Type": "AWS::DynamoDB::Table", "Properties": { - "KeySchema": [ + "AttributeDefinitions": [ { "AttributeName": "hashKey", - "KeyType": "HASH" + "AttributeType": "S" } ], - "AttributeDefinitions": [ + "KeySchema": [ { "AttributeName": "hashKey", - "AttributeType": "S" + "KeyType": "HASH" } ], "ProvisionedThroughput": { @@ -56,23 +56,25 @@ ] }, "ScalableDimension": "dynamodb:table:ReadCapacityUnits", - "ServiceNamespace": "dynamodb", "ScheduledActions": [ { "ScalableTargetAction": { "MinCapacity": 20 }, "Schedule": "cron(0 8 * * ? *)", - "ScheduledActionName": "ScaleUpInTheMorning" + "ScheduledActionName": "ScaleUpInTheMorning", + "Timezone": "Etc/UTC" }, { "ScalableTargetAction": { "MaxCapacity": 20 }, "Schedule": "cron(0 20 * * ? *)", - "ScheduledActionName": "ScaleDownAtNight" + "ScheduledActionName": "ScaleDownAtNight", + "Timezone": "Etc/UTC" } - ] + ], + "ServiceNamespace": "dynamodb" } }, "TableReadScalingTargetTracking67DF0596": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/cdk.out index 588d7b269d34f..2313ab5436501 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/integ.json index 8db5a6b10f544..81c9e6f902331 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "34.0.0", "testCases": { "integ.autoscaling.lit": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/manifest.json index ceac2d72f9911..d4155ced6dcad 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "34.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-dynamodb.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-dynamodb.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/619c64c0f19a7d78d759641bfba47f06ebbd7ffb42aae71ec695a6777a534d01.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/865151155140d0ba599d3522f659db77ada497ea1a763cf11c3fb58d017a3082.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -71,6 +66,12 @@ ] }, "displayName": "aws-cdk-dynamodb" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/tree.json index a7da46d30ce88..07eb252a889ae 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.autoscaling.lit.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "aws-cdk-dynamodb": { "id": "aws-cdk-dynamodb", "path": "aws-cdk-dynamodb", @@ -26,16 +18,16 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::DynamoDB::Table", "aws:cdk:cloudformation:props": { - "keySchema": [ + "attributeDefinitions": [ { "attributeName": "hashKey", - "keyType": "HASH" + "attributeType": "S" } ], - "attributeDefinitions": [ + "keySchema": [ { "attributeName": "hashKey", - "attributeType": "S" + "keyType": "HASH" } ], "provisionedThroughput": { @@ -45,7 +37,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-dynamodb.CfnTable", + "fqn": "aws-cdk-lib.aws_dynamodb.CfnTable", "version": "0.0.0" } }, @@ -53,8 +45,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/Table/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "ReadScaling": { @@ -101,11 +93,11 @@ ] }, "scalableDimension": "dynamodb:table:ReadCapacityUnits", - "serviceNamespace": "dynamodb", "scheduledActions": [ { "scheduledActionName": "ScaleUpInTheMorning", "schedule": "cron(0 8 * * ? *)", + "timezone": "Etc/UTC", "scalableTargetAction": { "minCapacity": 20 } @@ -113,15 +105,17 @@ { "scheduledActionName": "ScaleDownAtNight", "schedule": "cron(0 20 * * ? *)", + "timezone": "Etc/UTC", "scalableTargetAction": { "maxCapacity": 20 } } - ] + ], + "serviceNamespace": "dynamodb" } }, "constructInfo": { - "fqn": "@aws-cdk/aws-applicationautoscaling.CfnScalableTarget", + "fqn": "aws-cdk-lib.aws_applicationautoscaling.CfnScalableTarget", "version": "0.0.0" } }, @@ -149,44 +143,68 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-applicationautoscaling.CfnScalingPolicy", + "fqn": "aws-cdk-lib.aws_applicationautoscaling.CfnScalingPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-applicationautoscaling.TargetTrackingScalingPolicy", + "fqn": "aws-cdk-lib.aws_applicationautoscaling.TargetTrackingScalingPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-applicationautoscaling.ScalableTarget", + "fqn": "aws-cdk-lib.aws_applicationautoscaling.ScalableTarget", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-applicationautoscaling.BaseScalableAttribute", + "fqn": "aws-cdk-lib.aws_applicationautoscaling.BaseScalableAttribute", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-dynamodb.Table", + "fqn": "aws-cdk-lib.aws_dynamodb.Table", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-dynamodb/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-dynamodb/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.2.70" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/aws-lambda-autoscaling.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/aws-lambda-autoscaling.assets.json index 784bf713b5a18..adda4ff7aab5e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/aws-lambda-autoscaling.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/aws-lambda-autoscaling.assets.json @@ -1,7 +1,7 @@ { "version": "34.0.0", "files": { - "4e491c14be2b36af5be729715edfad23d2db6e3050125cdd632fce51b0900fb5": { + "54ec09132268008f855bb0ad4863af3ceda54b0640d90c386503d8faf54eeae8": { "source": { "path": "aws-lambda-autoscaling.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "4e491c14be2b36af5be729715edfad23d2db6e3050125cdd632fce51b0900fb5.json", + "objectKey": "54ec09132268008f855bb0ad4863af3ceda54b0640d90c386503d8faf54eeae8.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/aws-lambda-autoscaling.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/aws-lambda-autoscaling.template.json index 6ac23d677363c..9da5f1d9d06f2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/aws-lambda-autoscaling.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/aws-lambda-autoscaling.template.json @@ -124,14 +124,16 @@ "MinCapacity": 20 }, "Schedule": "cron(0 8 * * ? *)", - "ScheduledActionName": "ScaleUpInTheMorning" + "ScheduledActionName": "ScaleUpInTheMorning", + "Timezone": "Etc/UTC" }, { "ScalableTargetAction": { "MaxCapacity": 20 }, "Schedule": "cron(0 20 * * ? *)", - "ScheduledActionName": "ScaleDownAtNight" + "ScheduledActionName": "ScaleDownAtNight", + "Timezone": "Etc/UTC" } ], "ServiceNamespace": "lambda" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/manifest.json index 20b77f5b33063..4f657607872f7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/manifest.json @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-lambda-autoscaling.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/4e491c14be2b36af5be729715edfad23d2db6e3050125cdd632fce51b0900fb5.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/54ec09132268008f855bb0ad4863af3ceda54b0640d90c386503d8faf54eeae8.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -86,15 +87,6 @@ "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } - ], - "MyLambdaCurrentVersionE7A382CC9ef7d0f7e3b3b55a2ac4da5225352f4d": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLambdaCurrentVersionE7A382CC9ef7d0f7e3b3b55a2ac4da5225352f4d", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] - } ] }, "displayName": "aws-lambda-autoscaling" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/tree.json index cec884fba04b0..7822036ae32e5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.autoscaling.lit.js.snapshot/tree.json @@ -219,6 +219,7 @@ { "scheduledActionName": "ScaleUpInTheMorning", "schedule": "cron(0 8 * * ? *)", + "timezone": "Etc/UTC", "scalableTargetAction": { "minCapacity": 20 } @@ -226,6 +227,7 @@ { "scheduledActionName": "ScaleDownAtNight", "schedule": "cron(0 20 * * ? *)", + "timezone": "Etc/UTC", "scalableTargetAction": { "maxCapacity": 20 } From 3697f552b8ee9522b067035600f372ab368bad6b Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 19 Sep 2023 14:29:44 -0400 Subject: [PATCH 26/27] fix cronoptions --- .../lib/schedule.ts | 44 +------------------ .../aws-autoscaling/lib/schedule.ts | 37 +--------------- 2 files changed, 2 insertions(+), 79 deletions(-) diff --git a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts index ef5c562d8dcf9..3954b0a81efaf 100644 --- a/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-applicationautoscaling/lib/schedule.ts @@ -44,46 +44,4 @@ export abstract class Schedule extends CoreSchedule { * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html#CronExpressions * @deprecated use core.CronOptions instead */ -export interface CronOptions { - /** - * The minute to run this rule at - * - * @default - Every minute - */ - readonly minute?: string; - - /** - * The hour to run this rule at - * - * @default - Every hour - */ - readonly hour?: string; - - /** - * The day of the month to run this rule at - * - * @default - Every day of the month - */ - readonly day?: string; - - /** - * The month to run this rule at - * - * @default - Every month - */ - readonly month?: string; - - /** - * The year to run this rule at - * - * @default - Every year - */ - readonly year?: string; - - /** - * The day of the week to run this rule at - * - * @default - Any day of the week - */ - readonly weekDay?: string; -} +export interface CronOptions extends CoreCronOptions {} diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts index f1ea53b43a5eb..79cc02545b5d9 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/schedule.ts @@ -50,39 +50,4 @@ export abstract class Schedule extends CoreSchedule { * @see http://crontab.org/ * @deprecated use core.CronOptions */ -export interface CronOptions { - /** - * The minute to run this rule at - * - * @default - Every minute - */ - readonly minute?: string; - - /** - * The hour to run this rule at - * - * @default - Every hour - */ - readonly hour?: string; - - /** - * The day of the month to run this rule at - * - * @default - Every day of the month - */ - readonly day?: string; - - /** - * The month to run this rule at - * - * @default - Every month - */ - readonly month?: string; - - /** - * The day of the week to run this rule at - * - * @default - Any day of the week - */ - readonly weekDay?: string; -} +export interface CronOptions extends CoreCronOptions {} From 77fd85408328fb8d9b3fb8344369ef85f9c2e504 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com> Date: Wed, 20 Sep 2023 08:59:42 -0400 Subject: [PATCH 27/27] Update packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts --- .../aws-scheduler-alpha/test/schedule-expression.test.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts b/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts index aeee9d5410443..6f71558c1a704 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts @@ -36,9 +36,6 @@ describe('schedule expression', () => { }); cron._bind(new Stack()); - // eslint-disable-next-line no-console - console.log(cron.expressionString, cron.timeZone); - // THEN expect(cron.timeZone).toEqual(TimeZone.EUROPE_LONDON); });