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 test for CA clone with replicated DS #4536

Merged
merged 1 commit into from
Aug 10, 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
391 changes: 391 additions & 0 deletions .github/workflows/ca-clone-replicated-ds-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,391 @@
name: CA clone with replicated DS
# https://github.com/dogtagpki/pki/wiki/Installing-CA-Clone-with-Replicated-DS

on:
workflow_call:
inputs:
db-image:
required: false
type: string

jobs:
test:
name: Test
runs-on: ubuntu-latest
env:
SHARED: /tmp/workdir/pki
steps:
- name: Clone repository
uses: actions/checkout@v3

- name: Retrieve PKI images
uses: actions/cache@v3
with:
key: pki-images-${{ github.sha }}
path: pki-images.tar

- name: Load PKI images
run: docker load --input pki-images.tar

- name: Create network
run: docker network create example

- name: Set up primary DS container
run: |
tests/bin/ds-container-create.sh primaryds
env:
IMAGE: ${{ inputs.db-image }}
HOSTNAME: primaryds.example.com
PASSWORD: Secret.123

- name: Connect primary DS container to network
run: docker network connect example primaryds --alias primaryds.example.com

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

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

# https://github.com/dogtagpki/pki/blob/master/docs/installation/ca/Installing_CA.md
- name: Install primary CA
run: |
docker exec primary pkispawn \
-f /usr/share/pki/server/examples/installation/ca.cfg \
-s CA \
-D pki_ds_url=ldap://primaryds.example.com:3389 \
-D pki_cert_id_generator=random \
-D pki_request_id_generator=random \
-D pki_client_admin_cert_p12=$SHARED/caadmin.p12 \
-v

- name: Check primary CA admin user
run: |
docker exec primary pki-server cert-export ca_signing \
--cert-file $SHARED/ca_signing.crt
docker exec primary pki client-cert-import ca_signing \
--ca-cert $SHARED/ca_signing.crt
docker exec primary pki pkcs12-import \
--pkcs12 $SHARED/caadmin.p12 \
--pkcs12-password Secret.123
docker exec primary pki -n caadmin ca-user-show caadmin

- name: Set up secondary DS container
run: |
tests/bin/ds-container-create.sh secondaryds
env:
IMAGE: ${{ inputs.db-image }}
HOSTNAME: secondaryds.example.com
PASSWORD: Secret.123

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

# https://github.com/dogtagpki/389-ds-base/wiki/Configuring-DS-Replication-with-DS-Tools
- name: Preparing DS backend
run: |
# check backends in primary DS
docker exec primaryds dsconf \
-D "cn=Directory Manager" \
-w Secret.123 \
ldap://primaryds.example.com:3389 \
backend suffix list

# create backend for CA in secondary DS
docker exec secondaryds dsconf \
-D "cn=Directory Manager" \
-w Secret.123 \
ldap://secondaryds.example.com:3389 \
backend create \
--suffix=dc=ca,dc=pki,dc=example,dc=com \
--be-name=ca

- name: Enable replication on primary DS
run: |
docker exec primaryds dsconf \
-D "cn=Directory Manager" \
-w Secret.123 \
ldap://primaryds.example.com:3389 \
replication enable \
--suffix=dc=ca,dc=pki,dc=example,dc=com \
--role=supplier \
--replica-id=1 \
--bind-dn="cn=Replication Manager,cn=config" \
--bind-passwd=Secret.123

- name: Enable replication on secondary DS
run: |
docker exec secondaryds dsconf \
-D "cn=Directory Manager" \
-w Secret.123 \
ldap://secondaryds.example.com:3389 \
replication enable \
--suffix=dc=ca,dc=pki,dc=example,dc=com \
--role=supplier \
--replica-id=2 \
--bind-dn="cn=Replication Manager,cn=config" \
--bind-passwd=Secret.123

- name: Create replication manager on primary DS
run: |
docker exec primaryds dsconf \
-D "cn=Directory Manager" \
-w Secret.123 \
ldap://primaryds.example.com:3389 \
repl-agmt create \
--suffix=dc=ca,dc=pki,dc=example,dc=com \
--host=secondaryds.example.com \
--port=3389 \
--conn-protocol=LDAP \
--bind-dn="cn=Replication Manager,cn=config" \
--bind-passwd=Secret.123 \
--bind-method=SIMPLE \
primaryds-to-secondaryds

- name: Create replication manager on secondary DS
run: |
docker exec secondaryds dsconf \
-D "cn=Directory Manager" \
-w Secret.123 \
ldap://secondaryds.example.com:3389 \
repl-agmt create \
--suffix=dc=ca,dc=pki,dc=example,dc=com \
--host=primaryds.example.com \
--port=3389 \
--conn-protocol=LDAP \
--bind-dn="cn=Replication Manager,cn=config" \
--bind-passwd=Secret.123 \
--bind-method=SIMPLE \
secondaryds-to-primaryds

- name: Initializing replication agreement
run: |
# start initialization
docker exec primaryds dsconf \
-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

counter=$((counter+1))
done

- name: Check entries in primary DS and secondary DS
run: |
# get DNs from primary DS
docker exec primaryds ldapsearch \
-H ldap://primaryds.example.com:3389 \
-x \
-D "cn=Directory Manager" \
-w Secret.123 \
-b "dc=ca,dc=pki,dc=example,dc=com" \
-o ldif_wrap=no \
-LLL \
dn \
| sed -ne 's/^dn: \(.*\)$/\1/p' | sort | tee primaryds.dn

