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

Add option to roles to enforce defaults #567

Merged
merged 11 commits into from
Apr 10, 2023
Merged
8 changes: 8 additions & 0 deletions .github/workflows/ci_standalone_versioned.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ jobs:
- name: Display Versions
run: which python && pip --version && ansible --version

- name: Build and install the collection
uses: redhat-cop/ansible_collections_tooling/actions/build_ansible_collection@main
with:
collection_namespace: infra
collection_name: controller_configuration
collection_version: 2.0.0
collection_repo: https://github.com/redhat-cop/controller_configuration/

- name: "Install Galaxy dependencies"
run: ansible-galaxy collection install -r .github/collections/requirements.yml

Expand Down
2 changes: 1 addition & 1 deletion ansible.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[defaults]
collections_paths=collections
collections_paths=collections:/home/runner/collections
roles_path=roles/
lookup_plugins=plugins/lookup/
4 changes: 4 additions & 0 deletions changelogs/fragments/enforce_defaults.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
minor_changes:
djdanielsson marked this conversation as resolved.
Show resolved Hide resolved
- added option to multiple roles to enforce defaults. This is described in each of the roles readmes and will slowly be rolled out to all applicable roles. This option enforces module/api defaults in order to prevent config drift. This makes it so if an option is NOT specified in a configuration it enforces the default value. It is not enabled by default.
...
74 changes: 74 additions & 0 deletions plugins/lookup/enforce_defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# (c) 2020 Ansible Project
# 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 = """
name: enforce_defaults
author: "Sean Sullivan (@sean-m-sullivan)"
version_added: "2.4.0"
short_description: Return difference for objects from Controller API
requirements:
- None
description:
- This plugin is used to return what the default value should be depending on conditions.
- If enforce default is true, it will return the default value. Otherwise it will return the omit.
- This is so the value used for the default filter can be turned on and off.
options:
enforce_default:
description: Whether to enforce the default value or use omit.
type: bool
default: False
default_value:
description:
- Value to supply if enforce_default is True.
- This should be empty value or some form of string.
default: ''
omit_value:
description:
- the omit value
type: str
default: ''
"""

EXAMPLES = """
- name: Test Filter
ansible.builtin.debug:
msg: "{{ nothing | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=false , default_value='', omit_value=omit), false) }}"

