Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pki-server <subsystem>-db-repl-agmt-init #4636

Merged
merged 2 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 93 additions & 51 deletions .github/workflows/ca-clone-replicated-ds-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ jobs:
--pkcs12-password Secret.123
docker exec primary pki -n caadmin ca-user-show caadmin

- name: Export system certs and keys from primary CA
run: |
docker exec primary pki-server ca-clone-prepare \
--pkcs12-file $SHARED/ca-certs.p12 \
--pkcs12-password Secret.123

docker exec primary pki-server cert-export ca_signing \
--cert-file $SHARED/ca_signing.crt

- name: Set up secondary DS container
run: |
tests/bin/ds-container-create.sh secondaryds
Expand All @@ -80,6 +89,32 @@ jobs:
- name: Connect secondary DS container to network
run: docker network connect example secondaryds --alias secondaryds.example.com

- name: Set up secondary PKI container
run: |
tests/bin/runner-init.sh secondary
env:
HOSTNAME: secondary.example.com

- name: Connect secondary PKI container to network
run: docker network connect example secondary --alias secondary.example.com

- name: Create secondary PKI server
run: |
docker exec secondary pki-server create
docker exec secondary pki-server nss-create --no-password

- name: Create secondary CA subsystem
run: |
docker exec secondary pki-server ca-create -v

- name: Import system certs and keys into secondary CA
run: |
docker exec secondary pki \
-d /etc/pki/pki-tomcat/alias \
pkcs12-import \
--pkcs12 $SHARED/ca-certs.p12 \
--password Secret.123

# https://github.com/dogtagpki/389-ds-base/wiki/Configuring-DS-Replication-with-DS-Tools
- name: Preparing DS backend
run: |
Expand Down Expand Up @@ -112,6 +147,22 @@ jobs:
--bind-dn="cn=Replication Manager,cn=config" \
--bind-passwd=Secret.123

# check replication manager
docker exec primaryds ldapsearch \
-H ldap://primaryds.example.com:3389 \
-D "cn=Directory Manager" \
-w Secret.123 \
-x \
-b "cn=Replication Manager,cn=config"

# check replica object
docker exec primaryds ldapsearch \
-H ldap://primaryds.example.com:3389 \
-D "cn=Directory Manager" \
-w Secret.123 \
-x \
-b "cn=replica,cn=dc\3Dca\2Cdc\3Dpki\2Cdc\3Dexample\2Cdc\3Dcom,cn=mapping tree,cn=config"

- name: Enable replication on secondary DS
run: |
docker exec secondaryds dsconf \
Expand All @@ -125,7 +176,23 @@ jobs:
--bind-dn="cn=Replication Manager,cn=config" \
--bind-passwd=Secret.123

- name: Create replication manager on primary DS
# check replication manager
docker exec secondaryds ldapsearch \
-H ldap://secondaryds.example.com:3389 \
-D "cn=Directory Manager" \
-w Secret.123 \
-x \
-b "cn=Replication Manager,cn=config"

# check replica object
docker exec secondaryds ldapsearch \
-H ldap://secondaryds.example.com:3389 \
-D "cn=Directory Manager" \
-w Secret.123 \
-x \
-b "cn=replica,cn=dc\3Dca\2Cdc\3Dpki\2Cdc\3Dexample\2Cdc\3Dcom,cn=mapping tree,cn=config"

- name: Create replication agreement on primary DS
run: |
docker exec primaryds dsconf \
-D "cn=Directory Manager" \
Expand All @@ -141,7 +208,16 @@ jobs:
--bind-method=SIMPLE \
primaryds-to-secondaryds

- name: Create replication manager on secondary DS
# check replication agreement
docker exec primaryds ldapsearch \
-H ldap://primaryds.example.com:3389 \
-D "cn=Directory Manager" \
-w Secret.123 \
-x \
-b "cn=primaryds-to-secondaryds,cn=replica,cn=dc\3Dca\2Cdc\3Dpki\2Cdc\3Dexample\2Cdc\3Dcom,cn=mapping tree,cn=config" \
dn

