Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ Applies to `.github/` and repository pull-request operations.

When changing CI-sensitive behavior, keep local validation aligned with [`Makefile`](Makefile) at the repo root.

**Local bar before push (authoritative for contributors):** `make pre-commit` — runs Rust `fmt-check`, `clippy`, `test`, plus `console-web` lint and Prettier check (see `Makefile`).
**Local bar before push (authoritative for contributors):** `make pre-commit` — runs Rust `fmt-check`, `clippy`, `test`, plus `console-web` lint, build, and Prettier check (see `Makefile`).

**CI workflow** [`.github/workflows/ci.yml`](workflows/ci.yml) `test-and-lint` job currently runs:

- `cargo nextest run --all --no-tests pass` and `cargo test --all --doc`
- `cargo fmt --all --check`
- `cargo clippy --all-features -- -D warnings`
- `make e2e-check`
- `console-web` dependency install, lint, build, and format check

It does **not** run `console-web` checks; still run **`make pre-commit` locally** before opening a PR so frontend changes are validated.
Still run **`make pre-commit` locally** before opening a PR so frontend changes are validated before CI.
27 changes: 24 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ on:
- "**.md"
- "**.txt"
- "docs/**"
- "deploy/**"
- "LICENSE*"
- ".gitignore"
- ".dockerignore"
Expand All @@ -38,7 +37,6 @@ on:
- "**.md"
- "**.txt"
- "docs/**"
- "deploy/**"
- "LICENSE*"
- ".gitignore"
- ".dockerignore"
Expand Down Expand Up @@ -74,7 +72,7 @@ jobs:
with:
concurrent_skipping: "same_content_newer"
cancel_others: true
paths_ignore: '["*.md", "docs/**", "deploy/**"]'
paths_ignore: '["*.md", "docs/**"]'
# Never skip release events and tag pushes
do_not_skip: '["workflow_dispatch", "schedule", "merge_group", "release", "push"]'

Expand Down Expand Up @@ -109,3 +107,26 @@ jobs:

- name: Check Rust-native e2e harness
run: make e2e-check

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.28.1

- name: Setup Node environment
uses: actions/setup-node@v5
with:
node-version: 24
cache: pnpm
cache-dependency-path: console-web/pnpm-lock.yaml

- name: Install console dependencies
working-directory: console-web
run: pnpm install --frozen-lockfile

- name: Check console frontend
working-directory: console-web
run: |
pnpm run lint
pnpm run build
pnpm run format:check
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ name: Publish Docker Image

