# SOP to create/migrate Duffy tenant
This SOP covers the process of how to create a duffy tenant
## Create new tenant
### Connect to duffy.ci.centos.org
```shell
ssh duffy.ci.centos.org
```
### Change to duffy user
```shell
sudo su - duffy
```
### Create tenant with the command below and save api key somewhere safe, it outputs the key as `<tenant name>: <API key>`
```shell
duffy admin create-tenant <tenant name> <ssh pub-key>
```
## Migrate/Update tenant
Migrating an existing Duffy tenant from older DB is like previous step but we just need to enforce a specific (and known) API key. So we can apply previous `duffy admin create-tenant` step but then calling `duffy admin update-tenant` to enforce existing API key to be "valid" in new DB :
```
duffy admin update-tenant --help
Usage: duffy admin update-tenant [OPTIONS] NAME
Update a tenant.
Options:
--ssh-key TEXT New SSH key for the tenant.
--api-key TEXT Either a new API key (UUID) for the tenant
or 'reset' to set automatically.
--node-quota INT_OR_NONE How many nodes the tenant can use at a time
(optional, will use default if unset).
--session-lifetime INTERVAL_OR_NONE
The initial session lifetime for this
tenant.
--session-lifetime-max INTERVAL_OR_NONE
The maximum session lifetime for this
tenant.
```
We just need first to retrieve existing duffy api key and ssh public keys from old Duffy DB
Let's assume for the example that projectname is "test-infra" :
```
MariaDB [duffy]> select * from users where projectname like '%test-infra%';
+--------------------------------------+-------------+-------------+------------+------------+
| apikey | projectname | jobname | createdat | limitnodes |
+--------------------------------------+-------------+-------------+------------+------------+
| d6e0483b-c9e1-40c7-a2a0-0f29f4961cde | test-infra | test-infr a | 2015-06-10 | 10 |
+--------------------------------------+-------------+-------------+------------+------------+
1 row in set (0.00 sec)
MariaDB [duffy]> select `key` from userkeys where project_id='d6e0483b-c9e1-40c7-a2a0-0f29f4961cde';
<output not shown here but multiple possible values
```
Now that we have both the apikey and ssh keys (can be multiple ones), we can use `duffy admin update-tenant` with new values
We can follow same `update-tenant` process to change node-quota and session-lifetime
!!! warning
for newly created CI tenants in openshift we had only *one* ssh keypair and so *one* ssh public key to import. But for previous/legacy jobs, it's possible that we have *multiple* ssh public keys. In that case, duffy cli lets you only import "one" string, which should absolutely contain new line character, so it can be done like this :
```
duffy admin update-tenant --api-key d6e0483b-c9e1-40c7-a2a0-0f29f4961cde --ssh-key "ssh-rsa <fake_one_>+W2EMNDARNa50KaFXQ3hM6TWLPwGhnG0Sj5l1obae0sNiEgzUejp1gNnTPWv/BLKdOH5yl14Z
> ssh-rsa <fake_two>SBLcm+f3Xy8WJEqtFF461XSoM97rSapDM9KH/h1tMqUyXnVTzbofQlGGAJw40+l9D4+F98Nbm95jWVmjQ+1N/uCiz0/Io5MDxZPq645mR4ChUAhrwE16JPr7c1DsYES7rTPbmC0lX9VCjhzxBSlbOzvxBuEipYt0FMKRlwvMzwPHONijvmx1AkB7t test-infra@jenkins-agent.ci.centos.org
> ssh-rsa <fake_key_three>PyqI7/BvcozCQQaM33LfbcpKb4ks0vw4+RH1AjnjC9r8SNivUiUQ9zg0RHXwUGRCK0iD70JGeO43Q7cSixtYfHu/MXm2feFNz01hsAIEGrlJVUlMzUyLYcqOu0BTKxIlKyK3tG1RLNvG/IDcaZMMBNS83k9phJyATvzXpeocyo6NgUVDeZstpunVv4xKQNX39nD4S/09jslXk6lZ8Pj7fyKf0rGOHuu7NpJOIb2rcSd8sC1MmsOGlY+EUuZ test-infra@CI" test-infra
```
It's really *important* that the whole --ssh-key "block" is seen as a string with newline inside so that it's correct injected for duffy job as different lines in remote .ssh/authorized_keys when duffy will contextualize the node
It's also important to add this <project>/<apikey> keypair in the `duffy_metaclient_usermap` list in ansible inventory, in the host_vars, so that if tenant is actually just using only old/legacy endpoint with his apikey, it will still be recognized by duffy (until we remote the legacy endpoint)
When committed to git and pushed, one can play the duffy role with the config tags and it will update 20_metaclient.yaml file used by metaclient service.
Once tenant is imported (apikey and ssh public key(s)) and ansible duffy role applied, the tenant can either use `icico` client (in compatibility mode) or already use the new duffy client (see below)
## Artifacts storage box
CI tenants are allowed to upload artifacts to one storage box, so we need to allow them to upload/rsync to it.
It's all controlled by the `artifacts_projects_list` list in ansible (host_vars) so don't forget to also add project and ssh public keys there too
## Duffy client configuration (external)
### Connect to the host that will have duffy client
```shell
ssh <host user>@<target host>
```
### Install duffy client using `pip`
```shell
pip3.8 install --user duffy[client]
```
### In the home path of the user, create `.config` directory if it doesn’t exist and create `.config/duffy` with the following content
```
client:
url: https://duffy.ci.centos.org/api/v1
auth:
name: <tenant name>
key: <API key>
```
### To create a session, the name of the pool is required. Check the pool available executing the command **_(Optional)_**
```shell
duffy client list-pools
```
### Request a session
```shell
duffy client request-session pool=<name of the pool>,quantity=<number of sessions wanted>
```
By default this command outputs a _json_, but it's possible to change the format to _yaml_ or _flat_ using `--format`. Under "node" key it's possible to find the hostname to be used. Log in to it as `root` user, using `ssh`.
```json
{
...output ommited...
"nodes": [
{
"hostname": "<hostname>.ci.centos.org",
"ipaddr": "<ip address>",
...output ommited...
}
```
### When needed to retire the session, connect to your duffy client host and execute the command
```shell
duffy client retire-session <session id>
```
It's possible to check the session id either when the session is requested, in the output under "session" key, or using the following command:
```shell
duffy client list-sessions
```