Skip to content

Commit

Permalink
[ADD] Admin user module
Browse files Browse the repository at this point in the history
  • Loading branch information
nitish-ks committed Dec 3, 2024
2 parents e85fcf4 + 3dbceaa commit 543a2a3
Show file tree
Hide file tree
Showing 12 changed files with 581 additions and 16 deletions.
40 changes: 24 additions & 16 deletions plugins/module_utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
NIOS_DTC_TOPOLOGY = 'dtc:topology'
NIOS_EXTENSIBLE_ATTRIBUTE = 'extensibleattributedef'
NIOS_VLAN = 'vlan'
NIOS_ADMINUSER = 'adminuser'

NIOS_PROVIDER_SPEC = {
'host': dict(fallback=(env_fallback, ['INFOBLOX_HOST'])),
Expand Down Expand Up @@ -696,27 +697,28 @@ def compare_objects(self, current_object, proposed_object):
# If the lists are of a different length, the objects cannot be
# equal, and False will be returned before comparing the list items
# this code part will work for members' assignment
if (key in ('members', 'options', 'delegate_to', 'forwarding_servers', 'stub_members')
if (key in ('members', 'options', 'delegate_to', 'forwarding_servers', 'stub_members', 'ssh_keys')
and (len(proposed_item) != len(current_item))):
return False

# Validate the Sequence of the List data
if key in ('external_servers', 'list_values') and not self.verify_list_order(proposed_item, current_item):
return False

for subitem in proposed_item:
if current_item:
# Host IPv4addrs wont contain use_nextserver and nextserver
# If DHCP is false.
dhcp_flag = current_item[0].get('configure_for_dhcp', False)
use_nextserver = subitem.get('use_nextserver', False)
if key == 'ipv4addrs' and not dhcp_flag:
subitem.pop('use_nextserver', None)
subitem.pop('nextserver', None)
elif key == 'ipv4addrs' and dhcp_flag and not use_nextserver:
subitem.pop('nextserver', None)
if not self.issubset(subitem, current_item):
return False
if key == 'ipv4addrs':
for subitem in proposed_item:
if current_item:
# Host IPv4addrs wont contain use_nextserver and nextserver
# If DHCP is false.
dhcp_flag = current_item[0].get('configure_for_dhcp', False)
use_nextserver = subitem.get('use_nextserver', False)
if key == 'ipv4addrs' and not dhcp_flag:
subitem.pop('use_nextserver', None)
subitem.pop('nextserver', None)
elif key == 'ipv4addrs' and dhcp_flag and not use_nextserver:
subitem.pop('nextserver', None)
if not self.issubset(subitem, current_item):
return False

# If the lists are of a different length, the objects and order of element mismatch
# Ignore DHCP options while comparing due to extra num param is get response
Expand Down Expand Up @@ -766,6 +768,11 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec):
except TypeError:
name = obj_filter['name']

return_fields = list(ib_spec.keys())

if (ib_obj_type == NIOS_ADMINUSER):
if 'password' in return_fields: return_fields.remove('password')

if old_name and new_name:
if (ib_obj_type == NIOS_HOST_RECORD):
# to check only by old_name if dns bypassing is set
Expand All @@ -789,7 +796,7 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec):
else:
test_obj_filter = dict([('name', old_name)])
# get the object reference
ib_obj = self.get_object(ib_obj_type, test_obj_filter, return_fields=list(ib_spec.keys()))
ib_obj = self.get_object(ib_obj_type, test_obj_filter, return_fields=return_fields)
if ib_obj:
obj_filter['name'] = new_name
elif old_ipv4addr_exists and (len(ib_obj) == 0):
Expand Down Expand Up @@ -860,7 +867,7 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec):
# check if test_obj_filter is empty copy passed obj_filter
else:
test_obj_filter = obj_filter
return_fields = list(ib_spec.keys())

if ib_obj_type == NIOS_HOST_RECORD:
ipv4addrs_return = [
'ipv4addrs.ipv4addr', 'ipv4addrs.mac', 'ipv4addrs.configure_for_dhcp', 'ipv4addrs.host',
Expand All @@ -871,6 +878,7 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec):
]
return_fields.extend(ipv4addrs_return)
return_fields.extend(ipv6addrs_return)

ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=return_fields)

