diff --git a/.env b/.env index 803b0a30..32a15a3c 100644 --- a/.env +++ b/.env @@ -2,3 +2,11 @@ # Copy it to .env or use --env-file=env.example on docker-compose command. REGISTRY=quay.io/ftrivino TAG=latest +KC_TAG=19.0.3 +# KITE = Keycloak Integration Test Environment +CI_PREFIX=kite +PLUGIN_TAG=kc19_intg +PLUGIN_VER=0.0.1 +PLUGIN_DIR=scim-keycloak-user-storage-spi-${PLUGIN_TAG} +PLUGIN_JAR=scim-user-spi-0.0.1-SNAPSHOT.jar +KCADM="podman exec -it kite-keycloak /opt/keycloak/bin/kcadm.sh" diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..443a1d00 --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +include .env + +up: datadir cert plugin + docker-compose up --detach + +stop: + docker-compose stop + +down: stop + docker-compose down + +datadir: +ifeq (,$(wildcard data/keycloak)) + mkdir -p data/keycloak +endif + +#cert: datadir ipaca +cert: datadir +ifeq (,$(wildcard data/keycloak/server.crt)) + cd data/configs && \ + openssl req -x509 -nodes -newkey rsa:4096 -keyout server.key \ + -out server.crt -sha256 -days 365 -subj '/CN=master.keycloak.test' && \ + mv server.* ../keycloak && \ + cd ../keycloak && \ + keytool -import -keystore server.keystore \ + -file server.crt -alias truststore \ + -trustcacerts -storepass Secret123 -noprompt && \ + chown 1000 server.* +endif + +ipaca: +ifeq (,$(wildcard data/keycloak/ipaca.crt)) + cd data/keycloak && \ + curl -o ipaca.crt http://master.ipa.test/ipa/config/ca.crt && \ + chown 1000 server.* +endif + +container: + $(MAKE) -C src + +plugin: datadir +ifeq (,$(wildcard data/keycloak/$(PLUGIN_JAR))) + cd data/keycloak && \ + wget https://github.com/justin-stephenson/scim-keycloak-user-storage-spi/archive/refs/tags/$(PLUGIN_TAG).tar.gz && \ + tar zxvf $(PLUGIN_TAG).tar.gz && \ + pushd $(PLUGIN_DIR) && \ + mvn clean package && \ + mv target/$(PLUGIN_JAR) ../ +endif + +bridge: + bash -c "src/install/setup_bridge.sh" + +clean: + rm -rf data/keycloak/* diff --git a/data/configs/dnsmasq.conf b/data/configs/dnsmasq.conf index 477f3e34..54f5f6c0 100644 --- a/data/configs/dnsmasq.conf +++ b/data/configs/dnsmasq.conf @@ -9,19 +9,25 @@ local=/test/ # These zones have their own DNS server server=/ipa.test/172.16.100.10 -server=/samba.test/172.16.100.30 server=/ad.test/172.16.200.10 # Add A records for LDAP and client machines address=/master.ldap.test/172.16.100.20 address=/client.test/172.16.100.40 +address=/master.keycloak.test/172.16.100.11 +address=/master.nextcloud.test/172.16.100.12 +address=/master.mariadb.test/172.16.100.13 +address=/ipa-tuura.bridge.test/172.16.100.14 # Add SRV record for LDAP srv-host=_ldap._tcp.ldap.test,master.ldap.test,389 # Add PTR records for all machines ptr-record=10.100.16.172.in-addr.arpa,master.ipa.test +ptr-record=11.100.16.172.in-addr.arpa,master.keycloak.test +ptr-record=12.100.16.172.in-addr.arpa,master.nextcloud.test +ptr-record=13.100.16.172.in-addr.arpa,master.mariadb.test +ptr-record=14.100.16.172.in-addr.arpa,ipa-tuura.bridge.test ptr-record=20.100.16.172.in-addr.arpa,master.ldap.test -ptr-record=30.100.16.172.in-addr.arpa,dc.samba.test ptr-record=40.100.16.172.in-addr.arpa,client.test ptr-record=10.200.16.172.in-addr.arpa,dc.ad.test diff --git a/docker-compose.yml b/docker-compose.yml index 401b7c30..3fdd95cd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ services: dns: restart: always image: ${REGISTRY}/ci-dns:latest - container_name: dns + container_name: ${CI_PREFIX}-dns env_file: ./env.containers volumes: - ./data/configs/dnsmasq.conf:/etc/dnsmasq.conf @@ -14,12 +14,12 @@ services: - label=disable - seccomp=unconfined networks: - sssd: + ipa-tuura: ipv4_address: 172.16.100.2 ipa: image: ${REGISTRY}/ci-ipa:${TAG} - container_name: ipa + container_name: ${CI_PREFIX}-ipa hostname: master.ipa.test dns: 172.16.100.2 env_file: ./env.containers @@ -34,17 +34,48 @@ services: - label=disable - seccomp=unconfined networks: - sssd: + ipa-tuura: ipv4_address: 172.16.100.10 + ipa-tuura: + image: quay.io/idmops/bridge:latest + #image: localhost/ipa-tuura/base:latest + container_name: ${CI_PREFIX}-ipa-tuura + hostname: ipa-tuura.bridge.test + ports: + - 8000:8000 + dns: 172.16.100.2 + env_file: ./env.containers + volumes: + - ./shared:/shared:rw + cap_add: + - SYS_ADMIN + - SYS_PTRACE + - AUDIT_WRITE + security_opt: + - apparmor=unconfined + - label=disable + - seccomp=unconfined + networks: + ipa-tuura: + ipv4_address: 172.16.100.14 + keycloak: - image: ${REGISTRY}/keycloak:${TAG} - container_name: keycloak + #image: ${REGISTRY}/keycloak:${TAG} + image: quay.io/keycloak/keycloak:${KC_TAG} + container_name: ${CI_PREFIX}-keycloak hostname: master.keycloak.test + ports: + - 8443:8443 dns: 172.16.100.2 env_file: ./env.containers volumes: - - ./shared:/shared:rw + #- ./shared:/shared:rw + - ./data/keycloak/server.crt:/opt/keycloak/conf/server.crt + - ./data/keycloak/server.key:/opt/keycloak/conf/server.key + - ./data/keycloak/server.keystore:/opt/keycloak/conf/server.keystore + - ./data/keycloak/ipaca.crt:/etc/ipaca.crt + - ./data/keycloak/scim-user-spi-${PLUGIN_VER}-SNAPSHOT.jar:/opt/keycloak/providers/scim.jar cap_add: - SYS_ADMIN - SYS_PTRACE @@ -53,12 +84,17 @@ services: - apparmor=unconfined - label=disable - seccomp=unconfined + entrypoint: + - /opt/keycloak/bin/kc.sh + - start + - --log-level=INFO,org.apache.http.wire:debug,org.keycloak:debug networks: - sssd: + ipa-tuura: ipv4_address: 172.16.100.11 + nextcloud: image: ${REGISTRY}/nextcloud:${TAG} - container_name: nextcloud + container_name: ${CI_PREFIX}-nextcloud hostname: master.nextcloud.test dns: 172.16.100.2 env_file: ./env.containers @@ -73,11 +109,11 @@ services: - label=disable - seccomp=unconfined networks: - sssd: + ipa-tuura: ipv4_address: 172.16.100.12 mariadb: image: ${REGISTRY}/mariadb:${TAG} - container_name: mariadb + container_name: ${CI_PREFIX}-mariadb hostname: master.mariadb.test dns: 172.16.100.2 env_file: ./env.containers @@ -92,11 +128,12 @@ services: - label=disable - seccomp=unconfined networks: - sssd: + ipa-tuura: ipv4_address: 172.16.100.13 + ldap: image: ${REGISTRY}/ci-ldap:${TAG} - container_name: ldap + container_name: ${CI_PREFIX}-ldap hostname: master.ldap.test dns: 172.16.100.2 env_file: ./env.containers @@ -110,11 +147,12 @@ services: - label=disable - seccomp=unconfined networks: - sssd: + ipa-tuura: ipv4_address: 172.16.100.20 + client: image: ${REGISTRY}/ci-client:${TAG} - container_name: client + container_name: ${CI_PREFIX}-client hostname: client.test dns: 172.16.100.2 env_file: ./env.containers @@ -129,11 +167,12 @@ services: - label=disable - seccomp=unconfined networks: - sssd: + ipa-tuura: ipv4_address: 172.16.100.40 + networks: - sssd: - name: sssd-ci + ipa-tuura: + name: ipa-tuura-ci driver: bridge ipam: config: diff --git a/env.containers b/env.containers index 87a732e7..eb9e5c01 100644 --- a/env.containers +++ b/env.containers @@ -1,2 +1,11 @@ # Environment variables set in all started containers CONTAINER=yes +KEYCLOAK_ADMIN=admin +KEYCLOAK_ADMIN_PASSWORD=Secret123 +KC_HOSTNAME=master.keycloak.test +KC_HOSTNAME_PORT=8443 +KC_HTTPS_CERTIFICATE_FILE=/opt/keycloak/conf/server.crt +KC_HTTPS_CERTIFICATE_KEY_FILE=/opt/keycloak/conf/server.key +KC_HTTPS_TRUST_STORE_FILE=/opt/keycloak/conf/server.keystore +KC_HTTPS_TRUST_STORE_PASSWORD=Secret123 +KC_HTTP_RELATIVE_PATH=/auth diff --git a/src/Containerfile b/src/Containerfile new file mode 100644 index 00000000..fdb786f5 --- /dev/null +++ b/src/Containerfile @@ -0,0 +1,42 @@ +FROM fedora:latest + +MAINTAINER Scott Poore + +ENV DJANGO_SUPERUSER_PASSWORD: Secret123 \ + DJANGO_SUPERUSER_USERNAME: scim \ + DJANGO_SUPERUSER_EMAIL: scim@ipa.test + +EXPOSE 8000 + +WORKDIR /ipa-tuura + +COPY ipa-tuura /ipa-tuura +COPY install/ipa-tuura.service /etc/systemd/system/ipa-tuura.service +COPY install/ipa-tuura.env /etc/sysconfig/ipa-tuura.env +COPY install/requirements.txt /ipa-tuura/requirements.txt + +# Leaving behind workaround for running specific fork/branch: +#RUN dnf -y install git +#RUN git clone https://github.com/f-trivino/ipa-tuura.git -b domains /opt/ipa-tuura +##RUN git clone https://github.com/Tiboris/ipa-tuura.git -b pr_check_workflow /opt/ipa-tuura +#RUN ln -s /opt/ipa-tuura/src/ipa-tuura /ipa-tuura +#RUN cp /opt/ipa-tuura/src/install/requirements.txt /ipa-tuura/requirements.txt + +# Need to install packages before linking service file so that the +# proper filesystem structure is in place for systemd +RUN dnf -y install sssd ipa-client realmd java-11-openjdk-headless \ + openssl maven unzip python3-pip git python3-netifaces \ + python3-devel krb5-devel gcc sssd-dbus wget openldap-clients \ + sssd sssd-ldap oddjob-mkhomedir realmd \ + --nodocs && \ + dnf clean all -y && \ + ln -s /etc/systemd/system/ipa-tuura.service \ + /etc/systemd/system/multi-user.target.wants/ipa-tuura.service && \ + ls -Fal /etc/systemd/system/multi-user.target.wants/* && \ + pip install -r /ipa-tuura/requirements.txt && \ + source /etc/sysconfig/ipa-tuura.env && \ + python3 /ipa-tuura/manage.py makemigrations ipatuura && \ + python3 /ipa-tuura/manage.py migrate && \ + python3 /ipa-tuura/manage.py createsuperuser --scim_username scim --noinput + +CMD ["/usr/sbin/init"] diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 00000000..7c9d522f --- /dev/null +++ b/src/Makefile @@ -0,0 +1,18 @@ +default: build + +build: + podman build -t ipa-tuura/base . + +run: + podman run --name bridge -d -p 8000:8000 ipa-tuura/base && \ + podman start bridge + +start: + podman start bridge + +exec: + podman exec -it bridge bash + +clean: + podman rm -f bridge && \ + podman image rm ipa-tuura/base diff --git a/src/install/ipa-tuura.env b/src/install/ipa-tuura.env new file mode 100644 index 00000000..75d4e273 --- /dev/null +++ b/src/install/ipa-tuura.env @@ -0,0 +1,5 @@ +DJANGO_SUPERUSER_USERNAME=scim +DJANGO_SUPERUSER_PASSWORD=Secret123 +DJANGO_SUPERUSER_EMAIL=scim@ipa.test +export DJANGO_SUPERUSER_USERNAME DJANGO_SUPERUSER_PASSWORD DJANGO_SUPERUSER_EMAIL + diff --git a/src/install/ipa-tuura.service b/src/install/ipa-tuura.service new file mode 100644 index 00000000..a9cb8461 --- /dev/null +++ b/src/install/ipa-tuura.service @@ -0,0 +1,17 @@ +[Unit] +Description=SCIMv2 Bridge Server +After=network.target + +[Service] +Type=idle +WorkingDirectory=/ipa-tuura/ +EnvironmentFile=/etc/sysconfig/ipa-tuura.env +# Fix this later +# User=scim +# Group=scim +ExecStart=/usr/bin/python3 /ipa-tuura/manage.py runserver 0.0.0.0:8000 +TimeoutStartSec=600 +TimeoutStopSec=600 + +[Install] +WantedBy=multi-user.target diff --git a/src/install/setup_bridge.sh b/src/install/setup_bridge.sh new file mode 100755 index 00000000..bcbd5cb3 --- /dev/null +++ b/src/install/setup_bridge.sh @@ -0,0 +1,51 @@ +#!/bin/bash -x + +podman exec -it kite-keycloak \ + /opt/keycloak/bin/kcadm.sh config truststore --trustpass Secret123 \ + /opt/keycloak/conf/server.keystore + +# sometimes need to retry login to connect successfully +for count in {1..10}; do + podman exec -it kite-keycloak \ + /opt/keycloak/bin/kcadm.sh config credentials \ + --server https://master.keycloak.test:8443/auth/ \ + --realm master --user admin --password Secret123 + if [ $? -eq 0 ]; then + break + else + sleep 10 + fi +done + + +# Setup SCIM Plugin in Keycloak to join IPA domain +podman exec -it kite-keycloak \ + /opt/keycloak/bin/kcadm.sh create components -r master \ + -s name=scimprov \ + -s providerId=scim \ + -s providerType=org.keycloak.storage.UserStorageProvider \ + -s 'config.scimurl=["ipa-tuura.bridge.test:8000"]' \ + -s 'config.loginusername=["scim"]' \ + -s 'config.loginpassword=["Secret123"]' \ + -s 'config.addintgdomain=["True"]' \ + -s 'config.domain=["http://ipa.test"]' \ + -s 'config.domainname=["ipa.test"]' \ + -s 'config.domaindesc=["Bridge to IPA Domain ipa.test"]' \ + -s 'config.domainurl=["https://ipa-tuura.bridge.test"]' \ + -s 'config.domainclientid=["admin"]' \ + -s 'config.domainclientsecret=["Secret123"]' \ + -s 'config.idprovider=["ipa"]' \ + -s 'config.cacert=["/etc/ipaca.crt"]' + +# -s 'config.domainuserextraattrs=["mail:mail, sn:sn: givenname:givenname"]' \ +# -s 'config.userDn=["ou=users,dc=ipa,dc=test"]' + +# getFirst("domainname")); +# getFirst("domaindesc")); +# getFirst("domainurl")); +# getFirst("domainclientid")); +# getFirst("domainclientsecret")); +# getFirst("idprovider")); +# getFirst("users_dn")); +# getFirst("cacert"); +