def main():
    module = AnsibleModule(
        argument_spec=dict(
            binary_path=dict(type="path"),
            chart_ref=dict(type="path", required=True),
            chart_repo_url=dict(type="str"),
            chart_version=dict(type="str"),
            include_crds=dict(type="bool", default=False),
            output_dir=dict(type="path"),
            release_values=dict(type="dict", default={}, aliases=["values"]),
            values_files=dict(type="list", default=[], elements="str"),
            update_repo_cache=dict(type="bool", default=False),
        ),
        supports_check_mode=True,
    )

    check_mode = module.check_mode
    bin_path = module.params.get("binary_path")
    chart_ref = module.params.get("chart_ref")
    chart_repo_url = module.params.get("chart_repo_url")
    chart_version = module.params.get("chart_version")
    include_crds = module.params.get("include_crds")
    output_dir = module.params.get("output_dir")
    release_values = module.params.get("release_values")
    values_files = module.params.get("values_files")
    update_repo_cache = module.params.get("update_repo_cache")

    if not IMP_YAML:
        module.fail_json(msg=missing_required_lib("yaml"),
                         exception=IMP_YAML_ERR)

    helm_cmd = bin_path or module.get_bin_path("helm", required=True)

    if update_repo_cache:
        update_cmd = helm_cmd + " repo update"
        run_helm(module, update_cmd)

    tmpl_cmd = template(
        helm_cmd,
        chart_ref,
        chart_repo_url=chart_repo_url,
        chart_version=chart_version,
        output_dir=output_dir,
        release_values=release_values,
        values_files=values_files,
        include_crds=include_crds,
    )

    if not check_mode:
        rc, out, err = run_helm(module, tmpl_cmd)
    else:
        out = err = ""
        rc = 0

    module.exit_json(failed=False,
                     changed=True,
                     command=tmpl_cmd,
                     stdout=out,
                     stderr=err,
                     rc=rc)
示例#2
0
def main():
    module = AnsibleModule(argument_spec=dict(
        binary_path=dict(type='path'),
        chart_ref=dict(type='path', required=True),
        chart_repo_url=dict(type='str'),
        chart_version=dict(type='str'),
        include_crds=dict(type='bool', default=False),
        output_dir=dict(type='path'),
        release_values=dict(type='dict', default={}, aliases=['values']),
        values_files=dict(type='list', default=[], elements='str'),
        update_repo_cache=dict(type='bool', default=False)),
                           supports_check_mode=True)

    check_mode = module.check_mode
    bin_path = module.params.get('binary_path')
    chart_ref = module.params.get('chart_ref')
    chart_repo_url = module.params.get('chart_repo_url')
    chart_version = module.params.get('chart_version')
    include_crds = module.params.get('include_crds')
    output_dir = module.params.get('output_dir')
    release_values = module.params.get('release_values')
    values_files = module.params.get('values_files')
    update_repo_cache = module.params.get('update_repo_cache')

    if not IMP_YAML:
        module.fail_json(msg=missing_required_lib("yaml"),
                         exception=IMP_YAML_ERR)

    helm_cmd = bin_path or module.get_bin_path('helm', required=True)

    if update_repo_cache:
        update_cmd = helm_cmd + " repo update"
        run_helm(module, update_cmd)

    tmpl_cmd = template(helm_cmd,
                        chart_ref,
                        chart_repo_url=chart_repo_url,
                        chart_version=chart_version,
                        output_dir=output_dir,
                        release_values=release_values,
                        values_files=values_files,
                        include_crds=include_crds)

    if not check_mode:
        rc, out, err = run_helm(module, tmpl_cmd)
    else:
        out = err = ""
        rc = 0

    module.exit_json(failed=False,
                     changed=True,
                     command=tmpl_cmd,
                     stdout=out,
                     stderr=err,
                     rc=rc)
示例#3
0
def helmdiff_check(
    module,
    helm_cmd,
    release_name,
    chart_ref,
    release_values,
    values_files=None,
    chart_version=None,
    replace=False,
):
    """
    Use helm diff to determine if a release would change by upgrading a chart.
    """
    cmd = helm_cmd + " diff upgrade"
    cmd += " " + release_name
    cmd += " " + chart_ref

    if chart_version is not None:
        cmd += " " + "--version=" + chart_version
    if not replace:
        cmd += " " + "--reset-values"

    if release_values != {}:
        fd, path = tempfile.mkstemp(suffix=".yml")
        with open(path, "w") as yaml_file:
            yaml.dump(release_values, yaml_file, default_flow_style=False)
        cmd += " -f=" + path

    if values_files:
        for values_file in values_files:
            cmd += " -f=" + values_file

    rc, out, err = run_helm(module, cmd)
    return len(out.strip()) > 0
示例#4
0
def fetch_chart_info(module, command, chart_ref):
    """
    Get chart info
    """
    inspect_command = command + " show chart " + chart_ref

    rc, out, err = run_helm(module, inspect_command)

    return yaml.safe_load(out)
