def _validate_schedule(self, **schedule): result = {} # allowed parameters valid_parameters = [ configuration.TIMEZONE, configuration.PERIODS, configuration.NAME, configuration.DESCRIPTION, configuration.OVERWRITE, configuration.METRICS, configuration.STOP_NEW_INSTANCES, configuration.USE_MAINTENANCE_WINDOW, configuration.SSM_MAINTENANCE_WINDOW, configuration.RETAINED_RUNNING, configuration.ENFORCED, configuration.HIBERNATE, configuration.OVERRIDE_STATUS, configuration.SCHEDULE_CONFIG_STACK ] for attr in schedule: if attr == ConfigAdmin.TYPE_ATTR: continue if attr not in valid_parameters: raise ValueError( ERR_SCHEDULE_UNKNOWN_PARAMETER.format( attr, valid_parameters)) # skip None values if schedule[attr] is None or len(str(schedule[attr])) == 0: continue # check periods set if attr == configuration.PERIODS: temp = self._ensure_set(schedule[attr]) if len(temp) > 0: result[attr] = temp continue if attr in [ configuration.NAME, configuration.SSM_MAINTENANCE_WINDOW ]: result[attr] = schedule[attr] continue # make sure these fields are valid booleans if attr in [ configuration.METRICS, configuration.STOP_NEW_INSTANCES, configuration.USE_MAINTENANCE_WINDOW, configuration.RETAINED_RUNNING, configuration.HIBERNATE, configuration.ENFORCED ]: bool_value = self._ensure_bool(schedule[attr]) if bool_value is None: raise ValueError( ERR_SCHEDULE_INVALID_BOOLEAN.format( schedule[attr], attr)) result[attr] = bool_value continue # overwrite status, now deprecated, use PROP_OVERRIDE_STATUS instead if attr == configuration.OVERWRITE: if configuration.OVERRIDE_STATUS in schedule: raise ValueError( ERR_SCHEDULE_OVERWRITE_OVERRIDE_EXCLUSIVE.format( configuration.OVERWRITE, configuration.OVERRIDE_STATUS)) bool_value = self._ensure_bool(schedule[attr]) if bool_value is None: raise ValueError( ERR_SCHEDULE_INVALID_BOOLEAN.format( schedule[attr], attr)) result[ configuration.OVERRIDE_STATUS] = configuration.OVERRIDE_STATUS_RUNNING if bool_value \ else configuration.OVERRIDE_STATUS_STOPPED continue if attr == configuration.OVERRIDE_STATUS: if configuration.OVERWRITE in schedule: raise ValueError( ERR_SCHEDULE_OVERWRITE_OVERRIDE_EXCLUSIVE.format( configuration.OVERWRITE, configuration.OVERRIDE_STATUS)) if schedule[attr] not in configuration.OVERRIDE_STATUS_VALUES: raise ValueError( ERR_SCHEDULE_INVALID_OVERRIDE.format( schedule[attr], attr, ",".join(configuration.OVERRIDE_STATUS_VALUES))) result[attr] = schedule[attr] continue # description if attr in [ configuration.DESCRIPTION, configuration.SCHEDULE_CONFIG_STACK ]: result[attr] = schedule[attr] continue # validate timezone if attr == configuration.TIMEZONE: timezone = schedule[configuration.TIMEZONE] if not SchedulerConfigBuilder.is_valid_timezone(timezone): raise ValueError( ERR_SCHEDULE_INVALID_TIMEZONE.format( timezone, configuration.TIMEZONE)) result[attr] = timezone # name is mandatory if configuration.NAME not in result: raise ValueError(ERR_SCHEDULE_NAME_MISSING) # if there is no overwrite there must be at least one period if configuration.OVERRIDE_STATUS not in schedule: if configuration.PERIODS not in schedule or len( schedule[configuration.PERIODS]) == 0: raise ValueError(ERR_SCHEDULE_NO_PERIOD) # validate if periods are in configuration if configuration.PERIODS in result: # get list of all configured periods periods = [p[configuration.NAME] for p in self._list_periods()] for period in result[configuration.PERIODS]: if period.split( configuration.INSTANCE_TYPE_SEP)[0] not in periods: raise ValueError( ERR_SCHEDULE_PERIOD_DOES_NOT_EXISTS.format(period)) # indicates this s a schedule result[ConfigAdmin.TYPE_ATTR] = "schedule" return result
def update_config(self, **settings): """ Updates configuration, validates new values :param settings: settings values :return: updated values """ valid_attributes = [ configuration.METRICS, configuration.CROSS_ACCOUNT_ROLES, configuration.DEFAULT_TIMEZONE, configuration.REGIONS, configuration.SCHEDULE_LAMBDA_ACCOUNT, configuration.TAGNAME, configuration.TRACE, ConfigAdmin.TYPE_ATTR, configuration.SCHEDULED_SERVICES, configuration.SCHEDULE_CLUSTERS, configuration.CREATE_RDS_SNAPSHOT, configuration.STARTED_TAGS, configuration.STOPPED_TAGS ] checked_settings = {} for attr in settings: if attr in [ConfigAdmin.TYPE_ATTR, configuration.NAME]: continue # only valid fields if attr not in valid_attributes: raise ValueError(ERR_UPDATE_UNKNOWN_PARAMETER.format(attr)) # remove None fields if settings[attr] is None: continue # remove empty strings if len(str(settings[attr])) == 0: continue # make sure these fields are set as sets if attr in [ configuration.REGIONS, configuration.CROSS_ACCOUNT_ROLES, configuration.SCHEDULED_SERVICES ]: temp = self._ensure_set(settings[attr]) if len(settings[attr]) > 0: checked_settings[attr] = temp continue # make sure these fields are valid booleans if attr in [ configuration.METRICS, configuration.TRACE, configuration.SCHEDULE_LAMBDA_ACCOUNT, configuration.CREATE_RDS_SNAPSHOT, configuration.SCHEDULE_CLUSTERS ]: bool_value = self._ensure_bool(settings[attr]) if bool_value is None: raise ValueError( ERR_UPDATE_INVALID_BOOL_PARAM.format( settings[attr], attr)) checked_settings[attr] = bool_value continue # validate timezone if attr == configuration.DEFAULT_TIMEZONE: default_tz = settings[configuration.DEFAULT_TIMEZONE] if not SchedulerConfigBuilder.is_valid_timezone(default_tz): raise ValueError( ERR_UPDATE_INVALID_TZ_PARAMETER.format( default_tz, configuration.DEFAULT_TIMEZONE)) checked_settings[attr] = default_tz continue checked_settings[attr] = settings[attr] if configuration.TAGNAME not in settings: raise ValueError(ERR_UPDATE_TAGNAME_EMPTY) for service in settings.get(configuration.SCHEDULED_SERVICES, []): if service not in ConfigAdmin.SUPPORTED_SERVICES: raise ValueError( ERR_UPDATE_UNKNOWN_SERVICE.format(service)) # keys for config item checked_settings[ConfigAdmin.TYPE_ATTR] = "config" checked_settings[configuration.NAME] = "scheduler" self._table.put_item_with_retries(Item=checked_settings) return ConfigAdmin._for_output(checked_settings)