- name: Create replication agreement on secondary DS
run: |
docker exec secondaryds dsconf \
-D "cn=Directory Manager" \
Expand All @@ -157,38 +233,24 @@ jobs:
--bind-method=SIMPLE \
secondaryds-to-primaryds

- name: Initializing replication agreement
run: |
# start initialization
docker exec primaryds dsconf \
# check replication agreement
docker exec secondaryds ldapsearch \
-H ldap://secondaryds.example.com:3389 \
-D "cn=Directory Manager" \
-w Secret.123 \
ldap://primaryds.example.com:3389 \
repl-agmt init \
--suffix=dc=ca,dc=pki,dc=example,dc=com \
primaryds-to-secondaryds

# wait for initialization to complete
counter=0
while [[ "$counter" -lt 30 ]]; do
sleep 1

docker exec primaryds dsconf \
-D "cn=Directory Manager" \
-w Secret.123 \
ldap://primaryds.example.com:3389 \
repl-agmt init-status \
--suffix=dc=ca,dc=pki,dc=example,dc=com \
primaryds-to-secondaryds \
> >(tee stdout) 2> >(tee stderr >&2) || true

STDOUT=$(cat stdout)
if [ "$STDOUT" = "Agreement successfully initialized." ]; then
break
fi
-x \
-b "cn=secondaryds-to-primaryds,cn=replica,cn=dc\3Dca\2Cdc\3Dpki\2Cdc\3Dexample\2Cdc\3Dcom,cn=mapping tree,cn=config" \
dn

counter=$((counter+1))
done
- name: Initializing replication agreement
run: |
docker exec secondary pki-server ca-db-repl-agmt-init \
--url ldap://primaryds.example.com:3389 \
--bind-dn "cn=Directory Manager" \
--bind-password Secret.123 \
--suffix dc=ca,dc=pki,dc=example,dc=com \
-v \
primaryds-to-secondaryds

- name: Check entries in primary DS and secondary DS
run: |
Expand Down Expand Up @@ -218,24 +280,6 @@ jobs:

diff primaryds.dn secondaryds.dn

- name: Export certs and keys from primary CA
run: |
docker exec primary pki-server ca-clone-prepare \
--pkcs12-file $SHARED/ca-certs.p12 \
--pkcs12-password Secret.123

docker exec primary pki-server cert-export ca_signing \
--cert-file $SHARED/ca_signing.crt

- name: Set up secondary PKI container
run: |
tests/bin/runner-init.sh secondary
env:
HOSTNAME: secondary.example.com

- name: Connect secondary PKI container to network
run: docker network connect example secondary --alias secondary.example.com

# https://github.com/dogtagpki/pki/wiki/Installing-CA-Clone-with-Existing-DS
- name: Install secondary CA
run: |
Expand All @@ -246,8 +290,6 @@ jobs:
-f /usr/share/pki/server/examples/installation/ca-clone.cfg \
-s CA \
-D pki_cert_chain_path=$SHARED/ca_signing.crt \
-D pki_clone_pkcs12_path=$SHARED/ca-certs.p12 \
-D pki_clone_pkcs12_password=Secret.123 \
-D pki_ds_url=ldap://secondaryds.example.com:3389 \
-D pki_ds_setup=False \
-v
Expand Down
155 changes: 155 additions & 0 deletions base/server/python/pki/server/cli/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import subprocess
import sys
import textwrap
import urllib.parse

import pki.cli
import pki.server.instance
Expand Down Expand Up @@ -220,6 +221,7 @@ def __init__(self, parent):

self.add_module(SubsystemDBAccessCLI(self))
self.add_module(SubsystemDBIndexCLI(self))
self.add_module(SubsystemDBReplicationCLI(self))
self.add_module(SubsystemDBVLVCLI(self))

@staticmethod
Expand Down Expand Up @@ -1325,6 +1327,159 @@ def execute(self, argv):
subsystem.rebuild_indexes()


class SubsystemDBReplicationCLI(pki.cli.CLI):
'''
{subsystem} replication management commands
'''

