Blame plugins/modules/ipavault.py

Packit Service ee01e6
#!/usr/bin/python
Packit Service 0a38ef
# -*- coding: utf-8 -*-
Packit Service 0a38ef
Packit Service 0a38ef
# Authors:
Packit Service 0a38ef
#   Rafael Guterres Jeffman <rjeffman@redhat.com>
Packit Service 0a38ef
#
Packit Service 0a38ef
# Copyright (C) 2019 Red Hat
Packit Service 0a38ef
# see file 'COPYING' for use and warranty information
Packit Service 0a38ef
#
Packit Service 0a38ef
# This program is free software; you can redistribute it and/or modify
Packit Service 0a38ef
# it under the terms of the GNU General Public License as published by
Packit Service 0a38ef
# the Free Software Foundation, either version 3 of the License, or
Packit Service 0a38ef
# (at your option) any later version.
Packit Service 0a38ef
#
Packit Service 0a38ef
# This program is distributed in the hope that it will be useful,
Packit Service 0a38ef
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 0a38ef
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 0a38ef
# GNU General Public License for more details.
Packit Service 0a38ef
#
Packit Service 0a38ef
# You should have received a copy of the GNU General Public License
Packit Service 0a38ef
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 0a38ef
Packit Service 0a38ef
ANSIBLE_METADATA = {
Packit Service 0a38ef
    "metadata_version": "1.0",
Packit Service 0a38ef
    "supported_by": "community",
Packit Service 0a38ef
    "status": ["preview"],
Packit Service 0a38ef
}
Packit Service 0a38ef
Packit Service 0a38ef
DOCUMENTATION = """
Packit Service 0a38ef
---
Packit Service 0a38ef
module: ipavault
Packit Service 0a38ef
short description: Manage vaults and secret vaults.
Packit Service 0a38ef
description: Manage vaults and secret vaults. KRA service must be enabled.
Packit Service 0a38ef
options:
Packit Service 0a38ef
  ipaadmin_principal:
Packit Service 0a38ef
    description: The admin principal
Packit Service 0a38ef
    default: admin
Packit Service 0a38ef
  ipaadmin_password:
Packit Service 0a38ef
    description: The admin password
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  name:
Packit Service 0a38ef
    description: The vault name
Packit Service 0a38ef
    required: true
Packit Service 0a38ef
    aliases: ["cn"]
Packit Service 0a38ef
  description:
Packit Service 0a38ef
    description: The vault description
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  public_key:
Packit Service 0a38ef
    description: Base64 encode public key.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service 0a38ef
    aliases: ["ipavaultpublickey", "vault_public_key"]
Packit Service 0a38ef
  public_key_file:
Packit Service 0a38ef
    description: Path to file with public key.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service 0a38ef
    aliases: ["vault_public_key_file"]
Packit Service 0a38ef
  private_key:
Packit Service 0a38ef
    description: Base64 encode private key.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service 0a38ef
    aliases: ["ipavaultprivatekey", "vault_private_key"]
Packit Service 0a38ef
  private_key_file:
Packit Service 0a38ef
    description: Path to file with private key.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service 0a38ef
    aliases: ["vault_private_key_file"]
Packit Service 0a38ef
  password:
Packit Service 0a38ef
    description: password to be used on symmetric vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service a166ed
    aliases: ["ipavaultpassword", "vault_password", "old_password"]
Packit Service 0a38ef
  password_file:
Packit Service 0a38ef
    description: file with password to be used on symmetric vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service a166ed
    aliases: ["vault_password_file", "old_password_file"]
Packit Service a166ed
  new_password:
Packit Service a166ed
    description: new password to be used on symmetric vault.
Packit Service a166ed
    required: false
Packit Service a166ed
    type: string
Packit Service a166ed
  new_password_file:
Packit Service a166ed
    description: file with new password to be used on symmetric vault.
Packit Service a166ed
    required: false
Packit Service a166ed
    type: string
Packit Service 0a38ef
  salt:
Packit Service 0a38ef
    description: Vault salt.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
    aliases: ["ipavaultsalt", "vault_salt"]
Packit Service 0a38ef
  vault_type:
Packit Service 0a38ef
    description: Vault types are based on security level.
Packit Service 0a38ef
    required: true
Packit Service 0a38ef
    default: symmetric
Packit Service 0a38ef
    choices: ["standard", "symmetric", "asymmetric"]
Packit Service 0a38ef
    aliases: ["ipavaulttype"]
Packit Service 0a38ef
  service:
Packit Service 0a38ef
    description: Any service can own one or more service vaults.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  username:
Packit Service 0a38ef
    description: Any user can own one or more user vaults.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service 0a38ef
    aliases: ["user"]
Packit Service 0a38ef
  shared:
Packit Service 0a38ef
    description: Vault is shared.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: boolean
Packit Service 0a38ef
  users:
Packit Service 0a38ef
    description: Users that are member of the vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  groups:
Packit Service 0a38ef
    description: Groups that are member of the vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  owners:
Packit Service 0a38ef
    description: Users that are owners of the vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  ownergroups:
Packit Service 0a38ef
    description: Groups that are owners of the vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  ownerservices:
Packit Service 0a38ef
    description: Services that are owners of the vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  services:
Packit Service 0a38ef
    description: Services that are member of the container.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  data:
Packit Service 0a38ef
    description: Data to be stored in the vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service 0a38ef
    aliases: ["ipavaultdata", "vault_data"]
Packit Service 0a38ef
  in:
Packit Service 0a38ef
    description: Path to file with data to be stored in the vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service 0a38ef
    aliases: ["datafile_in"]
Packit Service 0a38ef
  out:
Packit Service 0a38ef
    description: Path to file to store data retrieved from the vault.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: string
Packit Service 0a38ef
    aliases: ["datafile_out"]
Packit Service 0a38ef
  action:
Packit Service 0a38ef
    description: Work on vault or member level.
Packit Service 0a38ef
    default: vault
Packit Service 0a38ef
    choices: ["vault", "member"]
Packit Service 0a38ef
  state:
Packit Service 0a38ef
    description: State to ensure
Packit Service 0a38ef
    default: present
Packit Service 0a38ef
    choices: ["present", "absent", "retrieved"]
Packit Service 0a38ef
author:
Packit Service 0a38ef
    - Rafael Jeffman
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
EXAMPLES = """
Packit Service 0a38ef
# Ensure vault symvault is present
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    vault_type: symmetric
Packit Service 0a38ef
    password: SomeVAULTpassword
