Skip to content

Commit

Permalink
feat: adding schedule option for sagemaker models
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob-Powell authored and bigadsoleiman committed Mar 15, 2024
1 parent 8838856 commit 97cc5de
Show file tree
Hide file tree
Showing 9 changed files with 508 additions and 1 deletion.
60 changes: 60 additions & 0 deletions cli/aws-cron-expressions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
export const minuteExp = `(0?[0-9]|[1-5][0-9])`; // [0]0-59
export const hourExp = `(0?[0-9]|1[0-9]|2[0-3])`; // [0]0-23
export const dayOfMonthExp = `(0?[1-9]|[1-2][0-9]|3[0-1])`; // [0]1-31
export const monthExp = `(0?[1-9]|1[0-2]|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)`; // [0]1-12 or JAN-DEC
export const dayOfWeekExp = `([1-7]|SUN|MON|TUE|WED|THU|FRI|SAT)`; // 1-7 or SAT-SUN
export const yearExp = `((19[8-9][0-9])|(2[0-1][0-9][0-9]))`; // 1980-2199
export const numbers = `([0-9]*[1-9][0-9]*)`; // whole numbers greater than 0

export function dayOfWeekHash(): string {
return `(${dayOfWeekExp}#[1-5])`; // add hash expression to enable supported use case
}

function rangeRegex(values: string): string {
return `(${values}|(\\*\\-${values})|(${values}\\-${values})|(${values}\\-\\*))`;
}

function listRangeRegex(values: string): string {
const range = rangeRegex(values);
return `(${range}(\\,${range})*)`;
}

function slashRegex(values: string): string {
const range = rangeRegex(values);
return `((\\*|${range}|${values})\\/${numbers})`;
}

function listSlashRegex(values: string): string {
const slash = slashRegex(values);
const slashOrRange = `(${slash}|${rangeRegex(values)})`;
return `(${slashOrRange}(\\,${slashOrRange})*)`;
}

function commonRegex(values: string): string {
return `(${listRangeRegex(values)}|\\*|${listSlashRegex(values)})`;
}

export function minuteRegex(): string {
return `^(${commonRegex(minuteExp)})$`;
}

export function hourRegex(): string {
return `^(${commonRegex(hourExp)})$`;
}

export function dayOfMonthRegex(): string {
return `^(${commonRegex(dayOfMonthExp)}|\\?|L|LW|${dayOfMonthExp}W)$`;
}

export function monthRegex(): string {
return `^(${commonRegex(monthExp)})$`;
}

export function dayOfWeekRegex(): string {
const rangeList = listRangeRegex(dayOfWeekExp);
return `^(${rangeList}|\\*|\\?|${dayOfWeekExp}L|L|L-[1-7]|${dayOfWeekHash()})$`;
}

export function yearRegex(): string {
return `^(${commonRegex(yearExp)})$`;
}
57 changes: 57 additions & 0 deletions cli/aws-cron-validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
class AWSCronError extends Error {}

import {
minuteRegex,
hourRegex,
dayOfMonthRegex,
monthRegex,
dayOfWeekRegex,
yearRegex,
} from './aws-cron-expressions';

export class AWSCronValidator {

public static validate(expression: string): string {
if (!expression.trim()) {
throw new AWSCronError(
`No parameters entered, this format is required in UTC: 0 20 ? * SUN-FRI *`
);
}
const valueCount = expression.split(" ").length;
if (valueCount !== 6) {
throw new AWSCronError(
`Incorrect amount of parameters in '${expression}'. 6 required, ${valueCount} provided.`
);
}

const [minute, hour, dayOfMonth, month, dayOfWeek, year] = expression.split(" ");

// special handling for Day of Month and Day of Week
if (!((dayOfMonth === "?" && dayOfWeek !== "?") || (dayOfMonth !== "?" && dayOfWeek === "?"))) {
throw new AWSCronError(
`Invalid combination of day-of-month '${dayOfMonth}' and day-of-week '${dayOfWeek}'. One must be a question mark (?)`
);
}

if (!new RegExp(minuteRegex()).test(minute)) {
throw new AWSCronError(`Invalid minute value '${minute}'.`);
}
if (!new RegExp(hourRegex()).test(hour)) {
throw new AWSCronError(`Invalid hour value '${hour}'.`);
}
if (!new RegExp(dayOfMonthRegex()).test(dayOfMonth)) {
throw new AWSCronError(`Invalid day-of-month value '${dayOfMonth}'.`);
}
if (!new RegExp(monthRegex(), 'i').test(month)) {
throw new AWSCronError(`Invalid month value '${month}'.`);
}
if (!new RegExp(dayOfWeekRegex(), 'i').test(dayOfWeek)) {
throw new AWSCronError(`Invalid day-of-week value '${dayOfWeek}'.`);
}
if (!new RegExp(yearRegex()).test(year)) {
throw new AWSCronError(`Invalid year value '${year}'.`);
}

return expression;
}
}
Loading

0 comments on commit 97cc5de

Please sign in to comment.