Пример #1
0
    def _run_step_in_regions(self, action, step, regions):
        """
        Called from :py:meth:`~.run`; run a given step in all applicable /
        specified regions.

        :param action: Name of the action to do, "run" or "dryrun"
        :type action: str
        :param step: A reference to the :py:class:`~.BaseStep` subclass to run
        :type step: object
        :param regions: list of string region names to run in
        :type regions: list
        """
        for r_idx, region_name in enumerate(regions):
            if step.name in ['policygen', 'dryrun-diff']:
                # Some steps need a config with %%AWS_REGION%% un-interpolated
                region_conf = self.config
            else:
                region_conf = self.config.config_for_region(region_name)
            if not step.run_in_region(region_name, region_conf):
                logger.info(
                    bold('SKIPPING Step %s in REGION %d of %d (%s)' %
                         (step.name, r_idx + 1, len(regions), region_name)))
                continue
            logger.info(
                bold('Step %s in REGION %d of %d (%s)' %
                     (step.name, r_idx + 1, len(regions), region_name)))
            if action == 'run':
                step(region_name, region_conf).run()
            else:
                step(region_name, region_conf).dryrun()
            sys.stdout.flush()
            sys.stderr.flush()
Пример #2
0
    def test_run_in_regions_dryrun_skip_some(self):
        m_conf = Mock(spec_set=ManheimConfig)
        m_conf_r1 = Mock(spec_set=ManheimConfig)
        m_conf_r2 = Mock(spec_set=ManheimConfig)
        m_conf_r3 = Mock(spec_set=ManheimConfig)

        def se_conf_for_region(rname):
            if rname == 'r1':
                return m_conf_r1
            if rname == 'r2':
                return m_conf_r2
            if rname == 'r3':
                return m_conf_r3

        m_conf.config_for_region.side_effect = se_conf_for_region

        with patch('%s.logger' % pbm, autospec=True) as mock_logger:
            with patch('%s.ManheimConfig.from_file' % pbm) as mock_cff:
                mock_cff.return_value = m_conf
                runner.CustodianRunner('acctName')._run_step_in_regions(
                    'dryrun', self.cls2, ['r2', 'r3'])
        assert self.cls2.mock_calls == [
            call.run_in_region('r2', m_conf_r2),
            call.run_in_region('r3', m_conf_r3),
            call('r3', m_conf_r3),
            call().dryrun()
        ]
        assert m_conf.config_for_region.mock_calls == [call('r2'), call('r3')]
        assert mock_logger.mock_calls == [
            call.info(bold('SKIPPING Step cls2 in REGION 1 of 2 (r2)')),
            call.info(bold('Step cls2 in REGION 2 of 2 (r3)'))
        ]
Пример #3
0
    def run(self, action, regions=[], step_names=[], skip_steps=[]):
        """
        Main method to run all steps. This calls :py:meth:`~._steps_to_run`
        to determine which step classes to run and the order to run them in,
        and then loops through that list calling the :py:meth:`~.BaseStep.run`
        or :py:meth:`~.BaseStep.dryrun` method on each of them, according to the
        ``action`` specified.

        :param action: Name of the action to do, "run" or "dryrun"
        :type action: str
        :param regions: list of string region names to run in; if left empty,
          run in all regions listed in config file
        :type regions: list
        :param step_names: list of string step names to run; if not specified,
          will run all defined steps. Steps are always run in the order defined
          in :py:attr:`~.ordered_step_classes`.
        :type step_names: list
        :param skip_steps: list of string step names to skip running
        :type skip_steps: list
        """
        self._validate_account()
        to_run = self._steps_to_run(step_names, skip_steps)
        if to_run == self.ordered_step_classes:
            logger.info(bold(
                'Beginning %s - %d steps' % (action, len(to_run))
            ))
        else:
            logger.info(bold(
                'Beginning %s - %d of %d steps selected' % (
                    action, len(to_run), len(self.ordered_step_classes)
                )
            ))
        if regions:
            if not set(regions).issubset(set(self.config.regions)):
                raise RuntimeError(
                    'ERROR: All specified region names must be listed in the '
                    '"regions" section of the config file '
                    '(%s)' % self._config_path
                )
        else:
            # use all regions from config file
            regions = self.config.regions
        for idx, step in enumerate(to_run):
            logger.info(bold(
                'Step %d of %d - %s' % (idx + 1, len(to_run), step.name)
            ))
            self._run_step_in_regions(action, step, regions)
        logger.info(bold('SUCCESS: All %d steps complete!' % len(to_run)))