on:
workflow_run:
workflows: [ "Build and Test" ]
workflows: [ "Continuous Integration" ]
types: [ completed ]
workflow_dispatch:
inputs:
Expand Down
8 changes: 5 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ Before every commit, you **MUST** pass the same checks as `make pre-commit` (see
5. **Console (frontend)** — from repo root:

```bash
cd console-web && npm run lint
cd console-web && npx prettier --check "**/*.{ts,tsx,js,jsx,json,css,md}"
cd console-web && pnpm run lint
cd console-web && pnpm run build
cd console-web && pnpm run format:check
```

#### Quick Commands
Expand All @@ -66,8 +67,9 @@ make clippy
# Rust tests
make test

# Frontend: ESLint + Prettier check (requires npm install in console-web/)
# Frontend: ESLint + build + Prettier check (requires pnpm install in console-web/)
make console-lint
make console-build
make console-fmt-check

# Full gate before push (Rust + console-web): same as project / AGENTS.md rules
Expand Down
49 changes: 2 additions & 47 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ rcgen = "0.13"
sha2 = "0.10"
hmac = "0.12"
hex = "0.4"
base64 = "0.22"
ring = "0.17"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
url = "2.5"
shadow-rs = "1.5.0"
Expand All @@ -45,7 +47,6 @@ hyper = "1"
hyper-util = { version = "0.1", features = ["server-auto", "service", "tokio"] }
tower = "0.5"
tower-http = { version = "0.6", features = ["cors", "trace", "compression-gzip"] }
jsonwebtoken = "9.3"
http = "1.2"
utoipa = { version = "5", features = ["chrono"] }
utoipa-swagger-ui = { version = "8", features = ["axum", "vendored"] }
Expand Down
21 changes: 13 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

.PHONY: pre-commit fmt fmt-check clippy test build help
.PHONY: docker-build-operator docker-build-console-web docker-build-all
.PHONY: console-lint console-fmt console-fmt-check
.PHONY: console-lint console-build console-fmt console-fmt-check
.PHONY: e2e-check e2e-live-create .e2e-live-install-cert-manager e2e-live-run e2e-live-faults e2e-live-update e2e-live-delete

# Default target
Expand All @@ -37,6 +37,7 @@ help:
@echo " make docker-build-console-web - Build the console-web frontend image (CONSOLE_WEB_IMAGE_REPO?=rustfs/console-web CONSOLE_WEB_IMAGE_TAG?=dev)"
@echo " make docker-build-all - Build both operator and console-web images"
@echo " make console-lint - Run frontend ESLint checks (console-web)"
@echo " make console-build - Build frontend static assets (console-web)"
@echo " make console-fmt - Format frontend code with Prettier (console-web)"
@echo " make console-fmt-check - Check frontend formatting with Prettier (console-web)"
@echo " make e2e-check - Check Rust-native e2e harness (fmt + test + clippy)"
Expand All @@ -46,8 +47,8 @@ help:
@echo " make e2e-live-update - Rebuild image and update the live environment (load + rollout)"
@echo " make e2e-live-delete - Delete live Kind environment and clean dedicated storage"

# pre-commit checks: Rust main crate + e2e harness + frontend (lint + format checks)
pre-commit: fmt-check clippy test e2e-check console-lint console-fmt-check
# pre-commit checks: Rust main crate + e2e harness + frontend (lint + build + format checks)
pre-commit: fmt-check clippy test e2e-check console-lint console-build console-fmt-check
@echo "pre-commit: all checks passed"

# Format Rust code.
Expand All @@ -66,17 +67,21 @@ clippy:
test:
cargo test --all

# Run frontend ESLint checks. Run npm install in console-web first.
# Run frontend ESLint checks. Run pnpm install in console-web first.
console-lint:
cd console-web && npm run lint
cd console-web && pnpm run lint

# Format frontend code with Prettier. Run npm install in console-web first.
# Build frontend. Run pnpm install in console-web first.
console-build:
cd console-web && pnpm run build

# Format frontend code with Prettier. Run pnpm install in console-web first.
console-fmt:
cd console-web && npm run format
cd console-web && pnpm run format

# Check frontend formatting with Prettier without modifying files.
console-fmt-check:
cd console-web && npm run format:check
cd console-web && pnpm run format:check

# Build the project.
build:
Expand Down
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A Kubernetes operator for [RustFS](https://rustfs.com/) object storage, written in Rust with [kube-rs](https://github.com/kube-rs/kube). It reconciles a **`Tenant` custom resource** (`rustfs.com/v1alpha1`), validates referenced credential and KMS Secrets, and applies RBAC, Services, and StatefulSets so RustFS runs as an erasure-coded cluster inside your cluster.

**Status:** v0.1.0 pre-release — under active development, **not production-ready**.
**Status:** v0.1.0 pre-release — under active development.

## Features

Expand Down Expand Up @@ -43,6 +43,9 @@ cargo run -- server
# Run the operator HTTP console API (default :9090)
cargo run -- console

# For local HTTP-only browser testing with console-web on :3000
CONSOLE_COOKIE_SECURE=false CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000 cargo run -- console

# Or choose a custom Console API port
cargo run -- console --port 19090
```
Expand All @@ -64,7 +67,7 @@ From the repo root:

| Command | Purpose |
|--------|---------|
| `make pre-commit` | Full local gate: Rust `fmt` / `clippy` / `test` + `console-web` ESLint and Prettier (run after `pnpm install` in `console-web/`). |
| `make pre-commit` | Full local gate: Rust `fmt` / `clippy` / `test` + `console-web` ESLint, build, and Prettier (run after `pnpm install` in `console-web/`). |
| `make fmt` / `make clippy` / `make test` | Individual Rust checks. |
| `make console-lint` / `make console-fmt-check` | Frontend only. |
| `make e2e-check` | Validate the e2e harness without creating a live cluster. |
Expand All @@ -74,7 +77,7 @@ From the repo root:
| `make e2e-live-update` | Rebuild images, reload them into Kind, and roll out control-plane deployments. |
| `make e2e-live-delete` | Delete the dedicated Kind cluster and its local storage. |

CI (`.github/workflows/ci.yml`) runs Rust tests (including `nextest`), `cargo fmt --check`, and `clippy`; it does **not** run `console-web` checks — use **`make pre-commit`** before opening a PR so frontend changes are validated.
CI (`.github/workflows/ci.yml`) runs Rust tests (including `nextest`), `cargo fmt --check`, `clippy`, the Rust-native e2e harness checks, and `console-web` lint/build/format checks. Use **`make pre-commit`** before opening a PR so local validation stays aligned.

Contribution workflow, commit style, and PR expectations: [`CONTRIBUTING.md`](CONTRIBUTING.md).

Expand Down Expand Up @@ -128,14 +131,17 @@ Port-forward the operator Console Web UI:
kubectl --context kind-rustfs-e2e -n rustfs-system port-forward svc/rustfs-operator-console-frontend 18080:80
```

Get a login token for the e2e Console:
Get a login token for the e2e Console. The Console login form expects a
Kubernetes ServiceAccount bearer token with permissions granted to the Console
ServiceAccount. After login, the Console stores it in an encrypted session
cookie; users do not pass this token on later API requests:

```bash
TOKEN=$(kubectl --context kind-rustfs-e2e -n rustfs-system create token rustfs-operator-console --duration=24h)
printf '%s\n' "$TOKEN"
```

Open `http://127.0.0.1:18080` and paste the token into the login form. The frontend proxies `/api/v1` to the Console API inside the cluster, so the Web UI only needs the frontend port-forward above.
Open `http://127.0.0.1:18080` and paste the token into the login form. The dev/e2e Console deployment sets `CONSOLE_COOKIE_SECURE=false` for HTTP port-forwarding. The frontend proxies `/api/v1` to the Console API inside the cluster, so the Web UI only needs the frontend port-forward above.

Port-forward the e2e Tenant S3 API and Tenant Console:

Expand Down
14 changes: 10 additions & 4 deletions console-web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ Open [http://localhost:3000](http://localhost:3000). The app calls the console A

### Local dev with backend

Run the operator console HTTP API (e.g. `cargo run -- console`, default port **9090**). Then either:
Run the operator console HTTP API (e.g. `CONSOLE_COOKIE_SECURE=false cargo run -- console`, default port **9090** for local HTTP-only browser testing). Then either:

- Use same-origin: e.g. put frontend and backend behind one dev server that proxies `/api/v1` to the backend, and run the frontend with `NEXT_PUBLIC_API_BASE_URL=` (empty or `/api/v1`), or
- Use different ports: run frontend on 3000, backend on 9090, and set `NEXT_PUBLIC_API_BASE_URL=http://localhost:9090/api/v1`. The backend allows `http://localhost:3000` by default (CORS).
- Use different ports: run frontend on 3000, backend on 9090, set `NEXT_PUBLIC_API_BASE_URL=http://localhost:9090/api/v1`, and set `CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000` on the backend.

Login uses a Kubernetes ServiceAccount bearer token. For a local e2e cluster,
generate one with `kubectl -n rustfs-system create token rustfs-operator-console --duration=24h`
and paste the printed token into the login form. After login, the backend stores
it in an encrypted `session` cookie.

## Build

Expand All @@ -38,15 +43,16 @@ When frontend and backend are deployed in the same cluster and exposed under **o

2. Enable the console frontend in the Helm chart and Ingress (see [deploy/rustfs-operator/README.md](../deploy/rustfs-operator/README.md#console-ui-frontend--backend-in-k8s)). The Ingress will serve `/` from this app and `/api` from the backend.

3. Do **not** set `NEXT_PUBLIC_API_BASE_URL` (or set it to `/api/v1`). The browser will send requests to the same origin, so cookies and CORS work without extra config.
3. Do **not** set `NEXT_PUBLIC_API_BASE_URL` (or set it to `/api/v1`). The browser will send requests to the same origin, so cookies and CORS work without extra config. Production deployments should serve the host over HTTPS because Console session cookies are `Secure` by default.

If the frontend is served from a **different host** than the API, set at build time:

```bash
NEXT_PUBLIC_API_BASE_URL=https://api.example.com/api/v1 pnpm build
```

Then configure the backend with `CORS_ALLOWED_ORIGINS` (see deploy README).
Then configure the backend with `CORS_ALLOWED_ORIGINS` and, for cross-site
frontend/API hosts, `CONSOLE_COOKIE_SAME_SITE=None` (see deploy README).

## Environment variables

Expand Down
Loading
Loading