# R2lab redeux

I'd like to modernize all this stack; there's a lot to do !

## PLCAPI Replacement: r2lab-api

for starters I'd like to get rid of the PLCAPI thing; it's actually been recycled from a much older project,
it was convenient at the time but clearly we can do better

the current code is in `/Users/tparment/git/plcapi`, but don't look at it too
closely as it is way more complex than what we actually need here

in this first step we want to rewrite from scratch a fastapi tool that will replace it down the line
we're not concerned with preserving compatibility, xmlrpc is too old anyway

### scope

for now we only focus on this new component;
the plan is to create a new repository for it

there will be of course a lot of consequences on the rest of the stack, but we
can deal with that later; for now we just want to have a working API server that
can manage users, slices and leases

for the record, the impacted pieces of the stack are:

- rhubarbe as its needs to know who owns the leases at any given time - and
  potentially know more about authentication/authorization if we want to have
  some user-level access control in rhubarbe itself
- the sidecar server holds more general information about the testbed and its state
  right now it's a websockets server, I'm toying with the idea to rewrite it as well in a later stage
- he web interface; right now we have 2, one dedicated to PLCAPI, and one more
  general one; we'll probably want to merge them into a single one that talks to
  the new API

### data model

what we need to preserve from there is just:

- a notion of users;
- a notion of slices; a slice is essentially a collection of users
- a notion of leases; right now we have one single resource which is the whole
  testbed, but we can easily imagine having multiple resources in the future,
  and then a lease would be a reservation of a resource for a given slice and a
  given time period
- users have ssh keys

leases can be given to a slice, for a given resource (in our case the whole testbed for now) and a given time period (start/end); there should be a configurable granularity for the time period, right now it's 10 minute

### technical stack

- fastapi for the web server
- uvicorn for the ASGI server
- sqlmodel / sqlalchemy for the database
- alembic for database migrations - if any because there's not much to migrate, but it's good to have it in place
- also we'll need a tool to bootstrap the database from the current PLCAPI state, but that can be a one-off script
- JWT tokens for authentication
- PostGreSQL for the database; PLCAPI already runs on PostGreSQL

### deployment

and for the record the current PLCAPI stack runs on r2labapi.inria.fr, which is
a VM somewhere in the Inria network; we have full control there to run another
API server, possibly on a different port; I don't expect firewall problems since
it's supposed to be reached from the internal network, but we'll see about that
later

### authentication & authorization

- currently users have a username and a password stored as a hash in the
  database; we can keep that for now
- for authentication we can use JWT tokens, which is a common choice for fastapi
  applications; we can have a login endpoint that takes a username and password,
  verifies them, and returns a JWT token that can be used for subsequent
  requests
- authorization: the current DB also has a notion of "is_admin" for users, we need to keep that
  as well
- for now we can just have a simple role-based access control, where admins can do everything and regular users can only do certain things  
  in everyday life, users essentially get leases and that's about it;  
  admins otoh can validate user registration requests, create slices, assign users to slices

### API endpoints

proposed by claude, we can start with that and iterate on it:

  Auth
    POST   /auth/login                    → JWT token
    POST   /auth/register                 → self-registration (pending approval)

  Users
    GET    /users                         → list (admin)
    GET    /users/me                      → current user profile
    GET    /users/{id}                    → detail (admin)
    PATCH  /users/{id}                    → update (admin, or self for own keys)
    PATCH  /users/{id}/approve            → approve registration (admin)
    DELETE /users/{id}                    → delete (admin)

  Slices
    GET    /slices                        → list (admin; members see their own)
    POST   /slices                        → create (admin)
    GET    /slices/{id}                   → detail
    PATCH  /slices/{id}                   → update (admin)
    DELETE /slices/{id}                   → delete (admin)
    PUT    /slices/{id}/members/{user_id} → add member (admin)
    DELETE /slices/{id}/members/{user_id} → remove member (admin)

  Resources
    GET    /resources                     → list
    GET    /resources/{id}                → detail

  Leases
    GET    /leases                        → list (filterable: resource, slice, date range)
    GET    /leases/current                → active lease for a resource
    POST   /leases                        → create (must be member of the slice)
    PATCH  /leases/{id}                   → update (admin or lease owner)
    DELETE /leases/{id}                   → cancel (admin or lease owner)

some of these endpoints may be open to the world (i.e. even to non-users); if
needed we can add a basic ddos protection mechanism, but I don't expect that to
be a problem since this is an internal API

### web interface

can be discussed later; we had a quite thorough web interface for PLCAPI, but it was a bit clunky
we'll have to rewrite one, but we can do that in a second phase, after we have the API in place; 
for now we'll use a CLI tool to interact with the API, which will be easier to develop and test