示例#5
0
def test_run_helm_with_params():
    module = MockedModule()
    module.params = {
        "api_key": "my-api-key",
        "ca_cert": "my-ca-cert",
        "host": "some-host",
        "kube_context": "my-context",
        "release_namespace": "a-release-namespace",
        "validate_certs": False,
    }

    run_helm(module, "helm foo")

    assert module.r["command"] == "helm foo"
    assert module.r["environ_update"]["HELM_KUBEAPISERVER"] == "some-host"
    assert module.r["environ_update"]["HELM_KUBECONTEXT"] == "my-context"
    assert module.r["environ_update"]["HELM_KUBETOKEN"] == "my-api-key"
    assert module.r["environ_update"][
        "HELM_NAMESPACE"] == "a-release-namespace"
    assert module.r["environ_update"]["KUBECONFIG"]
    assert not os.path.exists(module.r["environ_update"]["KUBECONFIG"])
示例#6
0
def get_repository_status(module, command, repository_name):
    list_command = command + " repo list --output=yaml"

    rc, out, err = run_helm(module, list_command, fails_on_error=False)

    # no repo => rc=1 and 'no repositories to show' in output
    if rc == 1 and "no repositories to show" in err:
        return None
    elif rc != 0:
        module.fail_json(
            msg=
            "Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}"
            .format(rc, out, err),
            command=list_command)

    return get_repository(yaml.safe_load(out), repository_name)
示例#7
0
def get_release_status(module, command, release_name):
    """
    Get Release state from deployed release
    """

    list_command = command + " list --output=yaml --filter " + release_name

    rc, out, err = run_helm(module, list_command)

    release = get_release(yaml.safe_load(out), release_name)

    if release is None:  # not install
        return None

    release["values"] = get_values(module, command, release_name)

    return release
示例#8
0
def get_release_status(module, command, release_name):
    list_command = command + " list --output=yaml --filter " + release_name

    rc, out, err = run_helm(module, list_command)

    if rc != 0:
        module.fail_json(
            msg="Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}".format(rc, out, err),
            command=list_command
        )

    release = get_release(yaml.safe_load(out), release_name)

    if release is None:  # not install
        return None

    release['values'] = get_values(module, command, release_name)

    return release
def get_release_status(module, command, release_name, release_state):
    list_command = command + " list --output=yaml"

    valid_release_states = [
        "all",
        "deployed",
        "failed",
        "pending",
        "superseded",
        "uninstalled",
        "uninstalling",
    ]

    for local_release_state in release_state:
        if local_release_state in valid_release_states:
            list_command += " --%s" % local_release_state

    list_command += " --filter " + release_name
    rc, out, err = run_helm(module, list_command)

    if rc != 0:
        module.fail_json(
            msg=
            "Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}"
            .format(rc, out, err),
            command=list_command,
        )

    release = get_release(yaml.safe_load(out), release_name)

    if release is None:  # not install
        return None

    release["values"] = get_values(module, command, release_name)

    return release
示例#10
0
def run_repo_update(module, command):
    """
    Run Repo update
    """
    repo_update_command = command + " repo update"
    rc, out, err = run_helm(module, repo_update_command)
示例#11
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            binary_path=dict(type='path'),
            release_namespace=dict(type='str', aliases=['namespace']),
            plugin_name=dict(type='str', ),
            # Helm options
            context=dict(type='str',
                         aliases=['kube_context'],
                         fallback=(env_fallback, ['K8S_AUTH_CONTEXT'])),
            kubeconfig=dict(type='path',
                            aliases=['kubeconfig_path'],
                            fallback=(env_fallback, ['K8S_AUTH_KUBECONFIG'])),

            # Generic auth key
            host=dict(type='str', fallback=(env_fallback, ['K8S_AUTH_HOST'])),
            ca_cert=dict(type='path',
                         aliases=['ssl_ca_cert'],
                         fallback=(env_fallback, ['K8S_AUTH_SSL_CA_CERT'])),
            validate_certs=dict(type='bool',
                                default=True,
                                aliases=['verify_ssl'],
                                fallback=(env_fallback,
                                          ['K8S_AUTH_VERIFY_SSL'])),
            api_key=dict(type='str',
                         no_log=True,
                         fallback=(env_fallback, ['K8S_AUTH_API_KEY']))),
        mutually_exclusive=[("context", "ca_cert"),
                            ("context", "validate_certs"),
                            ("kubeconfig", "ca_cert"),
                            ("kubeconfig", "validate_certs")],
        supports_check_mode=True,
    )

    bin_path = module.params.get('binary_path')

    if bin_path is not None:
        helm_cmd_common = bin_path
    else:
        helm_cmd_common = 'helm'

    helm_cmd_common = module.get_bin_path(helm_cmd_common, required=True)

    helm_cmd_common += " plugin"

    plugin_name = module.params.get('plugin_name')
    helm_plugin_list = helm_cmd_common + " list"
    rc, out, err = run_helm(module, helm_plugin_list)
    if rc != 0 or (out == '' and err == ''):
        module.fail_json(
            msg="Failed to get Helm plugin info",
            command=helm_plugin_list,
            stdout=out,
            stderr=err,
            rc=rc,
        )

    plugin_list = []
    if out:
        for line in out.splitlines():
            if line.startswith("NAME"):
                continue
            name, version, description = line.split('\t', 3)
            name = name.strip()
            version = version.strip()
            description = description.strip()
            if plugin_name is None:
                plugin_list.append({
                    'name': name,
                    'version': version,
                    'description': description,
                })
                continue

            if plugin_name == name:
                plugin_list.append({
                    'name': name,
                    'version': version,
                    'description': description,
                })
                break

    module.exit_json(
        changed=True,
        command=helm_plugin_list,
        stdout=out,
        stderr=err,
        rc=rc,
        plugin_list=plugin_list,
    )
