summaryrefslogtreecommitdiffstats
path: root/ansible_collections/kubernetes/core/plugins/lookup/kustomize.py
blob: 88a039e676feba29c73a98a4074c886f356bdd61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#
#  Copyright 2021 Red Hat | Ansible
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

DOCUMENTATION = """
    name: kustomize

    short_description: Build a set of kubernetes resources using a 'kustomization.yaml' file.

    version_added: 2.2.0

    author:
      - Aubin Bikouo (@abikouo)
    notes:
      - If both kustomize and kubectl are part of the PATH, kustomize will be used by the plugin.
    description:
      - Uses the kustomize or the kubectl tool.
      - Return the result of C(kustomize build) or C(kubectl kustomize).
    options:
      dir:
        description:
        - The directory path containing 'kustomization.yaml',
          or a git repository URL with a path suffix specifying same with respect to the repository root.
        - If omitted, '.' is assumed.
        default: "."
      binary_path:
        description:
        - The path of a kustomize or kubectl binary to use.
      opt_dirs:
        description:
        - An optional list of directories to search for the executable in addition to PATH.
      enable_helm:
        description:
        - Enable the helm chart inflation generator
        default: "False"

    requirements:
      - "python >= 3.6"
"""

EXAMPLES = """
- name: Run lookup using kustomize
  ansible.builtin.set_fact:
    resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kustomize') }}"

- name: Run lookup using kubectl kustomize
  ansible.builtin.set_fact:
    resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl') }}"

- name: Create kubernetes resources for lookup output
  kubernetes.core.k8s:
    definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization') }}"

- name: Create kubernetes resources for lookup output with `--enable-helm` set
  kubernetes.core.k8s:
    definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization', enable_helm=True) }}"
"""

RETURN = """
  _list:
    description:
      - YAML string for the object definitions returned from the tool execution.
    type: str
    sample:
      kind: ConfigMap
      apiVersion: v1
      metadata:
        name: my-config-map
        namespace: default
      data:
        key1: val1
"""

import subprocess

from ansible.errors import AnsibleLookupError
from ansible.module_utils.common.process import get_bin_path
from ansible.plugins.lookup import LookupBase


def get_binary_from_path(name, opt_dirs=None):
    opt_arg = {}
    try:
        if opt_dirs is not None:
            if not isinstance(opt_dirs, list):
                opt_dirs = [opt_dirs]
            opt_arg["opt_dirs"] = opt_dirs
        bin_path = get_bin_path(name, **opt_arg)
        return bin_path
    except ValueError:
        return None


def run_command(command):
    cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return cmd.communicate()


class LookupModule(LookupBase):
    def run(
        self,
        terms,
        variables=None,
        dir=".",
        binary_path=None,
        opt_dirs=None,
        enable_helm=False,
        **kwargs
    ):
        executable_path = binary_path
        if executable_path is None:
            executable_path = get_binary_from_path(name="kustomize", opt_dirs=opt_dirs)
            if executable_path is None:
                executable_path = get_binary_from_path(
                    name="kubectl", opt_dirs=opt_dirs
                )

            # validate that at least one tool was found
            if executable_path is None:
                raise AnsibleLookupError(
                    "Failed to find required executable 'kubectl' and 'kustomize' in paths"
                )

        # check input directory
        kustomization_dir = dir

        command = [executable_path]
        if executable_path.endswith("kustomize"):
            command += ["build", kustomization_dir]
        elif executable_path.endswith("kubectl"):
            command += ["kustomize", kustomization_dir]
        else:
            raise AnsibleLookupError(
                "unexpected tool provided as parameter {0}, expected one of kustomize, kubectl.".format(
                    executable_path
                )
            )

        if enable_helm:
            command += ["--enable-helm"]

        (out, err) = run_command(command)
        if err:
            raise AnsibleLookupError(
                "kustomize command failed with: {0}".format(err.decode("utf-8"))
            )
        return [out.decode("utf-8")]