Ejemplo n.º 1
0
def _parse_chart(
    all_config: Tuple[str, Union[ChartOpts, LocalChartOpts],
                      pulumi.ResourceOptions]
) -> pulumi.Output:
    release_name, config, opts = all_config

    # Create temporary directory and file to hold chart data and override values.
    with NamedTemporaryFile() as overrides:
        with TemporaryDirectory() as chart_dir:
            if isinstance(config, ChartOpts):
                chart_to_fetch = f'{config.repo}/{config.chart}' if config.repo else config.chart

                # Configure fetch options.
                fetch_opts_dict = {}
                if config.fetch_opts is not None:
                    fetch_opts_dict = {
                        k: v
                        for k, v in vars(config.fetch_opts).items()
                        if v is not None
                    }
                fetch_opts_dict["destination"] = chart_dir
                if config.version is not None:
                    fetch_opts_dict["version"] = config.version
                fetch_opts = FetchOpts(**fetch_opts_dict)

                # Fetch the chart.
                _fetch(chart_to_fetch, fetch_opts)
                fetched_chart_name = os.listdir(chart_dir)[0]
                chart = os.path.join(chart_dir, fetched_chart_name)
            else:
                chart = config.path

            default_values = os.path.join(chart, 'values.yaml')

            # Write overrides file.
            vals = config.values if config.values is not None else {}
            data = json.dumps(vals).encode('utf-8')
            overrides.write(data)

            namespace_arg = ['--namespace', config.namespace
                             ] if config.namespace else []

            # Use 'helm template' to create a combined YAML manifest.
            cmd = [
                'helm', 'template', chart, '--name', release_name, '--values',
                default_values, '--values', overrides.name
            ]
            cmd.extend(namespace_arg)

            output = subprocess.run(cmd,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE,
                                    universal_newlines=True,
                                    check=True)
            yaml_str: str = output.stdout

            # Parse the manifest and create the specified resources.
            return _parse_yaml_document(yaml.safe_load_all(yaml_str), opts,
                                        config.transformations)
Ejemplo n.º 2
0
def _parse_chart(all_config: Tuple[str, Union[ChartOpts, LocalChartOpts], pulumi.ResourceOptions]) -> pulumi.Output:
    release_name, config, opts = all_config

    # Create temporary directory and file to hold chart data and override values.
    # Note: We're intentionally using the lower-level APIs here because the async Outputs are being handled in
    # a different scope, which was causing the temporary files/directory to be deleted before they were referenced
    # in the Output handlers. We manually clean these up once we're done with another async handler that depends
    # on the result of the operations.
    overrides, overrides_filename = mkstemp()
    chart_dir = mkdtemp()

    if isinstance(config, ChartOpts):
        if config.repo and 'http' in config.repo:
            raise ValueError('`repo` specifies the name of the Helm chart repo.'
                             'Use `fetch_opts.repo` to specify a URL.')
        chart_to_fetch = f'{config.repo}/{config.chart}' if config.repo else config.chart

        # Configure fetch options.
        fetch_opts_dict = {}
        if config.fetch_opts is not None:
            fetch_opts_dict = {k: v for k, v in vars(config.fetch_opts).items() if v is not None}
        fetch_opts_dict["destination"] = chart_dir
        if config.version is not None:
            fetch_opts_dict["version"] = config.version
        fetch_opts = FetchOpts(**fetch_opts_dict)

        # Fetch the chart.
        _fetch(chart_to_fetch, fetch_opts)
        fetched_chart_name = os.listdir(chart_dir)[0]
        chart = os.path.join(chart_dir, fetched_chart_name)
    else:
        chart = config.path

    default_values = os.path.join(chart, 'values.yaml')

    # Write overrides file.
    vals = config.values if config.values is not None else {}
    data = pulumi.Output.from_input(vals).apply(lambda x: json.dumps(x))
    file = open(overrides, 'w')
    pulumi.Output.all(file, data).apply(_write_override_file)

    namespace_arg = ['--namespace', config.namespace] if config.namespace else []

    # Use 'helm template' to create a combined YAML manifest.
    cmd = ['helm', 'template', chart, '--name', release_name,
           '--values', default_values, '--values', overrides_filename]
    cmd.extend(namespace_arg)

    chart_resources = pulumi.Output.all(cmd, data).apply(_run_helm_cmd)

    # Parse the manifest and create the specified resources.
    resources = chart_resources.apply(
        lambda yaml_str: _parse_yaml_document(yaml.safe_load_all(yaml_str), opts, config.transformations))

    pulumi.Output.all(file, chart_dir, resources).apply(_cleanup_temp_dir)
    return resources