示例#12
0
def test_run_helm_naked():
    module = MockedModule()
    run_helm(module, "helm foo")

    assert module.r["command"] == "helm foo"
    assert module.r["environ_update"] == {}
示例#13
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            binary_path=dict(type='path'),
            release_namespace=dict(type='str', aliases=['namespace']),
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            plugin_path=dict(type='str', ),
            plugin_name=dict(type='str', ),
            # Helm options
            context=dict(type='str',
                         aliases=['kube_context'],
                         fallback=(env_fallback, ['K8S_AUTH_CONTEXT'])),
            kubeconfig=dict(type='path',
                            aliases=['kubeconfig_path'],
                            fallback=(env_fallback, ['K8S_AUTH_KUBECONFIG'])),

            # Generic auth key
            host=dict(type='str', fallback=(env_fallback, ['K8S_AUTH_HOST'])),
            ca_cert=dict(type='path',
                         aliases=['ssl_ca_cert'],
                         fallback=(env_fallback, ['K8S_AUTH_SSL_CA_CERT'])),
            validate_certs=dict(type='bool',
                                default=True,
                                aliases=['verify_ssl'],
                                fallback=(env_fallback,
                                          ['K8S_AUTH_VERIFY_SSL'])),
            api_key=dict(type='str',
                         no_log=True,
                         fallback=(env_fallback, ['K8S_AUTH_API_KEY']))),
        supports_check_mode=True,
        required_if=[
            ("state", "present", ("plugin_path", )),
            ("state", "absent", ("plugin_name", )),
        ],
        mutually_exclusive=[('plugin_name', 'plugin_path'),
                            ("context", "ca_cert"),
                            ("context", "validate_certs"),
                            ("kubeconfig", "ca_cert"),
                            ("kubeconfig", "validate_certs")],
    )

    bin_path = module.params.get('binary_path')
    state = module.params.get('state')

    if bin_path is not None:
        helm_cmd_common = bin_path
    else:
        helm_cmd_common = 'helm'

    helm_cmd_common = module.get_bin_path(helm_cmd_common, required=True)

    helm_cmd_common += " plugin"

    if state == 'present':
        helm_cmd_common += " install %s" % module.params.get('plugin_path')
        if not module.check_mode:
            rc, out, err = run_helm(module,
                                    helm_cmd_common,
                                    fails_on_error=False)
        else:
            rc, out, err = (0, '', '')

        if rc == 1 and 'plugin already exists' in err:
            module.exit_json(failed=False,
                             changed=False,
                             msg="Plugin already exists",
                             command=helm_cmd_common,
                             stdout=out,
                             stderr=err,
                             rc=rc)
        elif rc == 0:
            module.exit_json(
                failed=False,
                changed=True,
                msg="Plugin installed successfully",
                command=helm_cmd_common,
                stdout=out,
                stderr=err,
                rc=rc,
            )
        else:
            module.fail_json(
                msg="Failure when executing Helm command.",
                command=helm_cmd_common,
                stdout=out,
                stderr=err,
                rc=rc,
            )
    elif state == 'absent':
        plugin_name = module.params.get('plugin_name')
        helm_plugin_list = helm_cmd_common + " list"
        rc, out, err = run_helm(module, helm_plugin_list)
        if rc != 0 or (out == '' and err == ''):
            module.fail_json(
                msg="Failed to get Helm plugin info",
                command=helm_plugin_list,
                stdout=out,
                stderr=err,
                rc=rc,
            )

        if out:
            found = False
            for line in out.splitlines():
                if line.startswith("NAME"):
                    continue
                name, dummy, dummy = line.split('\t', 3)
                name = name.strip()
                if name == plugin_name:
                    found = True
                    break
            if found:
                helm_uninstall_cmd = "%s uninstall %s" % (helm_cmd_common,
                                                          plugin_name)
                if not module.check_mode:
                    rc, out, err = run_helm(module,
                                            helm_uninstall_cmd,
                                            fails_on_error=False)
                else:
                    rc, out, err = (0, '', '')

                if rc == 0:
                    module.exit_json(changed=True,
                                     msg="Plugin uninstalled successfully",
                                     command=helm_uninstall_cmd,
                                     stdout=out,
                                     stderr=err,
                                     rc=rc)
                module.fail_json(
                    msg="Failed to get Helm plugin uninstall",
                    command=helm_uninstall_cmd,
                    stdout=out,
                    stderr=err,
                    rc=rc,
                )
            else:
                module.exit_json(
                    failed=False,
                    changed=False,
                    msg="Plugin not found or is already uninstalled",
                    command=helm_plugin_list,
                    stdout=out,
                    stderr=err,
                    rc=rc)