Packit Service 0a38ef
    salt: MTIzNDU2Nzg5MAo=
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure group ipausers is a vault member.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    groups: ipausers
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure group ipausers is not a vault member.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    groups: ipausers
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
    state: absent
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure vault users are present.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    users:
Packit Service 0a38ef
    - user01
Packit Service 0a38ef
    - user02
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure vault users are absent.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    users:
Packit Service 0a38ef
    - user01
Packit Service 0a38ef
    - user02
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
    status: absent
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure user owns vault.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
    owners: user01
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure user does not own vault.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    owners: user01
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
    status: absent
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure data is archived to a symmetric vault
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    password: SomeVAULTpassword
Packit Service 0a38ef
    data: >
Packit Service 0a38ef
      Data archived.
Packit Service 0a38ef
      More data archived.
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
Packit Service 0a38ef
# Retrieve data archived from a symmetric vault
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    password: SomeVAULTpassword
Packit Service 0a38ef
    state: retrieved
Packit Service 0a38ef
  register: result
Packit Service 0a38ef
- debug:
Packit Service a166ed
    msg: "{{ result.vault.data }}"
Packit Service a166ed
Packit Service a166ed
# Change password of a symmetric vault
Packit Service a166ed
- ipavault:
Packit Service a166ed
    ipaadmin_password: SomeADMINpassword
Packit Service a166ed
    name: symvault
Packit Service a166ed
    username: admin
Packit Service a166ed
    old_password: SomeVAULTpassword
Packit Service a166ed
    new_password: SomeNEWpassword
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure vault symvault is absent
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: symvault
Packit Service 0a38ef
    user: admin
Packit Service 0a38ef
    state: absent
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure asymmetric vault is present.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: asymvault
Packit Service 0a38ef
    username: user01
Packit Service 0a38ef
    description: An asymmetric vault
Packit Service 0a38ef
    vault_type: asymmetric
Packit Service a166ed
    public_key: |
Packit Service 0a38ef
      LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR
Packit Service 0a38ef
      HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi
Packit Service 0a38ef
      9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM
Packit Service 0a38ef
      295VTFEMnFOZERYeGtSaFFETXBiUEVSWWlHbE1jbzdhN0hIVDk1bGNQbmhObVFkb3VGdHlV
Packit Service 0a38ef
      bFBUVS96V1kKZldYWTBOeU1UbUtoeFRseUV3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVk
Packit Service 0a38ef
      tLS0tLQo=
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure data is archived in an asymmetric vault
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: asymvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    data: >
Packit Service 0a38ef
      Data archived.
Packit Service 0a38ef
      More data archived.
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
Packit Service 0a38ef
# Retrive data archived in an asymmetric vault, using a private key file.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: asymvault
Packit Service 0a38ef
    username: admin
Packit Service 0a38ef
    private_key_file: private.pem
Packit Service 0a38ef
    state: retrieved
Packit Service 0a38ef
Packit Service 0a38ef
# Ensure asymmetric vault is absent.
Packit Service 0a38ef
- ipavault:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: asymvault
Packit Service 0a38ef
    username: user01
Packit Service 0a38ef
    vault_type: asymmetric
