diff --git a/openldap_primitives_knf/charms/openldap-proxy_ubuntu-20.04-amd64.charm b/openldap_primitives_knf/charms/openldap-proxy_ubuntu-20.04-amd64.charm new file mode 100644 index 0000000000000000000000000000000000000000..b5fc3e96e4178fb8a28aceb8220a83c3e744f9b6 Binary files /dev/null and b/openldap_primitives_knf/charms/openldap-proxy_ubuntu-20.04-amd64.charm differ diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/.gitignore b/openldap_primitives_knf/charms/ops/openldap-operator/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2c3f0e5ed7915b3800370e2f37f7661e29df6742 --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/.gitignore @@ -0,0 +1,7 @@ +venv/ +build/ +*.charm + +.coverage +__pycache__/ +*.py[cod] diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/.jujuignore b/openldap_primitives_knf/charms/ops/openldap-operator/.jujuignore new file mode 100644 index 0000000000000000000000000000000000000000..6ccd559eabeae93e4d23215fa450130fa9b37ace --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/.jujuignore @@ -0,0 +1,3 @@ +/venv +*.py[cod] +*.charm diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/LICENSE b/openldap_primitives_knf/charms/ops/openldap-operator/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7 --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/README.md b/openldap_primitives_knf/charms/ops/openldap-operator/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6a0d44b6ab5d96cc9df10154f24182a5cb8802f1 --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/README.md @@ -0,0 +1,5 @@ +# openldap-operator + +## Description + +Proxy charm that exposes operations against an openldap server. diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/actions.yaml b/openldap_primitives_knf/charms/ops/openldap-operator/actions.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8c0d6664e1065528b6cfae6f54b59cd0a5e38d24 --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/actions.yaml @@ -0,0 +1,21 @@ +# Copyright 2022 David Garcia +# See LICENSE file for licensing details. +# +# TEMPLATE-TODO: change this example to suit your needs. +# If you don't need actions, you can remove the file entirely. +# It ties in to the example _on_fortune_action handler in src/charm.py +# +# Learn more about actions at: https://juju.is/docs/sdk/actions + +get-user-info: + description: Get user information + params: + cn: + type: string + description: Common name (username) + dc: + type: string + description: Domain component. Dot-separated domain. + required: + - cn + - dc diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/charmcraft.yaml b/openldap_primitives_knf/charms/ops/openldap-operator/charmcraft.yaml new file mode 100644 index 0000000000000000000000000000000000000000..048d45441c7e0645e78ac0b7b392bb510408b49a --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/charmcraft.yaml @@ -0,0 +1,10 @@ +# Learn more about charmcraft.yaml configuration at: +# https://juju.is/docs/sdk/charmcraft-config +type: "charm" +bases: + - build-on: + - name: "ubuntu" + channel: "20.04" + run-on: + - name: "ubuntu" + channel: "20.04" diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/config.yaml b/openldap_primitives_knf/charms/ops/openldap-operator/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9f4523ef023a06421cec75723fc136e88e8b5b6e --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/config.yaml @@ -0,0 +1,13 @@ +# Copyright 2022 David Garcia +# See LICENSE file for licensing details. +# +# TEMPLATE-TODO: change this example to suit your needs. +# If you don't need a config, you can remove the file entirely. +# It ties in to the example _on_config_changed handler in src/charm.py +# +# Learn more about config at: https://juju.is/docs/sdk/config + +options: + osm-config: + description: OSM configuration. + type: string diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/metadata.yaml b/openldap_primitives_knf/charms/ops/openldap-operator/metadata.yaml new file mode 100644 index 0000000000000000000000000000000000000000..53fe09f7c6f8b54c999f087c9e53a73f493239aa --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/metadata.yaml @@ -0,0 +1,12 @@ +# Copyright 2022 David Garcia +# See LICENSE file for licensing details. + +# For a complete list of supported options, see: +# https://juju.is/docs/sdk/metadata-reference +name: openldap-proxy +display-name: Openldap +description: | + Proxy charm that exposes operations against an openldap server. +summary: | + Proxy charm that exposes operations against an openldap server. + diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/requirements.txt b/openldap_primitives_knf/charms/ops/openldap-operator/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..6ded729a580276a538c929ae6dafac737f272d8c --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/requirements.txt @@ -0,0 +1,2 @@ +ops >= 1.4.0 +ldap3 diff --git a/openldap_primitives_knf/charms/ops/openldap-operator/src/charm.py b/openldap_primitives_knf/charms/ops/openldap-operator/src/charm.py new file mode 100755 index 0000000000000000000000000000000000000000..0b1d9ae4b196927bddfafcd5fc3e23a1dc9a4849 --- /dev/null +++ b/openldap_primitives_knf/charms/ops/openldap-operator/src/charm.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +# Copyright 2022 David Garcia +# See LICENSE file for licensing details. +# +# Learn more at: https://juju.is/docs/sdk + +import json +import logging +from typing import Tuple + +from ops.charm import CharmBase +from ops.main import main +from ops.model import ActiveStatus, BlockedStatus + +from ldap3 import Server, Connection, ALL, SUBTREE, ALL_ATTRIBUTES + +logger = logging.getLogger(__name__) + + +USER = "cn=admin,dc=example,dc=org" +PASSWORD = "admin" + + +class Service: + def __init__(self, service_info): + self._service_info = service_info + + @property + def ip(self): + return self._service_info["ip"][0] + + def get_port(self, port_name): + return self._service_info["ports"][port_name]["port"] + + +class OsmConfig: + def __init__(self, charm: CharmBase) -> None: + self._charm = charm + + def get_service(self, service_name: str) -> Service: + osm_config = json.loads(self._charm.config["osm-config"]) + services = [ + s_values + for s_name, s_values in osm_config["v0"]["k8s"]["services"].items() + if service_name in s_name + ] + return Service(services[0]) + + +class Ldap: + def __init__(self, ldap_uri: str) -> None: + self.ldap_uri = ldap_uri + self.connection = None + + def _connect(self): + server = Server(self.ldap_uri, get_info=ALL) + self.connection = Connection( + server, user="cn=admin,dc=example,dc=org", password="admin" + ) + if not self.connection.bind(): + raise Exception("cannot connect to ldap server") + + def _disconnect(self): + if not self.connection or self.connection.closed: + return + self.connection.unbind() + + def get_user_info(self, cn, dc): + self._connect() + try: + if self.connection.search( + search_base=f"{cn},{dc}", + search_filter="(objectclass=*)", + search_scope=SUBTREE, + attributes=ALL_ATTRIBUTES, + ): + return self.connection.entries + finally: + self._disconnect() + + +class OpenldapOperatorCharm(CharmBase): + """Charm the service.""" + + def __init__(self, *args): + super().__init__(*args) + self.osm_config = OsmConfig(self) + self.framework.observe(self.on.config_changed, self._on_config_changed) + self.framework.observe( + self.on.get_user_info_action, self._on_get_user_info_action + ) + + def _on_config_changed(self, _): + """Handler for config-changed event.""" + osm_config = self.config.get("osm-config") + if not osm_config: + self.unit.status = BlockedStatus("osm-config missing") + return + logger.info(f"osm-config={osm_config}") + self.unit.status = ActiveStatus() + + def _on_get_user_info_action(self, event): + """Handler for get-user-info action.""" + cn_param = event.params["cn"] + dc_param = event.params["dc"] + cn = f"cn={cn_param}" + dc = ",".join([f"dc={dc_component}" for dc_component in dc_param.split(".")]) + try: + openldap_service = self.osm_config.get_service("stable-openldap") + ldap_uri = ( + f'ldap://{openldap_service.ip}:{openldap_service.get_port("ldap-port")}' + ) + ldap = Ldap(ldap_uri) + user_info = ldap.get_user_info(cn, dc) + event.set_results({"output": user_info}) + except Exception as e: + event.fail(f"Failed getting user info: {e}") + + +if __name__ == "__main__": + main(OpenldapOperatorCharm) diff --git a/openldap_primitives_knf/openldap_vnfd.yaml b/openldap_primitives_knf/openldap_vnfd.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1dd9fda162fc91645e474667b31a144b4781a1b9 --- /dev/null +++ b/openldap_primitives_knf/openldap_vnfd.yaml @@ -0,0 +1,36 @@ +vnfd: + description: KNF with single KDU using a helm-chart for openldap version 1.2.3 + df: + - id: default-df + lcm-operations-configuration: + operate-vnf-op-config: + day1-2: + - id: ldap + execution-environment-list: + - id: openldap-ee + juju: + charm: openldap-proxy_ubuntu-20.04-amd64.charm + config-primitive: + - name: get-user-info + execution-environment-ref: openldap-ee + parameter: + - data-type: STRING + name: cn + - data-type: STRING + name: dc + ext-cpd: + - id: mgmt-ext + k8s-cluster-net: mgmtnet + id: openldap_knf + k8s-cluster: + nets: + - id: mgmtnet + kdu: + - name: ldap + helm-chart: stable/openldap + service: + - name: stable-openldap + mgmt-cp: mgmt-ext + product-name: openldap_knf + provider: Telefonica + version: 1.0 diff --git a/openldap_primitives_ns/README.md b/openldap_primitives_ns/README.md new file mode 100644 index 0000000000000000000000000000000000000000..93fb79c6bfbb5bb6723650a7b2a6c3a0fb19844c --- /dev/null +++ b/openldap_primitives_ns/README.md @@ -0,0 +1,46 @@ +# SIMPLE OPEN-LDAP CHART + +Descriptors that installs an openldap version 1.2.1 chart in a K8s cluster + +There is one VNF (openldap\_vnf) with only one KDU. + +There is one NS that connects the VNF to a mgmt network + +## Onboarding and instantiation + +```bash +osm nfpkg-create openldap_knf.tar.gz +osm nspkg-create openldap_ns.tar.gz +osm ns-create --ns_name ldap --nsd_name openldap_ns --vim_account | --ssh_keys ${HOME}/.ssh/id_rsa.pub +``` + +### Instantiation option + +Some parameters could be passed during the instantiation. + +* replicaCount: Number of Open LDAP replicas that will be created + +```bash +osm ns-create --ns_name ldap --nsd_name openldap_ns --vim_account | --config '{additionalParamsForVnf: [{"member-vnf-index": "openldap", "additionalParams": {"replicaCount": "2"}}]}' +osm ns-create --ns_name ldap --nsd_name openldap_ns --vim_account | --config_file params.yaml +``` + +## Test deployment + +```bash +helm -n list +kubectl -n get all +kubectl -n get service +``` + +## Testing LDAP server + +```bash +sudo apt-get update +sudo apt-get install ldap-utils +# With LB: +ldapsearch -x -H ldap://:389 -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w osm4u +# With NodePort +ldapsearch -x -H ldap://: -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w osm4u +``` + diff --git a/openldap_primitives_ns/openldap_nsd.yaml b/openldap_primitives_ns/openldap_nsd.yaml new file mode 100644 index 0000000000000000000000000000000000000000..980fd2e8f8921813d6074fb8bfdb44a94182d57a --- /dev/null +++ b/openldap_primitives_ns/openldap_nsd.yaml @@ -0,0 +1,22 @@ +nsd: + nsd: + - description: NS consisting of a single KNF openldap_knf connected to mgmt network + designer: OSM + df: + - id: default-df + vnf-profile: + - id: openldap + virtual-link-connectivity: + - constituent-cpd-id: + - constituent-base-element-id: openldap + constituent-cpd-id: mgmt-ext + virtual-link-profile-id: mgmtnet + vnfd-id: openldap_knf + id: openldap_ns + name: openldap_ns + version: 1.0 + virtual-link-desc: + - id: mgmtnet + mgmt-network: true + vnfd-id: + - openldap_knf diff --git a/openldap_primitives_ns/params/params.yaml b/openldap_primitives_ns/params/params.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8844ecb1777d8f4d4e7bb0a347fadca0e1cb04df --- /dev/null +++ b/openldap_primitives_ns/params/params.yaml @@ -0,0 +1,24 @@ +vld: +- name: mgmtnet + vim-network-name: internal +additionalParamsForVnf: +- member-vnf-index: openldap + additionalParamsForKdu: + - kdu_name: ldap + additionalParams: + # replicaCount: 2 + # service.loadBalancerIP: '172.21.251.X' # MetalLB IP Address + # service.type: NodePort + service: + type: NodePort + # loadBalancerIP: '172.21.251.X' # MetalLB IP Address + adminPassword: osm4u + configPassword: osm4u + env: + LDAP_ORGANISATION: "Example Inc." + LDAP_DOMAIN: "example.org" + LDAP_BACKEND: "hdb" + LDAP_TLS: "true" + LDAP_TLS_ENFORCE: "false" + LDAP_REMOVE_CONFIG_AFTER_SETUP: "true" +