Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kerberos keys Support for Bloxone Ansible v2 #66

Merged
merged 12 commits into from
Feb 3, 2025
1 change: 1 addition & 0 deletions meta/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ action_groups:
keys:
- tsig_key
- tsig_key_info
- kerberos_key_info
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in TF, we didn't support CRUD for kerberos_key, because it was difficult to do with the way the API was designed and TF data consistency rules. But in Ansible, you should be able to do it.


infra:
- infra_join_token
Expand Down
215 changes: 215 additions & 0 deletions plugins/modules/kerberos_key_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright: Infoblox Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function

__metaclass__ = type

DOCUMENTATION = r"""
---
module: kerberos_key_info
short_description: Retrieves Kerberos Keys
description:
- Retrieves information about existing Kerberos Keys.
version_added: 2.0.0
author: Infoblox Inc. (@infobloxopen)
options:
id:
description:
- ID of the object
type: str
required: false
filters:
description:
- Filter dict to filter objects
type: dict
required: false
filter_query:
description:
- Filter query to filter objects
type: str
required: false
tag_filters:
description:
- Filter dict to filter objects by tags
type: dict
required: false
tag_filter_query:
description:
- Filter query to filter objects by tags
type: str
required: false

extends_documentation_fragment:
- infoblox.bloxone.common
""" # noqa: E501

EXAMPLES = r"""
- name: Get Kerberos key information by filters (principal)
infoblox.bloxone.kerberos_key_info:
filters:
principal: "{{ principal }}"

- name: Get Kerberos key information by raw filter query
infoblox.bloxone.kerberos_key_info:
filter_query: "principal=='{{ principal }}'"

- name: Get Kerberos key information by tag filters
infoblox.bloxone.kerberos_key_info:
tag_filters:
location: "site-1"
"""

RETURN = r"""
id:
description:
- ID of the Kerberos object
type: str
returned: Always
objects:
description:
- Kerberos object
type: list
elements: dict
returned: Always
contains:
algorithm:
description:
- "Encryption algorithm of the key in accordance with RFC 3961."
type: str
returned: Always
comment:
description:
- "The description for Kerberos key. May contain 0 to 1024 characters. Can include UTF-8."
type: str
returned: Always
domain:
description:
- "Kerberos realm of the principal."
type: str
returned: Always
id:
description:
- "The resource identifier."
type: str
returned: Always
principal:
description:
- "Kerberos principal associated with key."
type: str
returned: Always
tags:
description:
- "The tags for the Kerberos key in JSON format."
type: dict
returned: Always
uploaded_at:
description:
- "Upload time for the key."
type: str
returned: Always
version:
description:
- "The version number (KVNO) of the key."
type: int
returned: Always
""" # noqa: E501

from ansible_collections.infoblox.bloxone.plugins.module_utils.modules import BloxoneAnsibleModule

try:
from keys import KerberosApi
from universal_ddi_client import ApiException, NotFoundException
except ImportError:
pass # Handled by BloxoneAnsibleModule


class KerberosKeyInfoModule(BloxoneAnsibleModule):
def __init__(self, *args, **kwargs):
super(KerberosKeyInfoModule, self).__init__(*args, **kwargs)
self._existing = None
self._limit = 1000

def find_by_id(self):
try:
resp = KerberosApi(self.client).read(self.params["id"])
return [resp.result]
except NotFoundException as e:
return None

def find(self):
if self.params["id"] is not None:
return self.find_by_id()

filter_str = None
if self.params["filters"] is not None:
filter_str = " and ".join([f"{k}=='{v}'" for k, v in self.params["filters"].items()])
elif self.params["filter_query"] is not None:
filter_str = self.params["filter_query"]

tag_filter_str = None
if self.params["tag_filters"] is not None:
tag_filter_str = " and ".join([f"{k}=='{v}'" for k, v in self.params["tag_filters"].items()])
elif self.params["tag_filter_query"] is not None:
tag_filter_str = self.params["tag_filter_query"]

all_results = []
offset = 0