示例#14
0
def main():
    global module

    module = AnsibleModule(
        argument_spec=dict(
            binary_path=dict(type="path"),
            repo_name=dict(type="str", aliases=["name"], required=True),
            repo_url=dict(type="str", aliases=["url"]),
            repo_username=dict(type="str", aliases=["username"]),
            repo_password=dict(type="str", aliases=["password"], no_log=True),
            repo_state=dict(
                default="present", choices=["present", "absent"], aliases=["state"]
            ),
            pass_credentials=dict(type="bool", default=False),
            # Generic auth key
            host=dict(type="str", fallback=(env_fallback, ["K8S_AUTH_HOST"])),
            ca_cert=dict(
                type="path",
                aliases=["ssl_ca_cert"],
                fallback=(env_fallback, ["K8S_AUTH_SSL_CA_CERT"]),
            ),
            validate_certs=dict(
                type="bool",
                default=True,
                aliases=["verify_ssl"],
                fallback=(env_fallback, ["K8S_AUTH_VERIFY_SSL"]),
            ),
            api_key=dict(
                type="str", no_log=True, fallback=(env_fallback, ["K8S_AUTH_API_KEY"])
            ),
        ),
        required_together=[["repo_username", "repo_password"]],
        required_if=[("repo_state", "present", ["repo_url"])],
        supports_check_mode=True,
    )

    if not IMP_YAML:
        module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)

    changed = False

    bin_path = module.params.get("binary_path")
    repo_name = module.params.get("repo_name")
    repo_url = module.params.get("repo_url")
    repo_username = module.params.get("repo_username")
    repo_password = module.params.get("repo_password")
    repo_state = module.params.get("repo_state")
    pass_credentials = module.params.get("pass_credentials")

    if bin_path is not None:
        helm_cmd = bin_path
    else:
        helm_cmd = module.get_bin_path("helm", required=True)

    repository_status = get_repository_status(module, helm_cmd, repo_name)

    if repo_state == "absent" and repository_status is not None:
        helm_cmd = delete_repository(helm_cmd, repo_name)
        changed = True
    elif repo_state == "present":
        if repository_status is None:
            helm_cmd = install_repository(
                helm_cmd,
                repo_name,
                repo_url,
                repo_username,
                repo_password,
                pass_credentials,
            )
            changed = True
        elif repository_status["url"] != repo_url:
            module.fail_json(
                msg="Repository already have a repository named {0}".format(repo_name)
            )

    if module.check_mode:
        module.exit_json(changed=changed)
    elif not changed:
        module.exit_json(changed=False, repo_name=repo_name, repo_url=repo_url)

    rc, out, err = run_helm(module, helm_cmd)

    if repo_password is not None:
        helm_cmd = helm_cmd.replace(repo_password, "******")

    if rc != 0:
        module.fail_json(
            msg="Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}".format(
                rc, out, err
            ),
            command=helm_cmd,
        )

    module.exit_json(changed=changed, stdout=out, stderr=err, command=helm_cmd)