Packit Service 0a38ef
    state: absent
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
RETURN = """
Packit Service a166ed
vault:
Packit Service a166ed
  description: Vault dict with archived data.
Packit Service a166ed
  returned: If state is `retrieved`.
Packit Service a166ed
  type: dict
Packit Service a166ed
  options:
Packit Service a166ed
    data:
Packit Service a166ed
      description: The vault data.
Packit Service a166ed
      returned: always
Packit Service a166ed
      type: string
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
import os
Packit Service 0a38ef
from base64 import b64decode
Packit Service 0a38ef
from ansible.module_utils.basic import AnsibleModule
Packit Service 0a38ef
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
Packit Service 0a38ef
    temp_kdestroy, valid_creds, api_connect, api_command, \
Packit Service a166ed
    gen_add_del_lists, compare_args_ipa, module_params_get, exit_raw_json
Packit Service 0a38ef
from ipalib.errors import EmptyModlist
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def find_vault(module, name, username, service, shared):
Packit Service 0a38ef
    _args = {
Packit Service 0a38ef
        "all": True,
Packit Service 0a38ef
        "cn": name,
Packit Service 0a38ef
    }
Packit Service 0a38ef
Packit Service 0a38ef
    if username is not None:
Packit Service 0a38ef
        _args['username'] = username
Packit Service 0a38ef
    elif service is not None:
Packit Service 0a38ef
        _args['service'] = service
Packit Service 0a38ef
    else:
Packit Service 0a38ef
        _args['shared'] = shared
Packit Service 0a38ef
Packit Service 0a38ef
    _result = api_command(module, "vault_find", name, _args)
Packit Service 0a38ef
Packit Service 0a38ef
    if len(_result["result"]) > 1:
Packit Service 0a38ef
        module.fail_json(
Packit Service 0a38ef
            msg="There is more than one vault '%s'" % (name))
Packit Service 0a38ef
    if len(_result["result"]) == 1:
Packit Service 0a38ef
        return _result["result"][0]
Packit Service 0a38ef
Packit Service 0a38ef
    return None
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def gen_args(description, username, service, shared, vault_type, salt,
Packit Service 0a38ef
             password, password_file, public_key, public_key_file, vault_data,
Packit Service 0a38ef
             datafile_in, datafile_out):
Packit Service 0a38ef
    _args = {}
Packit Service 0a38ef
Packit Service 0a38ef
    if description is not None:
Packit Service 0a38ef
        _args['description'] = description
Packit Service 0a38ef
    if username is not None:
Packit Service 0a38ef
        _args['username'] = username
Packit Service 0a38ef
    if service is not None:
Packit Service 0a38ef
        _args['service'] = service
Packit Service 0a38ef
    if shared is not None:
Packit Service 0a38ef
        _args['shared'] = shared
Packit Service 0a38ef
    if vault_type is not None:
Packit Service 0a38ef
        _args['ipavaulttype'] = vault_type
Packit Service 0a38ef
    if salt is not None:
Packit Service 0a38ef
        _args['ipavaultsalt'] = salt
Packit Service 0a38ef
    if public_key is not None:
Packit Service 0a38ef
        _args['ipavaultpublickey'] = b64decode(public_key.encode('utf-8'))
Packit Service 0a38ef
    if public_key_file is not None:
Packit Service 0a38ef
        with open(public_key_file, 'r') as keyfile:
Packit Service 0a38ef
            keydata = keyfile.read()
Packit Service 0a38ef
            _args['ipavaultpublickey'] = keydata.strip().encode('utf-8')
Packit Service 0a38ef
Packit Service 0a38ef
    return _args
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def gen_member_args(args, users, groups, services):
Packit Service 0a38ef
    _args = args.copy()
Packit Service 0a38ef
Packit Service 0a38ef
    for arg in ['ipavaulttype', 'description', 'ipavaultpublickey',
Packit Service 0a38ef
                'ipavaultsalt']:
Packit Service 0a38ef
        if arg in _args:
Packit Service 0a38ef
            del _args[arg]
Packit Service 0a38ef
Packit Service 0a38ef
    if any([users, groups, services]):
Packit Service 0a38ef
        if users is not None:
Packit Service 0a38ef
            _args['user'] = users
Packit Service 0a38ef
        if groups is not None:
Packit Service 0a38ef
            _args['group'] = groups
Packit Service 0a38ef
        if services is not None:
Packit Service 0a38ef
            _args['services'] = services
Packit Service 0a38ef
Packit Service 0a38ef
        return _args
Packit Service 0a38ef
Packit Service 0a38ef
    return None
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def data_storage_args(args, data, password, password_file, private_key,
Packit Service 0a38ef
                      private_key_file, datafile_in, datafile_out):
Packit Service 0a38ef
    _args = {}
Packit Service 0a38ef
Packit Service 0a38ef
    if 'username' in args:
Packit Service 0a38ef
        _args['username'] = args['username']
Packit Service 0a38ef
    if 'service' in args:
Packit Service 0a38ef
        _args['service'] = args['service']
Packit Service 0a38ef
    if 'shared' in args:
Packit Service 0a38ef
        _args['shared'] = args['shared']
Packit Service 0a38ef
Packit Service 0a38ef
    if password is not None:
Packit Service 0a38ef
        _args['password'] = password
Packit Service 0a38ef
    if password_file is not None:
Packit Service 0a38ef
        _args['password_file'] = password_file
Packit Service 0a38ef
Packit Service 0a38ef
    if private_key is not None:
Packit Service 0a38ef
        _args['private_key'] = private_key
Packit Service 0a38ef
    if private_key_file is not None:
Packit Service 0a38ef
        _args['private_key_file'] = private_key_file
Packit Service 0a38ef
Packit Service 0a38ef
    if datafile_in is not None:
Packit Service 0a38ef
        _args['in'] = datafile_in
Packit Service 0a38ef
    else:
Packit Service 0a38ef
        if data is None:
Packit Service 0a38ef
            _args['data'] = b''
Packit Service 0a38ef
        else:
Packit Service 0a38ef
            _args['data'] = data.encode('utf-8')
Packit Service 0a38ef
Packit Service 0a38ef
    if datafile_out is not None:
Packit Service 0a38ef
        _args['out'] = datafile_out
Packit Service 0a38ef
Packit Service 0a38ef
    if private_key_file is not None:
Packit Service 0a38ef
        _args['private_key_file'] = private_key_file
Packit Service 0a38ef
Packit Service 0a38ef
    return _args
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def check_parameters(module, state, action, description, username, service,
Packit Service 0a38ef
                     shared, users, groups, services, owners, ownergroups,
Packit Service 0a38ef
                     ownerservices, vault_type, salt, password, password_file,
Packit Service 0a38ef
                     public_key, public_key_file, private_key,
Packit Service a166ed
                     private_key_file, vault_data, datafile_in, datafile_out,
Packit Service a166ed
                     new_password, new_password_file):
Packit Service 0a38ef
    invalid = []
Packit Service 0a38ef
    if state == "present":
Packit Service 0a38ef
        invalid = ['private_key', 'private_key_file', 'datafile_out']
Packit Service 0a38ef
Packit Service a166ed
        if all([password, password_file]) \
Packit Service a166ed
           or all([new_password, new_password_file]):
Packit Service a166ed
            module.fail_json(msg="Password specified multiple times.")
Packit Service a166ed
Packit Service a166ed
        if any([new_password, new_password_file]) \
Packit Service a166ed
           and not any([password, password_file]):
Packit Service a166ed
            module.fail_json(
Packit Service a166ed
                msg="Either `password` or `password_file` must be provided to "
Packit Service a166ed
                    "change symmetric vault password.")
Packit Service a166ed
Packit Service 0a38ef
        if action == "member":
Packit Service 0a38ef
            invalid.extend(['description'])
Packit Service 0a38ef
Packit Service 0a38ef
    elif state == "absent":
Packit Service 0a38ef
        invalid = ['description', 'salt', 'vault_type', 'private_key',
Packit Service 0a38ef
                   'private_key_file', 'datafile_in', 'datafile_out',
Packit Service a166ed
                   'vault_data', 'new_password', 'new_password_file']
Packit Service 0a38ef
Packit Service 0a38ef
        if action == "vault":
Packit Service 0a38ef
            invalid.extend(['users', 'groups', 'services', 'owners',
Packit Service 0a38ef
                            'ownergroups', 'ownerservices', 'password',
Packit Service 0a38ef
                            'password_file', 'public_key', 'public_key_file'])
Packit Service 0a38ef
Packit Service 0a38ef
    elif state == "retrieved":
Packit Service 0a38ef
        invalid = ['description', 'salt', 'datafile_in', 'users', 'groups',
Packit Service 0a38ef
                   'owners', 'ownergroups', 'public_key', 'public_key_file',
Packit Service a166ed
                   'vault_data', 'new_password', 'new_password_file']
Packit Service 0a38ef
        if action == 'member':
Packit Service 0a38ef
            module.fail_json(
Packit Service 0a38ef
                msg="State `retrieved` do not support action `member`.")
Packit Service 0a38ef
Packit Service 0a38ef
    for arg in invalid:
Packit Service 0a38ef
        if vars()[arg] is not None:
Packit Service 0a38ef
            module.fail_json(
Packit Service 0a38ef
                msg="Argument '%s' can not be used with state '%s', "
Packit Service 0a38ef
                    "action '%s'" % (arg, state, action))
Packit Service 0a38ef
Packit Service 0a38ef
    for arg in invalid:
Packit Service 0a38ef
        if vars()[arg] is not None:
Packit Service 0a38ef
            module.fail_json(
Packit Service 0a38ef
                msg="Argument '%s' can not be used with state '%s', "
Packit Service 0a38ef
                    "action '%s'" % (arg, state, action))
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def check_encryption_params(module, state, action, vault_type, salt,
Packit Service 0a38ef
                            password, password_file, public_key,
Packit Service 0a38ef
                            public_key_file, private_key, private_key_file,
Packit Service a166ed
                            vault_data, datafile_in, datafile_out,
Packit Service a166ed
                            new_password, new_password_file, res_find):
Packit Service 0a38ef
    vault_type_invalid = []
Packit Service a166ed
Packit Service a166ed
    if vault_type is None and res_find is not None:
Packit Service a166ed
        vault_type = res_find['ipavaulttype']
Packit Service a166ed
        if isinstance(vault_type, (tuple, list)):
Packit Service a166ed
            vault_type = vault_type[0]
Packit Service a166ed
Packit Service 0a38ef
    if vault_type == "standard":
Packit Service 0a38ef
        vault_type_invalid = ['public_key', 'public_key_file', 'password',
Packit Service a166ed
                              'password_file', 'salt', 'new_password',
Packit Service a166ed
                              'new_password_file']
Packit Service 0a38ef
Packit Service 0a38ef
    if vault_type is None or vault_type == "symmetric":
Packit Service 0a38ef
        vault_type_invalid = ['public_key', 'public_key_file',
Packit Service 0a38ef
                              'private_key', 'private_key_file']
Packit Service 0a38ef
Packit Service 0a38ef
        if password is None and password_file is None and action != 'member':
Packit Service 0a38ef
            module.fail_json(
Packit Service 0a38ef
                msg="Symmetric vault requires password or password_file "
Packit Service 0a38ef
                    "to store data or change `salt`.")
Packit Service 0a38ef
Packit Service a166ed
        if any([new_password, new_password_file]) and res_find is None:
Packit Service a166ed
            module.fail_json(
Packit Service a166ed
                msg="Cannot modify password of inexistent vault.")
Packit Service a166ed
Packit Service a166ed
        if (
Packit Service a166ed
            salt is not None
Packit Service a166ed
            and not(
Packit Service a166ed
                any([password, password_file])
Packit Service a166ed
                and any([new_password, new_password_file])
Packit Service a166ed
            )
Packit Service a166ed
        ):
Packit Service a166ed
            module.fail_json(
Packit Service a166ed
                msg="Vault `salt` can only change when changing the password.")
Packit Service a166ed
Packit Service 0a38ef
    if vault_type == "asymmetric":
Packit Service a166ed
        vault_type_invalid = [
Packit Service a166ed
            'password', 'password_file', 'new_password', 'new_password_file'
Packit Service a166ed
        ]
Packit Service 0a38ef
        if not any([public_key, public_key_file]) and res_find is None:
Packit Service 0a38ef
            module.fail_json(
Packit Service 0a38ef
                msg="Assymmetric vault requires public_key "
Packit Service 0a38ef
                    "or public_key_file to store data.")
Packit Service 0a38ef
Packit Service 0a38ef
    for param in vault_type_invalid:
Packit Service 0a38ef
        if vars()[param] is not None:
Packit Service 0a38ef
            module.fail_json(
Packit Service 0a38ef
                msg="Argument '%s' cannot be used with vault type '%s'" %
Packit Service 0a38ef
                (param, vault_type or 'symmetric'))
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service a166ed
def change_password(module, res_find, password, password_file, new_password,
Packit Service a166ed
                    new_password_file):
Packit Service a166ed
    """
