コード例 #1
0
def test_get_desired_state_and_type_2(mocker):
    instance = {}
    schedule = InstanceSchedule(name='test-1',
                                periods={},
                                timezone='UTC',
                                override_status=None,
                                description=None,
                                use_metrics=None,
                                stop_new_instances=None,
                                schedule_dt=None,
                                use_maintenance_window=True,
                                ssm_maintenance_window=True,
                                enforced=False,
                                hibernate=False,
                                retain_running=False)
    instance['maintenance_window'] = None
    instance["account"] = 'test'
    instance["region"] = 'us-east-1'
    instance["service"] = 'ec2'
    instance["id"] = 'ut12y21232u'
    inst = as_namedtuple('ec2' + "Instance", instance, excludes=["tags"])
    ec2_service = Ec2Service()
    scheduler_configuration = {}
    scheduler = InstanceScheduler(ec2_service, scheduler_configuration)
    mocker.patch.object(scheduler, '_logger')
    inst_state, inst_type = scheduler.get_desired_state_and_type(
        schedule, inst)
    assert inst_state == 'stopped'
コード例 #2
0
    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
コード例 #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
コード例 #4
0
    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
コード例 #5
0
    def _build_schedule(self, schedule_config, dflt_tz, scheduler_use_config,
                        dt):

        # gets the timezone
        def get_timezone(schedule_configuration):
            schedule_timezone = schedule_configuration.get(
                configuration.TIMEZONE)
            if not schedule_timezone:
                schedule_timezone = dflt_tz

            validated = SchedulerConfigBuilder.validated_timezone(
                schedule_timezone)
            if validated is None:
                raise ValueError(
                    MSG_INVALID_SCHEDULE_TIMEZONE.format(
                        schedule_timezone, schedule_configuration))
            return validated

        def get_schedule_name(config):
            schedule_name = config.get(configuration.NAME, None)
            if not schedule_name:
                raise ValueError(MSG_NAME_MISSING_IN_SCHEDULE.format(config))
            return schedule_name

        def get_override_status(config):
            if configuration.OVERWRITE in config:
                if configuration.OVERRIDE_STATUS in config:
                    raise ValueError(
                        MSG_OVERWRITE_OVERRIDE_MUTUAL_EXCLUSIVE.format(
                            configuration.OVERWRITE,
                            configuration.OVERRIDE_STATUS))
                overwrite = config[configuration.OVERWRITE]
                return configuration.OVERRIDE_STATUS_RUNNING if overwrite else configuration.OVERRIDE_STATUS_STOPPED
            status = config.get(configuration.OVERRIDE_STATUS, None)
            if status is not None and status not in configuration.OVERRIDE_STATUS_VALUES:
                raise ValueError(
                    MSG_INVALID_OVERRIDE_STATUS.format(
                        status, configuration.OVERRIDE_STATUS,
                        ",".join(configuration.OVERRIDE_STATUS_VALUES)))
            return status

        try:

            timezone = get_timezone(schedule_config)
            override_status = get_override_status(schedule_config)
            periods_for_schedule = []

            # ignore periods if there is an always on or if override_status option is used
            if not override_status:
                # use current date and time for timezone of schedule
                current_schema_dt = dt.now(
                    SchedulerConfigBuilder._get_timezone(timezone))
                periods_for_schedule = self._get_schedule_periods(
                    schedule_config, current_schema_dt)

            return InstanceSchedule(
                name=get_schedule_name(schedule_config),
                periods=periods_for_schedule,
                timezone=timezone,
                override_status=override_status,
                description=schedule_config.get(configuration.DESCRIPTION, ""),
                use_metrics=schedule_config.get(configuration.METRICS,
                                                scheduler_use_config),
                stop_new_instances=schedule_config.get(
                    configuration.STOP_NEW_INSTANCES, True),
                use_maintenance_window=schedule_config.get(
                    configuration.USE_MAINTENANCE_WINDOW, False),
                ssm_maintenance_window=schedule_config.get(
                    configuration.SSM_MAINTENANCE_WINDOW, None),
                enforced=schedule_config.get(configuration.ENFORCED, False),
                hibernate=schedule_config.get(configuration.HIBERNATE, False),
                retain_running=schedule_config.get(
                    configuration.RETAINED_RUNNING))

        except ValueError as ex:
            if self._logger is not None:
                self._logger.error(str(ex))
            return None