示例#15
0
文件: helm.py 项目: hhue13/ansible
def main():
    global module
    module = AnsibleModule(
        argument_spec=dict(
            binary_path=dict(type='path'),
            chart_ref=dict(type='path'),
            chart_repo_url=dict(type='str'),
            chart_version=dict(type='str'),
            release_name=dict(type='str', required=True, aliases=['name']),
            release_namespace=dict(type='str',
                                   required=True,
                                   aliases=['namespace']),
            release_state=dict(default='present',
                               choices=['present', 'absent'],
                               aliases=['state']),
            release_values=dict(type='dict', default={}, aliases=['values']),
            values_files=dict(type='list', default=[], elements='str'),
            update_repo_cache=dict(type='bool', default=False),

            # Helm options
            disable_hook=dict(type='bool', default=False),
            force=dict(type='bool', default=False),
            context=dict(type='str',
                         aliases=['kube_context'],
                         fallback=(env_fallback, ['K8S_AUTH_CONTEXT'])),
            kubeconfig=dict(type='path',
                            aliases=['kubeconfig_path'],
                            fallback=(env_fallback, ['K8S_AUTH_KUBECONFIG'])),
            purge=dict(type='bool', default=True),
            wait=dict(type='bool', default=False),
            wait_timeout=dict(type='str'),
            atomic=dict(type='bool', default=False),
            create_namespace=dict(type='bool', default=False),
            replace=dict(type='bool', default=False),
            skip_crds=dict(type='bool', default=False),
            history_max=dict(type='int'),

            # Generic auth key
            host=dict(type='str', fallback=(env_fallback, ['K8S_AUTH_HOST'])),
            ca_cert=dict(type='path',
                         aliases=['ssl_ca_cert'],
                         fallback=(env_fallback, ['K8S_AUTH_SSL_CA_CERT'])),
            validate_certs=dict(type='bool',
                                default=True,
                                aliases=['verify_ssl'],
                                fallback=(env_fallback,
                                          ['K8S_AUTH_VERIFY_SSL'])),
            api_key=dict(type='str',
                         no_log=True,
                         fallback=(env_fallback, ['K8S_AUTH_API_KEY']))),
        required_if=[('release_state', 'present',
                      ['release_name', 'chart_ref']),
                     ('release_state', 'absent', ['release_name'])],
        mutually_exclusive=[
            ("context", "ca_cert"),
            ("kubeconfig", "ca_cert"),
            ("replace", "history_max"),
        ],
        supports_check_mode=True,
    )

    if not IMP_YAML:
        module.fail_json(msg=missing_required_lib("yaml"),
                         exception=IMP_YAML_ERR)

    changed = False

    bin_path = module.params.get('binary_path')
    chart_ref = module.params.get('chart_ref')
    chart_repo_url = module.params.get('chart_repo_url')
    chart_version = module.params.get('chart_version')
    release_name = module.params.get('release_name')
    release_state = module.params.get('release_state')
    release_values = module.params.get('release_values')
    values_files = module.params.get('values_files')
    update_repo_cache = module.params.get('update_repo_cache')

    # Helm options
    disable_hook = module.params.get('disable_hook')
    force = module.params.get('force')
    purge = module.params.get('purge')
    wait = module.params.get('wait')
    wait_timeout = module.params.get('wait_timeout')
    atomic = module.params.get('atomic')
    create_namespace = module.params.get('create_namespace')
    replace = module.params.get('replace')
    skip_crds = module.params.get('skip_crds')
    history_max = module.params.get('history_max')

    if bin_path is not None:
        helm_cmd_common = bin_path
    else:
        helm_cmd_common = module.get_bin_path('helm', required=True)

    if update_repo_cache:
        run_repo_update(module, helm_cmd_common)

    # Get real/deployed release status
    release_status = get_release_status(module, helm_cmd_common, release_name)

    # keep helm_cmd_common for get_release_status in module_exit_json
    helm_cmd = helm_cmd_common
    if release_state == "absent" and release_status is not None:
        if replace:
            module.fail_json(
                msg="replace is not applicable when state is absent")

        helm_cmd = delete(helm_cmd, release_name, purge, disable_hook)
        changed = True
    elif release_state == "present":

        if chart_version is not None:
            helm_cmd += " --version=" + chart_version

        if chart_repo_url is not None:
            helm_cmd += " --repo=" + chart_repo_url

        # Fetch chart info to have real version and real name for chart_ref from archive, folder or url
        chart_info = fetch_chart_info(module, helm_cmd, chart_ref)

        if release_status is None:  # Not installed
            helm_cmd = deploy(helm_cmd,
                              release_name,
                              release_values,
                              chart_ref,
                              wait,
                              wait_timeout,
                              disable_hook,
                              False,
                              values_files=values_files,
                              atomic=atomic,
                              create_namespace=create_namespace,
                              replace=replace,
                              skip_crds=skip_crds,
                              history_max=history_max)
            changed = True

        else:

            if has_plugin(helm_cmd_common, "diff") and not chart_repo_url:
                would_change = helmdiff_check(module, helm_cmd_common,
                                              release_name, chart_ref,
                                              release_values, values_files,
                                              chart_version, replace)
            else:
                module.warn(
                    "The default idempotency check can fail to report changes in certain cases. "
                    "Install helm diff for better results.")
                would_change = default_check(release_status, chart_info,
                                             release_values, values_files)

            if force or would_change:
                helm_cmd = deploy(helm_cmd,
                                  release_name,
                                  release_values,
                                  chart_ref,
                                  wait,
                                  wait_timeout,
                                  disable_hook,
                                  force,
                                  values_files=values_files,
                                  atomic=atomic,
                                  create_namespace=create_namespace,
                                  replace=replace,
                                  skip_crds=skip_crds,
                                  history_max=history_max)
                changed = True

    if module.check_mode:
        check_status = {
            'values': {
                "current": {},
                "declared": {},
            }
        }
        if release_status:
            check_status['values']['current'] = release_status['values']
            check_status['values']['declared'] = release_status

        module.exit_json(
            changed=changed,
            command=helm_cmd,
            status=check_status,
            stdout='',
            stderr='',
        )
    elif not changed:
        module.exit_json(
            changed=False,
            status=release_status,
            stdout='',
            stderr='',
            command=helm_cmd,
        )

    rc, out, err = run_helm(module, helm_cmd)

    module.exit_json(
        changed=changed,
        stdout=out,
        stderr=err,
        status=get_release_status(module, helm_cmd_common, release_name),
        command=helm_cmd,
    )