Packit Service a166ed
    Change the password of a symmetric vault.
Packit Service a166ed
Packit Service a166ed
    To change the password of a vault, it is needed to retrieve the stored
Packit Service a166ed
    data with the current password, and store the data again, with the new
Packit Service a166ed
    password, forcing it to override the old one.
Packit Service a166ed
    """
Packit Service a166ed
    # verify parameters.
Packit Service a166ed
    if not any([new_password, new_password_file]):
Packit Service a166ed
        return []
Packit Service a166ed
    if res_find["ipavaulttype"][0] != "symmetric":
Packit Service a166ed
        module.fail_json(msg="Cannot change password of `%s` vault."
Packit Service a166ed
                             % res_find["ipavaulttype"])
Packit Service a166ed
Packit Service a166ed
    # prepare arguments to retrieve data.
Packit Service a166ed
    name = res_find["cn"][0]
Packit Service a166ed
    args = {}
Packit Service a166ed
    if password:
Packit Service a166ed
        args["password"] = password
Packit Service a166ed
    if password_file:
Packit Service a166ed
        args["password_file"] = password_file
Packit Service a166ed
    # retrieve current stored data
Packit Service a166ed
    result = api_command(module, 'vault_retrieve', name, args)
Packit Service a166ed
Packit Service a166ed
    # modify arguments to store data with new password.
Packit Service a166ed
    args = {"override_password": True, "data": result['result']['data']}
Packit Service a166ed
    if new_password:
Packit Service a166ed
        args["password"] = new_password
Packit Service a166ed
    if new_password_file:
Packit Service a166ed
        args["password_file"] = new_password_file
Packit Service a166ed
    # return the command to store data with the new password.
Packit Service a166ed
    return [(name, "vault_archive", args)]
Packit Service a166ed
Packit Service a166ed
Packit Service 0a38ef
def main():
Packit Service 0a38ef
    ansible_module = AnsibleModule(
Packit Service 0a38ef
        argument_spec=dict(
Packit Service 0a38ef
            # generalgroups
Packit Service 0a38ef
            ipaadmin_principal=dict(type="str", default="admin"),
Packit Service 0a38ef
            ipaadmin_password=dict(type="str", required=False, no_log=True),
Packit Service 0a38ef
Packit Service 0a38ef
            name=dict(type="list", aliases=["cn"], default=None,
Packit Service 0a38ef
                      required=True),
Packit Service 0a38ef
Packit Service 0a38ef
            description=dict(required=False, type="str", default=None),
Packit Service 0a38ef
            vault_type=dict(type="str", aliases=["ipavaulttype"],
Packit Service 0a38ef
                            default=None, required=False,
Packit Service 0a38ef
                            choices=["standard", "symmetric", "asymmetric"]),
Packit Service 0a38ef
            vault_public_key=dict(type="str", required=False, default=None,
Packit Service 0a38ef
                                  aliases=['ipavaultpublickey', 'public_key']),
Packit Service 0a38ef
            vault_public_key_file=dict(type="str", required=False,
Packit Service 0a38ef
                                       default=None,
Packit Service 0a38ef
                                       aliases=['public_key_file']),
Packit Service 0a38ef
            vault_private_key=dict(
Packit Service 0a38ef
                type="str", required=False, default=None, no_log=True,
Packit Service 0a38ef
                aliases=['ipavaultprivatekey', 'private_key']),
Packit Service 0a38ef
            vault_private_key_file=dict(type="str", required=False,
Packit Service 0a38ef
                                        default=None,
Packit Service 0a38ef
                                        aliases=['private_key_file']),
Packit Service 0a38ef
            vault_salt=dict(type="str", required=False, default=None,
Packit Service 0a38ef
                            aliases=['ipavaultsalt', 'salt']),
Packit Service 0a38ef
            username=dict(type="str", required=False, default=None,
Packit Service 0a38ef
                          aliases=['user']),
Packit Service 0a38ef
            service=dict(type="str", required=False, default=None),
Packit Service 0a38ef
            shared=dict(type="bool", required=False, default=None),
Packit Service 0a38ef
Packit Service 0a38ef
            users=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            groups=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            services=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            owners=dict(required=False, type='list', default=None,
Packit Service 0a38ef
                        aliases=['ownerusers']),
Packit Service 0a38ef
            ownergroups=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            ownerservices=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            vault_data=dict(type="str", required=False, default=None,
Packit Service 0a38ef
                            no_log=True, aliases=['ipavaultdata', 'data']),
Packit Service 0a38ef
            datafile_in=dict(type="str", required=False, default=None,
Packit Service 0a38ef
                             aliases=['in']),
Packit Service 0a38ef
            datafile_out=dict(type="str", required=False, default=None,
Packit Service 0a38ef
                              aliases=['out']),
Packit Service 0a38ef
            vault_password=dict(type="str", required=False, default=None,
Packit Service a166ed
                                no_log=True,
Packit Service a166ed
                                aliases=['ipavaultpassword', 'password',
Packit Service a166ed
                                         "old_password"]),
Packit Service 0a38ef
            vault_password_file=dict(type="str", required=False, default=None,
Packit Service a166ed
                                     no_log=False,
Packit Service a166ed
                                     aliases=[
Packit Service a166ed
                                        'password_file', "old_password_file"
Packit Service a166ed
                                     ]),
Packit Service a166ed
            new_password=dict(type="str", required=False, default=None,
Packit Service a166ed
                              no_log=True),
Packit Service a166ed
            new_password_file=dict(type="str", required=False, default=None,
Packit Service a166ed
                                   no_log=False),
Packit Service 0a38ef
            # state
Packit Service 0a38ef
            action=dict(type="str", default="vault",
Packit Service 0a38ef
                        choices=["vault", "data", "member"]),
Packit Service 0a38ef
            state=dict(type="str", default="present",
Packit Service 0a38ef
                       choices=["present", "absent", "retrieved"]),
Packit Service 0a38ef
        ),
Packit Service 0a38ef
        supports_check_mode=True,
Packit Service 0a38ef
        mutually_exclusive=[['username', 'service', 'shared'],
Packit Service 0a38ef
                            ['datafile_in', 'vault_data'],
Packit Service a166ed
                            ['new_password', 'new_password_file'],
Packit Service 0a38ef
                            ['vault_password', 'vault_password_file'],
Packit Service 0a38ef
                            ['vault_public_key', 'vault_public_key_file']],
Packit Service 0a38ef
    )
Packit Service 0a38ef
Packit Service 0a38ef
    ansible_module._ansible_debug = True
Packit Service 0a38ef
Packit Service 0a38ef
    # general
Packit Service 0a38ef
    ipaadmin_principal = module_params_get(ansible_module,
Packit Service 0a38ef
                                           "ipaadmin_principal")
Packit Service 0a38ef
    ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
Packit Service 0a38ef
    names = module_params_get(ansible_module, "name")
Packit Service 0a38ef
Packit Service 0a38ef
    # present
Packit Service 0a38ef
    description = module_params_get(ansible_module, "description")
Packit Service 0a38ef
Packit Service 0a38ef
    username = module_params_get(ansible_module, "username")
Packit Service 0a38ef
    service = module_params_get(ansible_module, "service")
Packit Service 0a38ef
    shared = module_params_get(ansible_module, "shared")
Packit Service 0a38ef
Packit Service 0a38ef
    users = module_params_get(ansible_module, "users")
Packit Service 0a38ef
    groups = module_params_get(ansible_module, "groups")
Packit Service 0a38ef
    services = module_params_get(ansible_module, "services")
Packit Service 0a38ef
    owners = module_params_get(ansible_module, "owners")
Packit Service 0a38ef
    ownergroups = module_params_get(ansible_module, "ownergroups")
Packit Service 0a38ef
    ownerservices = module_params_get(ansible_module, "ownerservices")
Packit Service 0a38ef
Packit Service 0a38ef
    vault_type = module_params_get(ansible_module, "vault_type")
Packit Service 0a38ef
    salt = module_params_get(ansible_module, "vault_salt")
Packit Service 0a38ef
    password = module_params_get(ansible_module, "vault_password")
Packit Service 0a38ef
    password_file = module_params_get(ansible_module, "vault_password_file")
Packit Service a166ed
    new_password = module_params_get(ansible_module, "new_password")
Packit Service a166ed
    new_password_file = module_params_get(ansible_module, "new_password_file")
Packit Service 0a38ef
    public_key = module_params_get(ansible_module, "vault_public_key")
Packit Service 0a38ef
    public_key_file = module_params_get(ansible_module,
Packit Service 0a38ef
                                        "vault_public_key_file")
Packit Service 0a38ef
    private_key = module_params_get(ansible_module, "vault_private_key")
Packit Service 0a38ef
    private_key_file = module_params_get(ansible_module,
Packit Service 0a38ef
                                         "vault_private_key_file")
Packit Service 0a38ef
Packit Service 0a38ef
    vault_data = module_params_get(ansible_module, "vault_data")
Packit Service 0a38ef
Packit Service 0a38ef
    datafile_in = module_params_get(ansible_module, "datafile_in")
Packit Service 0a38ef
    datafile_out = module_params_get(ansible_module, "datafile_out")
Packit Service 0a38ef
Packit Service 0a38ef
    action = module_params_get(ansible_module, "action")
Packit Service 0a38ef
    state = module_params_get(ansible_module, "state")
Packit Service 0a38ef
Packit Service 0a38ef
    # Check parameters
Packit Service 0a38ef
Packit Service 0a38ef
    if state == "present":
Packit Service 0a38ef
        if len(names) != 1:
Packit Service 0a38ef
            ansible_module.fail_json(
Packit Service 0a38ef
                msg="Only one vault can be added at a time.")
Packit Service 0a38ef
Packit Service 0a38ef
    elif state == "absent":
Packit Service 0a38ef
        if len(names) < 1:
Packit Service 0a38ef
            ansible_module.fail_json(msg="No name given.")
Packit Service 0a38ef
Packit Service 0a38ef
    elif state == "retrieved":
Packit Service 0a38ef
        if len(names) != 1:
Packit Service 0a38ef
            ansible_module.fail_json(
Packit Service 0a38ef
                msg="Only one vault can be retrieved at a time.")
Packit Service 0a38ef
Packit Service 0a38ef
    else:
Packit Service 0a38ef
        ansible_module.fail_json(msg="Invalid state '%s'" % state)
Packit Service 0a38ef
Packit Service 0a38ef
    check_parameters(ansible_module, state, action, description, username,
Packit Service 0a38ef
                     service, shared, users, groups, services, owners,
Packit Service 0a38ef
                     ownergroups, ownerservices, vault_type, salt, password,
Packit Service 0a38ef
                     password_file, public_key, public_key_file, private_key,
Packit Service a166ed
                     private_key_file, vault_data, datafile_in, datafile_out,
Packit Service a166ed
                     new_password, new_password_file)
Packit Service 0a38ef
    # Init
Packit Service 0a38ef
Packit Service 0a38ef
    changed = False
Packit Service 0a38ef
    exit_args = {}
Packit Service 0a38ef
    ccache_dir = None
Packit Service 0a38ef
    ccache_name = None
Packit Service 0a38ef
    try:
Packit Service 0a38ef
        if not valid_creds(ansible_module, ipaadmin_principal):
Packit Service 0a38ef
            ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
Packit Service 0a38ef
                                                 ipaadmin_password)
Packit Service 0a38ef
            # Need to set krb5 ccache name, due to context='ansible-freeipa'
Packit Service 0a38ef
            if ccache_name is not None:
Packit Service 0a38ef
                os.environ["KRB5CCNAME"] = ccache_name
Packit Service 0a38ef
Packit Service 0a38ef
        api_connect(context='ansible-freeipa')
Packit Service 0a38ef
Packit Service 0a38ef
        commands = []
Packit Service 0a38ef
Packit Service 0a38ef
        for name in names:
Packit Service 0a38ef
            # Make sure vault exists
Packit Service 0a38ef
            res_find = find_vault(
Packit Service 0a38ef
                ansible_module, name, username, service, shared)
Packit Service 0a38ef
Packit Service 0a38ef
            # Generate args
Packit Service 0a38ef
            args = gen_args(description, username, service, shared, vault_type,
Packit Service 0a38ef
                            salt, password, password_file, public_key,
Packit Service 0a38ef
                            public_key_file, vault_data, datafile_in,
Packit Service 0a38ef
                            datafile_out)
Packit Service 0a38ef
            pwdargs = None
Packit Service 0a38ef
Packit Service 0a38ef
            # Set default vault_type if needed.
Packit Service 0a38ef
            if vault_type is None and vault_data is not None:
Packit Service 0a38ef
                if res_find is not None:
Packit Service 0a38ef
                    res_vault_type = res_find.get('ipavaulttype')[0]
Packit Service 0a38ef
                    args['ipavaulttype'] = vault_type = res_vault_type
Packit Service 0a38ef
                else:
Packit Service a166ed
                    args['ipavaulttype'] = vault_type = u"symmetric"
Packit Service 0a38ef
Packit Service 0a38ef
            # Create command
Packit Service 0a38ef
            if state == "present":
Packit Service 0a38ef
                # verify data encription args
Packit Service 0a38ef
                check_encryption_params(
Packit Service 0a38ef
                    ansible_module, state, action, vault_type, salt, password,
Packit Service 0a38ef
                    password_file, public_key, public_key_file, private_key,
Packit Service 0a38ef
                    private_key_file, vault_data, datafile_in, datafile_out,
Packit Service a166ed
                    new_password, new_password_file, res_find)
Packit Service 0a38ef
Packit Service 0a38ef
                # Found the vault
Packit Service 0a38ef
                if action == "vault":
Packit Service 0a38ef
                    if res_find is not None:
Packit Service 0a38ef
                        # For all settings is args, check if there are
Packit Service 0a38ef
                        # different settings in the find result.
Packit Service 0a38ef
                        # If yes: modify
Packit Service 0a38ef
                        if not compare_args_ipa(ansible_module, args,
Packit Service 0a38ef
                                                res_find):
Packit Service 0a38ef
                            commands.append([name, "vault_mod_internal", args])
Packit Service 0a38ef
Packit Service 0a38ef
                    else:
Packit Service a166ed
                        if vault_type == 'symmetric' \
Packit Service a166ed
                           and 'ipavaultsalt' not in args:
Packit Service a166ed
                            args['ipavaultsalt'] = os.urandom(32)
Packit Service a166ed
Packit Service 0a38ef
                        commands.append([name, "vault_add_internal", args])
Packit Service a166ed
Packit Service 0a38ef
                        if vault_type != 'standard' and vault_data is None:
Packit Service 0a38ef
                            vault_data = ''
Packit Service 0a38ef
Packit Service 0a38ef
                        # Set res_find to empty dict for next steps
Packit Service 0a38ef
                        res_find = {}
Packit Service 0a38ef
Packit Service 0a38ef
                    # Generate adittion and removal lists
Packit Service 0a38ef
                    user_add, user_del = \
Packit Service 0a38ef
                        gen_add_del_lists(users,
Packit Service 0a38ef
                                          res_find.get('member_user', []))
Packit Service 0a38ef
                    group_add, group_del = \
Packit Service 0a38ef
                        gen_add_del_lists(groups,
Packit Service 0a38ef
                                          res_find.get('member_group', []))
Packit Service 0a38ef
                    service_add, service_del = \
Packit Service 0a38ef
                        gen_add_del_lists(services,
Packit Service 0a38ef
                                          res_find.get('member_service', []))
Packit Service 0a38ef
Packit Service 0a38ef
                    owner_add, owner_del = \
Packit Service 0a38ef
                        gen_add_del_lists(owners,
Packit Service 0a38ef
                                          res_find.get('owner_user', []))
Packit Service 0a38ef
Packit Service 0a38ef
                    ownergroups_add, ownergroups_del = \
Packit Service 0a38ef
                        gen_add_del_lists(ownergroups,
Packit Service 0a38ef
                                          res_find.get('owner_group', []))
Packit Service 0a38ef
Packit Service 0a38ef
                    ownerservice_add, ownerservice_del = \
Packit Service 0a38ef
                        gen_add_del_lists(ownerservices,
Packit Service 0a38ef
                                          res_find.get('owner_service', []))
Packit Service 0a38ef
Packit Service 0a38ef
                    # Add users and groups
Packit Service 0a38ef
                    user_add_args = gen_member_args(args, user_add,
Packit Service 0a38ef
                                                    group_add, service_add)
Packit Service 0a38ef
                    if user_add_args is not None:
Packit Service 0a38ef
                        commands.append(
Packit Service 0a38ef
                            [name, 'vault_add_member', user_add_args])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Remove users and groups
Packit Service 0a38ef
                    user_del_args = gen_member_args(args, user_del,
Packit Service 0a38ef
                                                    group_del, service_del)
Packit Service 0a38ef
                    if user_del_args is not None:
Packit Service 0a38ef
                        commands.append(
Packit Service 0a38ef
                            [name, 'vault_remove_member', user_del_args])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Add owner users and groups
Packit Service 0a38ef
                    owner_add_args = gen_member_args(
Packit Service 0a38ef
                        args, owner_add, ownergroups_add, ownerservice_add)
Packit Service 0a38ef
                    if owner_add_args is not None:
Packit Service 0a38ef
                        commands.append(
Packit Service 0a38ef
                            [name, 'vault_add_owner', owner_add_args])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Remove owner users and groups
Packit Service 0a38ef
                    owner_del_args = gen_member_args(
Packit Service 0a38ef
                        args, owner_del, ownergroups_del, ownerservice_del)
Packit Service 0a38ef
                    if owner_del_args is not None:
Packit Service 0a38ef
                        commands.append(
Packit Service 0a38ef
                            [name, 'vault_remove_owner', owner_del_args])
Packit Service 0a38ef
Packit Service 0a38ef
                elif action in "member":
Packit Service 0a38ef
                    # Add users and groups
Packit Service 0a38ef
                    if any([users, groups, services]):
Packit Service 0a38ef
                        user_args = gen_member_args(args, users, groups,
Packit Service 0a38ef
                                                    services)
Packit Service 0a38ef
                        commands.append([name, 'vault_add_member', user_args])
Packit Service 0a38ef
                    if any([owners, ownergroups, ownerservices]):
Packit Service 0a38ef
                        owner_args = gen_member_args(args, owners, ownergroups,
Packit Service 0a38ef
                                                     ownerservices)
Packit Service 0a38ef
                        commands.append([name, 'vault_add_owner', owner_args])
Packit Service 0a38ef
Packit Service 0a38ef
                pwdargs = data_storage_args(
Packit Service 0a38ef
                    args, vault_data, password, password_file, private_key,
Packit Service 0a38ef
                    private_key_file, datafile_in, datafile_out)
Packit Service 0a38ef
                if any([vault_data, datafile_in]):
Packit Service 0a38ef
                    commands.append([name, "vault_archive", pwdargs])
Packit Service 0a38ef
Packit Service a166ed
                cmds = change_password(
Packit Service a166ed
                    ansible_module, res_find, password, password_file,
Packit Service a166ed
                    new_password, new_password_file)
Packit Service a166ed
                commands.extend(cmds)
Packit Service a166ed
Packit Service 0a38ef
            elif state == "retrieved":
Packit Service 0a38ef
                if res_find is None:
Packit Service 0a38ef
                    ansible_module.fail_json(
Packit Service 0a38ef
                        msg="Vault `%s` not found to retrieve data." % name)
Packit Service 0a38ef
Packit Service 0a38ef
                # verify data encription args
Packit Service 0a38ef
                check_encryption_params(
Packit Service 0a38ef
                    ansible_module, state, action, vault_type, salt, password,
Packit Service 0a38ef
                    password_file, public_key, public_key_file, private_key,
Packit Service 0a38ef
                    private_key_file, vault_data, datafile_in, datafile_out,
Packit Service a166ed
                    new_password, new_password_file, res_find)
Packit Service 0a38ef
Packit Service 0a38ef
                pwdargs = data_storage_args(
Packit Service 0a38ef
                    args, vault_data, password, password_file, private_key,
Packit Service 0a38ef
                    private_key_file, datafile_in, datafile_out)
Packit Service 0a38ef
                if 'data' in pwdargs:
Packit Service 0a38ef
                    del pwdargs['data']
Packit Service 0a38ef
Packit Service 0a38ef
                commands.append([name, "vault_retrieve", pwdargs])
Packit Service 0a38ef
Packit Service 0a38ef
            elif state == "absent":
Packit Service 0a38ef
                if 'ipavaulttype' in args:
Packit Service 0a38ef
                    del args['ipavaulttype']
Packit Service 0a38ef
Packit Service 0a38ef
                if action == "vault":
Packit Service 0a38ef
                    if res_find is not None:
Packit Service 0a38ef
                        commands.append([name, "vault_del", args])
Packit Service 0a38ef
Packit Service 0a38ef
                elif action == "member":
Packit Service 0a38ef
                    # remove users and groups
Packit Service 0a38ef
                    if any([users, groups, services]):
Packit Service 0a38ef
                        user_args = gen_member_args(
Packit Service 0a38ef
                            args, users, groups, services)
Packit Service 0a38ef
                        commands.append(
Packit Service 0a38ef
                            [name, 'vault_remove_member', user_args])
Packit Service 0a38ef
Packit Service 0a38ef
                    if any([owners, ownergroups, ownerservices]):
Packit Service 0a38ef
                        owner_args = gen_member_args(
Packit Service 0a38ef
                            args, owners, ownergroups, ownerservices)
Packit Service 0a38ef
                        commands.append(
Packit Service 0a38ef
                            [name, 'vault_remove_owner', owner_args])
Packit Service 0a38ef
                else:
Packit Service 0a38ef
                    ansible_module.fail_json(
Packit Service 0a38ef
                        msg="Invalid action '%s' for state '%s'" %
Packit Service 0a38ef
                        (action, state))
Packit Service 0a38ef
            else:
Packit Service 0a38ef
                ansible_module.fail_json(msg="Unknown state '%s'" % state)
Packit Service 0a38ef
Packit Service 0a38ef
        # Execute commands
Packit Service 0a38ef
Packit Service 0a38ef
        errors = []
Packit Service 0a38ef
        for name, command, args in commands:
Packit Service 0a38ef
            try:
Packit Service 0a38ef
                result = api_command(ansible_module, command, name, args)
Packit Service 0a38ef
Packit Service 0a38ef
                if command == 'vault_archive':
Packit Service 0a38ef
                    changed = 'Archived data into' in result['summary']
Packit Service 0a38ef
                elif command == 'vault_retrieve':
Packit Service 0a38ef
                    if 'result' not in result:
Packit Service 0a38ef
                        raise Exception("No result obtained.")
Packit Service a166ed
                    if "data" in result["result"]:
Packit Service a166ed
                        data_return = exit_args.setdefault("vault", {})
Packit Service a166ed
                        data_return["data"] = result["result"]["data"]
Packit Service 0a38ef
                    else:
Packit Service a166ed
                        if not datafile_out:
Packit Service a166ed
                            raise Exception("No data retrieved.")
Packit Service 0a38ef
                    changed = False
Packit Service 0a38ef
                else:
Packit Service 0a38ef
                    if "completed" in result:
Packit Service 0a38ef
                        if result["completed"] > 0:
Packit Service 0a38ef
                            changed = True
Packit Service 0a38ef
                    else:
Packit Service 0a38ef
                        changed = True
Packit Service 0a38ef
            except EmptyModlist:
Packit Service 0a38ef
                result = {}
Packit Service 0a38ef
            except Exception as exception:
Packit Service 0a38ef
                ansible_module.fail_json(
Packit Service 0a38ef
                    msg="%s: %s: %s" % (command, name, str(exception)))
Packit Service 0a38ef
Packit Service 0a38ef
            # Get all errors
Packit Service 0a38ef
            # All "already a member" and "not a member" failures in the
Packit Service 0a38ef
            # result are ignored. All others are reported.
Packit Service 0a38ef
            if "failed" in result and len(result["failed"]) > 0:
Packit Service 0a38ef
                for item in result["failed"]:
Packit Service 0a38ef
                    failed_item = result["failed"][item]
Packit Service 0a38ef
                    for member_type in failed_item:
Packit Service 0a38ef
                        for member, failure in failed_item[member_type]:
Packit Service 0a38ef
                            if "already a member" in failure \
Packit Service 0a38ef
                               or "not a member" in failure:
Packit Service 0a38ef
                                continue
Packit Service 0a38ef
                            errors.append("%s: %s %s: %s" % (
Packit Service 0a38ef
                                command, member_type, member, failure))
Packit Service 0a38ef
        if len(errors) > 0:
Packit Service 0a38ef
            ansible_module.fail_json(msg=", ".join(errors))
Packit Service 0a38ef
Packit Service 0a38ef
    except Exception as exception:
Packit Service 0a38ef
        ansible_module.fail_json(msg=str(exception))
Packit Service 0a38ef
Packit Service 0a38ef
    finally:
Packit Service 0a38ef
        temp_kdestroy(ccache_dir, ccache_name)
Packit Service 0a38ef
Packit Service 0a38ef
    # Done
Packit Service a166ed
Packit Service a166ed
    # exit_raw_json is a replacement for ansible_module.exit_json that
Packit Service a166ed
    # does not mask the output.
Packit Service a166ed
    exit_raw_json(ansible_module, changed=changed, **exit_args)
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
if __name__ == "__main__":
Packit Service 0a38ef
    main()