while True:
try:
resp = KerberosApi(self.client).list(
offset=offset, limit=self._limit, filter=filter_str, tfilter=tag_filter_str
)
all_results.extend(resp.results)

if len(resp.results) < self._limit:
break
offset += self._limit

except ApiException as e:
self.fail_json(msg=f"Failed to execute command: {e.status} {e.reason} {e.body}")

return all_results

def run_command(self):
result = dict(objects=[])

if self.check_mode:
self.exit_json(**result)

find_results = self.find()

all_results = []
for r in find_results:
all_results.append(r.model_dump(by_alias=True, exclude_none=True))

result["objects"] = all_results
self.exit_json(**result)


def main():
# define available arguments/parameters a user can pass to the module
module_args = dict(
id=dict(type="str", required=False),
filters=dict(type="dict", required=False),
filter_query=dict(type="str", required=False),
tag_filters=dict(type="dict", required=False),
tag_filter_query=dict(type="str", required=False),
)

module = KerberosKeyInfoModule(
argument_spec=module_args,
supports_check_mode=True,
mutually_exclusive=[
["id", "filters", "filter_query"],
["id", "tag_filters", "tag_filter_query"],
],
)
module.run_command()


if __name__ == "__main__":
main()
71 changes: 71 additions & 0 deletions tests/integration/targets/keys_kerberos_info/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
- module_defaults:
group/infoblox.bloxone.all:
portal_url: "{{ portal_url }}"
portal_key: "{{ portal_key }}"

block:
- ansible.builtin.set_fact:
principal: "DNS/ns.b1ddi.neo1.com"
tag_value: "tf_acc_test"

- name: Get Kerberos key information by Filters (domain)
infoblox.bloxone.kerberos_key_info:
filters:
domain: "NEO1.COM"
register: kerberos_info
- assert:
that:
- kerberos_info.objects | length == 5
- kerberos_info.objects[0].algorithm is defined
- kerberos_info.objects[0].domain is defined
- kerberos_info.objects[0].id is defined
- kerberos_info.objects[0].principal == "DNS/ns.b1ddi.neo1.com"
- kerberos_info.objects[0].domain == "NEO1.COM"
- kerberos_info.objects[0].uploaded_at is defined
- kerberos_info.objects[0].version is defined

- name: Get Kerberos key information by Filters (principal)
infoblox.bloxone.kerberos_key_info:
filters:
principal: "{{ principal }}"
register: kerberos_info
- assert:
that:
- kerberos_info.objects | length == 5
- kerberos_info.objects[0].algorithm is defined
- kerberos_info.objects[0].domain is defined
- kerberos_info.objects[0].id is defined
- kerberos_info.objects[0].principal == "DNS/ns.b1ddi.neo1.com"
- kerberos_info.objects[0].uploaded_at is defined
- kerberos_info.objects[0].version is defined

- name: Get Kerberos key information by filter query
infoblox.bloxone.kerberos_key_info:
filter_query: "principal=='{{ principal }}'"
register: kerberos_info
- assert:
that:
- kerberos_info.objects | length == 5
- kerberos_info.objects[0].algorithm is defined
- kerberos_info.objects[0].domain is defined
- kerberos_info.objects[0].id is defined
- kerberos_info.objects[0].principal == "DNS/ns.b1ddi.neo1.com"
- kerberos_info.objects[0].uploaded_at is defined
- kerberos_info.objects[0].version is defined

- name: Get Kerberos key information by tag filters
infoblox.bloxone.kerberos_key_info:
tag_filters:
used_for: "{{ tag_value }}"
register: kerberos_info
- assert:
that:
- kerberos_info.objects | length == 5
- kerberos_info.objects[0].algorithm is defined
- kerberos_info.objects[0].domain is defined
- kerberos_info.objects[0].id is defined
- kerberos_info.objects[0].principal == "DNS/ns.b1ddi.neo1.com"
- kerberos_info.objects[0].tags.used_for == "tf_acc_test"
- kerberos_info.objects[0].uploaded_at is defined
- kerberos_info.objects[0].id is defined