2023-03-29 13:35:19 +02:00

115 lines
3.8 KiB
Python

# GNU General Public License v3.0+ (see COPYING.GPL or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = """
lookup: vault_cloud_config
short_description: Get cloud config
extends_documentation_fragment:
- community.hashi_vault.connection
- community.hashi_vault.connection.plugins
- community.hashi_vault.auth
- community.hashi_vault.auth.plugins
options:
user_path:
description: Path to the user name
required: True
project_name:
description: Cloud project name to use
project_id:
description: Cloud project id to use
domain_id:
description: Cloud domain id to use
domain_name:
description: Cloud domain name to use
_terms:
description: |
Additional options to be set on the cloud config (root level).
type: str
"""
from ansible.errors import AnsibleError
from ansible.utils.display import Display
from ansible_collections.community.hashi_vault.plugins.plugin_utils._hashi_vault_lookup_base import HashiVaultLookupBase
from ansible_collections.community.hashi_vault.plugins.module_utils._hashi_vault_common import HashiVaultValueError
display = Display()
HAS_HVAC = False
try:
import hvac
HAS_HVAC = True
except ImportError:
HAS_HVAC = False
class LookupModule(HashiVaultLookupBase):
def run(self, terms, variables=None, **kwargs):
if not HAS_HVAC:
raise AnsibleError("Please pip install hvac to use the vault_read lookup.")
ret = []
self.set_options(direct=kwargs, var_options=variables)
self.process_deprecations()
self.connection_options.process_connection_options()
client_args = self.connection_options.get_hvac_connection_options()
client = self.helper.get_vault_client(**client_args)
try:
self.authenticator.validate()
self.authenticator.authenticate(client)
except (NotImplementedError, HashiVaultValueError) as e:
raise AnsibleError(e)
user_path = self.get_option('user_path')
auth_attrs = ['auth_url', 'user_domain_id', 'user_domain_name',
'username', 'password', 'token']
cloud_config = {'auth': {}}
user_data = None
try:
data = client.read(user_path)
try:
if not data:
raise AnsibleError(
f"No data at path '{user_path}'.")
# sentinel field checks
check_dd = data['data']['data']
check_md = data['data']['metadata']
# unwrap nested data
auth = data['data']['data']
for k, v in auth.items():
# We want only supported keys to remain under auth. All
# rest are placed as root props
if k in auth_attrs:
cloud_config['auth'][k] = v
else:
cloud_config[k] = v
except KeyError:
pass
except hvac.exceptions.Forbidden:
raise AnsibleError(
f"Forbidden: Permission Denied to path '{user_path}'.")
# We allow asking for specific project/domain
for opt in ['domain_id', 'domain_name', 'project_name', 'project_id']:
opt_val = self.get_option(opt)
if opt_val:
cloud_config['auth'][opt] = opt_val
# Add all other options passed as terms
for term in terms:
try:
dt = term.split('=')
val = dt[1]
cloud_config[dt[0]] = val if not val.isnumeric() else int(val)
except IndexError:
pass
ret.append(cloud_config)
return ret