module FastlyConfig # Handles updates to our Fastly configurations class Update FASTLY_CONFIGS = %w[Snippets].freeze def self.call new.run end attr_reader :fastly, :service def initialize @fastly = Fastly.new(api_key: ApplicationConfig["FASTLY_API_KEY"]) @service = fastly.get_service(ApplicationConfig["FASTLY_SERVICE_ID"]) end def run(configs: FASTLY_CONFIGS) validate_configs(configs) active_version = get_active_version(service) config_handlers = configs.map { |config| "FastlyConfig::#{config}".constantize.new(fastly, active_version) } configs_updated = config_handlers.any?(&:update_needed?) return unless configs_updated new_version = active_version.clone config_handlers.each { |config_handler| config_handler.update(new_version) } new_version.activate! log_to_datadog(configs, new_version) Rails.logger.info("Fastly updated to version #{new_version.number}.") rescue Fastly::Error => e error_msg = JSON.parse(e.message) raise e unless unauthorized_error?(error_msg) && Rails.env.development? nil end private def get_active_version(service) service.versions.reverse_each.detect(&:active?) end def log_to_datadog(configs, new_version) tags = [ "new_version:#{new_version.number}", "configs_updated:#{configs.join(', ')}", ] DatadogStatsClient.increment("fastly.update", tags: tags) end def validate_configs(configs) raise FastlyConfig::Errors::InvalidConfigsFormat unless configs.is_a? Array configs.each do |config| raise FastlyConfig::Errors::InvalidConfig.new(config, FASTLY_CONFIGS) unless FASTLY_CONFIGS.include? config end end def unauthorized_error?(error_msg) error_msg["msg"] == "Provided credentials are missing or invalid" end end end