# How to provision an Infomaniak Public Cloud project for `mgf-cloud`

> **You want to:** stand up a fresh Infomaniak Public Cloud (OpenStack) project and
> get a working `clouds.yaml` so `mgf-cloud` can authenticate against it.
> **You have:** an Infomaniak account with **Public Cloud approved** (it is
> approval-gated — request it from the Manager and wait for approval; this can take
> a day or two).
> **You'll end up with:** an **Active** OpenStack project + a `clouds.yaml` in
> `my_stuff/` that `mgf.cloud.config.load()` resolves cleanly.

The whole flow is ~10 minutes of clicking + a short provisioning wait. The
screenshots below are from a real run (account/resource IDs are **this** account's
— yours will differ; **none of them are secrets**, but never screenshot or commit a
password, an RC-file secret, or an application-credential secret).

---

## Steps

### 1. Open the Public Cloud product

Manager → **Cloud Computing** → **Public Cloud**. You'll see your Public Cloud
product(s). A freshly-approved account often shows **`Projects: 0`** — that's the
state you start from.

![Public Cloud product list](images/infomaniak/01-public-cloud-list.png)

> ⚠️ **Pitfall — duplicate products.** The approval flow sometimes leaves **two**
> identically-named products (both `0.00 €`, `0 Projects`). Pick **one** to use and
> consider deleting the other so you're not maintaining two empty containers.

### 2. Create the OpenStack project

Click into the product → **Create a project**. Give it:
- a **project name** (e.g. `mgf-fed`),
- an **OpenStack user password** (this becomes your OpenStack user's password —
  store it like any secret),
- a **region** — choose **`dc3-a` (Geneva)**, the federation default (DR is `dc4-a`).

Hit **Add**. The project then provisions in the background:

![Project being created](images/infomaniak/02-project-creating.png)

> Provisioning is **not instant** — you'll get an **email** when it's ready. Don't
> proceed until then.

### 3. Confirm the project is Active

After the email, the product dashboard shows the project **Active**, with an
**OpenStack access** entry and an **Access Horizon** button:

![Project active](images/infomaniak/03-project-active.png)

### 4. Download the `clouds.yaml`

Open the project's **Control panel** → scroll to **OpenStack access** → click the
**⋮** (three dots) on the access row. Choose **Download the clouds.yaml file**
(also grab **Download the OpenStackRC file** as a backup — same fields, env-var form):

![OpenStack access — download clouds.yaml](images/infomaniak/04-openstack-access-download.png)

The Control panel also shows the IDs you'll want for `defaults.py` / debugging:
**ID OpenStack** (`PCP-…`), **ID Public Cloud**, **ID Project**, and the OpenStack
**user** (`PCU-…`).

### 5. Place it where `mgf-cloud` looks

Save the downloaded file to the repo's gitignored secrets dir:

```sh
mkdir -p my_stuff
mv ~/Downloads/clouds.yaml my_stuff/clouds.yaml      # NEVER commit this
export MGF_CLOUD_CLOUDS_YAML="$PWD/my_stuff/clouds.yaml"
```

`config.load()` resolves credentials in this order: explicit path →
`$MGF_CLOUD_CLOUDS_YAML` → `OS_*` env (a sourced `openrc.sh`) → the standard
OpenStack paths (`~/.config/openstack/clouds.yaml`, `/etc/openstack/clouds.yaml`,
`./clouds.yaml`).

> ⚠️ **Pitfall — missing password.** Infomaniak's `clouds.yaml` is sometimes shipped
> **without** the password (it expects `OS_PASSWORD` at runtime). If the `auth:`
> block has no `password:` line, add it with the password you set in step 2 — or
> source the `openrc.sh` so `OS_PASSWORD` is in the env.
>
> ⚠️ **Pitfall — cloud name.** `mgf-cloud` reads the `openstack` cloud entry by
> default (`from_clouds_yaml(..., cloud="openstack")`). If Infomaniak's file names
> the top-level cloud something else, rename that key to `openstack`.

---

## Verify

Offline credential resolution (works today, no network — proves the file is found
+ well-formed):

```sh
export MGF_CLOUD_CLOUDS_YAML="$PWD/my_stuff/clouds.yaml"
python -c "from mgf.cloud import config; print(config.load())"
# → prints the resolved Credentials (auth_url, region, user/app-cred set);
#   a CredentialsError means the file wasn't found or is missing required fields.
```

Live verification (once the Infomaniak adapter — Pass 3 — ships) is an opt-in
integration test that creates + destroys a single nano VM against the project.

---

## Common pitfalls

- **Billing is on.** The free-credit *discovery offer* is over for new projects —
  **all usage is billed**. Keep test VMs to the nano flavour (`a2-ram2-disk20`) and
  **destroy them** after; floating IPs and volumes bill even when the VM is off.
- **Default quotas are "level 2."** GPUs / XXL instances / higher limits need a
  support request (Manager → Contact Support).
- **Secrets discipline (AG-18 / SC-01 / PKG-03).** `clouds.yaml`, the `openrc.sh`,
  and any password live in **`my_stuff/` only** — gitignored, never committed.
- **Region.** Default `dc3-a` (Geneva); DR `dc4-a`. The region in `clouds.yaml`
  must match where the project was created.

## Cross-references

- [`docs/design/DESIGN.md`](../design/DESIGN.md) §5 (Credentials & config) + §6
  (Infomaniak domain defaults).
- `src/mgf/cloud/config.py` — the resolver (`load` / `from_clouds_yaml` / `from_env`).
- [`mgf-standard` AG-18 / SC-01 / PKG-03](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/) — the secrets-in-`my_stuff/` boundary.
