Example #1
0
 def test__get_step_implementer_name_class_does_not_exist_given_module_path(self):
     with self.assertRaisesRegex(
             StepRunnerException,
             r"Could not dynamically load step \(foo\) step implementer"
             r" \(tests.helpers.sample_step_implementers.DoesNotExist\) from module \(tests.helpers.sample_step_implementers\) with class name \(DoesNotExist\)"):
         StepRunner._StepRunner__get_step_implementer_class('foo',
                                                              'tests.helpers.sample_step_implementers.DoesNotExist')
Example #2
0
    def _run_step_implementer_test(
        self,
        config,
        step,
        expected_step_results,
        test_dir,
        environment=None
    ):
        working_dir_path = os.path.join(test_dir.path, 'step-runner-working')
        factory = StepRunner(
            config=config,
            results_file_name='step-runner-results.yml',
            work_dir_path=working_dir_path
        )
        factory.run_step(
            step_name=step,
            environment=environment
        )

        pickle = f'{working_dir_path}/step-runner-results.pkl'
        workflow_result = WorkflowResult.load_from_pickle_file(pickle)

        step_result = workflow_result.get_step_result(
            step_name=step
        )
        self.assertEqual(step_result, expected_step_results)
Example #3
0
 def test_run_step_config_only_sub_step_and_is_dict_rather_then_array(self):
     config = {
         'step-runner-config': {
             'foo': {
                 'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer'
             }
         }
     }
     with TempDirectory() as temp_dir:
         factory = StepRunner(config)
         factory.run_step('foo')
Example #4
0
    def test_run_step_with_no_config(self):
        config = {
            'step-runner-config': {
            }
        }

        factory = StepRunner(config)

        with self.assertRaisesRegex(
           AssertionError,
               r"Can not run step \(foo\) because no step configuration provided."):
               factory.run_step('foo')
Example #5
0
 def test_run_step_config_implementer_specified_and_no_sub_step_config_specified_StepImplementer(self):
     config = {
         'step-runner-config': {
             'foo': [
                 {
                     'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer'
                 }
             ]
         }
     }
     with TempDirectory() as temp_dir:
         factory = StepRunner(config)
         factory.run_step('foo')
Example #6
0
 def test__get_step_implementer_name_class_is_not_subclass_of_StepImplementer(self):
     with self.assertRaisesRegex(
             StepRunnerException,
             re.compile(
                 r"Step \(foo\) is configured to use step implementer "
                 r"\(tests.helpers.sample_step_implementers.NotSubClassOfStepImplementer\) "
                 r"from module \(tests.helpers.sample_step_implementers\) with class name "
                 r"\(NotSubClassOfStepImplementer\), and dynamically loads as class "
                 r"\(<class 'tests.helpers.sample_step_implementers.NotSubClassOfStepImplementer'>\) "
                 r"which is not a subclass of required parent class "
                 r"\(<class 'ploigos_step_runner.step_implementer.StepImplementer'>\)."
             )
     ):
         StepRunner._StepRunner__get_step_implementer_class('foo',
                                                              'tests.helpers.sample_step_implementers.NotSubClassOfStepImplementer')
Example #7
0
 def test__get_step_implementer_class_exists_include_module(self):
     self.assertIsNotNone(
         StepRunner._StepRunner__get_step_implementer_class(
             'foo',
             'tests.helpers.sample_step_implementers.FooStepImplementer'
         )
     )
Example #8
0
    def test_init_valid_config(self):
        config = {
            'step-runner-config': {
            }
        }

        StepRunner(config)
Example #9
0
    def test_run_step_multiple_sub_steps_first_sub_step_fail_contine_sub_steps_on_failure_str(
        self,
        foo_step_implementer_run_step_mock,
        foo_step_implementer2_run_step_mock
    ):
        config = {
            'step-runner-config': {
                'foo': [
                    {
                        'name': 'Mock Sub Step 1',
                        'continue-sub-steps-on-failure': 'true',
                        'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer'
                    },
                    {
                        'name': 'Mock Sub Step 2',
                        'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer2'
                    }
                ]
            }
        }

        # mock return value
        mock_sub_step_1_result = StepResult(
            step_name='foo',
            sub_step_name='Mock Sub Step 1',
            sub_step_implementer_name='tests.helpers.sample_step_implementers.FooStepImplementer'
        )
        mock_sub_step_1_result.success = False
        mock_sub_step_2_result = StepResult(
            step_name='foo',
            sub_step_name='Mock Sub Step 2',
            sub_step_implementer_name='tests.helpers.sample_step_implementers.FooStepImplementer'
        )
        mock_sub_step_2_result.success = True

        foo_step_implementer_run_step_mock.return_value = mock_sub_step_1_result
        foo_step_implementer2_run_step_mock.return_value = mock_sub_step_2_result

        # run test
        step_runner = StepRunner(config)
        actual_success = step_runner.run_step('foo')

        # validate
        self.assertFalse(actual_success)
        foo_step_implementer_run_step_mock.assert_called_once()
        foo_step_implementer2_run_step_mock.assert_called_once()
