def build_schedule_from_maintenance_window(period_str):
        """
        Builds a Instance running schedule based on an RDS preferred maintenance windows string in format ddd:hh:mm-ddd:hh:mm
        :param period_str: rds maintenance windows string
        :return: Instance running schedule with timezone UTC
        """

        # get elements of period
        start_string, stop_string = period_str.split("-")
        start_day_string, start_hhmm_string = start_string.split(":", 1)
        stop_day_string, stop_hhmm_string = stop_string.split(":", 1)

        # weekday set builder
        weekdays_builder = WeekdaySetBuilder()

        start_weekday = weekdays_builder.build(start_day_string)
        start_time = SchedulerConfigBuilder.get_time_from_string(start_hhmm_string)
        end_time = SchedulerConfigBuilder.get_time_from_string(stop_hhmm_string)

        # windows with now day overlap, can do with one period for schedule
        if start_day_string == stop_day_string:
            periods = [
                {
                    "period": RunningPeriod(name=MAINTENANCE_PERIOD_NAME,
                                            begintime=start_time,
                                            endtime=end_time,
                                            weekdays=start_weekday)
                }]
        else:
            # window with day overlap, need two periods for schedule
            end_time_day1 = SchedulerConfigBuilder.get_time_from_string("23:59")
            begin_time_day2 = SchedulerConfigBuilder.get_time_from_string("00:00")
            stop_weekday = weekdays_builder.build(stop_day_string)
            periods = [
                {
                    "period": RunningPeriod(name=MAINTENANCE_PERIOD_NAME + "-{}".format(start_day_string),
                                            begintime=start_time,
                                            endtime=end_time_day1,
                                            weekdays=start_weekday),
                    "instancetype": None
                },
                {
                    "period": RunningPeriod(name=MAINTENANCE_PERIOD_NAME + "-{}".format(stop_day_string),
                                            begintime=begin_time_day2,
                                            endtime=end_time,
                                            weekdays=stop_weekday),
                    "instancetype": None
                }]

        # create schedule with period(s) and timezone UTC
        schedule = InstanceSchedule(name=MAINTENANCE_SCHEDULE_NAME, periods=periods, timezone="UTC", enforced=True)

        return schedule
    def _build_period(cls, period_configuration, dt):
        def get_periodname(config):
            period_name = config.get(configuration.NAME)
            if not period_name:
                raise ValueError(MSG_NAME_MISSING_IN_PERIOD.format(config))
            return period_name

        # reads a start and end time from config
        def get_begin_and_end(period_name, config):

            begin = SchedulerConfigBuilder.get_time_from_string(
                config.get(configuration.BEGINTIME))
            end = SchedulerConfigBuilder.get_time_from_string(
                config.get(configuration.ENDTIME))
            if (begin and end) and begin > end:
                raise ValueError(
                    MSG_BEGIN_MUST_BEFORE_END.format(begin, end, period_name))
            return begin, end

        def build_period_config_set(period_config, set_builder, config_name):
            config_set = period_config.get(config_name)
            if config_set:
                return set_builder.build(config_set)
            else:
                return None

        name = get_periodname(period_configuration)
        begin_time, end_time = get_begin_and_end(name, period_configuration)

        week_days = build_period_config_set(
            period_configuration,
            WeekdaySetBuilder(year=dt.year, month=dt.month, day=dt.day),
            configuration.WEEKDAYS)
        months = build_period_config_set(period_configuration,
                                         MonthSetBuilder(),
                                         configuration.MONTHS)
        monthdays = build_period_config_set(
            period_configuration,
            MonthdaySetBuilder(year=dt.year, month=dt.month),
            configuration.MONTHDAYS)

        return RunningPeriod(name=name,
                             begintime=begin_time,
                             endtime=end_time,
                             weekdays=week_days,
                             months=months,
                             monthdays=monthdays)