Ejemplo n.º 3
0
def _parse_chart(all_config: Tuple[Union[ChartOpts, LocalChartOpts], pulumi.ResourceOptions]) -> pulumi.Output:
    config, opts = all_config

    json_opts = config.to_json()

    # Rather than using the default provider for the following invoke call, use the version specified
    # in package.json.
    invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version())

    objects = json_opts.apply(lambda x: pulumi.runtime.invoke('kubernetes:helm:template',
                                                              {'jsonOpts': x}, invoke_opts).value['result'])
    return objects.apply(lambda x: _parse_yaml_document(x, opts, config.transformations))
Ejemplo n.º 4
0
def _parse_chart(
    all_config: Tuple[str, Union[ChartOpts, LocalChartOpts],
                      pulumi.ResourceOptions]
) -> pulumi.Output:
    release_name, config, opts = all_config

    # Create temporary directory and file to hold chart data and override values.
    # Note: We're intentionally using the lower-level APIs here because the async Outputs are being handled in
    # a different scope, which was causing the temporary files/directory to be deleted before they were referenced
    # in the Output handlers. We manually clean these up once we're done with another async handler that depends
    # on the result of the operations.
    overrides, overrides_filename = mkstemp()
    chart_dir = mkdtemp()

    if isinstance(config, ChartOpts):
        if config.repo and 'http' in config.repo:
            raise ValueError(
                '`repo` specifies the name of the Helm chart repo.'
                'Use `fetch_opts.repo` to specify a URL.')
        chart_to_fetch = f'{config.repo}/{config.chart}' if config.repo else config.chart

        # Configure fetch options.
        fetch_opts_dict = {}
        if config.fetch_opts is not None:
            fetch_opts_dict = {
                k: v
                for k, v in vars(config.fetch_opts).items() if v is not None
            }
        fetch_opts_dict["destination"] = chart_dir
        if config.version is not None:
            fetch_opts_dict["version"] = config.version
        fetch_opts = FetchOpts(**fetch_opts_dict)

        # Fetch the chart.
        _fetch(chart_to_fetch, fetch_opts)
        # Sort the directories into alphabetical order, and choose the first
        fetched_chart_name = sorted(os.listdir(chart_dir), key=str.lower)[0]
        chart = os.path.join(chart_dir, fetched_chart_name)
    else:
        chart = config.path

    default_values = os.path.join(chart, 'values.yaml')

    # Write overrides file.
    vals = config.values if config.values is not None else {}
    data = pulumi.Output.from_input(vals).apply(lambda x: json.dumps(x))
    file = open(overrides, 'w')
    pulumi.Output.all(file, data).apply(_write_override_file)

    apiversions_arg = [
        f'--api-versions={version}' for version in config.api_versions
    ] if config.api_versions else []
    namespace_arg = ['--namespace', config.namespace
                     ] if config.namespace else []
    crd_arg = ['--include-crds'] if _is_helm_v3() else []

    # Use 'helm template' to create a combined YAML manifest.
    cmd = [
        'helm', 'template', chart, '--name-template', release_name, '--values',
        default_values, '--values', overrides_filename
    ]
    cmd.extend(apiversions_arg)
    cmd.extend(namespace_arg)
    cmd.extend(crd_arg)

    chart_resources = pulumi.Output.all(cmd, data).apply(_run_helm_cmd)

    # Rather than using the default provider for the following invoke call, use the version specified
    # in package.json.
    invoke_opts = pulumi.InvokeOptions(version=_utilities.get_version())

    objects = chart_resources.apply(
        lambda text: pulumi.runtime.invoke('kubernetes:yaml:decode', {
            'text': text,
            'defaultNamespace': config.namespace
        }, invoke_opts).value['result'])

    # Parse the manifest and create the specified resources.
    resources = objects.apply(lambda objects: _parse_yaml_document(
        objects, opts, config.transformations))

    pulumi.Output.all(file, chart_dir, resources).apply(_cleanup_temp_dir)
    return resources