示例#1
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)
示例#2
0
文件: helm.py 项目: Dwiib/Eth-Cluster
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
示例#3
0
文件: helm.py 项目: Dwiib/Eth-Cluster
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)
示例#4
0
def test_run_helm_with_params():
    module = MockedModule()
    module.params = {
        "api_key": "my-api-key",
        "ca_cert": "my-ca-cert",
        "host": "some-host",
        "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"])
示例#5
0
文件: helm.py 项目: Dwiib/Eth-Cluster
def has_plugin(command, plugin):
    """
    Check if helm plugin is installed.
    """

    cmd = command + " plugin list"
    rc, out, err = run_helm(module, cmd)
    for line in out.splitlines():
        if line.startswith("NAME"):
            continue
        name, _rest = line.split(None, 1)
        if name == plugin:
            return True
    return False
示例#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
文件: helm.py 项目: Dwiib/Eth-Cluster
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
示例#9
0
文件: helm.py 项目: Dwiib/Eth-Cluster
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),

            # 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"),
            ("context", "validate_certs"),
            ("kubeconfig", "ca_cert"),
            ("kubeconfig", "validate_certs")
        ],
        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')

    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)
            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)
                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,
    )
示例#10
0
文件: helm.py 项目: Dwiib/Eth-Cluster
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 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)
示例#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 test_run_helm_naked():
    module = MockedModule()
    run_helm(module, "helm foo")

    assert module.r["command"] == "helm foo"
    assert module.r["environ_update"] == {}