Пример #4
0
 def test_run_invalid_region_name(self):
     m_conf = Mock(spec_set=ManheimConfig)
     type(m_conf).regions = PropertyMock(return_value=['r1', 'r2', 'r3'])
     with patch('%s.CustodianRunner.ordered_step_classes' % pbm,
                self.steps):
         with patch.multiple('%s.CustodianRunner' % pbm,
                             autospec=True,
                             _steps_to_run=DEFAULT,
                             _run_step_in_regions=DEFAULT,
                             _validate_account=DEFAULT) as mocks:
             mocks['_steps_to_run'].return_value = [self.cls2, self.cls3]
             with patch('%s.logger' % pbm, autospec=True) as mock_logger:
                 with patch('%s.ManheimConfig.from_file' % pbm) as mock_cff:
                     mock_cff.return_value = m_conf
                     with pytest.raises(RuntimeError) as exc:
                         cls = runner.CustodianRunner('acctName')
                         cls.run('dryrun',
                                 regions=['notValid'],
                                 step_names=['cls2', 'cls3', 'cls4'],
                                 skip_steps=['cls4'])
     assert str(exc.value) == 'ERROR: All specified region names must be ' \
                              'listed in the "regions" section of the ' \
                              'config file (manheim-c7n-tools.yml)'
     assert mocks['_steps_to_run'].mock_calls == [
         call(cls, ['cls2', 'cls3', 'cls4'], ['cls4'])
     ]
     assert mocks['_run_step_in_regions'].mock_calls == []
     assert self.cls1.mock_calls == []
     assert self.cls2.mock_calls == []
     assert self.cls3.mock_calls == []
     assert self.cls4.mock_calls == []
     assert mock_logger.mock_calls == [
         call.info(bold('Beginning dryrun - 2 of 4 steps selected'))
     ]
     assert mocks['_validate_account'].mock_calls == [call(cls)]
Пример #5
0
    def test_run_in_regions_policygen_run(self):
        m_conf = Mock(spec_set=ManheimConfig)
        m_conf_r1 = Mock(spec_set=ManheimConfig)
        m_conf_r2 = Mock(spec_set=ManheimConfig)
        m_conf_r3 = Mock(spec_set=ManheimConfig)

        def se_conf_for_region(rname):
            if rname == 'r1':
                return m_conf_r1
            if rname == 'r2':
                return m_conf_r2
            if rname == 'r3':
                return m_conf_r3

        m_conf.config_for_region.side_effect = se_conf_for_region

        with patch('%s.logger' % pbm, autospec=True) as mock_logger:
            with patch('%s.ManheimConfig.from_file' % pbm) as mock_cff:
                mock_cff.return_value = m_conf
                with patch('%s.PolicygenStep' % pbm,
                           autospec=True) as mock_pgs:
                    type(mock_pgs).name = PropertyMock(
                        return_value='policygen')
                    mock_pgs.run_in_region.return_value = True
                    runner.CustodianRunner('acctName')._run_step_in_regions(
                        'run', mock_pgs, ['r1', 'r2', 'r3'])
        assert mock_pgs.mock_calls == [
            call.run_in_region('r1', m_conf),
            call('r1', m_conf),
            call().run(),
            call.run_in_region('r2', m_conf),
            call('r2', m_conf),
            call().run(),
            call.run_in_region('r3', m_conf),
            call('r3', m_conf),
            call().run()
        ]
        assert m_conf.config_for_region.mock_calls == []
        assert mock_logger.mock_calls == [
            call.info(bold('Step policygen in REGION 1 of 3 (r1)')),
            call.info(bold('Step policygen in REGION 2 of 3 (r2)')),
            call.info(bold('Step policygen in REGION 3 of 3 (r3)'))
        ]
Пример #6
0
 def test_run_dryrun_some_steps_some_regions(self):
     m_conf = Mock(spec_set=ManheimConfig)
     type(m_conf).regions = PropertyMock(return_value=['r1', 'r2', 'r3'])
     with patch('%s.CustodianRunner.ordered_step_classes' % pbm,
                self.steps):
         with patch.multiple('%s.CustodianRunner' % pbm,
                             autospec=True,
                             _steps_to_run=DEFAULT,
                             _run_step_in_regions=DEFAULT,
                             _validate_account=DEFAULT) as mocks:
             mocks['_steps_to_run'].return_value = [self.cls2, self.cls3]
             with patch('%s.logger' % pbm, autospec=True) as mock_logger:
                 with patch('%s.ManheimConfig.from_file' % pbm) as mock_cff:
                     mock_cff.return_value = m_conf
                     cls = runner.CustodianRunner('aName')
                     cls.run('dryrun',
                             regions=['r2'],
                             step_names=['cls2', 'cls3', 'cls4'],
                             skip_steps=['cls4'])
     assert mocks['_steps_to_run'].mock_calls == [
         call(cls, ['cls2', 'cls3', 'cls4'], ['cls4'])
     ]
     assert mocks['_run_step_in_regions'].mock_calls == [
         call(cls, 'dryrun', self.cls2, ['r2']),
         call(cls, 'dryrun', self.cls3, ['r2'])
     ]
     assert self.cls1.mock_calls == []
     assert self.cls2.mock_calls == []
     assert self.cls3.mock_calls == []
     assert self.cls4.mock_calls == []
     assert mock_logger.mock_calls == [
         call.info(bold('Beginning dryrun - 2 of 4 steps selected')),
         call.info(bold('Step 1 of 2 - cls2')),
         call.info(bold('Step 2 of 2 - cls3')),
         call.info(bold('SUCCESS: All 2 steps complete!'))
     ]
     assert mock_cff.mock_calls == [call('manheim-c7n-tools.yml', 'aName')]
     assert mocks['_validate_account'].mock_calls == [call(cls)]
Пример #7
0
 def test_bold(self):
     assert bold('foo') == "\033[1mfoo\033[0m"