# Domains and pulp_rpm
## **MY** Data! Mine!
* PulpCON 2023, 2023-11-06 1500UTC
* Grant Gainey (ggainey@redhat.com)
* Slides can be found at https://hackmd.io/@ggainey/rpm-domain-demo
---
## Agenda
* Introduction
* Review of Domains
* Demo Setup
* Demo
* Key Takeaways
* Q&A
---
## Review of Domains
* Why Domains?
* How?
* Who?
* Caveats
----
* Why?
* Allow for isolation in **multi-tenant installations**
* API access (via Domain-specific RBAC setup)
* Artifact storage (Each Domain has its own storage)
* Content-delivery is NOT domain-controlled
* That's what ContentGuards are for
----
* How?
* Users given Domain-specific RBAC access
* Objects scoped to the Domain they are created in
* Objects **cannot** be shared "cross-domain"
* Storage specified per-domain
* Pulp's de-duplication is **NOT** Cross-Domain
* Activated by setting `DOMAIN_ENABLED=True`
----
* Caveats
* Pulp will **FAIL TO START** unless all plugins support
* Content- and API-urls change to include the domain
* e.g., Content at `/pulp/content/MYDOMAIN/foo-repo/`
* e.g., API at `/pulp/MYDOMAIN/api/v3/remotes/`
* Some entities are **NOT** Domain-specific
* Users, Groups, AccessPolicies, Roles
----
* Who has Domain support?
* pulpcore/3.23+
* pulp_file/1.13+
* pulp_certguard/1.6+
* pulp_rpm/3.22+
* pulp_gem/0.4+
---
## Demo Setup
* Two Domains: The `default`, and `private` domain
* Three users, `admin` (the instance-admin), `robert` (an rpm-admin for domain "private") and `norm` (no access to anything)
* A repository, `default-repo`, with associated Remote and Distribution
* In pulp-cli - if no domain is specified, 'default' is assumed
---
## Demo!
### Setting the scene
* show: starting-conditions
* setup: users, domains, repos
* show: where we are now
----
## Demo!
### Repository creation/access
* TRY: **robert**, create repo in **default** - FAIL, RBAC
* TRY: **robert**, create repo in **private** - SUCCESS, rpm.admin
* TRY: **norm**, read repo in **default** - FAIL, RBAC
* TRY: **admin**, update **private**-repo to use **default**-remote - FAIL, CROSS_DOMAIN
----
## Demo!
### Trying to access content via the API
* TRY: **admin**, find package-by-name in **default** - SUCCEED
* TRY: **robert**, find same package - FAIL, DOMAIN_SPECIFIC
* TRY: **robert**, upload same RPM to **private**-repo, then access - SUCCEED
* TRY: using wget on **private**-domain distribution - SUCCEED, no ContentGuard
* teardown
---
## Demo Scripts
* show
* setup
* experiments
* teardown
----
### Show
```bash=
#!/usr/bin/bash
echo ">>> Show USERS:"
echo "pulp user list | jq '.[] | .username'"
pulp user list | jq '.[] | .username'
echo ">>> Show DOMAINS:"
echo "pulp domain list | jq '.[] | {name, description}'"
pulp domain list | jq '.[] | {name, description, pulp_href}'
echo ">>> Show ROLES:"
for u in robert norm
do
echo ">>> USER ${u}:"
echo "pulp user role-assignment list \
--username ${u} | jq '.[] | .role, .domain'"
pulp user role-assignment list \
--username ${u} | jq '.[] | {role, domain}'
done
echo ">>> Show REPOSITORIES:"
for d in $(pulp domain list | jq -r '.[] | .name')
do
echo "pulp --domain ${d} repository list | jq '.[] | {name, pulp_href}'"
pulp --domain "${d}" repository list | jq '.[] | {name, pulp_href}'
done
```
----
### Setup
```bash=
#!/usr/bin/bash
echo ">>> Create default Remote"
pulp rpm remote create \
--name ${DEFAULT_REPO} \
--url https://fixtures.pulpproject.org/rpm-signed/ \
--policy on_demand
echo ">>> Create default Repository"
pulp rpm repository create --name ${DEFAULT_REPO} --remote ${DEFAULT_REPO} --autopublish
echo ">>> Sync default Repository"
pulp rpm repository sync --name ${DEFAULT_REPO}
echo ">>> Create user 'robert'"
pulp user create --username robert --password ${ROBERT_PWD}
echo ">>> Create user 'norm'"
pulp user create --username norm --password ${NORM_PWD}
echo ">>> Create Domain ${PRIVATE_DOMAIN}"
pulp domain create \
--name ${PRIVATE_DOMAIN} \
--description "robert's domain" \
--storage-class pulpcore.app.models.storage.FileSystem \
--storage-settings "{\"MEDIA_ROOT\": \"/var/lib/pulp/media/\"}"
echo ">>> Give 'robert' rpm.admin in ${PRIVATE_DOMAIN}"
pulp user role-assignment add --username robert --role "rpm.admin" --domain ${PRIVATE_DOMAIN}
echo ">>> Role Assignments:"
for u in robert norm
do
echo "USER ${u}:"
pulp user role-assignment list --username ${u} | jq '.[] | .role, .domain'
done
```
----
### Access Demo
```bash=
#!/usr/bin/bash
echo ">>> TRY: robert, create repo in default - ERR..."
pulp --username robert --password ${ROBERT_PWD} rpm repository create --name ${PRIVATE_REPO}
echo ">>> TRY: robert, create repo in private - SUCCEED..."
pulp --domain ${PRIVATE_DOMAIN} --username robert --password ${ROBERT_PWD} rpm repository create --name ${PRIVATE_REPO} --autopublish
pulp --domain ${PRIVATE_DOMAIN} --username robert --password ${ROBERT_PWD} rpm distribution create --name ${PRIVATE_REPO} --repository ${PRIVATE_REPO} --base-path ${PRIVATE_REPO}
echo ">>> TRY: norm, read repo in default - ERR..."
pulp --username norm --password ${NORM_PWD} rpm repository show --name ${DEFAULT_REPO}
echo ">>> TRY: admin, copy content from default to private - ERR..."
export DEFAULT_REMOTE_HREF=$(pulp rpm remote show --name ${DEFAULT_REPO} | jq -r .pulp_href)
pulp --domain ${PRIVATE_DOMAIN} rpm repository sync --repository ${PRIVATE_REPO} --remote ${DEFAULT_REMOTE_HREF}
echo ">>> TRY: admin, find package-by-name - SUCCEED..."
pulp rpm content list --name zebra
echo ">>> TRY: robert, find same name - ERR..."
pulp --username robert --password ${ROBERT_PWD} rpm content list --name zebra
echo ">>> TRY: robert, upload same-name RPM to private repo, then access artifact - SUCCEED..."
pulp --domain ${PRIVATE_DOMAIN} --username robert --password ${ROBERT_PWD} rpm content upload --repository ${PRIVATE_REPO} --file ./zebra-0.1-2.noarch.rpm
pulp --domain ${PRIVATE_DOMAIN} --username robert --password ${ROBERT_PWD} rpm publication create --repository ${PRIVATE_REPO}
pulp --domain ${PRIVATE_DOMAIN} --username robert --password ${ROBERT_PWD} rpm content list --name zebra
echo ">>> TRY: using wget on private-domain distribution - SUCCEED..."
http http://localhost:5001/pulp/content/private/private/
```
----
### Teardown
```bash=
#!/usr/bin/bash
# Delete created repos, users, and domains
echo ">>> Destroy ${PRIVATE_DOMAIN}-domain objects..."
pulp rpm repository destroy --name ${DEFAULT_REPO}
pulp rpm remote destroy --name ${DEFAULT_REPO}
echo ">>> Destroy ${PRIVATE_DOMAIN}-domain objects..."
pulp --domain ${PRIVATE_DOMAIN} rpm distribution destroy --name ${PRIVATE_REPO}
pulp --domain ${PRIVATE_DOMAIN} rpm repository destroy --name ${PRIVATE_REPO}
echo ">>> Destroy ${PRIVATE_DOMAIN}..."
pulp domain destroy --name ${PRIVATE_DOMAIN}
echo ">>> Destroy Users..."
pulp user destroy --username robert
pulp user destroy --username norm
```
---
## Review
* Domains isolate API-access and storage
* Domains are built on top of Pulp's RBAC support
* Domains are only useable if **all** installed plugins support Domains
* External content-access is not Domain-controlled, but ContentGuard-controlled
* **BONUS**: pulp-cli profiles (q.v.) allow specifying domain/user/password
* you can skip typing out all the auth-stuff on every command!
* can be overridden on the command-line
---
## Q&A
---
## Thanks!
* Links:
* Domain Documentation
* https://docs.pulpproject.org/pulpcore/workflows/domains-multi-tenancy.html
* https://docs.google.com/presentation/d/129sL8I1tqck6tmJrMtlSUQKMkJLoNAjz-mvyYGnyJ48/
* Grant's Demo scripts
* http://github.com/ggainey/pulp_startup/rpm_domain_demo
{"title":"Domains and pulp_rpm - MY Content! Mine!","description":"Introduction","contributors":"[{\"id\":\"1a6032ad-e6b7-434d-aa35-96e6ebf50256\",\"add\":10967,\"del\":3008}]"}