require "aws-sdk-cloudwatchevents" class Jets::CLI::Schedule class Validate < Base def run are_you_sure? check_exist! valid = perform if valid log.info "Validation passed. config/jets/schedule.yml is valid" if File.exist?("config/sidekiq.yml") log.info <<~EOL You can remove config/sidekiq.yml now. It is no longer needed. rm config/sidekiq.yml EOL end else log.info "Validation failed. Please fix the errors and try again." log.info "Docs: https://docs.rubyonjets.com/docs/jobs/schedule/" exit 1 end end # interface method: used by deploy to translate on_deploy def perform items = YAML.load_file("config/jets/schedule.yml") items = ActiveSupport::HashWithIndifferentAccess.new(items) items.each do |key, value| validate_item(key, value) end !@@has_errors end def check_exist! unless File.exist?("config/jets/schedule.yml") abort "config/jets/schedule.yml does not exist. Nothing to validate." end end @@rule_name = "validation_rule_#{Time.now.to_i}_#{rand(1000)}" @@has_errors = false def validate_item(key, value) log.debug "To validate, creating live event rule for #{key}" log.debug "value: #{value.inspect}" schedule_expression = if value[:cron] "cron(#{value[:cron]})" elsif value[:rate] expr = rate_expression(value[:rate]) "rate(#{expr})" else raise "No schedule expression found for: #{key}" end # Create the rule with the provided cron expression client.put_rule( name: @@rule_name, schedule_expression: schedule_expression, state: "DISABLED" # Disable the rule to prevent it from being triggered ) # log.info "Valid rule: #{key}" # log.info " Schedule expression: #{schedule_expression}" true # If no error is raised, the cron expression is valid rescue Aws::CloudWatchEvents::Errors::ValidationException => e log.error "Invalid rule: #{key}" log.error "Schedule expression: #{schedule_expression}" # log.error "Validation Error: #{e.message}" # commented out to reduce noise, not useful @@has_errors ||= true false # If ValidationException is raised, the cron expression is invalid ensure # Delete the rule after validation (whether it's valid or not) begin client.delete_rule(name: @@rule_name) rescue nil end end def are_you_sure? message = <<~EOL Will validate: config/jets/schedule.yml It does this by creating a live test event rule for each entry in schedule.yml and then deleting it. EOL sure?(message) end def client Aws::CloudWatchEvents::Client.new end memoize :client end end