From e3ef15616bca454e653b2f28e751ff561f84b33e Mon Sep 17 00:00:00 2001 From: Martin van Es Date: Fri, 1 Mar 2024 14:45:54 +0100 Subject: [PATCH 01/18] WIP --- plsc.yml.example | 2 ++ sbs.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/plsc.yml.example b/plsc.yml.example index 8b73dd8..f37c3a8 100644 --- a/plsc.yml.example +++ b/plsc.yml.example @@ -15,6 +15,8 @@ ldap: sbs: src: host: https://sbs.example.net + # host: test + # sync: sync.json user: sysread passwd: changethispassword verify_ssl: True diff --git a/sbs.py b/sbs.py index 67b6e0b..0f2230f 100644 --- a/sbs.py +++ b/sbs.py @@ -37,6 +37,9 @@ def __init__(self, config): self.retry = config.get('retry', 3) self.recording_requested = config.get('recorder', False) + if self.host == 'test': + self.sync = config['sync'] + if config.get("ipv4_only", False): import urllib3.util.connection as urllib3_connection @@ -69,6 +72,9 @@ class SBSNoContentException(Exception): logger.debug(f"API: {request}...") + if self.host == 'test' and request == 'api/plsc/sync': + return json.loads(open(self.sync, 'r').read()) + # retry the entire process a few times` for i in range(0, self.retry): try: From 43bd18023e5777c6a9b83a91a3aaf70b333f58c0 Mon Sep 17 00:00:00 2001 From: Martin van Es Date: Thu, 7 Mar 2024 17:07:08 +0100 Subject: [PATCH 02/18] Add dump_sbs.py --- dump_sbs.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 dump_sbs.py diff --git a/dump_sbs.py b/dump_sbs.py new file mode 100755 index 0000000..3b9506a --- /dev/null +++ b/dump_sbs.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +import sys +import yaml +import json + +from sbs import SBS + + +def main(): + if len(sys.argv) < 2: + sys.exit(sys.argv[0] + " ") + + with open(sys.argv[1]) as f: + config = yaml.safe_load(f) + + src = SBS(config['sbs']['src']) + sync = src.api("api/plsc/sync") + + print(json.dumps(sync, indent=2)) + + +if __name__ == "__main__": + main() From 013fb2ffb88fe000db82e43d87de250442a22ba2 Mon Sep 17 00:00:00 2001 From: Martin van Es Date: Fri, 8 Mar 2024 10:20:24 +0100 Subject: [PATCH 03/18] Add docker-compose.yml --- docker-compose.yml | 23 +++++++++ misc/ldif/KEEP | 0 misc/schema/eduMember.ldif | 27 +++++++++++ misc/schema/eduPerson.ldif | 83 +++++++++++++++++++++++++++++++++ misc/schema/groupOfMembers.ldif | 19 ++++++++ misc/schema/ldapPublicKey.ldif | 21 +++++++++ misc/schema/sczGroup.ldif | 23 +++++++++ misc/schema/voPerson.ldif | 44 +++++++++++++++++ 8 files changed, 240 insertions(+) create mode 100644 docker-compose.yml create mode 100644 misc/ldif/KEEP create mode 100644 misc/schema/eduMember.ldif create mode 100644 misc/schema/eduPerson.ldif create mode 100644 misc/schema/groupOfMembers.ldif create mode 100644 misc/schema/ldapPublicKey.ldif create mode 100644 misc/schema/sczGroup.ldif create mode 100644 misc/schema/voPerson.ldif diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..43d96ac --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +--- +version: "2" + +services: + ldap: + image: ghcr.io/surfscz/sram-ldap:main + ports: + - 1389:1389 + environment: + LDAP_ROOT: "dc=services,dc=vnet" + LDAP_ADMIN_USERNAME: "admin" + LDAP_ADMIN_PASSWORD: "changethispassword" + LDAP_CONFIG_ADMIN_USERNAME: "admin" + LDAP_CONFIG_ADMIN_PASSWORD: "changethispassword" + LDAP_CONFIG_ADMIN_ENABLED: "yes" + LDAP_CUSTOM_SCHEMA_DIR: "/opt/ldap/schema" + LDAP_SKIP_DEFAULT_TREE: "yes" + LDAP_ENABLE_TLS: "no" + # LDAP_CUSTOM_LDIF_DIR: "/opt/ldap/ldif" + volumes: + - ./misc/schema:/opt/ldap/schema + - ./misc/ldif:/opt/ldap/ldif + # - ./misc/ldap:/bitnami/openldap diff --git a/misc/ldif/KEEP b/misc/ldif/KEEP new file mode 100644 index 0000000..e69de29 diff --git a/misc/schema/eduMember.ldif b/misc/schema/eduMember.ldif new file mode 100644 index 0000000..42894d5 --- /dev/null +++ b/misc/schema/eduMember.ldif @@ -0,0 +1,27 @@ +dn: cn=eduMember,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: eduMember +# Internet X.500 Schema for Ldappc +# Includes the eduMember ObjectClass schema +# +# +# An auxiliary object class, "eduMember," is a convenient container +# for an extensible set of attributes concerning group memberships. +# At this time, the only attributes specified as belonging to the +# object class are "isMemberOf" and "hasMember." +# +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.5.1.1 + NAME 'isMemberOf' + DESC 'identifiers for groups to which containing entity belongs' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.5.1.2 + NAME 'hasMember' + DESC 'identifiers for entities that are members of the group' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcObjectClasses: ( 1.3.6.1.4.1.5923.1.5.2.1 + NAME 'eduMember' + AUXILIARY + MAY ( isMemberOf $ hasMember ) + ) diff --git a/misc/schema/eduPerson.ldif b/misc/schema/eduPerson.ldif new file mode 100644 index 0000000..e4f2c96 --- /dev/null +++ b/misc/schema/eduPerson.ldif @@ -0,0 +1,83 @@ +dn: cn=eduperson,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: eduperson +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.1 + NAME 'eduPersonAffiliation' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.7 + NAME 'eduPersonEntitlement' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.2 + NAME 'eduPersonNickName' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.3 + NAME 'eduPersonOrgDN' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY distinguishedNameMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.4 + NAME 'eduPersonOrgUnitDN' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY distinguishedNameMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.5 + NAME 'eduPersonPrimaryAffiliation' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.8 + NAME 'eduPersonPrimaryOrgUnitDN' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY distinguishedNameMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.6 + NAME 'eduPersonPrincipalName' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.12 + NAME 'eduPersonPrincipalNamePrior' + DESC 'eduPersonPrincipalNamePrior per Internet2' + EQUALITY caseIgnoreMatch + SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.9 + NAME 'eduPersonScopedAffiliation' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.10 + NAME 'eduPersonTargetedID' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.11 + NAME 'eduPersonAssurance' + DESC 'eduPerson per Internet2 and EDUCAUSE' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.13 + NAME 'eduPersonUniqueId' + DESC 'eduPersonUniqueId per Internet2' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +olcAttributeTypes: ( 1.3.6.1.4.1.5923.1.1.1.16 + NAME 'eduPersonOrcid' + DESC 'ORCID researcher identifiers belonging to the principal' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcObjectClasses: ( 1.3.6.1.4.1.5923.1.1.2 + NAME 'eduPerson' + AUXILIARY + MAY ( + eduPersonAffiliation $ eduPersonNickname $ eduPersonOrgDN $ + eduPersonOrgUnitDN $ eduPersonPrimaryAffiliation $ + eduPersonPrincipalName $ eduPersonEntitlement $ eduPersonPrimaryOrgUnitDN $ + eduPersonScopedAffiliation $ eduPersonTargetedID $ eduPersonAssurance $ + eduPersonPrincipalNamePrior $ eduPersonUniqueId $ eduPersonOrcid ) + ) diff --git a/misc/schema/groupOfMembers.ldif b/misc/schema/groupOfMembers.ldif new file mode 100644 index 0000000..aa10094 --- /dev/null +++ b/misc/schema/groupOfMembers.ldif @@ -0,0 +1,19 @@ +# Internet X.500 Schema for Ldappc +# Includes the groupOfMembers ObjectClass schema +# +# Taken from RFC2307bis draft 2 +# https://tools.ietf.org/html/draft-howard-rfc2307bis-02 +# +# An structural object class, "groupOfMembers" is a convenient container +# for an extensible set of attributes concerning group memberships. +# +dn: cn=groupOfMembers,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: groupOfMembers +olcObjectClasses: ( 1.3.6.1.1.1.2.18 SUP top STRUCTURAL + NAME 'groupOfMembers' + DESC 'A group with members (DNs)' + MUST cn + MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ + description $ member ) + ) diff --git a/misc/schema/ldapPublicKey.ldif b/misc/schema/ldapPublicKey.ldif new file mode 100644 index 0000000..8968b6e --- /dev/null +++ b/misc/schema/ldapPublicKey.ldif @@ -0,0 +1,21 @@ +dn: cn=openssh-lpk-openldap,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: openssh-lpk-openldap +# +# LDAP Public Key Patch schema for use with openssh-ldappubkey +# useful with PKA-LDAP also +# +# Author: Eric AUGE +# +# Based on the proposal of : Mark Ruijter +# +# octetString SYNTAX +olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' + DESC 'MANDATORY: OpenSSH Public key' + EQUALITY octetStringMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) +# printableString SYNTAX yes|no +olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY + DESC 'MANDATORY: OpenSSH LPK olcObjectClasses:' + MUST ( sshPublicKey $ uid ) + ) diff --git a/misc/schema/sczGroup.ldif b/misc/schema/sczGroup.ldif new file mode 100644 index 0000000..d1b5cb3 --- /dev/null +++ b/misc/schema/sczGroup.ldif @@ -0,0 +1,23 @@ +# Internet X.500 Schema for Ldappc +# Includes the sczGroup ObjectClass schema +# +# An auxiliary object class, "sczGroup," is a convenient container +# for an extensible set of attributes concerning group memberships. +# At this time, the only attribute specified as belonging to the +# object class is "sczMember." +# +# It is specifically configured to support the memberOf overlay. +# +dn: cn=sczGroup,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: sczGroup +olcAttributeTypes: ( 1.3.6.1.4.1.1076.20.40.50.1.1 + NAME 'sczMember' + DESC 'DN identifiers for entities that are members of the group' + EQUALITY distinguishedNameMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +olcObjectClasses: ( 1.3.6.1.4.1.1076.20.40.50.1 + NAME 'sczGroup' + AUXILIARY + MAY ( sczMember ) + ) diff --git a/misc/schema/voPerson.ldif b/misc/schema/voPerson.ldif new file mode 100644 index 0000000..bdce11e --- /dev/null +++ b/misc/schema/voPerson.ldif @@ -0,0 +1,44 @@ +dn: cn=voperson,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: voperson +olcAttributeTypes: {0}( 1.3.6.1.4.1.34998.3.3.1.1 NAME 'voPersonApplicationUID + ' DESC 'voPerson Application-Specific User Identifier' EQUALITY caseIgnoreMat + ch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) +olcAttributeTypes: {1}( 1.3.6.1.4.1.34998.3.3.1.2 NAME 'voPersonAuthorName' DE + SC 'voPerson Author Name' EQUALITY caseIgnoreMatch SYNTAX '1.3.6.1.4.1.1466.1 + 15.121.1.15' ) +olcAttributeTypes: {2}( 1.3.6.1.4.1.34998.3.3.1.3 NAME 'voPersonCertificateDN' + DESC 'voPerson Certificate Distinguished Name' EQUALITY distinguishedNameMat + ch SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' ) +olcAttributeTypes: {3}( 1.3.6.1.4.1.34998.3.3.1.4 NAME 'voPersonCertificateIss + uerDN' DESC 'voPerson Certificate Issuer DN' EQUALITY distinguishedNameMatch + SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' ) +olcAttributeTypes: {4}( 1.3.6.1.4.1.34998.3.3.1.5 NAME 'voPersonExternalID' DE + SC 'voPerson Scoped External Identifier' EQUALITY caseIgnoreMatch SYNTAX '1.3 + .6.1.4.1.1466.115.121.1.15' ) +olcAttributeTypes: {5}( 1.3.6.1.4.1.34998.3.3.1.6 NAME 'voPersonID' DESC 'voPe + rson Unique Identifier' EQUALITY caseIgnoreMatch SYNTAX '1.3.6.1.4.1.1466.115 + .121.1.15' ) +olcAttributeTypes: {6}( 1.3.6.1.4.1.34998.3.3.1.7 NAME 'voPersonPolicyAgreemen + t' DESC 'voPerson Policy Agreement Indicator' EQUALITY caseIgnoreMatch SYNTAX + '1.3.6.1.4.1.1466.115.121.1.15' ) +olcAttributeTypes: {7}( 1.3.6.1.4.1.34998.3.3.1.8 NAME 'voPersonSoRID' DESC 'v + oPerson External Identifier' EQUALITY caseIgnoreMatch SYNTAX '1.3.6.1.4.1.146 + 6.115.121.1.15' ) +olcAttributeTypes: {8}( 1.3.6.1.4.1.34998.3.3.1.9 NAME 'voPersonStatus' DESC ' + voPerson Status' EQUALITY caseIgnoreMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1. + 15' ) +olcAttributeTypes: {9}( 1.3.6.1.4.1.34998.3.3.1.10 NAME 'voPersonAffiliation' + DESC 'voPerson Affiliation Within Local Scope' EQUALITY caseIgnoreMatch SYNTA + X '1.3.6.1.4.1.1466.115.121.1.15' ) +olcAttributeTypes: {10}( 1.3.6.1.4.1.34998.3.3.1.11 NAME 'voPersonExternalAffi + liation' DESC 'voPerson Scoped External Affiliation' EQUALITY caseIgnoreMatch + SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) +olcAttributeTypes: {11}( 1.3.6.1.4.1.34998.3.3.1.12 NAME 'voPersonScopedAffili + ation' DESC 'voPerson Affiliation With Explicit Local Scope' EQUALITY caseIgn + oreMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) +olcObjectClasses: {0}( 1.3.6.1.4.1.34998.3.3.1 NAME 'voPerson' AUXILIARY MAY ( + voPersonAffiliation $ voPersonApplicationUID $ voPersonAuthorName $ voPerson + CertificateDN $ voPersonCertificateIssuerDN $ voPersonExternalAffiliation $ v + oPersonExternalID $ voPersonID $ voPersonPolicyAgreement $ voPersonScopedAffi + liation $ voPersonSoRID $ voPersonStatus ) ) From edb800c59b2f83e21d2283305dc83878da521509 Mon Sep 17 00:00:00 2001 From: Martin van Es Date: Fri, 8 Mar 2024 14:35:00 +0100 Subject: [PATCH 04/18] Add dry-run.sh script and ldap container --- docker-compose.yml | 2 ++ dry-run.sh | 9 +++++++++ misc/ldif/config_1.ldif | 29 +++++++++++++++++++++++++++++ misc/ldif/config_2.ldif | 21 +++++++++++++++++++++ misc/plsc_test.yml | 25 +++++++++++++++++++++++++ 5 files changed, 86 insertions(+) create mode 100755 dry-run.sh create mode 100644 misc/ldif/config_1.ldif create mode 100644 misc/ldif/config_2.ldif create mode 100644 misc/plsc_test.yml diff --git a/docker-compose.yml b/docker-compose.yml index 43d96ac..ec768ef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,8 +16,10 @@ services: LDAP_CUSTOM_SCHEMA_DIR: "/opt/ldap/schema" LDAP_SKIP_DEFAULT_TREE: "yes" LDAP_ENABLE_TLS: "no" + LDAP_ENABLE_SYNCPROV: "yes" # LDAP_CUSTOM_LDIF_DIR: "/opt/ldap/ldif" volumes: - ./misc/schema:/opt/ldap/schema - ./misc/ldif:/opt/ldap/ldif + - ./backup.ldif:/backup.ldif # - ./misc/ldap:/bitnami/openldap diff --git a/dry-run.sh b/dry-run.sh new file mode 100755 index 0000000..718a84e --- /dev/null +++ b/dry-run.sh @@ -0,0 +1,9 @@ +#!/bin/sh +docker stop plsc-ldap-1 +docker rm plsc-ldap-1 +docker compose up -d +sleep 5 +docker exec plsc-ldap-1 slapmodify -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_1.ldif +docker exec plsc-ldap-1 slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_2.ldif +docker exec plsc-ldap-1 slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif +./run.sh misc/plsc_test.yml diff --git a/misc/ldif/config_1.ldif b/misc/ldif/config_1.ldif new file mode 100644 index 0000000..8ef3ffe --- /dev/null +++ b/misc/ldif/config_1.ldif @@ -0,0 +1,29 @@ +dn: cn=module{1},cn=config +changetype: Modify +add: olcModuleLoad +olcModuleLoad: {1}memberof.so +olcModuleLoad: {2}refint.so +olcModuleLoad: {3}dynlist.so + +dn: olcDatabase={2}mdb,cn=config +changetype: Modify +replace: olcDbIndex +olcDbIndex: objectClass eq,pres +olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub +olcDbIndex: entryUUID eq +olcDbIndex: o eq +olcDbIndex: dc eq +olcDbIndex: entryCSN eq + +replace: olcDbMaxSize +olcDbMaxSize: 1073741824 + +replace: olcAccess +olcAccess: {0}to dn.regex="(([^,]+),dc=services,dc=vnet)$" by dn.exact="cn=adm + in,dc=services,dc=vnet" write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred + ,cn=external,cn=auth write by dn.exact,expand="cn=admin,$1" read by * break +olcAccess: {1}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external + ,cn=auth manage by dn.regex="cn=[^,]+,dc=services,dc=vnet" read by dn.exact= + gidNumber=1000+uidNumber=1000,cn=peercred,cn=external,cn=auth manage by * br + eak +olcAccess: {2}to attrs=userPassword by self write by anonymous auth by * break diff --git a/misc/ldif/config_2.ldif b/misc/ldif/config_2.ldif new file mode 100644 index 0000000..6c08654 --- /dev/null +++ b/misc/ldif/config_2.ldif @@ -0,0 +1,21 @@ +dn: olcOverlay={1}memberof,olcDatabase={2}mdb,cn=config +objectClass: olcOverlayConfig +objectClass: olcMemberOfConfig +olcOverlay: {1}memberof +olcMemberOfRefInt: TRUE +olcMemberOfGroupOC: groupOfMembers +olcMemberOfMemberAD: member +olcMemberOfMemberOfAD: memberOf + +dn: olcOverlay={2}refint,olcDatabase={2}mdb,cn=config +objectClass: olcOverlayConfig +objectClass: olcRefintConfig +olcOverlay: {2}refint +olcRefintAttribute: memberof +olcRefintAttribute: member + +dn: olcOverlay={3}dynlist,olcDatabase={2}mdb,cn=config +objectClass: olcOverlayConfig +objectClass: olcDynListConfig +olcOverlay: {3}dynlist +olcDynListAttrSet: {0}organizationalRole labeledURI roleOccupant diff --git a/misc/plsc_test.yml b/misc/plsc_test.yml new file mode 100644 index 0000000..834620f --- /dev/null +++ b/misc/plsc_test.yml @@ -0,0 +1,25 @@ +--- +ldap: + src: + uri: ldap://localhost:1389/ + basedn: dc=services,dc=vnet + binddn: cn=admin,dc=services,dc=vnet + passwd: changethispassword + sizelimit: 5 + dst: + uri: ldap://localhost:1389/ + basedn: dc=services,dc=vnet + binddn: cn=admin,dc=services,dc=vnet + passwd: changethispassword + sizelimit: 5 +sbs: + src: + recorder: False + host: test + sync: sync.json + user: sysread + passwd: changethispassword + verify_ssl: False +pwd: '{CRYPT}!' +uid: 1000 +gid: 1000 From b7846d1ce8e96ff0546ca95c6a5f75ccdc3b5831 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 6 May 2024 17:52:28 +0200 Subject: [PATCH 05/18] Support remote docker host and properly use docker-compose --- dry-run.sh | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/dry-run.sh b/dry-run.sh index 718a84e..d0e5a19 100755 --- a/dry-run.sh +++ b/dry-run.sh @@ -1,9 +1,41 @@ -#!/bin/sh -docker stop plsc-ldap-1 -docker rm plsc-ldap-1 -docker compose up -d +#!/bin/bash + +set -e +shopt -s extglob # for the string postfix matching below + +# check if we're using a remote docker host +docker_host=$(docker context inspect -f '{{ .Endpoints.docker.Host }}') +docker_proto=${docker_host:0:6} +if [ "$docker_proto" == "tcp://" ]; then + # remove protocol + HOST=${docker_host:6} + # remove port number + HOST=${HOST%:+([[:digit:]])?(/)} + + echo "Using remote docker host $HOST ($docker_host)" + socat TCP4-LISTEN:1389,fork,reuseaddr TCP4:$HOST:1389 & + BG_PID=$! + + # kill socat when exiting + trap "kill $BG_PID" EXIT +fi + +COMPOSE_FILE="docker-compose.yml" +COMPOSE="docker compose --file ${COMPOSE_FILE}" + +echo "Starting containers" +${COMPOSE} kill && ${COMPOSE} rm -f || true +${COMPOSE} up --detach sleep 5 -docker exec plsc-ldap-1 slapmodify -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_1.ldif -docker exec plsc-ldap-1 slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_2.ldif -docker exec plsc-ldap-1 slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif + +echo "Configuring LDAP" +${COMPOSE} exec ldap slapmodify -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_1.ldif +${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_2.ldif + +echo "Loading data" +${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif + +echo "Runnign plsc" ./run.sh misc/plsc_test.yml + +exit 0 \ No newline at end of file From 74ebf5d08678ccba49905c8f144f2f05db7b9adf Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 6 May 2024 17:53:52 +0200 Subject: [PATCH 06/18] Use python from venv --- dry-run.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dry-run.sh b/dry-run.sh index d0e5a19..db76f44 100755 --- a/dry-run.sh +++ b/dry-run.sh @@ -35,7 +35,8 @@ ${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /o echo "Loading data" ${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif -echo "Runnign plsc" +echo "Running plsc" +export PATH=$(pwd)/venv/bin:${PATH} ./run.sh misc/plsc_test.yml exit 0 \ No newline at end of file From da7ee271a1fc476365d926ad8d8abd5bded0b907 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 6 May 2024 17:59:48 +0200 Subject: [PATCH 07/18] Move all dry_run stuff to own dir --- dry_run/.gitignore | 2 ++ docker-compose.yml => dry_run/docker-compose.yml | 8 +++----- dry-run.sh => dry_run/dry-run.sh | 2 +- {misc => dry_run}/ldif/KEEP | 0 {misc => dry_run}/ldif/config_1.ldif | 0 {misc => dry_run}/ldif/config_2.ldif | 0 misc/plsc_test.yml => dry_run/plsc_dryrun..yml | 0 {misc => dry_run}/schema/eduMember.ldif | 0 {misc => dry_run}/schema/eduPerson.ldif | 0 {misc => dry_run}/schema/groupOfMembers.ldif | 0 {misc => dry_run}/schema/ldapPublicKey.ldif | 0 {misc => dry_run}/schema/sczGroup.ldif | 0 {misc => dry_run}/schema/voPerson.ldif | 0 run.sh | 2 +- 14 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 dry_run/.gitignore rename docker-compose.yml => dry_run/docker-compose.yml (73%) rename dry-run.sh => dry_run/dry-run.sh (97%) rename {misc => dry_run}/ldif/KEEP (100%) rename {misc => dry_run}/ldif/config_1.ldif (100%) rename {misc => dry_run}/ldif/config_2.ldif (100%) rename misc/plsc_test.yml => dry_run/plsc_dryrun..yml (100%) rename {misc => dry_run}/schema/eduMember.ldif (100%) rename {misc => dry_run}/schema/eduPerson.ldif (100%) rename {misc => dry_run}/schema/groupOfMembers.ldif (100%) rename {misc => dry_run}/schema/ldapPublicKey.ldif (100%) rename {misc => dry_run}/schema/sczGroup.ldif (100%) rename {misc => dry_run}/schema/voPerson.ldif (100%) diff --git a/dry_run/.gitignore b/dry_run/.gitignore new file mode 100644 index 0000000..157198f --- /dev/null +++ b/dry_run/.gitignore @@ -0,0 +1,2 @@ +backup.ldif +sync.json \ No newline at end of file diff --git a/docker-compose.yml b/dry_run/docker-compose.yml similarity index 73% rename from docker-compose.yml rename to dry_run/docker-compose.yml index ec768ef..1f23db9 100644 --- a/docker-compose.yml +++ b/dry_run/docker-compose.yml @@ -17,9 +17,7 @@ services: LDAP_SKIP_DEFAULT_TREE: "yes" LDAP_ENABLE_TLS: "no" LDAP_ENABLE_SYNCPROV: "yes" - # LDAP_CUSTOM_LDIF_DIR: "/opt/ldap/ldif" volumes: - - ./misc/schema:/opt/ldap/schema - - ./misc/ldif:/opt/ldap/ldif - - ./backup.ldif:/backup.ldif - # - ./misc/ldap:/bitnami/openldap + - ./schema:/opt/ldap/schema + - ./ldif:/opt/ldap/ldif + - ./backup.ldif:/backup.ldif:ro \ No newline at end of file diff --git a/dry-run.sh b/dry_run/dry-run.sh similarity index 97% rename from dry-run.sh rename to dry_run/dry-run.sh index db76f44..f883a1d 100755 --- a/dry-run.sh +++ b/dry_run/dry-run.sh @@ -37,6 +37,6 @@ ${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /b echo "Running plsc" export PATH=$(pwd)/venv/bin:${PATH} -./run.sh misc/plsc_test.yml +../run.sh ./plsc_dryrun.yml exit 0 \ No newline at end of file diff --git a/misc/ldif/KEEP b/dry_run/ldif/KEEP similarity index 100% rename from misc/ldif/KEEP rename to dry_run/ldif/KEEP diff --git a/misc/ldif/config_1.ldif b/dry_run/ldif/config_1.ldif similarity index 100% rename from misc/ldif/config_1.ldif rename to dry_run/ldif/config_1.ldif diff --git a/misc/ldif/config_2.ldif b/dry_run/ldif/config_2.ldif similarity index 100% rename from misc/ldif/config_2.ldif rename to dry_run/ldif/config_2.ldif diff --git a/misc/plsc_test.yml b/dry_run/plsc_dryrun..yml similarity index 100% rename from misc/plsc_test.yml rename to dry_run/plsc_dryrun..yml diff --git a/misc/schema/eduMember.ldif b/dry_run/schema/eduMember.ldif similarity index 100% rename from misc/schema/eduMember.ldif rename to dry_run/schema/eduMember.ldif diff --git a/misc/schema/eduPerson.ldif b/dry_run/schema/eduPerson.ldif similarity index 100% rename from misc/schema/eduPerson.ldif rename to dry_run/schema/eduPerson.ldif diff --git a/misc/schema/groupOfMembers.ldif b/dry_run/schema/groupOfMembers.ldif similarity index 100% rename from misc/schema/groupOfMembers.ldif rename to dry_run/schema/groupOfMembers.ldif diff --git a/misc/schema/ldapPublicKey.ldif b/dry_run/schema/ldapPublicKey.ldif similarity index 100% rename from misc/schema/ldapPublicKey.ldif rename to dry_run/schema/ldapPublicKey.ldif diff --git a/misc/schema/sczGroup.ldif b/dry_run/schema/sczGroup.ldif similarity index 100% rename from misc/schema/sczGroup.ldif rename to dry_run/schema/sczGroup.ldif diff --git a/misc/schema/voPerson.ldif b/dry_run/schema/voPerson.ldif similarity index 100% rename from misc/schema/voPerson.ldif rename to dry_run/schema/voPerson.ldif diff --git a/run.sh b/run.sh index 2e5d357..d4157dd 100755 --- a/run.sh +++ b/run.sh @@ -13,4 +13,4 @@ elif [ ! -f "$1" ]; then fi /usr/bin/env python plsc_ordered.py "$1" -/usr/bin/env python plsc_flat.py "$1" +/usr/bin/env python plsc_flat.py "$1" \ No newline at end of file From c14cca262a6ebf9be2cb2e04789e0b1ccd0b2ac4 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 6 May 2024 18:29:59 +0200 Subject: [PATCH 08/18] automatically determine correct basedn --- dry_run/dry-run.sh | 5 +++++ dry_run/{plsc_dryrun..yml => plsc_dryrun.yml} | 0 2 files changed, 5 insertions(+) rename dry_run/{plsc_dryrun..yml => plsc_dryrun.yml} (100%) diff --git a/dry_run/dry-run.sh b/dry_run/dry-run.sh index f883a1d..5e074c9 100755 --- a/dry_run/dry-run.sh +++ b/dry_run/dry-run.sh @@ -20,6 +20,11 @@ if [ "$docker_proto" == "tcp://" ]; then trap "kill $BG_PID" EXIT fi + +# find basedn +export BASEDN=$( awk '/^dn: / { print $2; exit }' backup.ldif ) +echo "Found basedn '$BASEDN'" + COMPOSE_FILE="docker-compose.yml" COMPOSE="docker compose --file ${COMPOSE_FILE}" diff --git a/dry_run/plsc_dryrun..yml b/dry_run/plsc_dryrun.yml similarity index 100% rename from dry_run/plsc_dryrun..yml rename to dry_run/plsc_dryrun.yml From 99a2f3f30434db2252e4660a482e3b6d54540cec Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 6 May 2024 18:30:21 +0200 Subject: [PATCH 09/18] Dynamically check if ldap is running --- dry_run/docker-compose.yml | 2 +- dry_run/dry-run.sh | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/dry_run/docker-compose.yml b/dry_run/docker-compose.yml index 1f23db9..6addc03 100644 --- a/dry_run/docker-compose.yml +++ b/dry_run/docker-compose.yml @@ -7,7 +7,7 @@ services: ports: - 1389:1389 environment: - LDAP_ROOT: "dc=services,dc=vnet" + LDAP_ROOT: "${BASEDN}" LDAP_ADMIN_USERNAME: "admin" LDAP_ADMIN_PASSWORD: "changethispassword" LDAP_CONFIG_ADMIN_USERNAME: "admin" diff --git a/dry_run/dry-run.sh b/dry_run/dry-run.sh index 5e074c9..a5fd401 100755 --- a/dry_run/dry-run.sh +++ b/dry_run/dry-run.sh @@ -29,9 +29,19 @@ COMPOSE_FILE="docker-compose.yml" COMPOSE="docker compose --file ${COMPOSE_FILE}" echo "Starting containers" -${COMPOSE} kill && ${COMPOSE} rm -f || true +${COMPOSE} rm --force --stop || true ${COMPOSE} up --detach -sleep 5 + +echo -n "Waiting for ldap to start" +while sleep 0.5 +do + echo -n "." + if docker compose logs | grep -q '\*\* Starting slapd \*\*' + then + echo " Up!" + break + fi +done echo "Configuring LDAP" ${COMPOSE} exec ldap slapmodify -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_1.ldif From a2eeecfa637c2154d46dc28a0821d38bc220a21f Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 6 May 2024 18:31:55 +0200 Subject: [PATCH 10/18] check if file are present --- dry_run/dry-run.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dry_run/dry-run.sh b/dry_run/dry-run.sh index a5fd401..b95629b 100755 --- a/dry_run/dry-run.sh +++ b/dry_run/dry-run.sh @@ -3,6 +3,14 @@ set -e shopt -s extglob # for the string postfix matching below +# check if data file are present +if [ ! -f "backup.ldif" -o ! -f "sync.json" ]; then + echo "Data files backup.ldif and/or sync.json not found" + echo "Copy ldap backup (slapcat -n1 output) to backup.ldif" + echo "Copy SBS plsc sync output to sync.json" + exit 1 +fi + # check if we're using a remote docker host docker_host=$(docker context inspect -f '{{ .Endpoints.docker.Host }}') docker_proto=${docker_host:0:6} From 4ab1fbcc34a800e3d25ca61cb9ffe22808177817 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 6 May 2024 18:32:50 +0200 Subject: [PATCH 11/18] fix ldap config --- dry_run/ldif/config_1.ldif | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dry_run/ldif/config_1.ldif b/dry_run/ldif/config_1.ldif index 8ef3ffe..1092e6e 100644 --- a/dry_run/ldif/config_1.ldif +++ b/dry_run/ldif/config_1.ldif @@ -1,3 +1,8 @@ +dn: cn=config +changetype: Modify +add: olcAttributeOptions +olcAttributeOptions: "time-" + dn: cn=module{1},cn=config changetype: Modify add: olcModuleLoad From 2d4bb52b4642c2e08ddb4fcde0858db61e1bd34e Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 6 May 2024 18:33:09 +0200 Subject: [PATCH 12/18] plsc path --- dry_run/dry-run.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dry_run/dry-run.sh b/dry_run/dry-run.sh index b95629b..464f344 100755 --- a/dry_run/dry-run.sh +++ b/dry_run/dry-run.sh @@ -59,7 +59,7 @@ echo "Loading data" ${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif echo "Running plsc" -export PATH=$(pwd)/venv/bin:${PATH} -../run.sh ./plsc_dryrun.yml +export PATH=$(pwd)/../venv/bin:${PATH} +../run.sh $(pwd)/plsc_dryrun.yml exit 0 \ No newline at end of file From b396c2007eb94ab0e00dab29a57ed8d3b3d108ad Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Tue, 7 May 2024 10:16:56 +0200 Subject: [PATCH 13/18] dynamically generate plsc config (becasue we need base_dn in there) --- dry_run/dry-run.sh | 34 ++++++++++++++++++++++++++++++++-- dry_run/plsc_dryrun.yml | 25 ------------------------- 2 files changed, 32 insertions(+), 27 deletions(-) delete mode 100644 dry_run/plsc_dryrun.yml diff --git a/dry_run/dry-run.sh b/dry_run/dry-run.sh index 464f344..eeb633d 100755 --- a/dry_run/dry-run.sh +++ b/dry_run/dry-run.sh @@ -58,8 +58,38 @@ ${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /o echo "Loading data" ${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif +# generate plsc config +echo "Generating plsc config" +TMPFILE=$(mktemp plsc_XXXXXX.yml) +trap "rm -f $TMPFILE" EXIT +cat < "${TMPFILE}" + --- + ldap: + src: + uri: "ldap://localhost:1389/" + basedn: "${BASEDN}" + binddn: "cn=admin,${BASEDN}" + passwd: "changethispassword" + sizelimit: 5 + dst: + uri: "ldap://localhost:1389/" + basedn: "${BASEDN}" + binddn: "cn=admin,${BASEDN}" + passwd: "changethispassword" + sizelimit: 5 + sbs: + src: + host: "test" + sync: "dry_run/sync.json" + pwd: '{CRYPT}!' + uid: 1000 + gid: 1000 +EOF + +export LOGLEVEL=DEBUG echo "Running plsc" -export PATH=$(pwd)/../venv/bin:${PATH} -../run.sh $(pwd)/plsc_dryrun.yml +cd .. +export PATH=$(pwd)/venv/bin:${PATH} +./run.sh "./dry_run/${TMPFILE}" exit 0 \ No newline at end of file diff --git a/dry_run/plsc_dryrun.yml b/dry_run/plsc_dryrun.yml deleted file mode 100644 index 834620f..0000000 --- a/dry_run/plsc_dryrun.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -ldap: - src: - uri: ldap://localhost:1389/ - basedn: dc=services,dc=vnet - binddn: cn=admin,dc=services,dc=vnet - passwd: changethispassword - sizelimit: 5 - dst: - uri: ldap://localhost:1389/ - basedn: dc=services,dc=vnet - binddn: cn=admin,dc=services,dc=vnet - passwd: changethispassword - sizelimit: 5 -sbs: - src: - recorder: False - host: test - sync: sync.json - user: sysread - passwd: changethispassword - verify_ssl: False -pwd: '{CRYPT}!' -uid: 1000 -gid: 1000 From 6b221a7ba6954ab16d6ac856d1722eeb9ffda6f0 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Tue, 7 May 2024 10:17:12 +0200 Subject: [PATCH 14/18] define attributeoptions --- dry_run/ldif/config_1.ldif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dry_run/ldif/config_1.ldif b/dry_run/ldif/config_1.ldif index 1092e6e..0982061 100644 --- a/dry_run/ldif/config_1.ldif +++ b/dry_run/ldif/config_1.ldif @@ -1,7 +1,7 @@ dn: cn=config changetype: Modify add: olcAttributeOptions -olcAttributeOptions: "time-" +olcAttributeOptions: time- dn: cn=module{1},cn=config changetype: Modify From 6b2538e94064ae8b958ac58caf116e6850ce0dd8 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Tue, 7 May 2024 10:34:10 +0200 Subject: [PATCH 15/18] fix traps --- dry_run/dry-run.sh | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/dry_run/dry-run.sh b/dry_run/dry-run.sh index eeb633d..7b41911 100755 --- a/dry_run/dry-run.sh +++ b/dry_run/dry-run.sh @@ -3,8 +3,14 @@ set -e shopt -s extglob # for the string postfix matching below +cleanup() { + [ -n "$SOCAT_PID" ] && kill "$SOCAT_PID" 2>/dev/null || true + [ -n "$TMPFILE" ] && rm -f "${TMPFILE}" || true +} +trap cleanup EXIT + # check if data file are present -if [ ! -f "backup.ldif" -o ! -f "sync.json" ]; then +if [ ! -f "backup.ldif" ] || [ ! -f "sync.json" ]; then echo "Data files backup.ldif and/or sync.json not found" echo "Copy ldap backup (slapcat -n1 output) to backup.ldif" echo "Copy SBS plsc sync output to sync.json" @@ -21,16 +27,14 @@ if [ "$docker_proto" == "tcp://" ]; then HOST=${HOST%:+([[:digit:]])?(/)} echo "Using remote docker host $HOST ($docker_host)" - socat TCP4-LISTEN:1389,fork,reuseaddr TCP4:$HOST:1389 & - BG_PID=$! - - # kill socat when exiting - trap "kill $BG_PID" EXIT + socat "TCP4-LISTEN:1389,fork,reuseaddr" "TCP4:${HOST}:1389" & + SOCAT_PID=$! fi # find basedn -export BASEDN=$( awk '/^dn: / { print $2; exit }' backup.ldif ) +BASEDN=$( awk '/^dn: / { print $2; exit }' backup.ldif ) +export BASEDN echo "Found basedn '$BASEDN'" COMPOSE_FILE="docker-compose.yml" @@ -41,7 +45,7 @@ ${COMPOSE} rm --force --stop || true ${COMPOSE} up --detach echo -n "Waiting for ldap to start" -while sleep 0.5 +while sleep 0.2 do echo -n "." if docker compose logs | grep -q '\*\* Starting slapd \*\*' @@ -60,8 +64,7 @@ ${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /b # generate plsc config echo "Generating plsc config" -TMPFILE=$(mktemp plsc_XXXXXX.yml) -trap "rm -f $TMPFILE" EXIT +TMPFILE=$(mktemp -t plsc_XXXXXX.yml) cat < "${TMPFILE}" --- ldap: @@ -89,7 +92,7 @@ EOF export LOGLEVEL=DEBUG echo "Running plsc" cd .. -export PATH=$(pwd)/venv/bin:${PATH} -./run.sh "./dry_run/${TMPFILE}" +export PATH="$(pwd)/venv/bin:${PATH}" +./run.sh "${TMPFILE}" exit 0 \ No newline at end of file From e58b9281db6d0dca01096645ce04dc41b15c02b2 Mon Sep 17 00:00:00 2001 From: Martin van Es Date: Thu, 16 May 2024 09:51:58 +0200 Subject: [PATCH 16/18] Fix unrecognized option --- dry_run/docker-compose.yml | 1 - dry_run/dry-run.sh | 6 +++--- dry_run/ldif/config_1.ldif | 4 +--- dry_run/ldif/config_2.ldif | 22 +++------------------- 4 files changed, 7 insertions(+), 26 deletions(-) diff --git a/dry_run/docker-compose.yml b/dry_run/docker-compose.yml index 6addc03..e26bc53 100644 --- a/dry_run/docker-compose.yml +++ b/dry_run/docker-compose.yml @@ -1,5 +1,4 @@ --- -version: "2" services: ldap: diff --git a/dry_run/dry-run.sh b/dry_run/dry-run.sh index 7b41911..da9436b 100755 --- a/dry_run/dry-run.sh +++ b/dry_run/dry-run.sh @@ -56,8 +56,8 @@ do done echo "Configuring LDAP" -${COMPOSE} exec ldap slapmodify -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_1.ldif -${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 0 -l /opt/ldap/ldif/config_2.ldif +${COMPOSE} exec ldap ldapmodify -H ldap://localhost:1389/ -D cn=admin,cn=config -w changethispassword -f /opt/ldap/ldif/config_1.ldif +${COMPOSE} exec ldap ldapadd -H ldap://localhost:1389/ -D cn=admin,cn=config -w changethispassword -f /opt/ldap/ldif/config_2.ldif echo "Loading data" ${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif @@ -89,7 +89,7 @@ cat < "${TMPFILE}" gid: 1000 EOF -export LOGLEVEL=DEBUG +# export LOGLEVEL=DEBUG echo "Running plsc" cd .. export PATH="$(pwd)/venv/bin:${PATH}" diff --git a/dry_run/ldif/config_1.ldif b/dry_run/ldif/config_1.ldif index 0982061..6404f19 100644 --- a/dry_run/ldif/config_1.ldif +++ b/dry_run/ldif/config_1.ldif @@ -6,9 +6,7 @@ olcAttributeOptions: time- dn: cn=module{1},cn=config changetype: Modify add: olcModuleLoad -olcModuleLoad: {1}memberof.so -olcModuleLoad: {2}refint.so -olcModuleLoad: {3}dynlist.so +olcModuleLoad: {1}dynlist.so dn: olcDatabase={2}mdb,cn=config changetype: Modify diff --git a/dry_run/ldif/config_2.ldif b/dry_run/ldif/config_2.ldif index 6c08654..9816103 100644 --- a/dry_run/ldif/config_2.ldif +++ b/dry_run/ldif/config_2.ldif @@ -1,21 +1,5 @@ -dn: olcOverlay={1}memberof,olcDatabase={2}mdb,cn=config -objectClass: olcOverlayConfig -objectClass: olcMemberOfConfig -olcOverlay: {1}memberof -olcMemberOfRefInt: TRUE -olcMemberOfGroupOC: groupOfMembers -olcMemberOfMemberAD: member -olcMemberOfMemberOfAD: memberOf - -dn: olcOverlay={2}refint,olcDatabase={2}mdb,cn=config -objectClass: olcOverlayConfig -objectClass: olcRefintConfig -olcOverlay: {2}refint -olcRefintAttribute: memberof -olcRefintAttribute: member - -dn: olcOverlay={3}dynlist,olcDatabase={2}mdb,cn=config +dn: olcOverlay={1}dynlist,olcDatabase={2}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcDynListConfig -olcOverlay: {3}dynlist -olcDynListAttrSet: {0}organizationalRole labeledURI roleOccupant +olcOverlay: {1}dynlist +olcDynListAttrSet: {0}voPerson labeledURI member+memberOf@groupOfMembers From 7b6bb5ab215011b09f8acd9ebe1a9d4d5abdb012 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 27 May 2024 15:50:07 +0200 Subject: [PATCH 17/18] add support for ldifparser and remove clutter from output --- dry_run/.gitignore | 5 +++-- dry_run/dry-run.sh | 52 +++++++++++++++++++++++++++++++++---------- dry_run/ldifparser.py | 1 + 3 files changed, 44 insertions(+), 14 deletions(-) create mode 120000 dry_run/ldifparser.py diff --git a/dry_run/.gitignore b/dry_run/.gitignore index 157198f..b52d0c0 100644 --- a/dry_run/.gitignore +++ b/dry_run/.gitignore @@ -1,2 +1,3 @@ -backup.ldif -sync.json \ No newline at end of file +backup.ldif* +result.ldif* +sync.json* \ No newline at end of file diff --git a/dry_run/dry-run.sh b/dry_run/dry-run.sh index da9436b..602274d 100755 --- a/dry_run/dry-run.sh +++ b/dry_run/dry-run.sh @@ -4,7 +4,8 @@ set -e shopt -s extglob # for the string postfix matching below cleanup() { - [ -n "$SOCAT_PID" ] && kill "$SOCAT_PID" 2>/dev/null || true + [ -n "$COMPOSE" ] && ${COMPOSE} rm --force --stop >/dev/null 2>&1 || true + [ -n "$SOCAT_PID" ] && kill "$SOCAT_PID" || true [ -n "$TMPFILE" ] && rm -f "${TMPFILE}" || true } trap cleanup EXIT @@ -17,7 +18,12 @@ if [ ! -f "backup.ldif" ] || [ ! -f "sync.json" ]; then exit 1 fi +GREEN="\033[0;32m" +NORMAL="\033[0m" + # check if we're using a remote docker host +# in that case, we need to forward the local port 1389 to the real docker host +# because all scripts depend on the ldap being available locally docker_host=$(docker context inspect -f '{{ .Endpoints.docker.Host }}') docker_proto=${docker_host:0:6} if [ "$docker_proto" == "tcp://" ]; then @@ -27,7 +33,7 @@ if [ "$docker_proto" == "tcp://" ]; then HOST=${HOST%:+([[:digit:]])?(/)} echo "Using remote docker host $HOST ($docker_host)" - socat "TCP4-LISTEN:1389,fork,reuseaddr" "TCP4:${HOST}:1389" & + socat "TCP4-LISTEN:1389,fork,reuseaddr" "TCP4:${HOST}:1389" 2>/dev/null & SOCAT_PID=$! fi @@ -40,9 +46,10 @@ echo "Found basedn '$BASEDN'" COMPOSE_FILE="docker-compose.yml" COMPOSE="docker compose --file ${COMPOSE_FILE}" -echo "Starting containers" -${COMPOSE} rm --force --stop || true -${COMPOSE} up --detach +echo -n "Starting containers..." +${COMPOSE} rm --force --stop >/dev/null 2>&1 || true +${COMPOSE} up --detach >/dev/null 2>&1 +echo echo -n "Waiting for ldap to start" while sleep 0.2 @@ -56,11 +63,11 @@ do done echo "Configuring LDAP" -${COMPOSE} exec ldap ldapmodify -H ldap://localhost:1389/ -D cn=admin,cn=config -w changethispassword -f /opt/ldap/ldif/config_1.ldif -${COMPOSE} exec ldap ldapadd -H ldap://localhost:1389/ -D cn=admin,cn=config -w changethispassword -f /opt/ldap/ldif/config_2.ldif +${COMPOSE} exec ldap ldapmodify -H ldap://localhost:1389/ -D cn=admin,cn=config -w changethispassword -f /opt/ldap/ldif/config_1.ldif > /dev/null 2>&1 +${COMPOSE} exec ldap ldapadd -H ldap://localhost:1389/ -D cn=admin,cn=config -w changethispassword -f /opt/ldap/ldif/config_2.ldif > /dev/null 2>&1 echo "Loading data" -${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif +${COMPOSE} exec ldap slapadd -F /opt/bitnami/openldap/etc/slapd.d/ -n 2 -l /backup.ldif > /dev/null 2>&1 # generate plsc config echo "Generating plsc config" @@ -89,10 +96,31 @@ cat < "${TMPFILE}" gid: 1000 EOF -# export LOGLEVEL=DEBUG +# install venv +if ! test -d '../venv' +then + echo -n "Installing venv..." + python3 -mvenv ../venv + ../venv/bin/pip install -q --upgrade pip wheel setuptools + ../venv/bin/pip install -q -r ../requirements.txt + echo +fi + + +#export LOGLEVEL=DEBUG echo "Running plsc" -cd .. -export PATH="$(pwd)/venv/bin:${PATH}" -./run.sh "${TMPFILE}" +( + cd .. + export PATH="$(pwd)/venv/bin:${PATH}" + ./run.sh "${TMPFILE}" +) + +echo Dumping result +docker-compose -f docker-compose.yml exec -ti ldap slapcat -F /opt/bitnami/openldap/etc/slapd.d/ -o ldif-wrap=no -n2 > result.ldif 2>/dev/null + +echo Comparing result +../venv/bin/python ./ldifparser.py < backup.ldif > backup.ldif.parsed +../venv/bin/python ./ldifparser.py < result.ldif > result.ldif.parsed +diff --unified --text --color=always backup.ldif.parsed result.ldif.parsed && echo -e "${GREEN}No changes detected!${NORMAAL}" exit 0 \ No newline at end of file diff --git a/dry_run/ldifparser.py b/dry_run/ldifparser.py new file mode 120000 index 0000000..d6ebe07 --- /dev/null +++ b/dry_run/ldifparser.py @@ -0,0 +1 @@ +../../SRAM-deploy/roles/ldap_monitor/files/ldifparser.py \ No newline at end of file From de5fbcc234af1d68d56d8c17c135c6ba83326824 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 27 May 2024 15:53:22 +0200 Subject: [PATCH 18/18] ok, let's just duplicate the code then --- dry_run/ldifparser.py | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) mode change 120000 => 100644 dry_run/ldifparser.py diff --git a/dry_run/ldifparser.py b/dry_run/ldifparser.py deleted file mode 120000 index d6ebe07..0000000 --- a/dry_run/ldifparser.py +++ /dev/null @@ -1 +0,0 @@ -../../SRAM-deploy/roles/ldap_monitor/files/ldifparser.py \ No newline at end of file diff --git a/dry_run/ldifparser.py b/dry_run/ldifparser.py new file mode 100644 index 0000000..35fd383 --- /dev/null +++ b/dry_run/ldifparser.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +import sys +import ldif +from collections import OrderedDict + + +def kcmp(item): + (key, v) = item + parts = key.split(',')[::-1] + new_key = ','.join(parts) + return (new_key, v) + + +def freeze(o): + if isinstance(o, dict): + return OrderedDict({k: freeze(v) for k, v in sorted(o.items(), key=kcmp)}.items()) + if isinstance(o, list): + return sorted([freeze(v) for v in o]) + return o.decode('utf-8') + + +def my_print(o, depth): + if isinstance(o, OrderedDict): + for k, v in o.items(): + my_print(k, depth) + my_print(v, depth + 2) + elif isinstance(o, list): + for v in o: + my_print(v, depth) + else: + print(f"{' ' * depth}{o}") + + +ldifparser = ldif.LDIFRecordList(sys.stdin) +ldifparser.parse() + +data = {k: v for k, v in ldifparser.all_records} +f = freeze(data) + +# print(json.dumps(f, indent=2)) +my_print(f, 0)