def __init__(self, parent):
super(SubsystemDBReplicationCLI, self).__init__(
'repl',
inspect.cleandoc(self.__class__.__doc__).format(
subsystem=parent.parent.name.upper()))

self.parent = parent
self.add_module(SubsystemDBReplicationAgreementCLI(self))


class SubsystemDBReplicationAgreementCLI(pki.cli.CLI):
'''
{subsystem} replication agreement management commands
'''

def __init__(self, parent):
super(SubsystemDBReplicationAgreementCLI, self).__init__(
'agmt',
inspect.cleandoc(self.__class__.__doc__).format(
subsystem=parent.parent.name.upper()))

self.parent = parent
self.add_module(SubsystemDBReplicationAgreementInitCLI(self))


class SubsystemDBReplicationAgreementInitCLI(pki.cli.CLI):
'''
Initialize {subsystem} replication agreement
'''

help = '''\
Usage: pki-server {subsystem}-db-repl-agmt-init [OPTIONS] <name>

-i, --instance <instance ID> Instance ID (default: pki-tomcat)
--url <URL> Database URL
--bind-dn <DN> Database bind DN
--bind-password <password> Database bind password
--suffix <DN> Database suffix
-v, --verbose Run in verbose mode.
--debug Run in debug mode.
--help Show help message.
'''

def __init__(self, parent):
super(SubsystemDBReplicationAgreementInitCLI, self).__init__(
'init',
inspect.cleandoc(self.__class__.__doc__).format(
subsystem=parent.parent.parent.parent.name.upper()))

self.parent = parent

def print_help(self):
print(textwrap.dedent(self.__class__.help).format(
subsystem=self.parent.parent.parent.parent.name))

def execute(self, argv):
try:
opts, args = getopt.gnu_getopt(argv, 'i:v', [
'instance=',
'url=', 'bind-dn=', 'bind-password=', 'suffix=',
'verbose', 'debug', 'help'])

except getopt.GetoptError as e:
logger.error(e)
self.print_help()
sys.exit(1)

instance_name = 'pki-tomcat'
subsystem_name = self.parent.parent.parent.parent.name
url = None
bind_dn = None
bind_password = None
suffix = None

for o, a in opts:
if o in ('-i', '--instance'):
instance_name = a

elif o == '--url':
url = urllib.parse.urlparse(a)

elif o == '--bind-dn':
bind_dn = a

elif o == '--bind-password':
bind_password = a

elif o == '--suffix':
suffix = a

elif o in ('-v', '--verbose'):
logging.getLogger().setLevel(logging.INFO)

elif o == '--debug':
logging.getLogger().setLevel(logging.DEBUG)

elif o == '--help':
self.print_help()
sys.exit()

else:
logger.error('Invalid option: %s', o)
self.print_help()
sys.exit(1)

if len(args) < 1:
logger.error('Missing replication agreement name')
self.print_help()
sys.exit(1)

name = args[0]

instance = pki.server.instance.PKIInstance(instance_name)

if not instance.exists():
logger.error('Invalid instance: %s', instance_name)
sys.exit(1)

instance.load()

subsystem = instance.get_subsystem(subsystem_name)

if not subsystem:
logger.error('No %s subsystem in instance %s.',
subsystem_name.upper(), instance_name)
sys.exit(1)

ldap_config = {}

if url.scheme == 'ldaps':
ldap_config['ldapconn.secureConn'] = 'true'
else:
ldap_config['ldapconn.secureConn'] = 'false'

ldap_config['ldapconn.host'] = url.hostname
ldap_config['ldapconn.port'] = str(url.port)

ldap_config['ldapauth.authtype'] = 'BasicAuth'
ldap_config['ldapauth.bindDN'] = bind_dn
ldap_config['ldapauth.bindPassword'] = bind_password

ldap_config['basedn'] = suffix

subsystem.init_replication_agreement(
name,
ldap_config)


class SubsystemDBVLVCLI(pki.cli.CLI):

def __init__(self, parent):
Expand Down
Loading
Loading