# get DNs from secondary DS
docker exec secondaryds ldapsearch \
-H ldap://secondaryds.example.com:3389 \
-x \
-D "cn=Directory Manager" \
-w Secret.123 \
-b "dc=ca,dc=pki,dc=example,dc=com" \
-o ldif_wrap=no \
-LLL \
dn \
| sed -ne 's/^dn: \(.*\)$/\1/p' | sort > secondaryds.dn

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: |
# get CS.cfg from primary CA before cloning
docker cp primary:/etc/pki/pki-tomcat/ca/CS.cfg CS.cfg.primary

docker exec secondary pkispawn \
-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 \
-D pki_cert_id_generator=random \
-D pki_request_id_generator=random \
-v

- name: Check system certs in primary CA and secondary CA
run: |
# get system certs from primary CA (except sslserver)
docker exec primary pki-server cert-show ca_signing > system-certs.primary
echo >> system-certs.primary
docker exec primary pki-server cert-show ca_ocsp_signing >> system-certs.primary
echo >> system-certs.primary
docker exec primary pki-server cert-show ca_audit_signing >> system-certs.primary
echo >> system-certs.primary
docker exec primary pki-server cert-show subsystem >> system-certs.primary

# get system certs from secondary CA (except sslserver)
docker exec secondary pki-server cert-show ca_signing > system-certs.secondary
echo >> system-certs.secondary
docker exec secondary pki-server cert-show ca_ocsp_signing >> system-certs.secondary
echo >> system-certs.secondary
docker exec secondary pki-server cert-show ca_audit_signing >> system-certs.secondary
echo >> system-certs.secondary
docker exec secondary pki-server cert-show subsystem >> system-certs.secondary

cat system-certs.primary
diff system-certs.primary system-certs.secondary

- name: Check CS.cfg in primary CA after cloning
run: |
# get CS.cfg from primary CA after cloning
docker cp primary:/etc/pki/pki-tomcat/ca/CS.cfg CS.cfg.primary.after

diff CS.cfg.primary CS.cfg.primary.after

- name: Check CS.cfg in secondary CA
run: |
# get CS.cfg from secondary CA
docker cp secondary:/etc/pki/pki-tomcat/ca/CS.cfg CS.cfg.secondary

# normalize expected result:
# - remove params that cannot be compared
# - replace primary.example.com with secondary.example.com
# - replace primaryds.example.com with secondaryds.example.com
# - set ca.crl.MasterCRL.enableCRLCache to false (automatically disabled in the clone)
# - set ca.crl.MasterCRL.enableCRLUpdates to false (automatically disabled in the clone)
# - add params for the clone
sed -e '/^installDate=/d' \
-e '/^ca.sslserver.cert=/d' \
-e '/^ca.sslserver.certreq=/d' \
-e 's/primary.example.com/secondary.example.com/' \
-e 's/primaryds.example.com/secondaryds.example.com/' \
-e 's/^\(ca.crl.MasterCRL.enableCRLCache\)=.*$/\1=false/' \
-e 's/^\(ca.crl.MasterCRL.enableCRLUpdates\)=.*$/\1=false/' \
-e '$ a ca.certStatusUpdateInterval=0' \
-e '$ a ca.listenToCloneModifications=false' \
-e '$ a master.ca.agent.host=primary.example.com' \
-e '$ a master.ca.agent.port=8443' \
CS.cfg.primary.after \
| sort > expected

# normalize actual result:
# - remove params that cannot be compared
sed -e '/^installDate=/d' \
-e '/^ca.sslserver.cert=/d' \
-e '/^ca.sslserver.certreq=/d' \
CS.cfg.secondary \
| sort > actual

diff expected actual

- name: Check secondary CA admin user
run: |
docker exec secondary pki client-cert-import ca_signing \
--ca-cert $SHARED/ca_signing.crt
docker exec secondary pki pkcs12-import \
--pkcs12 $SHARED/caadmin.p12 \
--pkcs12-password Secret.123
docker exec secondary pki -n caadmin ca-user-show caadmin

- name: Check users in primary CA and secondary CA
run: |
docker exec primary pki -n caadmin ca-user-find | tee ca-users.primary
docker exec secondary pki -n caadmin ca-user-find > ca-users.secondary

diff ca-users.primary ca-users.secondary

- name: Check certs in primary CA and secondary CA
run: |
docker exec primary pki ca-cert-find | tee ca-certs.primary
docker exec secondary pki ca-cert-find > ca-certs.secondary

diff ca-certs.primary ca-certs.secondary

- name: Check security domain in primary CA and secondary CA
run: |
docker exec primary pki securitydomain-show | tee sd.primary
docker exec secondary pki securitydomain-show > sd.secondary

diff sd.primary sd.secondary

- name: Gather artifacts from primary containers
if: always()
run: |
tests/bin/ds-artifacts-save.sh --output=/tmp/artifacts/primary primaryds
tests/bin/pki-artifacts-save.sh primary
continue-on-error: true

- name: Gather artifacts from secondary containers
if: always()
run: |
tests/bin/ds-artifacts-save.sh --output=/tmp/artifacts/secondary secondaryds
tests/bin/pki-artifacts-save.sh secondary
continue-on-error: true

- name: Remove CA from secondary PKI container
run: docker exec secondary pkidestroy -i pki-tomcat -s CA -v

- name: Remove CA from primary PKI container
run: docker exec primary pkidestroy -i pki-tomcat -s CA -v

- name: Upload artifacts from primary containers
if: always()
uses: actions/upload-artifact@v3
with:
name: ca-clone-replicated-ds-primary
path: |
/tmp/artifacts/primary

- name: Upload artifacts from secondary containers
if: always()
uses: actions/upload-artifact@v3
with:
name: ca-clone-replicated-ds-secondary
path: |
/tmp/artifacts/secondary
Loading
Loading