示例#16
0
def main():
    global module

    module = AnsibleModule(
        argument_spec=dict(
            binary_path=dict(type='path'),
            repo_name=dict(type='str', aliases=['name'], required=True),
            repo_url=dict(type='str', aliases=['url']),
            repo_username=dict(type='str', aliases=['username']),
            repo_password=dict(type='str', aliases=['password'], no_log=True),
            repo_state=dict(default='present',
                            choices=['present', 'absent'],
                            aliases=['state']),
        ),
        required_together=[['repo_username', 'repo_password']],
        required_if=[
            ('repo_state', 'present', ['repo_url']),
        ],
        supports_check_mode=True,
    )

    if not IMP_YAML:
        module.fail_json(msg=missing_required_lib("yaml"),
                         exception=IMP_YAML_ERR)

    changed = False

    bin_path = module.params.get('binary_path')
    repo_name = module.params.get('repo_name')
    repo_url = module.params.get('repo_url')
    repo_username = module.params.get('repo_username')
    repo_password = module.params.get('repo_password')
    repo_state = module.params.get('repo_state')

    if bin_path is not None:
        helm_cmd = bin_path
    else:
        helm_cmd = module.get_bin_path('helm', required=True)

    repository_status = get_repository_status(module, helm_cmd, repo_name)

    if repo_state == "absent" and repository_status is not None:
        helm_cmd = delete_repository(helm_cmd, repo_name)
        changed = True
    elif repo_state == "present":
        if repository_status is None:
            helm_cmd = install_repository(helm_cmd, repo_name, repo_url,
                                          repo_username, repo_password)
            changed = True
        elif repository_status['url'] != repo_url:
            module.fail_json(
                msg="Repository already have a repository named {0}".format(
                    repo_name))

    if module.check_mode:
        module.exit_json(changed=changed)
    elif not changed:
        module.exit_json(changed=False, repo_name=repo_name, repo_url=repo_url)

    rc, out, err = run_helm(module, helm_cmd)

    if repo_password is not None:
        helm_cmd = helm_cmd.replace(repo_password, '******')

    if rc != 0:
        module.fail_json(
            msg=
            "Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}"
            .format(rc, out, err),
            command=helm_cmd)

    module.exit_json(changed=changed, stdout=out, stderr=err, command=helm_cmd)