"""

RETURN = """
_raw:
description:
- Will either return the omit value, or the default value.
"""

from ansible.plugins.lookup import LookupBase
from ansible.errors import AnsibleError
from ansible.module_utils._text import to_native
from ansible.utils.display import Display


class LookupModule(LookupBase):
display = Display()

def handle_error(self, **kwargs):
raise AnsibleError(to_native(kwargs.get("msg")))

def warn_callback(self, warning):
self.display.warning(warning)

def run(self, terms, variables=None, **kwargs):
self.set_options(direct=kwargs)

# Set Variables for user input
enforce_default = self.get_option("enforce_default")
default_value = self.get_option("default_value")
omit_value = self.get_option("omit_value")

if enforce_default:
return [default_value]
else:
return [omit_value]
16 changes: 16 additions & 0 deletions roles/applications/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ Currently:
|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.||
|`controller_applications`|`see below`|yes|Data structure describing your applications, described below.||

### Enforcing defaults

The following Variables compliment each other.
If Both variables are not set, enforcing default values is not done.
Enabling these variables enforce default values on options that are optional in the controller API.
This should be enabled to enforce configuration and prevent configuration drift. It is recomended to be enabled, however it is not enforced by default.

Enabling this will enforce configurtion without specifying every option in the configuration files.

'controller_configuration_applications_enforce_defaults' defaults to the value of 'controller_configuration_enforce_defaults' if it is not explicitly called. This allows for enforced defaults to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it.

|Variable Name|Default Value|Required|Description|
|:---:|:---:|:---:|:---:|
|`controller_configuration_applications_enforce_defaults`|`False`|no|Whether or not to enforce default option values on only the applications role|
|`controller_configuration_enforce_defaults`|`False`|no|This variable enables enforced default values as well, but is shared across multiple roles, see above.|

### Secure Logging Variables

The following Variables compliment each other.
Expand Down
1 change: 1 addition & 0 deletions roles/applications/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ controller_applications: []
controller_configuration_applications_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}"
controller_configuration_applications_async_retries: "{{ controller_configuration_async_retries | default(30) }}"
controller_configuration_applications_async_delay: "{{ controller_configuration_async_delay | default(1) }}"
controller_configuration_applications_enforce_defaults: "{{ controller_configuration_enforce_defaults | default('false') }}"
...
4 changes: 2 additions & 2 deletions roles/applications/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
name: "{{ __application_item.name | mandatory }}"
new_name: "{{ __application_item.new_name | default(omit, true) }}"
organization: "{{ __application_item.organization | mandatory }}"
description: "{{ __application_item.description | default(omit, true) }}"
description: "{{ __application_item.description | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_applications_enforce_defaults , default_value='', omit_value=omit), true) }}"
djdanielsson marked this conversation as resolved.
Show resolved Hide resolved
authorization_grant_type: "{{ __application_item.authorization_grant_type | default('password') }}"
client_type: "{{ __application_item.client_type | default('public') }}"
redirect_uris: "{{ __application_item.redirect_uris | default([]) }}"
skip_authorization: "{{ __application_item.skip_authorization | default(omit) }}"
skip_authorization: "{{ __application_item.skip_authorization | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_applications_enforce_defaults , default_value=false, omit_value=omit), true) }}"
state: "{{ __application_item.state | default(controller_state | default('present')) }}"

# Role specific options
Expand Down
16 changes: 16 additions & 0 deletions roles/organizations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ Currently:
|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|||
|`controller_organizations`|`see below`|yes|Data structure describing your organization or organizations Described below.||

### Enforcing defaults

The following Variables compliment each other.
If Both variables are not set, enforcing default values is not done.
Enabling these variables enforce default values on options that are optional in the controller API.
This should be enabled to enforce configuration and prevent configuration drift. It is recomended to be enabled, however it is not enforced by default.

Enabling this will enforce configurtion without specifying every option in the configuration files.

'controller_configuration_organizations_enforce_defaults' defaults to the value of 'controller_configuration_enforce_defaults' if it is not explicitly called. This allows for enforced defaults to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it.

|Variable Name|Default Value|Required|Description|
|:---:|:---:|:---:|:---:|
|`controller_configuration_organizations_enforce_defaults`|`False`|no|Whether or not to enforce default option values on only the applications role|
|`controller_configuration_enforce_defaults`|`False`|no|This variable enables enforced default values as well, but is shared across multiple roles, see above.|

### Secure Logging Variables

The following Variables compliment each other.
Expand Down
1 change: 1 addition & 0 deletions roles/organizations/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ controller_organizations: []
controller_configuration_organizations_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}"
controller_configuration_organizations_async_retries: "{{ controller_configuration_async_retries | default(30) }}"
controller_configuration_organizations_async_delay: "{{ controller_configuration_async_delay | default(1) }}"
controller_configuration_organizations_enforce_defaults: "{{ controller_configuration_enforce_defaults | default('false') }}"
assign_galaxy_credentials_to_org: true
assign_default_ee_to_org: true
...
16 changes: 8 additions & 8 deletions roles/organizations/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
- name: Add organizations
organization:
name: "{{ __controller_organizations_item.name | mandatory }}"
description: "{{ __controller_organizations_item.description | default(omit, true) }}"
description: "{{ __controller_organizations_item.description | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_organizations_enforce_defaults , default_value='', omit_value=omit), true) }}"
custom_virtualenv: "{{ __controller_organizations_item.custom_virtualenv | default(omit, true) }}"
max_hosts: "{{ __controller_organizations_item.max_hosts | default(omit, true) }}"
instance_groups: "{{ __controller_organizations_item.instance_groups | default(omit, true) }}"
max_hosts: "{{ __controller_organizations_item.max_hosts | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_organizations_enforce_defaults , default_value=0, omit_value=omit), true) }}"
instance_groups: "{{ __controller_organizations_item.instance_groups | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_organizations_enforce_defaults , default_value=[], omit_value=omit), true) }}"
default_environment: "{{ (__controller_organizations_item.default_environment.name | default(__controller_organizations_item.execution_environment | default(omit))) if (assign_default_ee_to_org is defined and assign_default_ee_to_org) else omit }}"
galaxy_credentials: "{{ (__controller_organizations_item.galaxy_credentials | default(omit)) if (assign_galaxy_credentials_to_org is defined and assign_galaxy_credentials_to_org) else omit }}"
notification_templates_approvals: "{{ __controller_organizations_item.notification_templates_approvals | default(__controller_organizations_item.related.notification_templates_approvals | default([]) | map(attribute='name') | list) | default(omit, true) }}"
notification_templates_started: "{{ __controller_organizations_item.notification_templates_started | default(__controller_organizations_item.related.notification_templates_started | default([]) | map(attribute='name') | list) | default(omit, true) }}"
notification_templates_success: "{{ __controller_organizations_item.notification_templates_success | default(__controller_organizations_item.related.notification_templates_success | default([]) | map(attribute='name') | list) | default(omit, true) }}"
notification_templates_error: "{{ __controller_organizations_item.notification_templates_error | default(__controller_organizations_item.related.notification_templates_error | default([]) | map(attribute='name') | list) | default(omit, true) }}"
galaxy_credentials: "{{ (__controller_organizations_item.galaxy_credentials | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_organizations_enforce_defaults , default_value=[], omit_value=omit), true)) if (assign_galaxy_credentials_to_org is defined and assign_galaxy_credentials_to_org) else omit }}"
notification_templates_approvals: "{{ __controller_organizations_item.notification_templates_approvals | default(__controller_organizations_item.related.notification_templates_approvals | default([]) | map(attribute='name') | list) | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_organizations_enforce_defaults , default_value=[], omit_value=omit), true) }}"
notification_templates_started: "{{ __controller_organizations_item.notification_templates_started | default(__controller_organizations_item.related.notification_templates_started | default([]) | map(attribute='name') | list) | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_organizations_enforce_defaults , default_value=[], omit_value=omit), true) }}"
notification_templates_success: "{{ __controller_organizations_item.notification_templates_success | default(__controller_organizations_item.related.notification_templates_success | default([]) | map(attribute='name') | list) | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_organizations_enforce_defaults , default_value=[], omit_value=omit), true) }}"
notification_templates_error: "{{ __controller_organizations_item.notification_templates_error | default(__controller_organizations_item.related.notification_templates_error | default([]) | map(attribute='name') | list) | default(lookup('infra.controller_configuration.enforce_defaults', enforce_default=controller_configuration_organizations_enforce_defaults , default_value=[], omit_value=omit), true) }}"
state: "{{ __controller_organizations_item.state | default(controller_state | default('present')) }}"

# Role Standard Options
Expand Down
1 change: 1 addition & 0 deletions tests/configs/controller_auth.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
controller_username: admin
controller_password: password
controller_validate_certs: false
controller_configuration_enforce_defaults: true
...