Example #10
0
    def test_run_step_config_specified_StepImplementer_does_not_exist(self):
        config = {
            'step-runner-config': {
                'foo': [
                    {
                        'implementer': 'DoesNotExist'
                    }
                ]
            }
        }

        factory = StepRunner(config)

        with self.assertRaisesRegex(
            StepRunnerException,
                r"Could not dynamically load step \(foo\) step implementer \(DoesNotExist\)"
                r" from module \(ploigos_step_runner.step_implementers.foo\) with class name \(DoesNotExist\)"):
            factory.run_step('foo')
Example #11
0
    def test_init_invalid_config(self):
        config = {
            'blarg-config': {
            }
        }

        with self.assertRaisesRegex(
                AssertionError,
                r"Failed to add invalid config. "
                r"Missing expected top level key \(step-runner-config\): {'blarg-config': {}}"):
            StepRunner(config)
Example #12
0
 def test_init_with_config_object(self):
     config = {
         Config.CONFIG_KEY: {
             'step-foo': {
                 'implementer': 'foo'
             }
         }
     }
     config = Config(config)
     factory = StepRunner(config)
     self.assertEqual(factory.config, config)
Example #13
0
    def test_init_with_dict(self):
        config = {
            Config.CONFIG_KEY: {
                'step-foo': {
                    'implementer': 'foo'
                }
            }
        }

        factory = StepRunner(config)
        sub_step_configs = factory.config.get_sub_step_configs('step-foo')
        self.assertEqual(len(sub_step_configs), 1)
Example #14
0
def main(argv=None):
    """Main entry point for Ploigos step runner.
    """
    parser = argparse.ArgumentParser(description='Ploigos Step Runner (psr)')
    parser.add_argument(
        '-s',
        '--step',
        required=True,
        help='Workflow step to run'
    )
    parser.add_argument(
        '-e',
        '--environment',
        required=False,
        help='The environment to run this step against.'
    )
    parser.add_argument(
        '-c',
        '--config',
        required=True,
        nargs='+',
        help='Workflow configuration files, or directories containing files, in yml or json'
    )
    parser.add_argument(
        '--step-config',
        metavar='STEP_CONFIG_KEY=STEP_CONFIG_VALUE',
        nargs='+',
        help='Override step config provided by the given config-file with these arguments.',
        action=ParseKeyValueArge
    )
    args = parser.parse_args(argv)

    obfuscated_stdout = TextIOSelectiveObfuscator(sys.stdout)
    obfuscated_stderr = TextIOSelectiveObfuscator(sys.stderr)
    DecryptionUtils.register_obfuscation_stream(obfuscated_stdout)
    DecryptionUtils.register_obfuscation_stream(obfuscated_stderr)

    with redirect_stdout(obfuscated_stdout), redirect_stderr(obfuscated_stderr):
        # validate args
        for config_file in args.config:
            if not os.path.exists(config_file) or os.stat(config_file).st_size == 0:
                print_error('specified -c/--config must exist and not be empty')
                sys.exit(101)

        try:
            config = Config(args.config)
        except (ValueError, AssertionError) as error:
            print_error(f"specified -c/--config is invalid configuration: {error}")
            sys.exit(102)

        config.set_step_config_overrides(args.step, args.step_config)
        # it is VERY important that the working dir be an absolute path because some
        # commands (looking at you maven) will change the context of relative paths on you
        step_runner = StepRunner(
            config=config,
            work_dir_path=os.path.abspath('step-runner-working')
        )

        try:
            if not step_runner.run_step(args.step, args.environment):
                print_error(f"Step {args.step} not successful")
                sys.exit(200)

        except Exception as error:  # pylint: disable=broad-except
            print_error(f"Fatal error calling step ({args.step}): {str(error)}")
            track = traceback.format_exc()
            print(track)
            sys.exit(300)
Example #15
0
 def test__get_step_implementer_class_exists_defaultt_steps_module(self):
     self.assertIsNotNone(
         StepRunner._StepRunner__get_step_implementer_class('container_image_static_compliance_scan', 'OpenSCAP')
     )
Example #16
0
 def test__get_step_implementer_class_does_not_exist_using_default_steps_module(self):
     with self.assertRaisesRegex(
             StepRunnerException,
             r"Could not dynamically load step \(foo\) step implementer \(bar\) "
             r"from module \(ploigos_step_runner.step_implementers.foo\) with class name \(bar\)"):
         StepRunner._StepRunner__get_step_implementer_class('foo', 'bar')