示例#17
0
def main():
    global module
    module = AnsibleModule(
        argument_spec=dict(
            binary_path=dict(type="path"),
            chart_ref=dict(type="path"),
            chart_repo_url=dict(type="str"),
            chart_version=dict(type="str"),
            release_name=dict(type="str", required=True, aliases=["name"]),
            release_namespace=dict(type="str", required=True, aliases=["namespace"]),
            release_state=dict(
                default="present", choices=["present", "absent"], aliases=["state"]
            ),
            release_values=dict(type="dict", default={}, aliases=["values"]),
            values_files=dict(type="list", default=[], elements="str"),
            update_repo_cache=dict(type="bool", default=False),
            # Helm options
            disable_hook=dict(type="bool", default=False),
            force=dict(type="bool", default=False),
            context=dict(
                type="str",
                aliases=["kube_context"],
                fallback=(env_fallback, ["K8S_AUTH_CONTEXT"]),
            ),
            kubeconfig=dict(
                type="path",
                aliases=["kubeconfig_path"],
                fallback=(env_fallback, ["K8S_AUTH_KUBECONFIG"]),
            ),
            purge=dict(type="bool", default=True),
            wait=dict(type="bool", default=False),
            wait_timeout=dict(type="str"),
            timeout=dict(type="str"),
            atomic=dict(type="bool", default=False),
            create_namespace=dict(type="bool", default=False),
            replace=dict(type="bool", default=False),
            skip_crds=dict(type="bool", default=False),
            history_max=dict(type="int"),
            # Generic auth key
            host=dict(type="str", fallback=(env_fallback, ["K8S_AUTH_HOST"])),
            ca_cert=dict(
                type="path",
                aliases=["ssl_ca_cert"],
                fallback=(env_fallback, ["K8S_AUTH_SSL_CA_CERT"]),
            ),
            validate_certs=dict(
                type="bool",
                default=True,
                aliases=["verify_ssl"],
                fallback=(env_fallback, ["K8S_AUTH_VERIFY_SSL"]),
            ),
            api_key=dict(
                type="str", no_log=True, fallback=(env_fallback, ["K8S_AUTH_API_KEY"])
            ),
        ),
        required_if=[
            ("release_state", "present", ["release_name", "chart_ref"]),
            ("release_state", "absent", ["release_name"]),
        ],
        mutually_exclusive=[
            ("context", "ca_cert"),
            ("kubeconfig", "ca_cert"),
            ("replace", "history_max"),
            ("wait_timeout", "timeout"),
        ],
        supports_check_mode=True,
    )

    if not IMP_YAML:
        module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)

    changed = False

    bin_path = module.params.get("binary_path")
    chart_ref = module.params.get("chart_ref")
    chart_repo_url = module.params.get("chart_repo_url")
    chart_version = module.params.get("chart_version")
    release_name = module.params.get("release_name")
    release_state = module.params.get("release_state")
    release_values = module.params.get("release_values")
    values_files = module.params.get("values_files")
    update_repo_cache = module.params.get("update_repo_cache")

    # Helm options
    disable_hook = module.params.get("disable_hook")
    force = module.params.get("force")
    purge = module.params.get("purge")
    wait = module.params.get("wait")
    wait_timeout = module.params.get("wait_timeout")
    atomic = module.params.get("atomic")
    create_namespace = module.params.get("create_namespace")
    replace = module.params.get("replace")
    skip_crds = module.params.get("skip_crds")
    history_max = module.params.get("history_max")
    timeout = module.params.get("timeout")

    if bin_path is not None:
        helm_cmd_common = bin_path
    else:
        helm_cmd_common = module.get_bin_path("helm", required=True)

    if update_repo_cache:
        run_repo_update(module, helm_cmd_common)

    # Get real/deployed release status
    release_status = get_release_status(module, helm_cmd_common, release_name)

    # keep helm_cmd_common for get_release_status in module_exit_json
    helm_cmd = helm_cmd_common
    opt_result = {}
    if release_state == "absent" and release_status is not None:
        if replace:
            module.fail_json(msg="replace is not applicable when state is absent")

        if wait:
            helm_version = get_helm_version(module, helm_cmd_common)
            if LooseVersion(helm_version) < LooseVersion("3.7.0"):
                opt_result["warnings"] = []
                opt_result["warnings"].append(
                    "helm uninstall support option --wait for helm release >= 3.7.0"
                )
                wait = False

        helm_cmd = delete(
            helm_cmd, release_name, purge, disable_hook, wait, wait_timeout
        )
        changed = True
    elif release_state == "present":

        if chart_version is not None:
            helm_cmd += " --version=" + chart_version

        if chart_repo_url is not None:
            helm_cmd += " --repo=" + chart_repo_url

        # Fetch chart info to have real version and real name for chart_ref from archive, folder or url
        chart_info = fetch_chart_info(module, helm_cmd, chart_ref)

        if release_status is None:  # Not installed
            helm_cmd = deploy(
                helm_cmd,
                release_name,
                release_values,
                chart_ref,
                wait,
                wait_timeout,
                disable_hook,
                False,
                values_files=values_files,
                atomic=atomic,
                create_namespace=create_namespace,
                replace=replace,
                skip_crds=skip_crds,
                history_max=history_max,
                timeout=timeout,
            )
            changed = True

        else:

            if has_plugin(helm_cmd_common, "diff") and not chart_repo_url:
                would_change = helmdiff_check(
                    module,
                    helm_cmd_common,
                    release_name,
                    chart_ref,
                    release_values,
                    values_files,
                    chart_version,
                    replace,
                )
            else:
                module.warn(
                    "The default idempotency check can fail to report changes in certain cases. "
                    "Install helm diff for better results."
                )
                would_change = default_check(
                    release_status, chart_info, release_values, values_files
                )

            if force or would_change:
                helm_cmd = deploy(
                    helm_cmd,
                    release_name,
                    release_values,
                    chart_ref,
                    wait,
                    wait_timeout,
                    disable_hook,
                    force,
                    values_files=values_files,
                    atomic=atomic,
                    create_namespace=create_namespace,
                    replace=replace,
                    skip_crds=skip_crds,
                    history_max=history_max,
                    timeout=timeout,
                )
                changed = True

    if module.check_mode:
        check_status = {"values": {"current": {}, "declared": {}}}
        if release_status:
            check_status["values"]["current"] = release_status["values"]
            check_status["values"]["declared"] = release_status

        module.exit_json(
            changed=changed,
            command=helm_cmd,
            status=check_status,
            stdout="",
            stderr="",
            **opt_result,
        )
    elif not changed:
        module.exit_json(
            changed=False,
            status=release_status,
            stdout="",
            stderr="",
            command=helm_cmd,
            **opt_result,
        )

    rc, out, err = run_helm(module, helm_cmd)

    module.exit_json(
        changed=changed,
        stdout=out,
        stderr=err,
        status=get_release_status(module, helm_cmd_common, release_name),
        command=helm_cmd,
        **opt_result,
    )
