charmlibs-interfaces-ldap 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,187 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+ cos-tool*
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .coverage-*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+ .report/
55
+
56
+ # Translations
57
+ *.mo
58
+ *.pot
59
+
60
+ # Django stuff:
61
+ *.log
62
+ local_settings.py
63
+ db.sqlite3
64
+ db.sqlite3-journal
65
+
66
+ # Flask stuff:
67
+ instance/
68
+ .webassets-cache
69
+
70
+ # Scrapy stuff:
71
+ .scrapy
72
+
73
+ # Sphinx documentation
74
+ docs/_build/
75
+
76
+ # PyBuilder
77
+ .pybuilder/
78
+ target/
79
+
80
+ # Jupyter Notebook
81
+ .ipynb_checkpoints
82
+
83
+ # IPython
84
+ profile_default/
85
+ ipython_config.py
86
+
87
+ # pyenv
88
+ # For a library or package, you might want to ignore these files since the code is
89
+ # intended to run in multiple environments; otherwise, check them in:
90
+ # .python-version
91
+
92
+ # pipenv
93
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
95
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
96
+ # install all needed dependencies.
97
+ #Pipfile.lock
98
+
99
+ # UV
100
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
101
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
102
+ # commonly ignored for libraries.
103
+ #uv.lock
104
+
105
+ # poetry
106
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
107
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
108
+ # commonly ignored for libraries.
109
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
110
+ #poetry.lock
111
+
112
+ # pdm
113
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
114
+ #pdm.lock
115
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
116
+ # in version control.
117
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
118
+ .pdm.toml
119
+ .pdm-python
120
+ .pdm-build/
121
+
122
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
123
+ __pypackages__/
124
+
125
+ # Celery stuff
126
+ celerybeat-schedule
127
+ celerybeat.pid
128
+
129
+ # SageMath parsed files
130
+ *.sage.py
131
+
132
+ # Environments
133
+ .env
134
+ .venv
135
+ env/
136
+ venv/
137
+ ENV/
138
+ env.bak/
139
+ venv.bak/
140
+
141
+ # Spyder project settings
142
+ .spyderproject
143
+ .spyproject
144
+
145
+ # Rope project settings
146
+ .ropeproject
147
+
148
+ # mkdocs documentation
149
+ /site
150
+
151
+ # mypy
152
+ .mypy_cache/
153
+ .dmypy.json
154
+ dmypy.json
155
+
156
+ # Pyre type checker
157
+ .pyre/
158
+
159
+ # pytype static type analyzer
160
+ .pytype/
161
+
162
+ # Cython debug symbols
163
+ cython_debug/
164
+
165
+ # PyCharm
166
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
167
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
168
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
169
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
170
+ .idea/
171
+
172
+ # PyPI configuration file
173
+ .pypirc
174
+
175
+ # packed charms
176
+ .packed
177
+
178
+ # temporary directory for packing charms
179
+ .tmp
180
+
181
+ # uv.lock from example libraries as we don't commit these
182
+ .example/**/uv.lock
183
+ .tutorial/**/uv.lock
184
+ interfaces/.example/**/uv.lock
185
+
186
+ # Workshop lock file (machine-local state)
187
+ .workshop.lock
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ Initial release. Migrated from `charms.glauth_k8s.v0.ldap` (v0.13).
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: charmlibs-interfaces-ldap
3
+ Version: 1.0.0
4
+ Summary: The charmlibs.interfaces.ldap package.
5
+ Project-URL: Documentation, https://canonical.com/juju/docs/charmlibs/reference/charmlibs/interfaces/ldap
6
+ Project-URL: Repository, https://github.com/canonical/charmlibs/tree/main/interfaces/ldap
7
+ Project-URL: Issues, https://github.com/canonical/charmlibs/issues
8
+ Project-URL: Changelog, https://github.com/canonical/charmlibs/blob/main/interfaces/ldap/CHANGELOG.md
9
+ Author: Identity Team at Canonical
10
+ License-Expression: Apache-2.0
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: ops<4,>=2.23.1
17
+ Requires-Dist: pydantic>=2.13.4
18
+ Description-Content-Type: text/markdown
19
+
20
+ # charmlibs.interfaces.ldap
21
+
22
+ The `ldap` interface library.
23
+
24
+ To install, add `charmlibs-interfaces-ldap` to your Python dependencies. Then in your Python code, import as:
25
+
26
+ ```py
27
+ from charmlibs.interfaces import ldap
28
+ ```
29
+
30
+ See the [reference documentation](https://canonical.com/juju/docs/charmlibs/reference/charmlibs/interfaces/ldap) for more.
@@ -0,0 +1,11 @@
1
+ # charmlibs.interfaces.ldap
2
+
3
+ The `ldap` interface library.
4
+
5
+ To install, add `charmlibs-interfaces-ldap` to your Python dependencies. Then in your Python code, import as:
6
+
7
+ ```py
8
+ from charmlibs.interfaces import ldap
9
+ ```
10
+
11
+ See the [reference documentation](https://canonical.com/juju/docs/charmlibs/reference/charmlibs/interfaces/ldap) for more.
@@ -0,0 +1,93 @@
1
+ # `ldap/v0`
2
+
3
+ ## Usage
4
+
5
+ This relation interface describes the expected behavior of any charm claiming to
6
+ be able to provide or consume the LDAP authentication configuration data.
7
+
8
+ ## Glossary of LDAP Terms
9
+
10
+ | Abbreviation | Term |
11
+ |:------------:|:--------------------------:|
12
+ | DN | Distinguished Name |
13
+ | DIT | Directory Information Tree |
14
+
15
+ ## Direction
16
+
17
+ ```mermaid
18
+ flowchart TD
19
+ Requirer -- user, \ngroup --> Provider
20
+ Provider -- urls, \nbase_dn, \nbind_dn, \nbind_password_secret, \nauth_method, \nstarttls --> Requirer
21
+ ```
22
+
23
+ ## Behavior
24
+
25
+ Both the `provider` and the `requirer` need to adhere to a certain set of
26
+ criteria to be considered compatible with the `ldap` interface.
27
+
28
+ Sensitive information is transmitted through Juju Secrets rather than directly
29
+ through the relation databag(s).
30
+
31
+ ### Provider
32
+
33
+ - Is expected to use `user` and `group` provided by the `requirer` to create a
34
+ bind DN in the DIT for the `requirer` to use for the `bind` operation. If
35
+ the `requirer` does not provide `user` and `group`, the `provider`
36
+ leverages `requirer`'s Juju application name and model name.
37
+ - Is expected to provide the `requirer` with necessary configuration for
38
+ performing LDAP authentications and operations.
39
+ - Is expected to update the application databag if any field's data is changed
40
+ in the `provider` charmed application.
41
+
42
+ ### Requirer
43
+
44
+ - Is expected to optionally provide `user` and `group` for the `provider` to
45
+ generate the bind DN.
46
+ - Is expected to consume the LDAP configuration data provided by the `provider`
47
+ to configure the `requirer`'s charmed application.
48
+
49
+ > #### ⚠️ Use of special characters
50
+ > Try to avoid the special characters
51
+ > listed [here](https://datatracker.ietf.org/doc/html/rfc2253#section-2.4)
52
+ > for the `user` and `group` in the `requirer`'s databag.
53
+
54
+ ## Relation Data
55
+
56
+ [\[Pydantic Schema\]](./schema.py)
57
+
58
+ ### Provider
59
+
60
+ The `provider` provides LDAP URL, base DN, and bind DN, and LDAP
61
+ authentication method for the `requirer` to connect and perform LDAP operations.
62
+ It should be placed in the **application** databag.
63
+
64
+ #### Example
65
+
66
+ ```yaml
67
+ relation-info:
68
+ - endpoint: ldap
69
+ related-endpoint: ldap
70
+ application-data:
71
+ urls: [ldap://ldap.canonical.com:3893, ldap://ldap.ubuntu.com:3893]
72
+ base_dn: dc=canonical,dc=com
73
+ bind_dn: cn=app,ou=model,dc=canonical,dc=com
74
+ bind_password_secret: secret://59060ecc-0495-4a80-8006-5f1fc13fd783/cjqub6vubg2s77p3nio0
75
+ auth_method: simple
76
+ starttls: true
77
+ ``````
78
+
79
+ ### Requirer
80
+
81
+ The `requirer` provides LDAP client information. It should be placed in the
82
+ **application** databag.
83
+
84
+ #### Example
85
+
86
+ ```yaml
87
+ relation-info:
88
+ - endpoint: ldap
89
+ related-endpoint: ldap
90
+ application-data:
91
+ user: sssd
92
+ group: machine-localhost
93
+ ```
@@ -0,0 +1,19 @@
1
+ name: ldap
2
+ version: 0
3
+ status: draft
4
+ lib: charmlibs.interfaces.ldap
5
+ summary: Configure and connect to a Lightweight Directory Access Protocol (LDAP) server.
6
+ description: |
7
+ The `ldap` interface supports sharing configuration and connection information for a Lightweight Directory Access Protocol (LDAP) server.
8
+ The provider is responsible for sharing the LDAP URL and other information needed for the requirer to connect and perform LDAP operations.
9
+
10
+ providers:
11
+ - name: glauth-k8s
12
+ url: https://github.com/canonical/glauth-k8s-operator
13
+ - name: authentik-ldap-outpost
14
+ url: https://github.com/canonical/authentik-ldap-outpost-operator
15
+ requirers:
16
+ - name: sssd
17
+ url: https://github.com/canonical/sssd-operator
18
+
19
+ maintainer: identity
@@ -0,0 +1,72 @@
1
+ # Copyright 2026 Canonical Ltd.
2
+ # See LICENSE file for licensing details.
3
+
4
+ """LDAP relation schema definitions.
5
+
6
+ This file defines the schemas for the provider and requirer sides of this
7
+ relation interface.
8
+
9
+ It must expose two interfaces.schema_base.DataBagSchema subclasses called:
10
+ - ProviderSchema
11
+ - RequirerSchema
12
+ """
13
+
14
+ from interface_tester.schema_base import DataBagSchema
15
+ from pydantic import AnyUrl, BaseModel, Field
16
+
17
+
18
+ class LdapProviderData(BaseModel):
19
+ """LDAP provider relation data schema."""
20
+
21
+ urls: list[AnyUrl] = Field(
22
+ description='List of LDAP URLs',
23
+ title='LDAP URLs',
24
+ example=['ldap://ldap.canonical.com:3893', 'ldap://ldap.ubuntu.com:3893'],
25
+ )
26
+ base_dn: str = Field(
27
+ description='The base entry as the starting point for LDAP search operation',
28
+ title='Base DN',
29
+ example='dc=canonical,dc=com',
30
+ )
31
+ bind_dn: str = Field(
32
+ description='The distinguished name (DN) of the bind account',
33
+ title='Bind DN',
34
+ example='cn=admin,ou=engineering,dc=canonical,dc=com',
35
+ )
36
+ bind_password_secret: str = Field(
37
+ description="The juju secret ID of the bind account's password",
38
+ example='secret://59060ecc-0495-4a80-8006-5f1fc13fd783/cjqub6vubg2s77p3nio0',
39
+ )
40
+ auth_method: str = Field(
41
+ description='The LDAP authentication method',
42
+ title='Authentication Method',
43
+ example='simple',
44
+ )
45
+ starttls: bool = Field(
46
+ description='The indicator of StartTLS operation enabled or not',
47
+ title='StartTLS',
48
+ example=True,
49
+ )
50
+
51
+
52
+ class LdapRequirerData(BaseModel):
53
+ """LDAP requirer relation data schema."""
54
+
55
+ user: str | None = Field(
56
+ description='The user name provided by the requirer charmed operator',
57
+ )
58
+ group: str | None = Field(
59
+ description='The group name provided by the requirer charmed operator',
60
+ )
61
+
62
+
63
+ class ProviderSchema(DataBagSchema):
64
+ """The schema for the provider side of the ldap interface."""
65
+
66
+ app: LdapProviderData
67
+
68
+
69
+ class RequirerSchema(DataBagSchema):
70
+ """The schema for the requirer side of the ldap interface."""
71
+
72
+ app: LdapRequirerData
@@ -0,0 +1,100 @@
1
+ [project]
2
+ name = "charmlibs-interfaces-ldap"
3
+ description = "The charmlibs.interfaces.ldap package."
4
+ readme = "README.md"
5
+ requires-python = ">=3.10"
6
+ authors = [
7
+ {name="Identity Team at Canonical"},
8
+ ]
9
+ license = "Apache-2.0"
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3",
12
+ "Intended Audience :: Developers",
13
+ "Operating System :: POSIX :: Linux",
14
+ "Development Status :: 5 - Production/Stable",
15
+ ]
16
+ dynamic = ["version"]
17
+ dependencies = [
18
+ # Libraries should use clear but wide dependency bounds to avoid overly constraining charms.
19
+ # Ops 3 is backwards compatible with Ops 2, but drops Python 3.8 support.
20
+ # Ops 3 has new features not present in Ops 2.23 (the last Ops 2 feature release).
21
+ # See the Ops 2.23 maintenance branch changelog and the Ops 3 changelog for current information:
22
+ # - https://github.com/canonical/operator/blob/2.23-maintenance/CHANGES.md
23
+ # - https://github.com/canonical/operator/blob/main/CHANGES.md
24
+ # Set the dependency bounds according to the features and fixes your library needs.
25
+ "ops>=2.23.1,<4",
26
+ "pydantic>=2.13.4",
27
+ ]
28
+
29
+ [dependency-groups]
30
+ lint = [ # installed for `just lint interfaces/ldap` (unit, functional, and integration are also installed)
31
+ # "typing_extensions",
32
+ ]
33
+ unit = [ # installed for `just unit interfaces/ldap`
34
+ "ops[testing]",
35
+ "charmlibs-interfaces-ldap",
36
+ ]
37
+ functional = [ # installed for `just functional interfaces/ldap`
38
+ ]
39
+ integration = [ # installed for `just integration interfaces/ldap`
40
+ "jubilant",
41
+ ]
42
+
43
+ [project.urls]
44
+ "Documentation" = "https://canonical.com/juju/docs/charmlibs/reference/charmlibs/interfaces/ldap"
45
+ "Repository" = "https://github.com/canonical/charmlibs/tree/main/interfaces/ldap"
46
+ "Issues" = "https://github.com/canonical/charmlibs/issues"
47
+ "Changelog" = "https://github.com/canonical/charmlibs/blob/main/interfaces/ldap/CHANGELOG.md"
48
+
49
+ [build-system]
50
+ requires = ["hatchling"]
51
+ build-backend = "hatchling.build"
52
+
53
+ [tool.hatch.build.targets.wheel]
54
+ packages = ["src/charmlibs"]
55
+
56
+ [tool.hatch.version]
57
+ path = "src/charmlibs/interfaces/ldap/_version.py"
58
+
59
+ [tool.uv.sources]
60
+
61
+
62
+ [tool.ruff]
63
+ extend = "../../pyproject.toml"
64
+ src = ["src", "tests/unit", "tests/functional", "tests/integration"] # correctly sort local imports in tests
65
+
66
+ [tool.ruff.lint.extend-per-file-ignores]
67
+ # add additional per-file-ignores here to avoid overriding repo-level config
68
+ "tests/**/*" = [
69
+ # "E501", # line too long
70
+ ]
71
+
72
+ [tool.pyright]
73
+ extends = "../../pyproject.toml"
74
+ include = ["src", "tests"]
75
+ pythonVersion = "3.10" # check no python > 3.10 features are used
76
+ reportUntypedFunctionDecorator = false
77
+ reportCallIssue = false
78
+ reportUnknownVariableType = false
79
+ reportIncompatibleMethodOverride = false
80
+ reportAssignmentType = false
81
+ reportUnknownMemberType = false
82
+ reportUnknownArgumentType = false
83
+ reportUnknownParameterType = false
84
+ reportMissingTypeArgument = false
85
+ reportDeprecated = false
86
+ reportUnnecessaryTypeIgnoreComment = false
87
+ reportUnnecessaryComparison = false
88
+ reportArgumentType = false
89
+ reportReturnType = false
90
+ reportGeneralTypeIssues = false
91
+
92
+ [tool.charmlibs.functional]
93
+ ubuntu = [] # ubuntu versions to run functional tests with, e.g. "24.04" (defaults to just "latest")
94
+ pebble = [] # pebble versions to run functional tests with, e.g. "v1.0.0", "master" (defaults to no pebble versions)
95
+ sudo = false # whether to run functional tests with sudo (defaults to false)
96
+
97
+ [tool.charmlibs.integration]
98
+ # tags to run integration tests with (defaults to running once with no tag, i.e. tags = [''])
99
+ # Available in CI in tests/integration/pack.sh and integration tests as CHARMLIBS_TAG
100
+ tags = [] # Not used by the pack.sh and integration tests generated by the template
@@ -0,0 +1,158 @@
1
+ # Copyright 2026 Canonical Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """The charmlibs.interfaces.ldap package.
16
+
17
+ Juju Charm Library for the `ldap` Juju Interface
18
+ ================================================
19
+
20
+ This Juju charm library contains the Provider and Requirer classes for handling
21
+ the ``ldap`` interface.
22
+
23
+ Requirer Charm
24
+ --------------
25
+
26
+ The requirer charm is expected to:
27
+
28
+ - Provide information for the provider charm to deliver LDAP related
29
+ information in the juju integration, in order to communicate with the LDAP
30
+ server and authenticate LDAP operations
31
+ - Listen to the custom juju event ``LdapReadyEvent`` to obtain the LDAP
32
+ related information from the integration
33
+ - Listen to the custom juju event ``LdapUnavailableEvent`` to handle the
34
+ situation when the LDAP integration is broken
35
+
36
+ .. code-block:: python
37
+
38
+ from charmlibs.interfaces.ldap import (
39
+ LdapRequirer,
40
+ LdapReadyEvent,
41
+ LdapUnavailableEvent,
42
+ )
43
+
44
+ class RequirerCharm(CharmBase):
45
+ # LDAP requirer charm that integrates with an LDAP provider charm.
46
+
47
+ def __init__(self, *args):
48
+ super().__init__(*args)
49
+
50
+ self.ldap_requirer = LdapRequirer(self)
51
+ self.framework.observe(
52
+ self.ldap_requirer.on.ldap_ready,
53
+ self._on_ldap_ready,
54
+ )
55
+ self.framework.observe(
56
+ self.ldap_requirer.on.ldap_unavailable,
57
+ self._on_ldap_unavailable,
58
+ )
59
+
60
+ def _on_ldap_ready(self, event: LdapReadyEvent) -> None:
61
+ # Consume the LDAP related information
62
+ ldap_data = self.ldap_requirer.consume_ldap_relation_data(
63
+ relation=event.relation,
64
+ )
65
+
66
+ # Configure the LDAP requirer charm
67
+ ...
68
+
69
+ def _on_ldap_unavailable(self, event: LdapUnavailableEvent) -> None:
70
+ # Handle the situation where the LDAP integration is broken
71
+ ...
72
+
73
+ As shown above, the library offers custom juju events to handle specific
74
+ situations, which are listed below:
75
+
76
+ - ``ldap_ready``: event emitted when the LDAP related information is ready for
77
+ requirer charm to use.
78
+ - ``ldap_unavailable``: event emitted when the LDAP integration is broken.
79
+
80
+ Additionally, the requirer charmed operator needs to declare the ``ldap``
81
+ interface in the ``metadata.yaml``:
82
+
83
+ .. code-block:: yaml
84
+
85
+ requires:
86
+ ldap:
87
+ interface: ldap
88
+
89
+ Provider Charm
90
+ --------------
91
+
92
+ The provider charm is expected to:
93
+
94
+ - Use the information provided by the requirer charm to provide LDAP related
95
+ information for the requirer charm to connect and authenticate to the LDAP
96
+ server
97
+ - Listen to the custom juju event ``LdapRequestedEvent`` to offer LDAP related
98
+ information in the integration
99
+
100
+ .. code-block:: python
101
+
102
+ from charmlibs.interfaces.ldap import (
103
+ LdapProvider,
104
+ LdapRequestedEvent,
105
+ )
106
+
107
+ class ProviderCharm(CharmBase):
108
+ # LDAP provider charm.
109
+
110
+ def __init__(self, *args):
111
+ super().__init__(*args)
112
+
113
+ self.ldap_provider = LdapProvider(self)
114
+ self.framework.observe(
115
+ self.ldap_provider.on.ldap_requested,
116
+ self._on_ldap_requested,
117
+ )
118
+
119
+ def _on_ldap_requested(self, event: LdapRequestedEvent) -> None:
120
+ # Consume the information provided by the requirer charm
121
+ requirer_data = event.data
122
+
123
+ # Prepare the LDAP related information using the requirer's data
124
+ ldap_data = ...
125
+
126
+ # Update the integration data
127
+ self.ldap_provider.update_relations_app_data(
128
+ relation.id,
129
+ ldap_data,
130
+ )
131
+
132
+ As shown above, the library offers custom juju events to handle specific
133
+ situations, which are listed below:
134
+
135
+ - ``ldap_requested``: event emitted when the requirer charm is requesting the
136
+ LDAP related information in order to connect and authenticate to the LDAP server.
137
+ """
138
+
139
+ from ._ldap import (
140
+ LdapProvider,
141
+ LdapProviderData,
142
+ LdapReadyEvent,
143
+ LdapRequestedEvent,
144
+ LdapRequirer,
145
+ LdapRequirerData,
146
+ LdapUnavailableEvent,
147
+ )
148
+ from ._version import __version__ as __version__
149
+
150
+ __all__ = [
151
+ 'LdapProvider',
152
+ 'LdapProviderData',
153
+ 'LdapReadyEvent',
154
+ 'LdapRequestedEvent',
155
+ 'LdapRequirer',
156
+ 'LdapRequirerData',
157
+ 'LdapUnavailableEvent',
158
+ ]