From 5604726bf7f92ab75d4f9b5a063dfb9dfb6bcfdc Mon Sep 17 00:00:00 2001 From: Liam Young Date: Wed, 27 Sep 2023 06:54:27 +0000 Subject: [PATCH] Always use config flags for ldap options Rather than trying to modle the 50+ ldap config options in the charms config.yaml, require the user to use the config flags option to insert them. --- charms/keystone-ldap-k8s/config.yaml | 196 +----------------- charms/keystone-ldap-k8s/src/charm.py | 63 +----- .../tests/unit/test_keystone_ldap_charm.py | 8 +- 3 files changed, 9 insertions(+), 258 deletions(-) diff --git a/charms/keystone-ldap-k8s/config.yaml b/charms/keystone-ldap-k8s/config.yaml index a8599027..2d291337 100644 --- a/charms/keystone-ldap-k8s/config.yaml +++ b/charms/keystone-ldap-k8s/config.yaml @@ -5,62 +5,17 @@ options: description: | Name of the keystone domain to configure; defaults to the deployed application name. - ldap-server: - type: string - default: - description: | - LDAP server URL for keystone LDAP identity backend. - - Examples: - ldap://10.10.10.10/ - ldaps://10.10.10.10/ - ldap://example.com:389,ldaps://ldaps.example.com:636 - ldap://active-directory-host.com:3268/ - ldaps://active-directory-host.com:3269/ - - An ldap:// URL will result in mandatory StartTLS usage if either the - charm's tls-ca-ldap option has been specified or if the 'certificates' - relation is present. - ldap-user: - type: string - default: - description: | - Username (Distinguished Name) used to bind to LDAP identity server. - For anonymous binding, leave ldap-user and ldap-password empty. - - Example: cn=admin,dc=test,dc=com - ldap-password: - type: string - default: - description: | - Password of the LDAP identity server. - For anonymous binding, leave ldap-user and ldap-password empty. - ldap-suffix: - type: string - default: - description: LDAP server suffix to be used by keystone. ldap-config-flags: type: string default: description: | - Additional LDAP configuration options. + The are ~50 LDAP configuration options supported by keystone. Use a json like string with double quotes and braces around all the options and single quotes around complex values. "{user_tree_dn: 'DC=dc1,DC=ad,DC=example,DC=com', user_allow_create: False, user_allow_delete: False}" See the README for more details. - - Note: The explicitly defined ldap-* charm config options take precedence - over the same LDAP config option also specified in ldap-config-flags. - - For example, if the LDAP config query_scope is defined in - ldap-query-scope as 'one' and in ldap-config-flags as - "{query_scope: 'sub'}" then the config query_scope is set to 'one'. - ldap-readonly: - type: boolean - default: True - description: LDAP identity server backend readonly to keystone. tls-ca-ldap: type: string default: null @@ -71,152 +26,3 @@ options: An LDAP url should also be considered as ldaps and StartTLS are both valid methods of using TLS (see RFC 4513) with StartTLS using a non-ldaps url which, of course, still requires a CA certificate. - ldap-query-scope: - type: string - default: - description: | - This option controls the scope level of data presented through LDAP. - ldap-user-tree-dn: - type: string - default: - description: | - This option sets the search base to use for the users. - ldap-user-filter: - type: string - default: - description: | - This option sets the LDAP search filter to use for the users. - ldap-user-objectclass: - type: string - default: - description: | - This option sets the LDAP object class for users. - ldap-user-id-attribute: - type: string - default: - description: | - This option sets the LDAP attribute mapped to User IDs in keystone. - ldap-user-name-attribute: - type: string - default: - description: | - This option sets the LDAP attribute mapped to User names in keystone. - ldap-user-enabled-attribute: - type: string - default: - description: | - This option sets the LDAP attribute mapped to the user enabled - attribute in keystone. - ldap-user-enabled-invert: - type: boolean - default: - description: | - Setting this option to True allows LDAP servers to use lock attributes. - This option has no effect when ldap-user-enabled-mask or - ldap-user-enabled-emulation are in use. - ldap-user-enabled-mask: - type: int - default: - description: | - Bitmask integer to select which bit indicates the enabled value if - the LDAP server represents enabled as a bit on an integer rather - than as a discrete boolean. If the option is set to 0, the mask is - not used. This option is typically used when ldap-user-enabled-attribute - is set to 'userAccessControl'. - ldap-user-enabled-default: - type: string - default: - description: | - The default value to enable users. The LDAP servers can use boolean or - bit in the user enabled attribute to indicate if a user is enabled or - disabled. If boolean is used by the ldap schema, then the appropriate - value for this option is 'True' or 'False'. If bit is used by the ldap - schema, this option should match an appropriate integer value based on - ldap-user-enabled-mask. Please note the integer value should be specified - as a string in quotes. This option is typically used when - ldap-user-enabled-attribute is set to 'userAccountControl'. - - Example: - Configuration options to use for ldap schema with userAccountControl as - control attribute, uses bit 1 in control attribute to indicate - enablement. - - ldap-user-enabled-attribute = "userAccountControl" - ldap-user-enabled-mask = 2 - ldap-user-enabled-default = "512" - - ldap-user-enabled-default should be set to integer value that represents - a user being enabled. For Active Directory, 512 represents Normal Account. - - For more information on how to set up those config options, please refer - to the OpenStack docs on Keystone and LDAP integration at - https://docs.openstack.org/keystone/latest/admin/configuration.html#integrate-identity-back-end-with-ldap - - ldap-user-enabled-emulation: - type: boolean - default: - description: | - If enabled, keystone uses an alternative method to determine if a user - is enabled or not by checking if they are a member of the group defined - by the ldap-user-enabled_emulation-dn option. - ldap-user-enabled-emulation-dn: - type: string - default: - description: | - DN of the group entry to hold enabled users when using enabled - emulation. Setting this option has no effect when - ldap-user-enabled-emulation is False. - ldap-group-tree-dn: - type: string - default: - description: | - This option sets the search base to use for the groups. - ldap-group-objectclass: - type: string - default: - description: | - This option sets the LDAP object class for groups. - ldap-group-id-attribute: - type: string - default: - description: | - This option sets the LDAP attribute mapped to group IDs in keystone. - ldap-group-name-attribute: - type: string - default: - description: | - This option sets the LDAP attribute mapped to group names in keystone. - ldap-group-member-attribute: - type: string - default: - description: | - This option sets the LDAP attribute that indicates user is a member - of the group. - ldap-group-members-are-ids: - type: boolean - default: - description: | - Enable this option if the members of group object class are keystone - user IDs rather than LDAP DNs. - ldap-use-pool: - type: boolean - default: - description: | - This option enables LDAP connection pooling. - ldap-pool-size: - type: int - default: - description: | - This option sets the size of LDAP connection pool. - ldap-pool-retry-max: - type: int - default: - description: | - This option allows to set the maximum number of retry attempts to connect - to LDAP server before aborting. - ldap-pool-connection-timeout: - type: int - default: - description: | - The connection timeout to use when pooling LDAP connections. A value of - -1 means the connection will never timeout. diff --git a/charms/keystone-ldap-k8s/src/charm.py b/charms/keystone-ldap-k8s/src/charm.py index b2807cc4..82aae19b 100755 --- a/charms/keystone-ldap-k8s/src/charm.py +++ b/charms/keystone-ldap-k8s/src/charm.py @@ -36,72 +36,17 @@ from ops.main import main # Log messages can be retrieved using juju debug-log logger = logging.getLogger(__name__) -LDAP_OPTINONS = [ - "server", - "user", - "password", - "suffix", - "readonly", - "query_scope", - "user_tree_dn", - "user_filter", - "user_objectclass", - "user_id_attribute", - "user_name_attribute", - "user_enabled_attribute", - "user_enabled_invert", - "user_enabled_mask", - "user_enabled_default", - "user_enabled_emulation", - "user_enabled_emulation_dn", - "group_tree_dn", - "group_objectclass", - "group_id_attribute", - "group_name_attribute", - "group_member_attribute", - "group_members_are_ids", - "use_pool", - "pool_size", - "pool_retry_max", - "pool_connection_timeout", -] - class LDAPConfigContext(config_contexts.ConfigContext): """Configuration context for cinder parameters.""" def context(self) -> dict: """Generate context information for cinder config.""" - # LDAP config follows the patterns that if a user has - # explicitly set a value then it should be rendered - # otherwise the option is omitted. This is slighttly - # complicated by the fact that the model.config does - # not include settings that have not been set. - context = {} - config_flags = {} - config = self.charm.model.config.get - for option in LDAP_OPTINONS: - config_option = "ldap-" + option.replace("_", "-") - config_value = config(config_option) - if config_value is not None and config_value != "": - context[option] = config_value - raw_config_flags = config("ldap-config-flags") + config = {} + raw_config_flags = self.charm.model.config["ldap-config-flags"] if raw_config_flags: - config_flags = json.loads(raw_config_flags) - for key, value in config_flags.items(): - if key in context.keys(): - logger.warning( - "Ignoring {} passed via ldap-config-flags, please use charm config to manage this setting".format( - key - ) - ) - else: - context[key] = value - if context.get("server"): - # Should probably change the config.yaml rather than having to - # rename the key - context["url"] = context.pop("server") - return {"config": context} + config = json.loads(raw_config_flags) + return {"config": config} class DomainConfigProvidesHandler(sunbeam_rhandlers.RelationHandler): diff --git a/charms/keystone-ldap-k8s/tests/unit/test_keystone_ldap_charm.py b/charms/keystone-ldap-k8s/tests/unit/test_keystone_ldap_charm.py index 55c3bbd5..07c6a02d 100644 --- a/charms/keystone-ldap-k8s/tests/unit/test_keystone_ldap_charm.py +++ b/charms/keystone-ldap-k8s/tests/unit/test_keystone_ldap_charm.py @@ -64,14 +64,14 @@ class TestKeystoneLDAPK8SCharm(test_utils.CharmTestCase): "group_name_attribute": "cn", "group_member_attribute": "memberUid", "group_members_are_ids": "true", + "url": "ldap://10.1.176.184", + "user": "cn=admin,dc=test,dc=com", + "password": "crapper", + "suffix": "dc=test,dc=com", } ) self.harness.update_config( { - "ldap-server": "ldap://10.1.176.184", - "ldap-user": "cn=admin,dc=test,dc=com", - "ldap-password": "crapper", - "ldap-suffix": "dc=test,dc=com", "domain-name": "userdomain", "ldap-config-flags": ldap_config_flags, }