示例#18
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            binary_path=dict(type="path"),
            state=dict(type="str",
                       default="present",
                       choices=["present", "absent", "latest"]),
            plugin_path=dict(type="str", ),
            plugin_name=dict(type="str", ),
            plugin_version=dict(type="str", ),
            # Helm options
            context=dict(
                type="str",
                aliases=["kube_context"],
                fallback=(env_fallback, ["K8S_AUTH_CONTEXT"]),
            ),
            kubeconfig=dict(
                type="path",
                aliases=["kubeconfig_path"],
                fallback=(env_fallback, ["K8S_AUTH_KUBECONFIG"]),
            ),
            # Generic auth key
            host=dict(type="str", fallback=(env_fallback, ["K8S_AUTH_HOST"])),
            ca_cert=dict(
                type="path",
                aliases=["ssl_ca_cert"],
                fallback=(env_fallback, ["K8S_AUTH_SSL_CA_CERT"]),
            ),
            validate_certs=dict(
                type="bool",
                default=True,
                aliases=["verify_ssl"],
                fallback=(env_fallback, ["K8S_AUTH_VERIFY_SSL"]),
            ),
            api_key=dict(type="str",
                         no_log=True,
                         fallback=(env_fallback, ["K8S_AUTH_API_KEY"])),
        ),
        supports_check_mode=True,
        required_if=[
            ("state", "present", ("plugin_path", )),
            ("state", "absent", ("plugin_name", )),
            ("state", "latest", ("plugin_name", )),
        ],
        mutually_exclusive=[
            ("plugin_name", "plugin_path"),
            ("context", "ca_cert"),
            ("context", "validate_certs"),
            ("kubeconfig", "ca_cert"),
            ("kubeconfig", "validate_certs"),
        ],
    )

    bin_path = module.params.get("binary_path")
    state = module.params.get("state")

    if bin_path is not None:
        helm_cmd_common = bin_path
    else:
        helm_cmd_common = "helm"

    helm_cmd_common = module.get_bin_path(helm_cmd_common, required=True)

    helm_cmd_common += " plugin"

    if state == "present":
        helm_cmd_common += " install %s" % module.params.get("plugin_path")
        plugin_version = module.params.get("plugin_version")
        if plugin_version is not None:
            helm_cmd_common += " --version=%s" % plugin_version
        if not module.check_mode:
            rc, out, err = run_helm(module,
                                    helm_cmd_common,
                                    fails_on_error=False)
        else:
            rc, out, err = (0, "", "")

        if rc == 1 and "plugin already exists" in err:
            module.exit_json(
                failed=False,
                changed=False,
                msg="Plugin already exists",
                command=helm_cmd_common,
                stdout=out,
                stderr=err,
                rc=rc,
            )
        elif rc == 0:
            module.exit_json(
                failed=False,
                changed=True,
                msg="Plugin installed successfully",
                command=helm_cmd_common,
                stdout=out,
                stderr=err,
                rc=rc,
            )
        else:
            module.fail_json(
                msg="Failure when executing Helm command.",
                command=helm_cmd_common,
                stdout=out,
                stderr=err,
                rc=rc,
            )
    elif state == "absent":
        plugin_name = module.params.get("plugin_name")
        rc, output, err = get_helm_plugin_list(module,
                                               helm_bin=helm_cmd_common)
        out = parse_helm_plugin_list(module, output=output.splitlines())

        if not out:
            module.exit_json(
                failed=False,
                changed=False,
                msg="Plugin not found or is already uninstalled",
                command=helm_cmd_common + " list",
                stdout=output,
                stderr=err,
                rc=rc,
            )

        found = False
        for line in out:
            if line[0] == plugin_name:
                found = True
                break
        if not found:
            module.exit_json(
                failed=False,
                changed=False,
                msg="Plugin not found or is already uninstalled",
                command=helm_cmd_common + " list",
                stdout=output,
                stderr=err,
                rc=rc,
            )

        helm_uninstall_cmd = "%s uninstall %s" % (helm_cmd_common, plugin_name)
        if not module.check_mode:
            rc, out, err = run_helm(module,
                                    helm_uninstall_cmd,
                                    fails_on_error=False)
        else:
            rc, out, err = (0, "", "")

        if rc == 0:
            module.exit_json(
                changed=True,
                msg="Plugin uninstalled successfully",
                command=helm_uninstall_cmd,
                stdout=out,
                stderr=err,
                rc=rc,
            )
        module.fail_json(
            msg="Failed to get Helm plugin uninstall",
            command=helm_uninstall_cmd,
            stdout=out,
            stderr=err,
            rc=rc,
        )
    elif state == "latest":
        plugin_name = module.params.get("plugin_name")
        rc, output, err = get_helm_plugin_list(module,
                                               helm_bin=helm_cmd_common)
        out = parse_helm_plugin_list(module, output=output.splitlines())

        if not out:
            module.exit_json(
                failed=False,
                changed=False,
                msg="Plugin not found",
                command=helm_cmd_common + " list",
                stdout=output,
                stderr=err,
                rc=rc,
            )

        found = False
        for line in out:
            if line[0] == plugin_name:
                found = True
                break
        if not found:
            module.exit_json(
                failed=False,
                changed=False,
                msg="Plugin not found",
                command=helm_cmd_common + " list",
                stdout=output,
                stderr=err,
                rc=rc,
            )

        helm_update_cmd = "%s update %s" % (helm_cmd_common, plugin_name)
        if not module.check_mode:
            rc, out, err = run_helm(module,
                                    helm_update_cmd,
                                    fails_on_error=False)
        else:
            rc, out, err = (0, "", "")

        if rc == 0:
            module.exit_json(
                changed=True,
                msg="Plugin updated successfully",
                command=helm_update_cmd,
                stdout=out,
                stderr=err,
                rc=rc,
            )
        module.fail_json(
            msg="Failed to get Helm plugin update",
            command=helm_update_cmd,
            stdout=out,
            stderr=err,
            rc=rc,
        )