Exemple #3
0
    def _schedule_from_maint_window(self, name, start, hours, interval):
        start_dt = start.replace(second=0, microsecond=0)
        start_before_begin = min(interval, 10)
        begin_dt = start_dt - timedelta(minutes=start_before_begin)
        end_dt = start_dt + timedelta(hours=hours)
        if begin_dt.day == end_dt.day:
            periods = [{
                "period":
                RunningPeriod(name="{}-period".format(name),
                              begintime=begin_dt.time(),
                              endtime=end_dt.time(),
                              monthdays={begin_dt.day},
                              months={begin_dt.month}),
                "instancetype":
                None
            }]
        elif end_dt - begin_dt <= timedelta(hours=24):
            periods = [{
                "period":
                RunningPeriod(
                    name="{}-period-1".format(name),
                    begintime=begin_dt.time(),
                    endtime=SchedulerConfigBuilder.get_time_from_string(
                        "23:59"),
                    monthdays={begin_dt.day},
                    months={begin_dt.month}),
                "instancetype":
                None
            }, {
                "period":
                RunningPeriod(
                    name="{}-period-2".format(name),
                    begintime=SchedulerConfigBuilder.get_time_from_string(
                        "00:00"),
                    endtime=end_dt.time(),
                    monthdays={end_dt.day},
                    months={end_dt.month}),
                "instancetype":
                None
            }]
        else:
            periods = [{
                "period":
                RunningPeriod(
                    name="{}-period-1".format(name),
                    begintime=begin_dt.time(),
                    endtime=SchedulerConfigBuilder.get_time_from_string(
                        "23:59"),
                    monthdays={begin_dt.day},
                    months={begin_dt.month}),
                "instancetype":
                None
            }, {
                "period":
                RunningPeriod(name="{}-period-2".format(name),
                              monthdays={(end_dt - timedelta(days=1)).day},
                              months={(end_dt - timedelta(days=1)).month}),
                "instancetype":
                None
            }, {
                "period":
                RunningPeriod(
                    name="{}-period-3".format(name),
                    begintime=SchedulerConfigBuilder.get_time_from_string(
                        "00:00"),
                    endtime=end_dt.time(),
                    monthdays={end_dt.day},
                    months={end_dt.month}),
                "instancetype":
                None
            }]

        schedule = InstanceSchedule(
            name=name,
            timezone="UTC",
            description="{} maintenance window".format(name),
            enforced=True,
            periods=periods)

        self._logger.info(INF_MAINT_WINDOW, name, begin_dt.isoformat(),
                          end_dt.isoformat())

        return schedule
    def configuration_from_dict(d):
        """
        This method builds a configuration object instance that is passed as a dictionary in the event of a lambda function
        :param d:
        :return:
        """

        config_args = {}
        for attr in [
                ATTR_TAGNAME, ATTR_DEFAULT_TIMEZONE, ATTR_TRACE,
                ATTR_ENABLE_SSM_MAINTENANCE_WINDOWS, ATTR_SCHEDULE_CLUSTERS,
                ATTR_CREATE_RDS_SNAPSHOT, ATTR_USE_METRICS,
                ATTR_SCHEDULE_LAMBDA_ACCOUNT, ATTR_STARTED_TAGS,
                ATTR_STOPPED_TAGS
        ]:
            config_args[attr] = d.get(attr, None)

        for attr in [
                ATTR_REGIONS, ATTR_CROSS_ACCOUNT_ROLES, ATTR_SCHEDULED_SERVICES
        ]:
            config_args[attr] = set(d.get(attr, []))

        periods = {}

        for period_name in d.get(ATTR_PERIODS, {}):
            period_data = d[ATTR_PERIODS][period_name]
            period_args = {ATTR_NAME: period_name}

            for attr in [ATTR_BEGINTIME, ATTR_ENDTIME]:
                if attr in period_data:
                    period_args[
                        attr] = SchedulerConfigBuilder.get_time_from_string(
                            period_data[attr])

            for attr in [ATTR_WEEKDAYS, ATTR_MONTHDAYS, ATTR_MONTHS]:
                if attr in period_data:
                    period_args[attr] = set(period_data.get(attr, None))

            period = RunningPeriod(**period_args)
            periods[period_name] = period

        config_args[ATTR_SCHEDULES] = {}

        for schedule_name in d.get(ATTR_SCHEDULES, {}):
            schedule_args = {}
            schedule_data = d[ATTR_SCHEDULES][schedule_name]
            for attr in [
                    ATTR_NAME, ATTR_TIMEZONE, ATTR_OVERRIDE_STATUS,
                    ATTR_STOP_NEW_INSTANCES, ATTR_USE_METRICS, ATTR_ENFORCED,
                    ATTR_HIBERNATE, ATTR_RETAIN_RUNNING,
                    ATTR_SSM_MAINTENANCE_WINDOW, ATTR_USE_MAINTENANCE_WINDOW
            ]:
                schedule_args[attr] = schedule_data.get(attr, None)

            for attr in [ATTR_SCHEDULE_DT]:
                if attr in schedule_data:
                    schedule_args[attr] = dateutil.parser.parse(
                        schedule_data[attr])

            if schedule_args[ATTR_OVERRIDE_STATUS] is None:

                schedule_args[ATTR_PERIODS] = []

                for period in schedule_data.get(ATTR_PERIODS):
                    temp = period.split(configuration.INSTANCE_TYPE_SEP)
                    if len(temp) > 1:
                        name = temp[0]
                        instance_type = temp[1]
                    else:
                        name = period
                        instance_type = None
                    schedule_args[ATTR_PERIODS].append({
                        ATTR_PERIOD:
                        periods[name],
                        ATTR_INSTANCE_TYPE:
                        instance_type
                    })

            schedule = InstanceSchedule(**schedule_args)
            config_args[ATTR_SCHEDULES][schedule_name] = schedule

        config = SchedulerConfig(**config_args)

        return config