Exemple #1
0
    def render_single_yaml(
        self,
        input_path: str,
        output_path: str,
        checker: BaseChecker = None,
        raw: bool = False,
    ) -> None:
        """
        Read in single YAML file from specified path, render environment variables,
        then write out to a known location in the working dir.
        """
        self.logger.info("Rendering YAML at %s to %s", input_path, output_path)

        with open(input_path, "r") as fh:
            content = fh.read()

        if not raw:
            env = dict(get_kv(self.workflow.environment.render(), multiple=True))

            rendered = render(content, env=env)
            rendered = render_jinja(rendered, env=env)
        else:
            rendered = content

        if checker:
            check_errors = checker.check(rendered)

            if check_errors:
                raise errors.ManifestCheck("\n".join(check_errors))

        with open(output_path, "w") as fh:
            fh.write(rendered)
Exemple #2
0
def render_config(workflow: "Workflow", config: dict) -> dict:
    # render the config prior to returning it
    content = yaml_dump(config)
    rendered_content = render(content, env=workflow.environment.data)

    rendered_config = yaml_load(rendered_content)

    print(f"rendered_config={rendered_config}")

    return rendered_config
Exemple #3
0
    def test_multiple_subs_on_same_line(self, *mocks):
        env = {'JOB_NAME': 'the-job', 'BUILD_NUMBER': '1234'}

        content = (
            '      - /tmp/jenkins/${JOB_NAME}/${BUILD_NUMBER}:/usr/local/src/results'
        )

        rendered = utils.render(content, env=env)

        expected = f'      - /tmp/jenkins/{env["JOB_NAME"]}/{env["BUILD_NUMBER"]}:/usr/local/src/results'

        self.assertEqual(expected, rendered)
Exemple #4
0
    def data(self):
        try:
            content = self.load()
        except NoSuchConfig:
            content = {}

        # if the content is empty return immediately
        if not content:
            return content

        rendered = render(content)

        return yaml_load(rendered)
    def render_single_yaml(self, input_path: str, output_path: str) -> None:
        '''
        Read in single YAML file from specified path, render environment variables,
        then write out to a known location in the working dir.
        '''
        self.logger.info("Rendering YAML at %s to %s", input_path, output_path)

        # TODO: Add support for multiple YAML documents in a single file
        with open(input_path, 'r') as fh:
            content = fh.read()

        rendered = render(content, env=self.workflow.environment.data)

        with open(output_path, 'w') as fh:
            fh.write(rendered)
Exemple #6
0
    def get_profile_compose_file(self, profile):
        """
        Processes the profile to generate the compose file
        """
        try:
            os.environ.update(self.env.data)
        except NoSuchConfig as exc:
            if not self.workflow.subcommand.is_env_error_okay(exc):
                raise

        filenames = get_overlay_filenames(profile)

        # merge multiple files together so that deploying stacks works
        # https://github.com/moby/moby/issues/30127
        if len(filenames) > 1:
            yaml_contents = []

            for item in filenames:
                with open(item, 'r') as fh:
                    yaml_contents.append(yaml.load(fh))

            merged = remerge(yaml_contents)
            content = yaml.dump(merged, default_flow_style=False)
        else:
            with open(filenames[0], 'r') as fh:
                content = fh.read()

        fh = tempfile.TemporaryFile(mode='w+')

        # render the file
        try:
            rendered = render(content)
        except EnvError as exc:
            if not self.workflow.subcommand.is_missing_profile_okay(exc):
                raise

            return fh

        fh.write(rendered)
        fh.flush()

        fh.seek(0, 0)

        return fh
Exemple #7
0
    def get_profile_compose_file(self, profile: dict):
        """
        Processes the profile to generate the compose file
        """
        content = self._compile(profile)
        fh = tempfile.TemporaryFile(mode="w+")

        # render the file
        try:
            rendered = render(content, env=self.workflow.environment.data)
        except EnvError as exc:
            if not self.workflow.subcommand.is_missing_profile_okay(exc):
                raise

            return fh

        fh.write(rendered)
        fh.flush()

        fh.seek(0, 0)

        return fh
Exemple #8
0
    def data(self) -> dict:
        """
        Returns the loaded config as a dictionary
        """
        if self._data is not None:
            return self._data

        data = self.load()

        # render placeholders
        for k, v in data.items():
            if not v.startswith(RUNTIME_PLACEHOLDER):
                continue

            location, location_ref = v.split("://", 1)
            location_ref = location_ref or k

            if k not in self._rendered_config:
                self._rendered_config[k] = v

            new_val = os.environ.get(location_ref)
            if new_val is None:
                if (hasattr(self.workflow.args, "action")
                        and self.is_env_modification_action()):
                    new_val = RUNTIME_PLACEHOLDER
                else:
                    raise errors.RuntimeEnvError(
                        f"runtime substitution for {k}={v} not found")

            data[k] = new_val

        # render substitutions
        sub_count = True
        while sub_count:
            # reset the substitution count to break the loop when no subs are made
            sub_count = 0

            for k, v in data.items():
                rendered = utils.render(v, env=data)

                if rendered != v:
                    sub_count += 1

                    if k not in self._rendered_config:
                        self._rendered_config[k] = v

                    data[k] = rendered

        if self.workflow.subcommand.update_version_env_vars:
            # regenerate the full docker image name
            self._docker_image = None

            data.update({
                DOCKER_IMAGE_VAR:
                self.set_docker_tag(self.docker_image),
                VERSION_VAR:
                self.version,
            })

        self._data = data

        return self._data
Exemple #9
0
    def data(self) -> dict:
        """
        Returns the loaded config as a dictionary
        """
        if self._data is not None:
            return self._data

        data = self.load()

        args = self.workflow.args

        action = None
        if 'action' in args:
            action = args.action

        # render placeholders
        for k, v in data.items():
            if not v.startswith('runtime://'):
                continue

            location, location_ref = v.split('://', 1)
            location_ref = location_ref or k

            if k not in self._rendered_config:
                self._rendered_config[k] = v

            new_val = os.environ.get(location_ref)
            if new_val is None:
                raise errors.RuntimeEnvError(
                    f'runtime substitution for {k}={v} not found')

            data[k] = new_val

        # render substitutions
        sub_count = True
        while sub_count:
            # reset the substitution count to break the loop when no subs are made
            sub_count = 0

            for k, v in data.items():
                rendered = utils.render(v, env=data)

                if rendered != v:
                    sub_count += 1

                    if k not in self._rendered_config:
                        self._rendered_config[k] = v

                    data[k] = rendered

        # set defaults when no value is set
        for k, v in self.cf_env.items():
            if k not in data:
                data[k] = v

        if self.workflow.subcommand.update_version_env_vars:
            data.update({
                DOCKER_IMAGE_VAR:
                self.set_docker_tag(self.docker_image),
                VERSION_VAR:
                self.version,
            })

        self._data = data

        return self._data