# prevents creation of a new A record with 'new_ipv4addr' when A record with a particular 'old_ipv4addr' is not found
Expand Down
292 changes: 292 additions & 0 deletions plugins/modules/nios_adminuser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
#!/usr/bin/python
# Copyright (c) 2018-2019 Red Hat, Inc.
# Copyright (c) 2020 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 = '''
---
module: nios_adminuser
author: "Nitish K S (@nitish-ks)"
short_description: Configure Infoblox NIOS Adminuser
version_added: "1.8.0"
description:
- Adds and/or removes instances of adminuser objects from
Infoblox NIOS servers. This module manages NIOS C(adminuser) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox-client
extends_documentation_fragment: infoblox.nios_modules.nios
notes:
- This module supports C(check_mode).
options:
name:
description:
- Specifies the adminuser name to add or remove from the system.
Users can also update the name as it is possible
to pass a dict containing I(new_name), I(old_name). See examples.
required: true
type: str
admin_groups:
description:
- The names of the Admin Groups to which this Admin User belongs.
Currently, this is limited to only one Admin Group.
required: true
type: list
password:
description:
- The password for the administrator to use when logging in.
type: str
no_log: true
auth_method:
description:
- Authentication method for the admin user.
default: KEYPAIR
choices:
- KEYPAIR
- KEYPAIR_PASSWORD
type: str
auth_type:
description:
- Authentication type for the admin user.
default: LOCAL
choices:
- LOCAL
- REMOTE
- SAML
- SAML_LOCAL
type: str
ca_certificate_issuer:
description:
- The CA certificate that is used for user lookup during authentication.
type: str
client_certificate_serial_number:
description:
- The serial number of the client certificate.
type: str
disable:
description:
- Determines whether the admin user is disabled or not. When this is set
to False, the admin user is enabled.
default: false
type: bool
email:
description:
- Email address of the admin user.
type: str
enable_certificate_authentication:
description:
- Determines whether the user is allowed to log in only with the
certificate. Regular username/password authentication will be disabled
for this user.
default: false
type: bool
time_zone:
description:
- The time zone for this admin user.
default: UTC
type: str
use_time_zone:
description:
- Use flag for I(time_zone).
default: false
type: bool
ssh_keys:
description:
- List of SSH keys for the admin user.
type: list
default: []
elements: dict
suboptions:
key_name:
description:
- Unique identifier for the key
type: str
key_type:
description:
- Type of the SSH key.
choices:
- ECDSA
- ED25519
- RSA
type: str
key_value:
description:
- SSH key text.
type: str
use_ssh_keys:
description:
- Enable/disable the ssh keypair authentication.
default: false
type: bool
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''

EXAMPLES = '''
- name: Create a new admin user
infoblox.nios_modules.nios_adminuser:
name: ansible_user
admin_groups: admin-group
password: "secure_password"
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update admin user name
infoblox.nios_modules.nios_adminuser:
name: {new_name: new_user, old_name: ansible_user}
admin_groups: admin-group
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Create admin user with remote authentication
infoblox.nios_modules.nios_adminuser:
name: remote_admin_user
admin_groups: admin-group
auth_type: "REMOTE"
email: "[email protected]"
use_time_zone: true
time_zone: 'US/Hawaii'
extattrs:
Site: "USA"
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Create admin user with ssh keys
infoblox.nios_modules.nios_adminuser:
name: cloud_user
admin_groups: cloud-api-only
comment: "Created by Ansible"
disable : false
password: "secure_password"
use_ssh_keys: true
ssh_keys:
- key_name: "sshkey1"
key_type: "RSA"
key_value: "ssh-rsa AAAAB..."
- key_name: "sshkey2"
key_type: "ECDSA"
key_value: "ecdsa-sha2-nistp256 AAAAE..."
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update admin user to enable certificate authentication
infoblox.nios_modules.nios_adminuser:
name: admin_user
admin_groups: admin-group
enable_certificate_authentication: true
ca_certificate_issuer: "cacertificate/b25lLmVhcF9j..."
client_certificate_serial_number: "397F9435000100000031"
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove admin user
infoblox.nios_modules.nios_adminuser:
name: new_user
admin_groups: admin-group
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''

RETURN = ''' # '''

from ansible.module_utils.basic import AnsibleModule
from ..module_utils.api import WapiModule
from ..module_utils.api import NIOS_ADMINUSER
from ..module_utils.api import normalize_ib_spec


def main():
''' Main entry point for module execution
'''
ssh_key_spec = dict(
key_name=dict(type='str'),
key_type=dict(type='str', choices=['ECDSA', 'ED25519', 'RSA']),
key_value=dict(type='str')
)

ib_spec = dict(
name=dict(required=True, ib_req=True),
admin_groups=dict(type='list', required=True, ib_req=True),
password=dict(no_log=True),
auth_method=dict(default='KEYPAIR', choices=['KEYPAIR', 'KEYPAIR_PASSWORD']),
auth_type=dict(default='LOCAL', choices=['LOCAL', 'REMOTE', 'SAML', 'SAML_LOCAL']),
ca_certificate_issuer=dict(),
client_certificate_serial_number=dict(),
disable=dict(type='bool',default=False),
email=dict(),
enable_certificate_authentication=dict(type='bool',default=False),
time_zone=dict(default='UTC'),
use_time_zone=dict(type='bool',default=False),
ssh_keys=dict(type='list', default=[], elements='dict', options=ssh_key_spec),
use_ssh_keys=dict(type='bool',default=False),
extattrs=dict(type='dict'),
comment=dict()
)

argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)

argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)

module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)

wapi = WapiModule(module)
result = wapi.run(NIOS_ADMINUSER, ib_spec)

module.exit_json(**result)


if __name__ == '__main__':
main()
3 changes: 3 additions & 0 deletions tests/integration/targets/nios_adminuser/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
shippable/cloud/group1
cloud/nios
destructive
3 changes: 3 additions & 0 deletions tests/integration/targets/nios_adminuser/defaults/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
testcase: "*"
test_items: []
3 changes: 3 additions & 0 deletions tests/integration/targets/nios_adminuser/meta/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
dependencies:
- prepare_nios_tests
3 changes: 3 additions & 0 deletions tests/integration/targets/nios_adminuser/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- name: Include idempotence tasks for adminuser
ansible.builtin.include_tasks: nios_adminuser_idempotence.yml
Loading

0 comments on commit 543a2a3

Please sign in to comment.