Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a69ed648f9 | |||
| 1405424ded | |||
| 62eecc5240 | |||
| d5580f01f2 | |||
| 296bbc5357 | |||
| 078dd39052 | |||
| e81903dd88 | |||
| 0838bcbab2 | |||
| acc4851549 | |||
| 9d7043a594 | |||
| 3d36c58d0d |
@@ -881,6 +881,10 @@ separate binary (`mcr-web`) that communicates with mcrsrv via gRPC.
|
||||
- CSRF protection via signed double-submit cookies on all mutating requests.
|
||||
- Session cookie: `HttpOnly`, `Secure`, `SameSite=Strict`.
|
||||
- All user input escaped by `html/template`.
|
||||
- Guest accounts are blocked at login. After MCIAS authentication succeeds,
|
||||
the web UI validates the token and checks roles; accounts with the `guest`
|
||||
role are denied access. This is defense-in-depth alongside the
|
||||
`env:restricted` MCIAS tag.
|
||||
|
||||
---
|
||||
|
||||
@@ -1059,7 +1063,7 @@ The audit log is append-only. It never contains credentials or token values.
|
||||
|
||||
| Threat | Mitigation |
|
||||
|--------|------------|
|
||||
| Unauthenticated access | All endpoints require MCIAS bearer token; `env:restricted` tag blocks guest/viewer login |
|
||||
| Unauthenticated access | All endpoints require MCIAS bearer token; `env:restricted` tag blocks guest/viewer login; web UI additionally rejects `guest` role at login |
|
||||
| Unauthorized push/delete | Policy engine enforces per-principal, per-repository access; default-deny for system accounts |
|
||||
| Digest mismatch (supply chain) | All uploads verified against client-supplied digest; rejected if mismatch |
|
||||
| Blob corruption | Content-addressed storage; digests verified on write. Periodic integrity scrub via `mcrctl scrub` (future) |
|
||||
|
||||
@@ -32,7 +32,7 @@ go test ./internal/server -run TestPushManifest
|
||||
## Tech Stack
|
||||
|
||||
- **Language:** Go 1.25+, `CGO_ENABLED=0`, statically linked
|
||||
- **Module path:** `git.wntrmute.dev/kyle/mcr`
|
||||
- **Module path:** `git.wntrmute.dev/mc/mcr`
|
||||
- **Database:** SQLite via `modernc.org/sqlite` (pure-Go, no CGo)
|
||||
- **Config:** TOML via `go-toml/v2`, env overrides via `MCR_*`
|
||||
- **APIs:** REST (chi) + gRPC (protobuf), kept in sync
|
||||
|
||||
17
Makefile
17
Makefile
@@ -1,6 +1,8 @@
|
||||
.PHONY: build test vet lint proto proto-lint clean docker all devserver
|
||||
.PHONY: build test vet lint proto proto-lint clean docker push all devserver
|
||||
|
||||
LDFLAGS := -trimpath -ldflags="-s -w -X main.version=$(shell git describe --tags --always --dirty)"
|
||||
MCR := mcr.svc.mcp.metacircular.net:8443
|
||||
VERSION := $(shell git describe --tags --always --dirty)
|
||||
LDFLAGS := -trimpath -ldflags="-s -w -X main.version=$(VERSION)"
|
||||
|
||||
mcrsrv:
|
||||
CGO_ENABLED=0 go build $(LDFLAGS) -o mcrsrv ./cmd/mcrsrv
|
||||
@@ -24,8 +26,8 @@ lint:
|
||||
golangci-lint run ./...
|
||||
|
||||
proto:
|
||||
protoc --go_out=. --go_opt=module=git.wntrmute.dev/kyle/mcr \
|
||||
--go-grpc_out=. --go-grpc_opt=module=git.wntrmute.dev/kyle/mcr \
|
||||
protoc --go_out=. --go_opt=module=git.wntrmute.dev/mc/mcr \
|
||||
--go-grpc_out=. --go-grpc_opt=module=git.wntrmute.dev/mc/mcr \
|
||||
proto/mcr/v1/*.proto
|
||||
|
||||
proto-lint:
|
||||
@@ -36,7 +38,12 @@ clean:
|
||||
rm -f mcrsrv mcr-web mcrctl
|
||||
|
||||
docker:
|
||||
docker build --build-arg VERSION=$(shell git describe --tags --always --dirty) -t mcr -f Dockerfile .
|
||||
docker build --build-arg VERSION=$(VERSION) -t $(MCR)/mcr:$(VERSION) -f Dockerfile.api .
|
||||
docker build --build-arg VERSION=$(VERSION) -t $(MCR)/mcr-web:$(VERSION) -f Dockerfile.web .
|
||||
|
||||
push: docker
|
||||
docker push $(MCR)/mcr:$(VERSION)
|
||||
docker push $(MCR)/mcr-web:$(VERSION)
|
||||
|
||||
devserver: mcrsrv
|
||||
@mkdir -p srv
|
||||
|
||||
26
PROGRESS.md
26
PROGRESS.md
@@ -32,6 +32,30 @@ See `PROJECT_PLAN.md` for the implementation roadmap and
|
||||
### Next Steps
|
||||
|
||||
1. Deploy to rift (issue MCR service token, generate TLS cert, update mc-proxy routes)
|
||||
2. Consider adding roles to MCIAS login response to eliminate the extra ValidateToken round-trip
|
||||
|
||||
### 2026-03-26 — Web UI: block guest login
|
||||
|
||||
**Task:** Prevent MCIAS guest accounts from logging into the web UI.
|
||||
|
||||
**Changes:**
|
||||
|
||||
- `internal/webserver/server.go`: Added `ValidateFunc` type; `New()`
|
||||
accepts a validate function to inspect tokens post-login.
|
||||
- `internal/webserver/auth.go`: After `loginFn` succeeds, calls
|
||||
`validateFn` to retrieve roles. Rejects accounts with the `guest`
|
||||
role before setting the session cookie.
|
||||
- `cmd/mcr-web/main.go`: Wires `ValidateFunc` via `authClient.ValidateToken()`.
|
||||
- `internal/webserver/server_test.go`: Added guest/user test accounts,
|
||||
`validateFn` returning role-appropriate responses, `TestLoginDeniesGuest`.
|
||||
- `ARCHITECTURE.md`: Updated Web UI security section and threat mitigations
|
||||
to document guest blocking as defense-in-depth.
|
||||
|
||||
**Design note:** MCIAS `/v1/auth/login` does not return roles, so the
|
||||
web UI makes a second `ValidateToken` call after login to inspect them.
|
||||
This is an extra MCIAS round-trip at login time (cached for 30s). A
|
||||
future MCIAS change to include roles in the login response would
|
||||
eliminate this.
|
||||
|
||||
### 2026-03-25 — Phase 13: Deployment Artifacts
|
||||
|
||||
@@ -688,7 +712,7 @@ Lint fix:
|
||||
entry points with cobra subcommands.
|
||||
|
||||
**Changes:**
|
||||
- `go.mod`: module `git.wntrmute.dev/kyle/mcr`, Go 1.25, cobra dependency
|
||||
- `go.mod`: module `git.wntrmute.dev/mc/mcr`, Go 1.25, cobra dependency
|
||||
- Directory skeleton: `cmd/mcrsrv/`, `cmd/mcr-web/`, `cmd/mcrctl/`,
|
||||
`internal/`, `proto/mcr/v1/`, `gen/mcr/v1/`, `web/templates/`,
|
||||
`web/static/`, `deploy/docker/`, `deploy/examples/`, `deploy/scripts/`,
|
||||
|
||||
@@ -63,7 +63,7 @@ produces a project that builds and lints cleanly with no functionality.
|
||||
### Step 0.1: Go module and directory structure
|
||||
|
||||
**Acceptance criteria:**
|
||||
- `go.mod` initialized with module path `git.wntrmute.dev/kyle/mcr`
|
||||
- `go.mod` initialized with module path `git.wntrmute.dev/mc/mcr`
|
||||
- Directory skeleton created per `ARCHITECTURE.md` §13:
|
||||
`cmd/mcrsrv/`, `cmd/mcr-web/`, `cmd/mcrctl/`, `internal/`, `proto/mcr/v1/`,
|
||||
`gen/mcr/v1/`, `web/`, `deploy/`
|
||||
|
||||
60
README.md
60
README.md
@@ -1,3 +1,59 @@
|
||||
MCR is the Metacircular Container Registry
|
||||
# MCR
|
||||
|
||||
This is a container registry integrated with MCIAS.
|
||||
Metacircular Container Registry -- an OCI Distribution Spec-compliant
|
||||
container registry for the Metacircular platform. MCR stores and serves
|
||||
container images with authentication delegated to MCIAS and a local
|
||||
policy engine for fine-grained access control. Metadata is stored in
|
||||
SQLite; blobs are stored as content-addressed files on the filesystem.
|
||||
|
||||
## Quick Start
|
||||
|
||||
Build the binaries:
|
||||
|
||||
```bash
|
||||
make all
|
||||
```
|
||||
|
||||
This produces three binaries:
|
||||
|
||||
| Binary | Purpose |
|
||||
|--------|---------|
|
||||
| `mcrsrv` | Registry server (OCI + admin REST + gRPC) |
|
||||
| `mcr-web` | Web UI (htmx, communicates with mcrsrv via gRPC) |
|
||||
| `mcrctl` | Admin CLI |
|
||||
|
||||
Copy and edit the example configuration:
|
||||
|
||||
```bash
|
||||
cp deploy/examples/mcr.toml /srv/mcr/mcr.toml
|
||||
# Edit TLS paths, database path, storage paths, MCIAS URL
|
||||
```
|
||||
|
||||
Run the server:
|
||||
|
||||
```bash
|
||||
./mcrsrv server --config /srv/mcr/mcr.toml
|
||||
```
|
||||
|
||||
The server starts two listeners:
|
||||
|
||||
| Port | Protocol | Purpose |
|
||||
|------|----------|---------|
|
||||
| 8443 | TCP | HTTPS -- OCI Distribution endpoints + admin REST API |
|
||||
| 9443 | TCP | gRPC admin API (TLS, MCIAS auth) |
|
||||
|
||||
Run the web UI:
|
||||
|
||||
```bash
|
||||
./mcr-web server --config /srv/mcr/mcr.toml
|
||||
```
|
||||
|
||||
| Port | Protocol | Purpose |
|
||||
|------|----------|---------|
|
||||
| 8080 | TCP | HTTP -- web UI (repository browsing, policy management) |
|
||||
|
||||
## Documentation
|
||||
|
||||
- [ARCHITECTURE.md](ARCHITECTURE.md) -- full technical specification, OCI compliance details, database schema, policy engine, and security model.
|
||||
- [RUNBOOK.md](RUNBOOK.md) -- operational procedures, health checks, backup/restore, incident response, and MCP deployment.
|
||||
- [CLAUDE.md](CLAUDE.md) -- context for AI-assisted development.
|
||||
|
||||
404
RUNBOOK.md
Normal file
404
RUNBOOK.md
Normal file
@@ -0,0 +1,404 @@
|
||||
# MCR Runbook
|
||||
|
||||
## Service Overview
|
||||
|
||||
MCR (Metacircular Container Registry) is an OCI Distribution
|
||||
Spec-compliant container registry for the Metacircular platform. It
|
||||
stores and serves container images, with authentication delegated to
|
||||
MCIAS and a local policy engine for fine-grained access control.
|
||||
|
||||
MCR runs as two containers:
|
||||
|
||||
- **mcr-api** -- the registry server. Exposes OCI Distribution endpoints
|
||||
and an admin REST API on port 8443 (HTTPS), plus a gRPC admin API on
|
||||
port 9443. Handles blob storage, manifest management, and
|
||||
token-based authentication via MCIAS.
|
||||
- **mcr-web** -- the web UI. Communicates with mcr-api via gRPC on port
|
||||
9443. Provides repository/tag browsing and ACL policy management for
|
||||
administrators. Listens on port 8080. Guest accounts are blocked at
|
||||
login; only `admin` and `user` roles can access the web interface.
|
||||
|
||||
Both are fronted by MC-Proxy for TLS routing. Metadata is stored in
|
||||
SQLite; blobs are stored as content-addressed files on the filesystem
|
||||
under `/srv/mcr/layers/`.
|
||||
|
||||
## Health Checks
|
||||
|
||||
### REST
|
||||
|
||||
```bash
|
||||
curl -k https://localhost:8443/v1/health
|
||||
```
|
||||
|
||||
Expected: HTTP 200.
|
||||
|
||||
### gRPC
|
||||
|
||||
Use the `AdminService.Health` RPC on port 9443. This method is public
|
||||
(no auth required).
|
||||
|
||||
### OCI Version Check
|
||||
|
||||
```bash
|
||||
curl -k https://localhost:8443/v2/
|
||||
```
|
||||
|
||||
Expected: HTTP 401 with `WWW-Authenticate` header (confirms the OCI
|
||||
endpoint is alive and responding). An authenticated request returns
|
||||
HTTP 200 with `{}`.
|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
mcrctl status --addr https://localhost:8443
|
||||
```
|
||||
|
||||
Expected output: `ok`
|
||||
|
||||
## Common Operations
|
||||
|
||||
### Start the Service (MCP)
|
||||
|
||||
1. Deploy via MCP:
|
||||
```bash
|
||||
mcp deploy mcr
|
||||
```
|
||||
2. Verify health:
|
||||
```bash
|
||||
curl -k https://localhost:8443/v1/health
|
||||
```
|
||||
|
||||
### Start the Service (Docker Compose)
|
||||
|
||||
1. Verify config exists: `ls /srv/mcr/mcr.toml`
|
||||
2. Start the containers:
|
||||
```bash
|
||||
docker compose -f deploy/docker/docker-compose-rift.yml up -d
|
||||
```
|
||||
3. Verify health:
|
||||
```bash
|
||||
curl -k https://localhost:8443/v1/health
|
||||
```
|
||||
|
||||
### Stop the Service
|
||||
|
||||
Via MCP:
|
||||
|
||||
```bash
|
||||
mcp stop mcr
|
||||
```
|
||||
|
||||
Via Docker Compose:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker/docker-compose-rift.yml stop
|
||||
```
|
||||
|
||||
MCR handles SIGTERM gracefully: it stops accepting new connections,
|
||||
drains in-flight requests (including ongoing uploads) for up to 60
|
||||
seconds, then force-closes remaining connections and exits.
|
||||
|
||||
### Restart the Service
|
||||
|
||||
Via MCP:
|
||||
|
||||
```bash
|
||||
mcp restart mcr
|
||||
```
|
||||
|
||||
Via Docker Compose:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker/docker-compose-rift.yml restart
|
||||
```
|
||||
|
||||
Verify health after restart:
|
||||
|
||||
```bash
|
||||
curl -k https://localhost:8443/v1/health
|
||||
```
|
||||
|
||||
### Backup (Snapshot)
|
||||
|
||||
MCR backups have two parts: the SQLite database (metadata) and the blob
|
||||
filesystem. The database snapshot alone is usable but incomplete --
|
||||
missing blobs return 404 on pull.
|
||||
|
||||
1. Run the snapshot command:
|
||||
```bash
|
||||
mcrsrv snapshot --config /srv/mcr/mcr.toml
|
||||
```
|
||||
2. The snapshot is saved to `/srv/mcr/backups/mcr-YYYYMMDD-HHMMSS.db`.
|
||||
3. Verify the snapshot file exists and has a reasonable size:
|
||||
```bash
|
||||
ls -lh /srv/mcr/backups/
|
||||
```
|
||||
4. For a complete backup, also copy the blob directory:
|
||||
```bash
|
||||
rsync -a /srv/mcr/layers/ /backup/mcr/layers/
|
||||
```
|
||||
|
||||
A systemd timer (`mcr-backup.timer`) runs the database snapshot daily
|
||||
at 02:00 UTC with 5-minute jitter.
|
||||
|
||||
### Restore from Snapshot
|
||||
|
||||
1. Stop the service (see above).
|
||||
2. Back up the current database:
|
||||
```bash
|
||||
cp /srv/mcr/mcr.db /srv/mcr/mcr.db.pre-restore
|
||||
```
|
||||
3. Copy the snapshot into place:
|
||||
```bash
|
||||
cp /srv/mcr/backups/mcr-YYYYMMDD-HHMMSS.db /srv/mcr/mcr.db
|
||||
```
|
||||
4. If restoring blobs as well:
|
||||
```bash
|
||||
rsync -a /backup/mcr/layers/ /srv/mcr/layers/
|
||||
```
|
||||
5. Start the service (see above).
|
||||
6. Verify the service is healthy:
|
||||
```bash
|
||||
curl -k https://localhost:8443/v1/health
|
||||
```
|
||||
7. Verify an image pull works:
|
||||
```bash
|
||||
docker pull mcr.svc.mcp.metacircular.net:8443/<repo>:<tag>
|
||||
```
|
||||
|
||||
### Log Inspection
|
||||
|
||||
Container logs (mcr-api):
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker/docker-compose-rift.yml logs --tail 100 mcr-api
|
||||
```
|
||||
|
||||
Container logs (mcr-web):
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker/docker-compose-rift.yml logs --tail 100 mcr-web
|
||||
```
|
||||
|
||||
Follow logs in real time:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker/docker-compose-rift.yml logs -f mcr-api mcr-web
|
||||
```
|
||||
|
||||
Via MCP:
|
||||
|
||||
```bash
|
||||
mcp logs mcr
|
||||
```
|
||||
|
||||
MCR logs to stderr as structured text (slog). Log level is configured
|
||||
via `[log] level` in `mcr.toml` (debug, info, warn, error).
|
||||
|
||||
### Garbage Collection
|
||||
|
||||
Garbage collection removes unreferenced blobs -- blobs no longer
|
||||
referenced by any manifest. GC acquires a registry-wide lock that
|
||||
blocks new blob uploads for the duration of the mark-and-sweep phase.
|
||||
Pulls are not blocked.
|
||||
|
||||
1. Trigger GC via CLI:
|
||||
```bash
|
||||
mcrctl gc --addr https://mcr.svc.mcp.metacircular.net:8443
|
||||
```
|
||||
2. Check GC status:
|
||||
```bash
|
||||
mcrctl gc status --addr https://mcr.svc.mcp.metacircular.net:8443
|
||||
```
|
||||
3. GC can also be triggered via the REST API:
|
||||
```bash
|
||||
curl -k -X POST -H "Authorization: Bearer <token>" https://localhost:8443/v1/gc
|
||||
```
|
||||
|
||||
If a previous GC crashed after the database sweep but before filesystem
|
||||
cleanup, orphaned files may remain on disk. Run reconciliation to clean
|
||||
them up:
|
||||
|
||||
```bash
|
||||
mcrctl gc --reconcile --addr https://mcr.svc.mcp.metacircular.net:8443
|
||||
```
|
||||
|
||||
## Incident Procedures
|
||||
|
||||
### Database Corruption
|
||||
|
||||
Symptoms: server fails to start with SQLite errors, or API requests
|
||||
return unexpected errors.
|
||||
|
||||
1. Stop the service.
|
||||
2. Check for WAL/SHM files alongside the database:
|
||||
```bash
|
||||
ls -la /srv/mcr/mcr.db*
|
||||
```
|
||||
3. Attempt an integrity check:
|
||||
```bash
|
||||
sqlite3 /srv/mcr/mcr.db "PRAGMA integrity_check;"
|
||||
```
|
||||
4. If integrity check fails, restore from the most recent snapshot:
|
||||
```bash
|
||||
cp /srv/mcr/mcr.db /srv/mcr/mcr.db.corrupt
|
||||
cp /srv/mcr/backups/mcr-YYYYMMDD-HHMMSS.db /srv/mcr/mcr.db
|
||||
```
|
||||
5. Start the service and verify health.
|
||||
6. Note: blobs on the filesystem are unaffected by database corruption.
|
||||
Images pushed after the snapshot was taken will be missing from
|
||||
metadata. Their blobs remain on disk and will be cleaned up by GC
|
||||
unless the metadata is re-created.
|
||||
|
||||
### TLS Certificate Expiry
|
||||
|
||||
Symptoms: health check fails with TLS errors, Docker clients get
|
||||
certificate verification errors on push/pull.
|
||||
|
||||
1. Check certificate expiry:
|
||||
```bash
|
||||
openssl x509 -in /srv/mcr/certs/cert.pem -noout -enddate
|
||||
```
|
||||
2. Replace the certificate and key files at the paths configured in
|
||||
`mcr.toml` (`[server] tls_cert` and `tls_key`).
|
||||
3. Restart the service to load the new certificate.
|
||||
4. Verify health:
|
||||
```bash
|
||||
curl -k https://localhost:8443/v1/health
|
||||
```
|
||||
|
||||
### MCIAS Outage
|
||||
|
||||
Symptoms: push/pull fails with 401 or 502 errors. Authentication
|
||||
cannot complete.
|
||||
|
||||
1. Confirm MCIAS is unreachable:
|
||||
```bash
|
||||
curl -k https://svc.metacircular.net:8443/v1/health
|
||||
```
|
||||
2. Cached token validation results remain valid for up to 30 seconds
|
||||
after the last successful MCIAS check. Operations using
|
||||
recently-validated tokens may continue briefly.
|
||||
3. Once cached tokens expire, all authenticated operations (push, pull,
|
||||
catalog, admin) will fail until MCIAS recovers.
|
||||
4. The OCI `/v2/` version check endpoint still responds (confirms MCR
|
||||
itself is running).
|
||||
5. Escalate to MCIAS (see Escalation below).
|
||||
|
||||
### Disk Full
|
||||
|
||||
Symptoms: blob uploads fail, database writes fail, container may crash.
|
||||
|
||||
1. Check disk usage:
|
||||
```bash
|
||||
df -h /srv/mcr/
|
||||
du -sh /srv/mcr/layers/ /srv/mcr/uploads/ /srv/mcr/mcr.db
|
||||
```
|
||||
2. Clean up stale uploads:
|
||||
```bash
|
||||
ls -la /srv/mcr/uploads/
|
||||
```
|
||||
Remove upload files that are old and have no matching in-progress
|
||||
upload in the database.
|
||||
3. Run garbage collection to reclaim unreferenced blobs:
|
||||
```bash
|
||||
mcrctl gc --addr https://mcr.svc.mcp.metacircular.net:8443
|
||||
```
|
||||
4. If GC does not free enough space, identify large repositories:
|
||||
```bash
|
||||
mcrctl repo list --addr https://mcr.svc.mcp.metacircular.net:8443
|
||||
```
|
||||
5. Delete unused tags or repositories to free space, then run GC again.
|
||||
6. If the disk is completely full and the service cannot start, manually
|
||||
remove orphaned files from `/srv/mcr/uploads/` to free enough space
|
||||
for the service to start, then run GC.
|
||||
|
||||
### Image Push/Pull Failures
|
||||
|
||||
Symptoms: `docker push` or `docker pull` returns errors.
|
||||
|
||||
1. Verify the service is running and healthy:
|
||||
```bash
|
||||
curl -k https://localhost:8443/v1/health
|
||||
```
|
||||
2. Test OCI endpoint:
|
||||
```bash
|
||||
curl -k https://localhost:8443/v2/
|
||||
```
|
||||
Expected: HTTP 401 with `WWW-Authenticate` header.
|
||||
3. Test authentication:
|
||||
```bash
|
||||
curl -k -u username:password https://localhost:8443/v2/token?service=mcr
|
||||
```
|
||||
Expected: HTTP 200 with a token response.
|
||||
4. Check if the issue is policy-related (403 Denied):
|
||||
```bash
|
||||
mcrctl policy list --addr https://mcr.svc.mcp.metacircular.net:8443
|
||||
```
|
||||
Review policy rules for the affected account and repository.
|
||||
5. Check audit log for denied requests:
|
||||
```bash
|
||||
mcrctl audit tail --n 20 --addr https://mcr.svc.mcp.metacircular.net:8443
|
||||
```
|
||||
6. For push failures, verify all referenced blobs exist before pushing
|
||||
the manifest. The error `MANIFEST_BLOB_UNKNOWN` means a layer was
|
||||
not uploaded before the manifest push.
|
||||
7. Check logs for detailed error information:
|
||||
```bash
|
||||
docker compose -f deploy/docker/docker-compose-rift.yml logs --tail 50 mcr-api
|
||||
```
|
||||
|
||||
## MCP Deployment
|
||||
|
||||
MCR is deployed via MCP as a two-component service on the `rift` node.
|
||||
|
||||
### Service Definition
|
||||
|
||||
```toml
|
||||
name = "mcr"
|
||||
node = "rift"
|
||||
active = true
|
||||
|
||||
[[components]]
|
||||
name = "api"
|
||||
image = "mcr.svc.mcp.metacircular.net:8443/mcr:v1.1.0"
|
||||
network = "mcpnet"
|
||||
user = "0:0"
|
||||
restart = "unless-stopped"
|
||||
ports = ["127.0.0.1:28443:8443", "127.0.0.1:29443:9443"]
|
||||
volumes = ["/srv/mcr:/srv/mcr"]
|
||||
cmd = ["server", "--config", "/srv/mcr/mcr.toml"]
|
||||
|
||||
[[components]]
|
||||
name = "web"
|
||||
image = "mcr.svc.mcp.metacircular.net:8443/mcr-web:v1.1.0"
|
||||
network = "mcpnet"
|
||||
user = "0:0"
|
||||
restart = "unless-stopped"
|
||||
ports = ["127.0.0.1:28080:8080"]
|
||||
volumes = ["/srv/mcr:/srv/mcr"]
|
||||
cmd = ["server", "--config", "/srv/mcr/mcr.toml"]
|
||||
```
|
||||
|
||||
### Port Mapping
|
||||
|
||||
| Component | Container Port | Host Port | Purpose |
|
||||
|-----------|---------------|-----------|---------|
|
||||
| mcr-api | 8443 | 28443 | HTTPS (OCI + admin REST) |
|
||||
| mcr-api | 9443 | 29443 | gRPC admin API |
|
||||
| mcr-web | 8080 | 28080 | Web UI (HTTP, behind MC-Proxy) |
|
||||
|
||||
Both containers share the `/srv/mcr` volume for configuration, database,
|
||||
and blob storage. They are connected to the `mcpnet` Docker network.
|
||||
|
||||
## Escalation
|
||||
|
||||
Escalate when:
|
||||
|
||||
- Database corruption cannot be resolved by restoring a snapshot.
|
||||
- MCIAS is down and registry operations are urgently needed.
|
||||
- Disk full cannot be resolved by GC and cleanup.
|
||||
- Push/pull failures persist after following the procedures above.
|
||||
- Any issue not covered by this runbook.
|
||||
|
||||
Escalation path: Kyle (platform owner).
|
||||
@@ -17,10 +17,10 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
mcrv1 "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/config"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/webserver"
|
||||
mcrv1 "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/config"
|
||||
"git.wntrmute.dev/mc/mcr/internal/webserver"
|
||||
)
|
||||
|
||||
var version = "dev"
|
||||
@@ -99,6 +99,14 @@ func runServer(configPath string) error {
|
||||
return authClient.Login(username, password)
|
||||
}
|
||||
|
||||
validateFn := func(token string) ([]string, error) {
|
||||
claims, err := authClient.ValidateToken(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return claims.Roles, nil
|
||||
}
|
||||
|
||||
// Generate CSRF key.
|
||||
csrfKey := make([]byte, 32)
|
||||
if _, err := rand.Read(csrfKey); err != nil {
|
||||
@@ -106,7 +114,7 @@ func runServer(configPath string) error {
|
||||
}
|
||||
|
||||
// Create web server.
|
||||
srv, err := webserver.New(registryClient, policyClient, auditClient, adminClient, loginFn, csrfKey)
|
||||
srv, err := webserver.New(registryClient, policyClient, auditClient, adminClient, loginFn, validateFn, csrfKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create web server: %w", err)
|
||||
}
|
||||
@@ -162,6 +170,7 @@ func runServer(configPath string) error {
|
||||
func dialGRPC(cfg *config.Config) (*grpc.ClientConn, error) {
|
||||
tlsCfg := &tls.Config{
|
||||
MinVersion: tls.VersionTLS13,
|
||||
ServerName: cfg.Web.TLSServerName,
|
||||
}
|
||||
|
||||
if cfg.Web.CACert != "" {
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
mcrv1 "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
mcrv1 "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
)
|
||||
|
||||
// apiClient wraps both REST and gRPC transports. When grpcAddr is set
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
mcrv1 "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
mcrv1 "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
)
|
||||
|
||||
var version = "dev"
|
||||
@@ -62,6 +62,7 @@ func main() {
|
||||
root.AddCommand(statusCmd())
|
||||
root.AddCommand(repoCmd())
|
||||
root.AddCommand(gcCmd())
|
||||
root.AddCommand(purgeCmd())
|
||||
root.AddCommand(policyCmd())
|
||||
root.AddCommand(auditCmd())
|
||||
root.AddCommand(snapshotCmd())
|
||||
|
||||
274
cmd/mcrctl/purge.go
Normal file
274
cmd/mcrctl/purge.go
Normal file
@@ -0,0 +1,274 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
mcrv1 "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
)
|
||||
|
||||
func purgeCmd() *cobra.Command {
|
||||
var (
|
||||
keep int
|
||||
repo string
|
||||
dryRun bool
|
||||
trigGC bool
|
||||
)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "purge",
|
||||
Short: "Remove old image tags, keeping the last N per repository",
|
||||
Long: `Purge removes old image tags from repositories based on a retention
|
||||
policy. The 'latest' tag is always kept. For each repository, tags are
|
||||
sorted by updated_at (most recent first) and only the --keep most recent
|
||||
are retained. Remaining tags' manifests are deleted, cascading to their
|
||||
tag references. Run with --gc to trigger garbage collection afterward.`,
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
return runPurge(keep, repo, dryRun, trigGC)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().IntVar(&keep, "keep", 3, "number of tags to keep per repo (excluding latest)")
|
||||
cmd.Flags().StringVar(&repo, "repo", "", "limit to repositories matching this glob pattern")
|
||||
cmd.Flags().BoolVar(&dryRun, "dry-run", false, "show what would be deleted without deleting")
|
||||
cmd.Flags().BoolVar(&trigGC, "gc", false, "trigger garbage collection after purging")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// tagWithTime is a tag with its timestamp for sorting.
|
||||
type tagWithTime struct {
|
||||
Name string
|
||||
Digest string
|
||||
UpdatedAt string
|
||||
}
|
||||
|
||||
func runPurge(keep int, repoPattern string, dryRun, trigGC bool) error {
|
||||
if keep < 0 {
|
||||
return fmt.Errorf("--keep must be non-negative")
|
||||
}
|
||||
|
||||
// List repositories.
|
||||
repos, err := listRepos()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Filter by pattern if given.
|
||||
if repoPattern != "" {
|
||||
var filtered []string
|
||||
for _, r := range repos {
|
||||
matched, _ := path.Match(repoPattern, r)
|
||||
if matched {
|
||||
filtered = append(filtered, r)
|
||||
}
|
||||
}
|
||||
repos = filtered
|
||||
}
|
||||
|
||||
if len(repos) == 0 {
|
||||
_, _ = fmt.Fprintln(os.Stdout, "No repositories matched.")
|
||||
return nil
|
||||
}
|
||||
|
||||
totalDeleted := 0
|
||||
|
||||
for _, repoName := range repos {
|
||||
tags, err := listTagsWithTime(repoName)
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "warning: skipping %s: %v\n", repoName, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Separate latest from versioned tags.
|
||||
var latest *tagWithTime
|
||||
var versioned []tagWithTime
|
||||
for _, t := range tags {
|
||||
if t.Name == "latest" {
|
||||
lt := t
|
||||
latest = <
|
||||
} else {
|
||||
versioned = append(versioned, t)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by updated_at descending (most recent first).
|
||||
sort.Slice(versioned, func(i, j int) bool {
|
||||
return versioned[i].UpdatedAt > versioned[j].UpdatedAt
|
||||
})
|
||||
|
||||
// Determine which tags to delete.
|
||||
if len(versioned) <= keep {
|
||||
continue // nothing to purge
|
||||
}
|
||||
|
||||
toDelete := versioned[keep:]
|
||||
|
||||
// Build set of digests that are still referenced by kept tags.
|
||||
keptDigests := make(map[string]bool)
|
||||
if latest != nil {
|
||||
keptDigests[latest.Digest] = true
|
||||
}
|
||||
for _, t := range versioned[:keep] {
|
||||
keptDigests[t.Digest] = true
|
||||
}
|
||||
|
||||
for _, t := range toDelete {
|
||||
if keptDigests[t.Digest] {
|
||||
// Manifest is shared with a kept tag — skip deletion.
|
||||
if dryRun {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "[skip] %s:%s (manifest shared with kept tag)\n", repoName, t.Name)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if dryRun {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "[delete] %s:%s (digest: %s, updated: %s)\n", repoName, t.Name, t.Digest[:12], t.UpdatedAt)
|
||||
} else {
|
||||
if err := deleteManifest(repoName, t.Digest); err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "warning: failed to delete %s:%s: %v\n", repoName, t.Name, err)
|
||||
continue
|
||||
}
|
||||
_, _ = fmt.Fprintf(os.Stdout, "deleted %s:%s\n", repoName, t.Name)
|
||||
}
|
||||
totalDeleted++
|
||||
}
|
||||
}
|
||||
|
||||
if dryRun {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "\nDry run: %d manifests would be deleted.\n", totalDeleted)
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(os.Stdout, "\nPurged %d manifests.\n", totalDeleted)
|
||||
}
|
||||
|
||||
// Trigger GC if requested and not a dry run.
|
||||
if trigGC && !dryRun && totalDeleted > 0 {
|
||||
_, _ = fmt.Fprintln(os.Stdout, "Triggering garbage collection...")
|
||||
if err := triggerGC(); err != nil {
|
||||
return fmt.Errorf("gc: %w", err)
|
||||
}
|
||||
_, _ = fmt.Fprintln(os.Stdout, "Garbage collection started.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// listRepos returns all repository names.
|
||||
func listRepos() ([]string, error) {
|
||||
if client.useGRPC() {
|
||||
resp, err := client.registry.ListRepositories(context.Background(), &mcrv1.ListRepositoriesRequest{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list repositories: %w", err)
|
||||
}
|
||||
var names []string
|
||||
for _, r := range resp.GetRepositories() {
|
||||
names = append(names, r.GetName())
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
data, err := client.restDo("GET", "/v1/repositories", nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list repositories: %w", err)
|
||||
}
|
||||
|
||||
var repos []struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &repos); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var names []string
|
||||
for _, r := range repos {
|
||||
names = append(names, r.Name)
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
// listTagsWithTime returns tags with timestamps for a repository.
|
||||
func listTagsWithTime(repoName string) ([]tagWithTime, error) {
|
||||
if client.useGRPC() {
|
||||
resp, err := client.registry.GetRepository(context.Background(), &mcrv1.GetRepositoryRequest{Name: repoName})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get repository: %w", err)
|
||||
}
|
||||
var tags []tagWithTime
|
||||
for _, t := range resp.GetTags() {
|
||||
tags = append(tags, tagWithTime{
|
||||
Name: t.GetName(),
|
||||
Digest: t.GetDigest(),
|
||||
UpdatedAt: t.GetUpdatedAt(),
|
||||
})
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
data, err := client.restDo("GET", "/v1/repositories/"+repoName, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get repository: %w", err)
|
||||
}
|
||||
|
||||
var detail struct {
|
||||
Tags []struct {
|
||||
Name string `json:"name"`
|
||||
Digest string `json:"digest"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
} `json:"tags"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &detail); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tags []tagWithTime
|
||||
for _, t := range detail.Tags {
|
||||
tags = append(tags, tagWithTime{
|
||||
Name: t.Name,
|
||||
Digest: t.Digest,
|
||||
UpdatedAt: t.UpdatedAt,
|
||||
})
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
// deleteManifest deletes a manifest by digest via the OCI API.
|
||||
func deleteManifest(repoName, digest string) error {
|
||||
if client.useGRPC() {
|
||||
// No gRPC RPC for OCI manifest delete — fall back to REST.
|
||||
// The OCI Distribution spec uses DELETE /v2/{name}/manifests/{reference}.
|
||||
}
|
||||
|
||||
// URL-encode the repo name for path segments with slashes.
|
||||
_, err := client.restDo("DELETE", "/v2/"+repoName+"/manifests/"+digest, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// triggerGC starts garbage collection.
|
||||
func triggerGC() error {
|
||||
if client.useGRPC() {
|
||||
_, err := client.registry.GarbageCollect(context.Background(), &mcrv1.GarbageCollectRequest{})
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := client.restDo("POST", "/v1/gc", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// formatRepoName truncates long repo names for display.
|
||||
func formatRepoName(name string, maxLen int) string {
|
||||
if len(name) <= maxLen {
|
||||
return name
|
||||
}
|
||||
parts := strings.Split(name, "/")
|
||||
if len(parts) > 1 {
|
||||
return "..." + parts[len(parts)-1]
|
||||
}
|
||||
return name[:maxLen-3] + "..."
|
||||
}
|
||||
@@ -16,17 +16,17 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/config"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/gc"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/oci"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/server"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/storage"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/config"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/gc"
|
||||
"git.wntrmute.dev/mc/mcr/internal/oci"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/server"
|
||||
"git.wntrmute.dev/mc/mcr/internal/storage"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/grpcserver"
|
||||
mcdsldb "git.wntrmute.dev/kyle/mcdsl/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/grpcserver"
|
||||
mcdsldb "git.wntrmute.dev/mc/mcdsl/db"
|
||||
)
|
||||
|
||||
var version = "dev"
|
||||
|
||||
@@ -25,9 +25,10 @@ service_name = "mcr"
|
||||
tags = ["env:restricted"]
|
||||
|
||||
[web]
|
||||
listen_addr = "127.0.0.1:8080" # Web UI listen address
|
||||
grpc_addr = "127.0.0.1:9443" # mcrsrv gRPC address for the web UI
|
||||
ca_cert = "" # CA cert for verifying mcrsrv gRPC TLS
|
||||
listen_addr = "127.0.0.1:8080" # Web UI listen address
|
||||
grpc_addr = "127.0.0.1:9443" # mcrsrv gRPC address for the web UI
|
||||
tls_server_name = "" # Override TLS server name (when dial address differs from cert SAN)
|
||||
ca_cert = "" # CA cert for verifying mcrsrv gRPC TLS
|
||||
|
||||
[log]
|
||||
level = "info" # debug, info, warn, error
|
||||
|
||||
@@ -30,9 +30,10 @@ service_name = "mcr"
|
||||
service_token = "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL21jaWFzLm1ldGFjaXJjdWxhci5uZXQiLCJzdWIiOiIwYWM3NDk3ZS0wZTE5LTRhOWMtYWI3Yi03YWZjMzc0ZDU3NzIiLCJleHAiOjE4MDYwMzczNzMsIm5iZiI6MTc3NDUwMTM3MywiaWF0IjoxNzc0NTAxMzczLCJqdGkiOiI1NTM0ZDU0OS1kYzY5LTRiNzctYTY5MC0xNzQ3NjE0MDUzYzEiLCJyb2xlcyI6bnVsbH0.bsnoGMrFzJJCIanGuiAvpqmlO2OssvFjYynQgiSt_TPMuLxziRuwuRIL9C_kRnHdF7C6c1mTHncKVj1hkLPiCg"
|
||||
|
||||
[web]
|
||||
listen_addr = ":8080"
|
||||
grpc_addr = "mcr:9443"
|
||||
ca_cert = "/srv/mcr/certs/ca.pem"
|
||||
listen_addr = ":8080"
|
||||
grpc_addr = "mcr-api:9443"
|
||||
tls_server_name = "mcr.svc.mcp.metacircular.net"
|
||||
ca_cert = "/srv/mcr/certs/ca.pem"
|
||||
|
||||
[log]
|
||||
level = "info"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
version = "0.1.0";
|
||||
version = "1.2.0";
|
||||
in
|
||||
{
|
||||
packages.${system} = {
|
||||
|
||||
@@ -1,14 +1,97 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.32.1
|
||||
// source: mcr/v1/admin.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
// HealthRequest is the request message for Health.
|
||||
type HealthRequest struct{}
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type HealthRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *HealthRequest) Reset() {
|
||||
*x = HealthRequest{}
|
||||
mi := &file_mcr_v1_admin_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *HealthRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*HealthRequest) ProtoMessage() {}
|
||||
|
||||
func (x *HealthRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_admin_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use HealthRequest.ProtoReflect.Descriptor instead.
|
||||
func (*HealthRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_admin_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// HealthResponse is the response message for Health.
|
||||
type HealthResponse struct {
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *HealthResponse) Reset() {
|
||||
*x = HealthResponse{}
|
||||
mi := &file_mcr_v1_admin_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *HealthResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*HealthResponse) ProtoMessage() {}
|
||||
|
||||
func (x *HealthResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_admin_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use HealthResponse.ProtoReflect.Descriptor instead.
|
||||
func (*HealthResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_admin_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *HealthResponse) GetStatus() string {
|
||||
@@ -17,3 +100,65 @@ func (x *HealthResponse) GetStatus() string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_mcr_v1_admin_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_mcr_v1_admin_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x12mcr/v1/admin.proto\x12\x06mcr.v1\"\x0f\n" +
|
||||
"\rHealthRequest\"(\n" +
|
||||
"\x0eHealthResponse\x12\x16\n" +
|
||||
"\x06status\x18\x01 \x01(\tR\x06status2G\n" +
|
||||
"\fAdminService\x127\n" +
|
||||
"\x06Health\x12\x15.mcr.v1.HealthRequest\x1a\x16.mcr.v1.HealthResponseB*Z(git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_mcr_v1_admin_proto_rawDescOnce sync.Once
|
||||
file_mcr_v1_admin_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_mcr_v1_admin_proto_rawDescGZIP() []byte {
|
||||
file_mcr_v1_admin_proto_rawDescOnce.Do(func() {
|
||||
file_mcr_v1_admin_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mcr_v1_admin_proto_rawDesc), len(file_mcr_v1_admin_proto_rawDesc)))
|
||||
})
|
||||
return file_mcr_v1_admin_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_mcr_v1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_mcr_v1_admin_proto_goTypes = []any{
|
||||
(*HealthRequest)(nil), // 0: mcr.v1.HealthRequest
|
||||
(*HealthResponse)(nil), // 1: mcr.v1.HealthResponse
|
||||
}
|
||||
var file_mcr_v1_admin_proto_depIdxs = []int32{
|
||||
0, // 0: mcr.v1.AdminService.Health:input_type -> mcr.v1.HealthRequest
|
||||
1, // 1: mcr.v1.AdminService.Health:output_type -> mcr.v1.HealthResponse
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_mcr_v1_admin_proto_init() }
|
||||
func file_mcr_v1_admin_proto_init() {
|
||||
if File_mcr_v1_admin_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_mcr_v1_admin_proto_rawDesc), len(file_mcr_v1_admin_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_mcr_v1_admin_proto_goTypes,
|
||||
DependencyIndexes: file_mcr_v1_admin_proto_depIdxs,
|
||||
MessageInfos: file_mcr_v1_admin_proto_msgTypes,
|
||||
}.Build()
|
||||
File_mcr_v1_admin_proto = out.File
|
||||
file_mcr_v1_admin_proto_goTypes = nil
|
||||
file_mcr_v1_admin_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,38 +1,92 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v6.32.1
|
||||
// source: mcr/v1/admin.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// AdminServiceServer is the server API for AdminService.
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
AdminService_Health_FullMethodName = "/mcr.v1.AdminService/Health"
|
||||
)
|
||||
|
||||
// AdminServiceClient is the client API for AdminService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type AdminServiceClient interface {
|
||||
Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error)
|
||||
}
|
||||
|
||||
type adminServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAdminServiceClient(cc grpc.ClientConnInterface) AdminServiceClient {
|
||||
return &adminServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *adminServiceClient) Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(HealthResponse)
|
||||
err := c.cc.Invoke(ctx, AdminService_Health_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AdminServiceServer is the server API for AdminService service.
|
||||
// All implementations must embed UnimplementedAdminServiceServer
|
||||
// for forward compatibility.
|
||||
type AdminServiceServer interface {
|
||||
Health(context.Context, *HealthRequest) (*HealthResponse, error)
|
||||
mustEmbedUnimplementedAdminServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedAdminServiceServer should be embedded to have forward
|
||||
// compatible implementations.
|
||||
// UnimplementedAdminServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedAdminServiceServer struct{}
|
||||
|
||||
func (UnimplementedAdminServiceServer) Health(context.Context, *HealthRequest) (*HealthResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Health not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Health not implemented")
|
||||
}
|
||||
func (UnimplementedAdminServiceServer) mustEmbedUnimplementedAdminServiceServer() {}
|
||||
func (UnimplementedAdminServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeAdminServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AdminServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAdminServiceServer interface {
|
||||
mustEmbedUnimplementedAdminServiceServer()
|
||||
}
|
||||
|
||||
func (UnimplementedAdminServiceServer) mustEmbedUnimplementedAdminServiceServer() {}
|
||||
|
||||
// RegisterAdminServiceServer registers the AdminServiceServer with the grpc.Server.
|
||||
func RegisterAdminServiceServer(s grpc.ServiceRegistrar, srv AdminServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedAdminServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&AdminService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func adminServiceHealthHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
func _AdminService_Health_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(HealthRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -42,47 +96,26 @@ func adminServiceHealthHandler(srv any, ctx context.Context, dec func(any) error
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.AdminService/Health",
|
||||
FullMethod: AdminService_Health_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AdminServiceServer).Health(ctx, req.(*HealthRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// AdminService_ServiceDesc is the grpc.ServiceDesc for AdminService.
|
||||
// AdminService_ServiceDesc is the grpc.ServiceDesc for AdminService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var AdminService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "mcr.v1.AdminService",
|
||||
HandlerType: (*AdminServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Health",
|
||||
Handler: adminServiceHealthHandler,
|
||||
Handler: _AdminService_Health_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "mcr/v1/admin.proto",
|
||||
}
|
||||
|
||||
// AdminServiceClient is the client API for AdminService.
|
||||
type AdminServiceClient interface {
|
||||
Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error)
|
||||
}
|
||||
|
||||
type adminServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
// NewAdminServiceClient creates a new AdminServiceClient.
|
||||
func NewAdminServiceClient(cc grpc.ClientConnInterface) AdminServiceClient {
|
||||
return &adminServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *adminServiceClient) Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) {
|
||||
out := new(HealthResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.AdminService/Health", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -1,18 +1,68 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.32.1
|
||||
// source: mcr/v1/audit.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
// AuditEvent represents an audit log entry.
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type AuditEvent struct {
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
EventTime string `protobuf:"bytes,2,opt,name=event_time,json=eventTime,proto3" json:"event_time,omitempty"`
|
||||
EventType string `protobuf:"bytes,3,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"`
|
||||
ActorId string `protobuf:"bytes,4,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
Repository string `protobuf:"bytes,5,opt,name=repository,proto3" json:"repository,omitempty"`
|
||||
Digest string `protobuf:"bytes,6,opt,name=digest,proto3" json:"digest,omitempty"`
|
||||
IpAddress string `protobuf:"bytes,7,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
Details map[string]string `protobuf:"bytes,8,rep,name=details,proto3" json:"details,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
EventTime string `protobuf:"bytes,2,opt,name=event_time,json=eventTime,proto3" json:"event_time,omitempty"`
|
||||
EventType string `protobuf:"bytes,3,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"`
|
||||
ActorId string `protobuf:"bytes,4,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"`
|
||||
Repository string `protobuf:"bytes,5,opt,name=repository,proto3" json:"repository,omitempty"`
|
||||
Digest string `protobuf:"bytes,6,opt,name=digest,proto3" json:"digest,omitempty"`
|
||||
IpAddress string `protobuf:"bytes,7,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"`
|
||||
Details map[string]string `protobuf:"bytes,8,rep,name=details,proto3" json:"details,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuditEvent) Reset() {
|
||||
*x = AuditEvent{}
|
||||
mi := &file_mcr_v1_audit_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuditEvent) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuditEvent) ProtoMessage() {}
|
||||
|
||||
func (x *AuditEvent) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_audit_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuditEvent.ProtoReflect.Descriptor instead.
|
||||
func (*AuditEvent) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_audit_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *AuditEvent) GetId() int64 {
|
||||
@@ -71,14 +121,46 @@ func (x *AuditEvent) GetDetails() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListAuditEventsRequest is the request message for ListAuditEvents.
|
||||
type ListAuditEventsRequest struct {
|
||||
Pagination *PaginationRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
EventType string `protobuf:"bytes,2,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"`
|
||||
ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
Repository string `protobuf:"bytes,4,opt,name=repository,proto3" json:"repository,omitempty"`
|
||||
Since string `protobuf:"bytes,5,opt,name=since,proto3" json:"since,omitempty"`
|
||||
Until string `protobuf:"bytes,6,opt,name=until,proto3" json:"until,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Pagination *PaginationRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
EventType string `protobuf:"bytes,2,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"`
|
||||
ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"`
|
||||
Repository string `protobuf:"bytes,4,opt,name=repository,proto3" json:"repository,omitempty"`
|
||||
Since string `protobuf:"bytes,5,opt,name=since,proto3" json:"since,omitempty"`
|
||||
Until string `protobuf:"bytes,6,opt,name=until,proto3" json:"until,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListAuditEventsRequest) Reset() {
|
||||
*x = ListAuditEventsRequest{}
|
||||
mi := &file_mcr_v1_audit_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListAuditEventsRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListAuditEventsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListAuditEventsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_audit_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListAuditEventsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListAuditEventsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_audit_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ListAuditEventsRequest) GetPagination() *PaginationRequest {
|
||||
@@ -123,9 +205,41 @@ func (x *ListAuditEventsRequest) GetUntil() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// ListAuditEventsResponse is the response message for ListAuditEvents.
|
||||
type ListAuditEventsResponse struct {
|
||||
Events []*AuditEvent `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Events []*AuditEvent `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListAuditEventsResponse) Reset() {
|
||||
*x = ListAuditEventsResponse{}
|
||||
mi := &file_mcr_v1_audit_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListAuditEventsResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListAuditEventsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListAuditEventsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_audit_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListAuditEventsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListAuditEventsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_audit_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ListAuditEventsResponse) GetEvents() []*AuditEvent {
|
||||
@@ -134,3 +248,101 @@ func (x *ListAuditEventsResponse) GetEvents() []*AuditEvent {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_mcr_v1_audit_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_mcr_v1_audit_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x12mcr/v1/audit.proto\x12\x06mcr.v1\x1a\x13mcr/v1/common.proto\"\xc3\x02\n" +
|
||||
"\n" +
|
||||
"AuditEvent\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x1d\n" +
|
||||
"\n" +
|
||||
"event_time\x18\x02 \x01(\tR\teventTime\x12\x1d\n" +
|
||||
"\n" +
|
||||
"event_type\x18\x03 \x01(\tR\teventType\x12\x19\n" +
|
||||
"\bactor_id\x18\x04 \x01(\tR\aactorId\x12\x1e\n" +
|
||||
"\n" +
|
||||
"repository\x18\x05 \x01(\tR\n" +
|
||||
"repository\x12\x16\n" +
|
||||
"\x06digest\x18\x06 \x01(\tR\x06digest\x12\x1d\n" +
|
||||
"\n" +
|
||||
"ip_address\x18\a \x01(\tR\tipAddress\x129\n" +
|
||||
"\adetails\x18\b \x03(\v2\x1f.mcr.v1.AuditEvent.DetailsEntryR\adetails\x1a:\n" +
|
||||
"\fDetailsEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xd9\x01\n" +
|
||||
"\x16ListAuditEventsRequest\x129\n" +
|
||||
"\n" +
|
||||
"pagination\x18\x01 \x01(\v2\x19.mcr.v1.PaginationRequestR\n" +
|
||||
"pagination\x12\x1d\n" +
|
||||
"\n" +
|
||||
"event_type\x18\x02 \x01(\tR\teventType\x12\x19\n" +
|
||||
"\bactor_id\x18\x03 \x01(\tR\aactorId\x12\x1e\n" +
|
||||
"\n" +
|
||||
"repository\x18\x04 \x01(\tR\n" +
|
||||
"repository\x12\x14\n" +
|
||||
"\x05since\x18\x05 \x01(\tR\x05since\x12\x14\n" +
|
||||
"\x05until\x18\x06 \x01(\tR\x05until\"E\n" +
|
||||
"\x17ListAuditEventsResponse\x12*\n" +
|
||||
"\x06events\x18\x01 \x03(\v2\x12.mcr.v1.AuditEventR\x06events2b\n" +
|
||||
"\fAuditService\x12R\n" +
|
||||
"\x0fListAuditEvents\x12\x1e.mcr.v1.ListAuditEventsRequest\x1a\x1f.mcr.v1.ListAuditEventsResponseB*Z(git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_mcr_v1_audit_proto_rawDescOnce sync.Once
|
||||
file_mcr_v1_audit_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_mcr_v1_audit_proto_rawDescGZIP() []byte {
|
||||
file_mcr_v1_audit_proto_rawDescOnce.Do(func() {
|
||||
file_mcr_v1_audit_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mcr_v1_audit_proto_rawDesc), len(file_mcr_v1_audit_proto_rawDesc)))
|
||||
})
|
||||
return file_mcr_v1_audit_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_mcr_v1_audit_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_mcr_v1_audit_proto_goTypes = []any{
|
||||
(*AuditEvent)(nil), // 0: mcr.v1.AuditEvent
|
||||
(*ListAuditEventsRequest)(nil), // 1: mcr.v1.ListAuditEventsRequest
|
||||
(*ListAuditEventsResponse)(nil), // 2: mcr.v1.ListAuditEventsResponse
|
||||
nil, // 3: mcr.v1.AuditEvent.DetailsEntry
|
||||
(*PaginationRequest)(nil), // 4: mcr.v1.PaginationRequest
|
||||
}
|
||||
var file_mcr_v1_audit_proto_depIdxs = []int32{
|
||||
3, // 0: mcr.v1.AuditEvent.details:type_name -> mcr.v1.AuditEvent.DetailsEntry
|
||||
4, // 1: mcr.v1.ListAuditEventsRequest.pagination:type_name -> mcr.v1.PaginationRequest
|
||||
0, // 2: mcr.v1.ListAuditEventsResponse.events:type_name -> mcr.v1.AuditEvent
|
||||
1, // 3: mcr.v1.AuditService.ListAuditEvents:input_type -> mcr.v1.ListAuditEventsRequest
|
||||
2, // 4: mcr.v1.AuditService.ListAuditEvents:output_type -> mcr.v1.ListAuditEventsResponse
|
||||
4, // [4:5] is the sub-list for method output_type
|
||||
3, // [3:4] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_mcr_v1_audit_proto_init() }
|
||||
func file_mcr_v1_audit_proto_init() {
|
||||
if File_mcr_v1_audit_proto != nil {
|
||||
return
|
||||
}
|
||||
file_mcr_v1_common_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_mcr_v1_audit_proto_rawDesc), len(file_mcr_v1_audit_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_mcr_v1_audit_proto_goTypes,
|
||||
DependencyIndexes: file_mcr_v1_audit_proto_depIdxs,
|
||||
MessageInfos: file_mcr_v1_audit_proto_msgTypes,
|
||||
}.Build()
|
||||
File_mcr_v1_audit_proto = out.File
|
||||
file_mcr_v1_audit_proto_goTypes = nil
|
||||
file_mcr_v1_audit_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,38 +1,92 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v6.32.1
|
||||
// source: mcr/v1/audit.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// AuditServiceServer is the server API for AuditService.
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
AuditService_ListAuditEvents_FullMethodName = "/mcr.v1.AuditService/ListAuditEvents"
|
||||
)
|
||||
|
||||
// AuditServiceClient is the client API for AuditService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type AuditServiceClient interface {
|
||||
ListAuditEvents(ctx context.Context, in *ListAuditEventsRequest, opts ...grpc.CallOption) (*ListAuditEventsResponse, error)
|
||||
}
|
||||
|
||||
type auditServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAuditServiceClient(cc grpc.ClientConnInterface) AuditServiceClient {
|
||||
return &auditServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *auditServiceClient) ListAuditEvents(ctx context.Context, in *ListAuditEventsRequest, opts ...grpc.CallOption) (*ListAuditEventsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListAuditEventsResponse)
|
||||
err := c.cc.Invoke(ctx, AuditService_ListAuditEvents_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AuditServiceServer is the server API for AuditService service.
|
||||
// All implementations must embed UnimplementedAuditServiceServer
|
||||
// for forward compatibility.
|
||||
type AuditServiceServer interface {
|
||||
ListAuditEvents(context.Context, *ListAuditEventsRequest) (*ListAuditEventsResponse, error)
|
||||
mustEmbedUnimplementedAuditServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedAuditServiceServer should be embedded to have forward
|
||||
// compatible implementations.
|
||||
// UnimplementedAuditServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedAuditServiceServer struct{}
|
||||
|
||||
func (UnimplementedAuditServiceServer) ListAuditEvents(context.Context, *ListAuditEventsRequest) (*ListAuditEventsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListAuditEvents not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method ListAuditEvents not implemented")
|
||||
}
|
||||
func (UnimplementedAuditServiceServer) mustEmbedUnimplementedAuditServiceServer() {}
|
||||
func (UnimplementedAuditServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeAuditServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AuditServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAuditServiceServer interface {
|
||||
mustEmbedUnimplementedAuditServiceServer()
|
||||
}
|
||||
|
||||
func (UnimplementedAuditServiceServer) mustEmbedUnimplementedAuditServiceServer() {}
|
||||
|
||||
// RegisterAuditServiceServer registers the AuditServiceServer with the grpc.Server.
|
||||
func RegisterAuditServiceServer(s grpc.ServiceRegistrar, srv AuditServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedAuditServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&AuditService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func auditServiceListAuditEventsHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
func _AuditService_ListAuditEvents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListAuditEventsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -42,47 +96,26 @@ func auditServiceListAuditEventsHandler(srv any, ctx context.Context, dec func(a
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.AuditService/ListAuditEvents",
|
||||
FullMethod: AuditService_ListAuditEvents_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuditServiceServer).ListAuditEvents(ctx, req.(*ListAuditEventsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// AuditService_ServiceDesc is the grpc.ServiceDesc for AuditService.
|
||||
// AuditService_ServiceDesc is the grpc.ServiceDesc for AuditService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var AuditService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "mcr.v1.AuditService",
|
||||
HandlerType: (*AuditServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ListAuditEvents",
|
||||
Handler: auditServiceListAuditEventsHandler,
|
||||
Handler: _AuditService_ListAuditEvents_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "mcr/v1/audit.proto",
|
||||
}
|
||||
|
||||
// AuditServiceClient is the client API for AuditService.
|
||||
type AuditServiceClient interface {
|
||||
ListAuditEvents(ctx context.Context, in *ListAuditEventsRequest, opts ...grpc.CallOption) (*ListAuditEventsResponse, error)
|
||||
}
|
||||
|
||||
type auditServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
// NewAuditServiceClient creates a new AuditServiceClient.
|
||||
func NewAuditServiceClient(cc grpc.ClientConnInterface) AuditServiceClient {
|
||||
return &auditServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *auditServiceClient) ListAuditEvents(ctx context.Context, in *ListAuditEventsRequest, opts ...grpc.CallOption) (*ListAuditEventsResponse, error) {
|
||||
out := new(ListAuditEventsResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.AuditService/ListAuditEvents", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -1,12 +1,63 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.32.1
|
||||
// source: mcr/v1/common.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
// PaginationRequest controls pagination for list RPCs.
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Pagination controls for list RPCs.
|
||||
type PaginationRequest struct {
|
||||
Limit int32 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||
Offset int32 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Limit int32 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||
Offset int32 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PaginationRequest) Reset() {
|
||||
*x = PaginationRequest{}
|
||||
mi := &file_mcr_v1_common_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PaginationRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PaginationRequest) ProtoMessage() {}
|
||||
|
||||
func (x *PaginationRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_common_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PaginationRequest.ProtoReflect.Descriptor instead.
|
||||
func (*PaginationRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_common_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PaginationRequest) GetLimit() int32 {
|
||||
@@ -22,3 +73,60 @@ func (x *PaginationRequest) GetOffset() int32 {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_mcr_v1_common_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_mcr_v1_common_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x13mcr/v1/common.proto\x12\x06mcr.v1\"A\n" +
|
||||
"\x11PaginationRequest\x12\x14\n" +
|
||||
"\x05limit\x18\x01 \x01(\x05R\x05limit\x12\x16\n" +
|
||||
"\x06offset\x18\x02 \x01(\x05R\x06offsetB*Z(git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_mcr_v1_common_proto_rawDescOnce sync.Once
|
||||
file_mcr_v1_common_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_mcr_v1_common_proto_rawDescGZIP() []byte {
|
||||
file_mcr_v1_common_proto_rawDescOnce.Do(func() {
|
||||
file_mcr_v1_common_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mcr_v1_common_proto_rawDesc), len(file_mcr_v1_common_proto_rawDesc)))
|
||||
})
|
||||
return file_mcr_v1_common_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_mcr_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_mcr_v1_common_proto_goTypes = []any{
|
||||
(*PaginationRequest)(nil), // 0: mcr.v1.PaginationRequest
|
||||
}
|
||||
var file_mcr_v1_common_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_mcr_v1_common_proto_init() }
|
||||
func file_mcr_v1_common_proto_init() {
|
||||
if File_mcr_v1_common_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_mcr_v1_common_proto_rawDesc), len(file_mcr_v1_common_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_mcr_v1_common_proto_goTypes,
|
||||
DependencyIndexes: file_mcr_v1_common_proto_depIdxs,
|
||||
MessageInfos: file_mcr_v1_common_proto_msgTypes,
|
||||
}.Build()
|
||||
File_mcr_v1_common_proto = out.File
|
||||
file_mcr_v1_common_proto_goTypes = nil
|
||||
file_mcr_v1_common_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,23 +1,73 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.32.1
|
||||
// source: mcr/v1/policy.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
// PolicyRule represents a policy rule.
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type PolicyRule struct {
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"`
|
||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Effect string `protobuf:"bytes,4,opt,name=effect,proto3" json:"effect,omitempty"`
|
||||
Roles []string `protobuf:"bytes,5,rep,name=roles,proto3" json:"roles,omitempty"`
|
||||
AccountTypes []string `protobuf:"bytes,6,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"`
|
||||
SubjectUuid string `protobuf:"bytes,7,opt,name=subject_uuid,json=subjectUuid,proto3" json:"subject_uuid,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
Actions []string `protobuf:"bytes,8,rep,name=actions,proto3" json:"actions,omitempty"`
|
||||
Repositories []string `protobuf:"bytes,9,rep,name=repositories,proto3" json:"repositories,omitempty"`
|
||||
Enabled bool `protobuf:"varint,10,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
CreatedBy string `protobuf:"bytes,11,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,12,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
UpdatedAt string `protobuf:"bytes,13,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"`
|
||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Effect string `protobuf:"bytes,4,opt,name=effect,proto3" json:"effect,omitempty"`
|
||||
Roles []string `protobuf:"bytes,5,rep,name=roles,proto3" json:"roles,omitempty"`
|
||||
AccountTypes []string `protobuf:"bytes,6,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"`
|
||||
SubjectUuid string `protobuf:"bytes,7,opt,name=subject_uuid,json=subjectUuid,proto3" json:"subject_uuid,omitempty"`
|
||||
Actions []string `protobuf:"bytes,8,rep,name=actions,proto3" json:"actions,omitempty"`
|
||||
Repositories []string `protobuf:"bytes,9,rep,name=repositories,proto3" json:"repositories,omitempty"`
|
||||
Enabled bool `protobuf:"varint,10,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
CreatedBy string `protobuf:"bytes,11,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,12,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
UpdatedAt string `protobuf:"bytes,13,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PolicyRule) Reset() {
|
||||
*x = PolicyRule{}
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PolicyRule) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PolicyRule) ProtoMessage() {}
|
||||
|
||||
func (x *PolicyRule) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PolicyRule.ProtoReflect.Descriptor instead.
|
||||
func (*PolicyRule) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_policy_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PolicyRule) GetId() int64 {
|
||||
@@ -111,9 +161,41 @@ func (x *PolicyRule) GetUpdatedAt() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// ListPolicyRulesRequest is the request message for ListPolicyRules.
|
||||
type ListPolicyRulesRequest struct {
|
||||
Pagination *PaginationRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Pagination *PaginationRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListPolicyRulesRequest) Reset() {
|
||||
*x = ListPolicyRulesRequest{}
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListPolicyRulesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListPolicyRulesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListPolicyRulesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListPolicyRulesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListPolicyRulesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_policy_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ListPolicyRulesRequest) GetPagination() *PaginationRequest {
|
||||
@@ -123,9 +205,41 @@ func (x *ListPolicyRulesRequest) GetPagination() *PaginationRequest {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListPolicyRulesResponse is the response message for ListPolicyRules.
|
||||
type ListPolicyRulesResponse struct {
|
||||
Rules []*PolicyRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Rules []*PolicyRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListPolicyRulesResponse) Reset() {
|
||||
*x = ListPolicyRulesResponse{}
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListPolicyRulesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListPolicyRulesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListPolicyRulesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListPolicyRulesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListPolicyRulesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_policy_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ListPolicyRulesResponse) GetRules() []*PolicyRule {
|
||||
@@ -135,17 +249,49 @@ func (x *ListPolicyRulesResponse) GetRules() []*PolicyRule {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreatePolicyRuleRequest is the request message for CreatePolicyRule.
|
||||
type CreatePolicyRuleRequest struct {
|
||||
Priority int32 `protobuf:"varint,1,opt,name=priority,proto3" json:"priority,omitempty"`
|
||||
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Effect string `protobuf:"bytes,3,opt,name=effect,proto3" json:"effect,omitempty"`
|
||||
Roles []string `protobuf:"bytes,4,rep,name=roles,proto3" json:"roles,omitempty"`
|
||||
AccountTypes []string `protobuf:"bytes,5,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"`
|
||||
SubjectUuid string `protobuf:"bytes,6,opt,name=subject_uuid,json=subjectUuid,proto3" json:"subject_uuid,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
Actions []string `protobuf:"bytes,7,rep,name=actions,proto3" json:"actions,omitempty"`
|
||||
Repositories []string `protobuf:"bytes,8,rep,name=repositories,proto3" json:"repositories,omitempty"`
|
||||
Enabled bool `protobuf:"varint,9,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Priority int32 `protobuf:"varint,1,opt,name=priority,proto3" json:"priority,omitempty"`
|
||||
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Effect string `protobuf:"bytes,3,opt,name=effect,proto3" json:"effect,omitempty"`
|
||||
Roles []string `protobuf:"bytes,4,rep,name=roles,proto3" json:"roles,omitempty"`
|
||||
AccountTypes []string `protobuf:"bytes,5,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"`
|
||||
SubjectUuid string `protobuf:"bytes,6,opt,name=subject_uuid,json=subjectUuid,proto3" json:"subject_uuid,omitempty"`
|
||||
Actions []string `protobuf:"bytes,7,rep,name=actions,proto3" json:"actions,omitempty"`
|
||||
Repositories []string `protobuf:"bytes,8,rep,name=repositories,proto3" json:"repositories,omitempty"`
|
||||
Enabled bool `protobuf:"varint,9,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreatePolicyRuleRequest) Reset() {
|
||||
*x = CreatePolicyRuleRequest{}
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *CreatePolicyRuleRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreatePolicyRuleRequest) ProtoMessage() {}
|
||||
|
||||
func (x *CreatePolicyRuleRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CreatePolicyRuleRequest.ProtoReflect.Descriptor instead.
|
||||
func (*CreatePolicyRuleRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_policy_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *CreatePolicyRuleRequest) GetPriority() int32 {
|
||||
@@ -211,9 +357,41 @@ func (x *CreatePolicyRuleRequest) GetEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetPolicyRuleRequest is the request message for GetPolicyRule.
|
||||
type GetPolicyRuleRequest struct {
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetPolicyRuleRequest) Reset() {
|
||||
*x = GetPolicyRuleRequest{}
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetPolicyRuleRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetPolicyRuleRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetPolicyRuleRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetPolicyRuleRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetPolicyRuleRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_policy_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *GetPolicyRuleRequest) GetId() int64 {
|
||||
@@ -223,19 +401,52 @@ func (x *GetPolicyRuleRequest) GetId() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// UpdatePolicyRuleRequest is the request message for UpdatePolicyRule.
|
||||
type UpdatePolicyRuleRequest struct {
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"`
|
||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Effect string `protobuf:"bytes,4,opt,name=effect,proto3" json:"effect,omitempty"`
|
||||
Roles []string `protobuf:"bytes,5,rep,name=roles,proto3" json:"roles,omitempty"`
|
||||
AccountTypes []string `protobuf:"bytes,6,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"`
|
||||
SubjectUuid string `protobuf:"bytes,7,opt,name=subject_uuid,json=subjectUuid,proto3" json:"subject_uuid,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
Actions []string `protobuf:"bytes,8,rep,name=actions,proto3" json:"actions,omitempty"`
|
||||
Repositories []string `protobuf:"bytes,9,rep,name=repositories,proto3" json:"repositories,omitempty"`
|
||||
Enabled bool `protobuf:"varint,10,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
UpdateMask []string `protobuf:"bytes,11,rep,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"`
|
||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Effect string `protobuf:"bytes,4,opt,name=effect,proto3" json:"effect,omitempty"`
|
||||
Roles []string `protobuf:"bytes,5,rep,name=roles,proto3" json:"roles,omitempty"`
|
||||
AccountTypes []string `protobuf:"bytes,6,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"`
|
||||
SubjectUuid string `protobuf:"bytes,7,opt,name=subject_uuid,json=subjectUuid,proto3" json:"subject_uuid,omitempty"`
|
||||
Actions []string `protobuf:"bytes,8,rep,name=actions,proto3" json:"actions,omitempty"`
|
||||
Repositories []string `protobuf:"bytes,9,rep,name=repositories,proto3" json:"repositories,omitempty"`
|
||||
Enabled bool `protobuf:"varint,10,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
// Field mask for partial updates — only fields listed here are applied.
|
||||
UpdateMask []string `protobuf:"bytes,11,rep,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UpdatePolicyRuleRequest) Reset() {
|
||||
*x = UpdatePolicyRuleRequest{}
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *UpdatePolicyRuleRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UpdatePolicyRuleRequest) ProtoMessage() {}
|
||||
|
||||
func (x *UpdatePolicyRuleRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UpdatePolicyRuleRequest.ProtoReflect.Descriptor instead.
|
||||
func (*UpdatePolicyRuleRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_policy_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *UpdatePolicyRuleRequest) GetId() int64 {
|
||||
@@ -315,9 +526,41 @@ func (x *UpdatePolicyRuleRequest) GetUpdateMask() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePolicyRuleRequest is the request message for DeletePolicyRule.
|
||||
type DeletePolicyRuleRequest struct {
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeletePolicyRuleRequest) Reset() {
|
||||
*x = DeletePolicyRuleRequest{}
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeletePolicyRuleRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeletePolicyRuleRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeletePolicyRuleRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeletePolicyRuleRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeletePolicyRuleRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_policy_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *DeletePolicyRuleRequest) GetId() int64 {
|
||||
@@ -327,5 +570,173 @@ func (x *DeletePolicyRuleRequest) GetId() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// DeletePolicyRuleResponse is the response message for DeletePolicyRule.
|
||||
type DeletePolicyRuleResponse struct{}
|
||||
type DeletePolicyRuleResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeletePolicyRuleResponse) Reset() {
|
||||
*x = DeletePolicyRuleResponse{}
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeletePolicyRuleResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeletePolicyRuleResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeletePolicyRuleResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_policy_proto_msgTypes[7]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeletePolicyRuleResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DeletePolicyRuleResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_policy_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
var File_mcr_v1_policy_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_mcr_v1_policy_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x13mcr/v1/policy.proto\x12\x06mcr.v1\x1a\x13mcr/v1/common.proto\"\x85\x03\n" +
|
||||
"\n" +
|
||||
"PolicyRule\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x1a\n" +
|
||||
"\bpriority\x18\x02 \x01(\x05R\bpriority\x12 \n" +
|
||||
"\vdescription\x18\x03 \x01(\tR\vdescription\x12\x16\n" +
|
||||
"\x06effect\x18\x04 \x01(\tR\x06effect\x12\x14\n" +
|
||||
"\x05roles\x18\x05 \x03(\tR\x05roles\x12#\n" +
|
||||
"\raccount_types\x18\x06 \x03(\tR\faccountTypes\x12!\n" +
|
||||
"\fsubject_uuid\x18\a \x01(\tR\vsubjectUuid\x12\x18\n" +
|
||||
"\aactions\x18\b \x03(\tR\aactions\x12\"\n" +
|
||||
"\frepositories\x18\t \x03(\tR\frepositories\x12\x18\n" +
|
||||
"\aenabled\x18\n" +
|
||||
" \x01(\bR\aenabled\x12\x1d\n" +
|
||||
"\n" +
|
||||
"created_by\x18\v \x01(\tR\tcreatedBy\x12\x1d\n" +
|
||||
"\n" +
|
||||
"created_at\x18\f \x01(\tR\tcreatedAt\x12\x1d\n" +
|
||||
"\n" +
|
||||
"updated_at\x18\r \x01(\tR\tupdatedAt\"S\n" +
|
||||
"\x16ListPolicyRulesRequest\x129\n" +
|
||||
"\n" +
|
||||
"pagination\x18\x01 \x01(\v2\x19.mcr.v1.PaginationRequestR\n" +
|
||||
"pagination\"C\n" +
|
||||
"\x17ListPolicyRulesResponse\x12(\n" +
|
||||
"\x05rules\x18\x01 \x03(\v2\x12.mcr.v1.PolicyRuleR\x05rules\"\xa5\x02\n" +
|
||||
"\x17CreatePolicyRuleRequest\x12\x1a\n" +
|
||||
"\bpriority\x18\x01 \x01(\x05R\bpriority\x12 \n" +
|
||||
"\vdescription\x18\x02 \x01(\tR\vdescription\x12\x16\n" +
|
||||
"\x06effect\x18\x03 \x01(\tR\x06effect\x12\x14\n" +
|
||||
"\x05roles\x18\x04 \x03(\tR\x05roles\x12#\n" +
|
||||
"\raccount_types\x18\x05 \x03(\tR\faccountTypes\x12!\n" +
|
||||
"\fsubject_uuid\x18\x06 \x01(\tR\vsubjectUuid\x12\x18\n" +
|
||||
"\aactions\x18\a \x03(\tR\aactions\x12\"\n" +
|
||||
"\frepositories\x18\b \x03(\tR\frepositories\x12\x18\n" +
|
||||
"\aenabled\x18\t \x01(\bR\aenabled\"&\n" +
|
||||
"\x14GetPolicyRuleRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\"\xd6\x02\n" +
|
||||
"\x17UpdatePolicyRuleRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x1a\n" +
|
||||
"\bpriority\x18\x02 \x01(\x05R\bpriority\x12 \n" +
|
||||
"\vdescription\x18\x03 \x01(\tR\vdescription\x12\x16\n" +
|
||||
"\x06effect\x18\x04 \x01(\tR\x06effect\x12\x14\n" +
|
||||
"\x05roles\x18\x05 \x03(\tR\x05roles\x12#\n" +
|
||||
"\raccount_types\x18\x06 \x03(\tR\faccountTypes\x12!\n" +
|
||||
"\fsubject_uuid\x18\a \x01(\tR\vsubjectUuid\x12\x18\n" +
|
||||
"\aactions\x18\b \x03(\tR\aactions\x12\"\n" +
|
||||
"\frepositories\x18\t \x03(\tR\frepositories\x12\x18\n" +
|
||||
"\aenabled\x18\n" +
|
||||
" \x01(\bR\aenabled\x12\x1f\n" +
|
||||
"\vupdate_mask\x18\v \x03(\tR\n" +
|
||||
"updateMask\")\n" +
|
||||
"\x17DeletePolicyRuleRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\"\x1a\n" +
|
||||
"\x18DeletePolicyRuleResponse2\x8f\x03\n" +
|
||||
"\rPolicyService\x12R\n" +
|
||||
"\x0fListPolicyRules\x12\x1e.mcr.v1.ListPolicyRulesRequest\x1a\x1f.mcr.v1.ListPolicyRulesResponse\x12G\n" +
|
||||
"\x10CreatePolicyRule\x12\x1f.mcr.v1.CreatePolicyRuleRequest\x1a\x12.mcr.v1.PolicyRule\x12A\n" +
|
||||
"\rGetPolicyRule\x12\x1c.mcr.v1.GetPolicyRuleRequest\x1a\x12.mcr.v1.PolicyRule\x12G\n" +
|
||||
"\x10UpdatePolicyRule\x12\x1f.mcr.v1.UpdatePolicyRuleRequest\x1a\x12.mcr.v1.PolicyRule\x12U\n" +
|
||||
"\x10DeletePolicyRule\x12\x1f.mcr.v1.DeletePolicyRuleRequest\x1a .mcr.v1.DeletePolicyRuleResponseB*Z(git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_mcr_v1_policy_proto_rawDescOnce sync.Once
|
||||
file_mcr_v1_policy_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_mcr_v1_policy_proto_rawDescGZIP() []byte {
|
||||
file_mcr_v1_policy_proto_rawDescOnce.Do(func() {
|
||||
file_mcr_v1_policy_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mcr_v1_policy_proto_rawDesc), len(file_mcr_v1_policy_proto_rawDesc)))
|
||||
})
|
||||
return file_mcr_v1_policy_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_mcr_v1_policy_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_mcr_v1_policy_proto_goTypes = []any{
|
||||
(*PolicyRule)(nil), // 0: mcr.v1.PolicyRule
|
||||
(*ListPolicyRulesRequest)(nil), // 1: mcr.v1.ListPolicyRulesRequest
|
||||
(*ListPolicyRulesResponse)(nil), // 2: mcr.v1.ListPolicyRulesResponse
|
||||
(*CreatePolicyRuleRequest)(nil), // 3: mcr.v1.CreatePolicyRuleRequest
|
||||
(*GetPolicyRuleRequest)(nil), // 4: mcr.v1.GetPolicyRuleRequest
|
||||
(*UpdatePolicyRuleRequest)(nil), // 5: mcr.v1.UpdatePolicyRuleRequest
|
||||
(*DeletePolicyRuleRequest)(nil), // 6: mcr.v1.DeletePolicyRuleRequest
|
||||
(*DeletePolicyRuleResponse)(nil), // 7: mcr.v1.DeletePolicyRuleResponse
|
||||
(*PaginationRequest)(nil), // 8: mcr.v1.PaginationRequest
|
||||
}
|
||||
var file_mcr_v1_policy_proto_depIdxs = []int32{
|
||||
8, // 0: mcr.v1.ListPolicyRulesRequest.pagination:type_name -> mcr.v1.PaginationRequest
|
||||
0, // 1: mcr.v1.ListPolicyRulesResponse.rules:type_name -> mcr.v1.PolicyRule
|
||||
1, // 2: mcr.v1.PolicyService.ListPolicyRules:input_type -> mcr.v1.ListPolicyRulesRequest
|
||||
3, // 3: mcr.v1.PolicyService.CreatePolicyRule:input_type -> mcr.v1.CreatePolicyRuleRequest
|
||||
4, // 4: mcr.v1.PolicyService.GetPolicyRule:input_type -> mcr.v1.GetPolicyRuleRequest
|
||||
5, // 5: mcr.v1.PolicyService.UpdatePolicyRule:input_type -> mcr.v1.UpdatePolicyRuleRequest
|
||||
6, // 6: mcr.v1.PolicyService.DeletePolicyRule:input_type -> mcr.v1.DeletePolicyRuleRequest
|
||||
2, // 7: mcr.v1.PolicyService.ListPolicyRules:output_type -> mcr.v1.ListPolicyRulesResponse
|
||||
0, // 8: mcr.v1.PolicyService.CreatePolicyRule:output_type -> mcr.v1.PolicyRule
|
||||
0, // 9: mcr.v1.PolicyService.GetPolicyRule:output_type -> mcr.v1.PolicyRule
|
||||
0, // 10: mcr.v1.PolicyService.UpdatePolicyRule:output_type -> mcr.v1.PolicyRule
|
||||
7, // 11: mcr.v1.PolicyService.DeletePolicyRule:output_type -> mcr.v1.DeletePolicyRuleResponse
|
||||
7, // [7:12] is the sub-list for method output_type
|
||||
2, // [2:7] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_mcr_v1_policy_proto_init() }
|
||||
func file_mcr_v1_policy_proto_init() {
|
||||
if File_mcr_v1_policy_proto != nil {
|
||||
return
|
||||
}
|
||||
file_mcr_v1_common_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_mcr_v1_policy_proto_rawDesc), len(file_mcr_v1_policy_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 8,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_mcr_v1_policy_proto_goTypes,
|
||||
DependencyIndexes: file_mcr_v1_policy_proto_depIdxs,
|
||||
MessageInfos: file_mcr_v1_policy_proto_msgTypes,
|
||||
}.Build()
|
||||
File_mcr_v1_policy_proto = out.File
|
||||
file_mcr_v1_policy_proto_goTypes = nil
|
||||
file_mcr_v1_policy_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,178 +1,34 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v6.32.1
|
||||
// source: mcr/v1/policy.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// PolicyServiceServer is the server API for PolicyService.
|
||||
type PolicyServiceServer interface {
|
||||
ListPolicyRules(context.Context, *ListPolicyRulesRequest) (*ListPolicyRulesResponse, error)
|
||||
CreatePolicyRule(context.Context, *CreatePolicyRuleRequest) (*PolicyRule, error)
|
||||
GetPolicyRule(context.Context, *GetPolicyRuleRequest) (*PolicyRule, error)
|
||||
UpdatePolicyRule(context.Context, *UpdatePolicyRuleRequest) (*PolicyRule, error)
|
||||
DeletePolicyRule(context.Context, *DeletePolicyRuleRequest) (*DeletePolicyRuleResponse, error)
|
||||
mustEmbedUnimplementedPolicyServiceServer()
|
||||
}
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
// UnimplementedPolicyServiceServer should be embedded to have forward
|
||||
// compatible implementations.
|
||||
type UnimplementedPolicyServiceServer struct{}
|
||||
const (
|
||||
PolicyService_ListPolicyRules_FullMethodName = "/mcr.v1.PolicyService/ListPolicyRules"
|
||||
PolicyService_CreatePolicyRule_FullMethodName = "/mcr.v1.PolicyService/CreatePolicyRule"
|
||||
PolicyService_GetPolicyRule_FullMethodName = "/mcr.v1.PolicyService/GetPolicyRule"
|
||||
PolicyService_UpdatePolicyRule_FullMethodName = "/mcr.v1.PolicyService/UpdatePolicyRule"
|
||||
PolicyService_DeletePolicyRule_FullMethodName = "/mcr.v1.PolicyService/DeletePolicyRule"
|
||||
)
|
||||
|
||||
func (UnimplementedPolicyServiceServer) ListPolicyRules(context.Context, *ListPolicyRulesRequest) (*ListPolicyRulesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListPolicyRules not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedPolicyServiceServer) CreatePolicyRule(context.Context, *CreatePolicyRuleRequest) (*PolicyRule, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreatePolicyRule not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedPolicyServiceServer) GetPolicyRule(context.Context, *GetPolicyRuleRequest) (*PolicyRule, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPolicyRule not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedPolicyServiceServer) UpdatePolicyRule(context.Context, *UpdatePolicyRuleRequest) (*PolicyRule, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdatePolicyRule not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedPolicyServiceServer) DeletePolicyRule(context.Context, *DeletePolicyRuleRequest) (*DeletePolicyRuleResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeletePolicyRule not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedPolicyServiceServer) mustEmbedUnimplementedPolicyServiceServer() {}
|
||||
|
||||
// RegisterPolicyServiceServer registers the PolicyServiceServer with the grpc.Server.
|
||||
func RegisterPolicyServiceServer(s grpc.ServiceRegistrar, srv PolicyServiceServer) {
|
||||
s.RegisterService(&PolicyService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func policyServiceListPolicyRulesHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(ListPolicyRulesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).ListPolicyRules(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.PolicyService/ListPolicyRules",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(PolicyServiceServer).ListPolicyRules(ctx, req.(*ListPolicyRulesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func policyServiceCreatePolicyRuleHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(CreatePolicyRuleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).CreatePolicyRule(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.PolicyService/CreatePolicyRule",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(PolicyServiceServer).CreatePolicyRule(ctx, req.(*CreatePolicyRuleRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func policyServiceGetPolicyRuleHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(GetPolicyRuleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).GetPolicyRule(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.PolicyService/GetPolicyRule",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(PolicyServiceServer).GetPolicyRule(ctx, req.(*GetPolicyRuleRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func policyServiceUpdatePolicyRuleHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(UpdatePolicyRuleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).UpdatePolicyRule(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.PolicyService/UpdatePolicyRule",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(PolicyServiceServer).UpdatePolicyRule(ctx, req.(*UpdatePolicyRuleRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func policyServiceDeletePolicyRuleHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(DeletePolicyRuleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).DeletePolicyRule(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.PolicyService/DeletePolicyRule",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(PolicyServiceServer).DeletePolicyRule(ctx, req.(*DeletePolicyRuleRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// PolicyService_ServiceDesc is the grpc.ServiceDesc for PolicyService.
|
||||
var PolicyService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "mcr.v1.PolicyService",
|
||||
HandlerType: (*PolicyServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ListPolicyRules",
|
||||
Handler: policyServiceListPolicyRulesHandler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreatePolicyRule",
|
||||
Handler: policyServiceCreatePolicyRuleHandler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPolicyRule",
|
||||
Handler: policyServiceGetPolicyRuleHandler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdatePolicyRule",
|
||||
Handler: policyServiceUpdatePolicyRuleHandler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeletePolicyRule",
|
||||
Handler: policyServiceDeletePolicyRuleHandler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "mcr/v1/policy.proto",
|
||||
}
|
||||
|
||||
// PolicyServiceClient is the client API for PolicyService.
|
||||
// PolicyServiceClient is the client API for PolicyService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type PolicyServiceClient interface {
|
||||
ListPolicyRules(ctx context.Context, in *ListPolicyRulesRequest, opts ...grpc.CallOption) (*ListPolicyRulesResponse, error)
|
||||
CreatePolicyRule(ctx context.Context, in *CreatePolicyRuleRequest, opts ...grpc.CallOption) (*PolicyRule, error)
|
||||
@@ -185,14 +41,14 @@ type policyServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
// NewPolicyServiceClient creates a new PolicyServiceClient.
|
||||
func NewPolicyServiceClient(cc grpc.ClientConnInterface) PolicyServiceClient {
|
||||
return &policyServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) ListPolicyRules(ctx context.Context, in *ListPolicyRulesRequest, opts ...grpc.CallOption) (*ListPolicyRulesResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListPolicyRulesResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.PolicyService/ListPolicyRules", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, PolicyService_ListPolicyRules_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -200,8 +56,9 @@ func (c *policyServiceClient) ListPolicyRules(ctx context.Context, in *ListPolic
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) CreatePolicyRule(ctx context.Context, in *CreatePolicyRuleRequest, opts ...grpc.CallOption) (*PolicyRule, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(PolicyRule)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.PolicyService/CreatePolicyRule", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, PolicyService_CreatePolicyRule_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,8 +66,9 @@ func (c *policyServiceClient) CreatePolicyRule(ctx context.Context, in *CreatePo
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) GetPolicyRule(ctx context.Context, in *GetPolicyRuleRequest, opts ...grpc.CallOption) (*PolicyRule, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(PolicyRule)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.PolicyService/GetPolicyRule", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, PolicyService_GetPolicyRule_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -218,8 +76,9 @@ func (c *policyServiceClient) GetPolicyRule(ctx context.Context, in *GetPolicyRu
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) UpdatePolicyRule(ctx context.Context, in *UpdatePolicyRuleRequest, opts ...grpc.CallOption) (*PolicyRule, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(PolicyRule)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.PolicyService/UpdatePolicyRule", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, PolicyService_UpdatePolicyRule_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -227,10 +86,188 @@ func (c *policyServiceClient) UpdatePolicyRule(ctx context.Context, in *UpdatePo
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) DeletePolicyRule(ctx context.Context, in *DeletePolicyRuleRequest, opts ...grpc.CallOption) (*DeletePolicyRuleResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(DeletePolicyRuleResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.PolicyService/DeletePolicyRule", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, PolicyService_DeletePolicyRule_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// PolicyServiceServer is the server API for PolicyService service.
|
||||
// All implementations must embed UnimplementedPolicyServiceServer
|
||||
// for forward compatibility.
|
||||
type PolicyServiceServer interface {
|
||||
ListPolicyRules(context.Context, *ListPolicyRulesRequest) (*ListPolicyRulesResponse, error)
|
||||
CreatePolicyRule(context.Context, *CreatePolicyRuleRequest) (*PolicyRule, error)
|
||||
GetPolicyRule(context.Context, *GetPolicyRuleRequest) (*PolicyRule, error)
|
||||
UpdatePolicyRule(context.Context, *UpdatePolicyRuleRequest) (*PolicyRule, error)
|
||||
DeletePolicyRule(context.Context, *DeletePolicyRuleRequest) (*DeletePolicyRuleResponse, error)
|
||||
mustEmbedUnimplementedPolicyServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedPolicyServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedPolicyServiceServer struct{}
|
||||
|
||||
func (UnimplementedPolicyServiceServer) ListPolicyRules(context.Context, *ListPolicyRulesRequest) (*ListPolicyRulesResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListPolicyRules not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) CreatePolicyRule(context.Context, *CreatePolicyRuleRequest) (*PolicyRule, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method CreatePolicyRule not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) GetPolicyRule(context.Context, *GetPolicyRuleRequest) (*PolicyRule, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetPolicyRule not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) UpdatePolicyRule(context.Context, *UpdatePolicyRuleRequest) (*PolicyRule, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method UpdatePolicyRule not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) DeletePolicyRule(context.Context, *DeletePolicyRuleRequest) (*DeletePolicyRuleResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method DeletePolicyRule not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) mustEmbedUnimplementedPolicyServiceServer() {}
|
||||
func (UnimplementedPolicyServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafePolicyServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to PolicyServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafePolicyServiceServer interface {
|
||||
mustEmbedUnimplementedPolicyServiceServer()
|
||||
}
|
||||
|
||||
func RegisterPolicyServiceServer(s grpc.ServiceRegistrar, srv PolicyServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedPolicyServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&PolicyService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _PolicyService_ListPolicyRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListPolicyRulesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).ListPolicyRules(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_ListPolicyRules_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).ListPolicyRules(ctx, req.(*ListPolicyRulesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PolicyService_CreatePolicyRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreatePolicyRuleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).CreatePolicyRule(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_CreatePolicyRule_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).CreatePolicyRule(ctx, req.(*CreatePolicyRuleRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PolicyService_GetPolicyRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPolicyRuleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).GetPolicyRule(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_GetPolicyRule_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).GetPolicyRule(ctx, req.(*GetPolicyRuleRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PolicyService_UpdatePolicyRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdatePolicyRuleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).UpdatePolicyRule(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_UpdatePolicyRule_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).UpdatePolicyRule(ctx, req.(*UpdatePolicyRuleRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PolicyService_DeletePolicyRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeletePolicyRuleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).DeletePolicyRule(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_DeletePolicyRule_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).DeletePolicyRule(ctx, req.(*DeletePolicyRuleRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// PolicyService_ServiceDesc is the grpc.ServiceDesc for PolicyService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var PolicyService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "mcr.v1.PolicyService",
|
||||
HandlerType: (*PolicyServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ListPolicyRules",
|
||||
Handler: _PolicyService_ListPolicyRules_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreatePolicyRule",
|
||||
Handler: _PolicyService_CreatePolicyRule_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPolicyRule",
|
||||
Handler: _PolicyService_GetPolicyRule_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdatePolicyRule",
|
||||
Handler: _PolicyService_UpdatePolicyRule_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeletePolicyRule",
|
||||
Handler: _PolicyService_DeletePolicyRule_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "mcr/v1/policy.proto",
|
||||
}
|
||||
|
||||
@@ -1,15 +1,65 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.32.1
|
||||
// source: mcr/v1/registry.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
// RepositoryMetadata is a repository summary for listing.
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type RepositoryMetadata struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
TagCount int32 `protobuf:"varint,2,opt,name=tag_count,json=tagCount,proto3" json:"tag_count,omitempty"`
|
||||
ManifestCount int32 `protobuf:"varint,3,opt,name=manifest_count,json=manifestCount,proto3" json:"manifest_count,omitempty"`
|
||||
TotalSize int64 `protobuf:"varint,4,opt,name=total_size,json=totalSize,proto3" json:"total_size,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
TagCount int32 `protobuf:"varint,2,opt,name=tag_count,json=tagCount,proto3" json:"tag_count,omitempty"`
|
||||
ManifestCount int32 `protobuf:"varint,3,opt,name=manifest_count,json=manifestCount,proto3" json:"manifest_count,omitempty"`
|
||||
TotalSize int64 `protobuf:"varint,4,opt,name=total_size,json=totalSize,proto3" json:"total_size,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RepositoryMetadata) Reset() {
|
||||
*x = RepositoryMetadata{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RepositoryMetadata) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RepositoryMetadata) ProtoMessage() {}
|
||||
|
||||
func (x *RepositoryMetadata) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RepositoryMetadata.ProtoReflect.Descriptor instead.
|
||||
func (*RepositoryMetadata) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *RepositoryMetadata) GetName() string {
|
||||
@@ -47,10 +97,43 @@ func (x *RepositoryMetadata) GetCreatedAt() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// TagInfo is a tag with its manifest digest.
|
||||
type TagInfo struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Digest string `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Digest string `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"`
|
||||
UpdatedAt string `protobuf:"bytes,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *TagInfo) Reset() {
|
||||
*x = TagInfo{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *TagInfo) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TagInfo) ProtoMessage() {}
|
||||
|
||||
func (x *TagInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TagInfo.ProtoReflect.Descriptor instead.
|
||||
func (*TagInfo) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *TagInfo) GetName() string {
|
||||
@@ -67,12 +150,51 @@ func (x *TagInfo) GetDigest() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// ManifestInfo is a manifest summary.
|
||||
func (x *TagInfo) GetUpdatedAt() string {
|
||||
if x != nil {
|
||||
return x.UpdatedAt
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ManifestInfo struct {
|
||||
Digest string `protobuf:"bytes,1,opt,name=digest,proto3" json:"digest,omitempty"`
|
||||
MediaType string `protobuf:"bytes,2,opt,name=media_type,json=mediaType,proto3" json:"media_type,omitempty"`
|
||||
Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Digest string `protobuf:"bytes,1,opt,name=digest,proto3" json:"digest,omitempty"`
|
||||
MediaType string `protobuf:"bytes,2,opt,name=media_type,json=mediaType,proto3" json:"media_type,omitempty"`
|
||||
Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ManifestInfo) Reset() {
|
||||
*x = ManifestInfo{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ManifestInfo) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ManifestInfo) ProtoMessage() {}
|
||||
|
||||
func (x *ManifestInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ManifestInfo.ProtoReflect.Descriptor instead.
|
||||
func (*ManifestInfo) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ManifestInfo) GetDigest() string {
|
||||
@@ -103,9 +225,41 @@ func (x *ManifestInfo) GetCreatedAt() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// ListRepositoriesRequest is the request message for ListRepositories.
|
||||
type ListRepositoriesRequest struct {
|
||||
Pagination *PaginationRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Pagination *PaginationRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListRepositoriesRequest) Reset() {
|
||||
*x = ListRepositoriesRequest{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListRepositoriesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListRepositoriesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListRepositoriesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListRepositoriesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListRepositoriesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ListRepositoriesRequest) GetPagination() *PaginationRequest {
|
||||
@@ -115,9 +269,41 @@ func (x *ListRepositoriesRequest) GetPagination() *PaginationRequest {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListRepositoriesResponse is the response message for ListRepositories.
|
||||
type ListRepositoriesResponse struct {
|
||||
Repositories []*RepositoryMetadata `protobuf:"bytes,1,rep,name=repositories,proto3" json:"repositories,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Repositories []*RepositoryMetadata `protobuf:"bytes,1,rep,name=repositories,proto3" json:"repositories,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListRepositoriesResponse) Reset() {
|
||||
*x = ListRepositoriesResponse{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListRepositoriesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListRepositoriesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListRepositoriesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListRepositoriesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListRepositoriesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ListRepositoriesResponse) GetRepositories() []*RepositoryMetadata {
|
||||
@@ -127,9 +313,41 @@ func (x *ListRepositoriesResponse) GetRepositories() []*RepositoryMetadata {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRepositoryRequest is the request message for GetRepository.
|
||||
type GetRepositoryRequest struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetRepositoryRequest) Reset() {
|
||||
*x = GetRepositoryRequest{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetRepositoryRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetRepositoryRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetRepositoryRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetRepositoryRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetRepositoryRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *GetRepositoryRequest) GetName() string {
|
||||
@@ -139,13 +357,45 @@ func (x *GetRepositoryRequest) GetName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetRepositoryResponse is the response message for GetRepository.
|
||||
type GetRepositoryResponse struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Tags []*TagInfo `protobuf:"bytes,2,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||
Manifests []*ManifestInfo `protobuf:"bytes,3,rep,name=manifests,proto3" json:"manifests,omitempty"`
|
||||
TotalSize int64 `protobuf:"varint,4,opt,name=total_size,json=totalSize,proto3" json:"total_size,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Tags []*TagInfo `protobuf:"bytes,2,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||
Manifests []*ManifestInfo `protobuf:"bytes,3,rep,name=manifests,proto3" json:"manifests,omitempty"`
|
||||
TotalSize int64 `protobuf:"varint,4,opt,name=total_size,json=totalSize,proto3" json:"total_size,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetRepositoryResponse) Reset() {
|
||||
*x = GetRepositoryResponse{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetRepositoryResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetRepositoryResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetRepositoryResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetRepositoryResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetRepositoryResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *GetRepositoryResponse) GetName() string {
|
||||
@@ -183,9 +433,41 @@ func (x *GetRepositoryResponse) GetCreatedAt() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// DeleteRepositoryRequest is the request message for DeleteRepository.
|
||||
type DeleteRepositoryRequest struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteRepositoryRequest) Reset() {
|
||||
*x = DeleteRepositoryRequest{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeleteRepositoryRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteRepositoryRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteRepositoryRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[7]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteRepositoryRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteRepositoryRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *DeleteRepositoryRequest) GetName() string {
|
||||
@@ -195,15 +477,113 @@ func (x *DeleteRepositoryRequest) GetName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// DeleteRepositoryResponse is the response message for DeleteRepository.
|
||||
type DeleteRepositoryResponse struct{}
|
||||
type DeleteRepositoryResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
// GarbageCollectRequest is the request message for GarbageCollect.
|
||||
type GarbageCollectRequest struct{}
|
||||
func (x *DeleteRepositoryResponse) Reset() {
|
||||
*x = DeleteRepositoryResponse{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeleteRepositoryResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteRepositoryResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteRepositoryResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[8]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteRepositoryResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteRepositoryResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
type GarbageCollectRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GarbageCollectRequest) Reset() {
|
||||
*x = GarbageCollectRequest{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GarbageCollectRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GarbageCollectRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GarbageCollectRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[9]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GarbageCollectRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GarbageCollectRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
// GarbageCollectResponse is the response message for GarbageCollect.
|
||||
type GarbageCollectResponse struct {
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` //nolint:revive,stylecheck // proto field name
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GarbageCollectResponse) Reset() {
|
||||
*x = GarbageCollectResponse{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GarbageCollectResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GarbageCollectResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GarbageCollectResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[10]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GarbageCollectResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GarbageCollectResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *GarbageCollectResponse) GetId() string {
|
||||
@@ -213,15 +593,80 @@ func (x *GarbageCollectResponse) GetId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetGCStatusRequest is the request message for GetGCStatus.
|
||||
type GetGCStatusRequest struct{}
|
||||
type GetGCStatusRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetGCStatusRequest) Reset() {
|
||||
*x = GetGCStatusRequest{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetGCStatusRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetGCStatusRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetGCStatusRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[11]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetGCStatusRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetGCStatusRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
// GCLastRun records the result of the last garbage collection run.
|
||||
type GCLastRun struct {
|
||||
StartedAt string `protobuf:"bytes,1,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"`
|
||||
CompletedAt string `protobuf:"bytes,2,opt,name=completed_at,json=completedAt,proto3" json:"completed_at,omitempty"`
|
||||
BlobsRemoved int32 `protobuf:"varint,3,opt,name=blobs_removed,json=blobsRemoved,proto3" json:"blobs_removed,omitempty"`
|
||||
BytesFreed int64 `protobuf:"varint,4,opt,name=bytes_freed,json=bytesFreed,proto3" json:"bytes_freed,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
StartedAt string `protobuf:"bytes,1,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"`
|
||||
CompletedAt string `protobuf:"bytes,2,opt,name=completed_at,json=completedAt,proto3" json:"completed_at,omitempty"`
|
||||
BlobsRemoved int32 `protobuf:"varint,3,opt,name=blobs_removed,json=blobsRemoved,proto3" json:"blobs_removed,omitempty"`
|
||||
BytesFreed int64 `protobuf:"varint,4,opt,name=bytes_freed,json=bytesFreed,proto3" json:"bytes_freed,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GCLastRun) Reset() {
|
||||
*x = GCLastRun{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GCLastRun) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GCLastRun) ProtoMessage() {}
|
||||
|
||||
func (x *GCLastRun) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[12]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GCLastRun.ProtoReflect.Descriptor instead.
|
||||
func (*GCLastRun) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
func (x *GCLastRun) GetStartedAt() string {
|
||||
@@ -252,10 +697,42 @@ func (x *GCLastRun) GetBytesFreed() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetGCStatusResponse is the response message for GetGCStatus.
|
||||
type GetGCStatusResponse struct {
|
||||
Running bool `protobuf:"varint,1,opt,name=running,proto3" json:"running,omitempty"`
|
||||
LastRun *GCLastRun `protobuf:"bytes,2,opt,name=last_run,json=lastRun,proto3" json:"last_run,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Running bool `protobuf:"varint,1,opt,name=running,proto3" json:"running,omitempty"`
|
||||
LastRun *GCLastRun `protobuf:"bytes,2,opt,name=last_run,json=lastRun,proto3" json:"last_run,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetGCStatusResponse) Reset() {
|
||||
*x = GetGCStatusResponse{}
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[13]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetGCStatusResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetGCStatusResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetGCStatusResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mcr_v1_registry_proto_msgTypes[13]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetGCStatusResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetGCStatusResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mcr_v1_registry_proto_rawDescGZIP(), []int{13}
|
||||
}
|
||||
|
||||
func (x *GetGCStatusResponse) GetRunning() bool {
|
||||
@@ -271,3 +748,146 @@ func (x *GetGCStatusResponse) GetLastRun() *GCLastRun {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_mcr_v1_registry_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_mcr_v1_registry_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x15mcr/v1/registry.proto\x12\x06mcr.v1\x1a\x13mcr/v1/common.proto\"\xaa\x01\n" +
|
||||
"\x12RepositoryMetadata\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x1b\n" +
|
||||
"\ttag_count\x18\x02 \x01(\x05R\btagCount\x12%\n" +
|
||||
"\x0emanifest_count\x18\x03 \x01(\x05R\rmanifestCount\x12\x1d\n" +
|
||||
"\n" +
|
||||
"total_size\x18\x04 \x01(\x03R\ttotalSize\x12\x1d\n" +
|
||||
"\n" +
|
||||
"created_at\x18\x05 \x01(\tR\tcreatedAt\"T\n" +
|
||||
"\aTagInfo\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n" +
|
||||
"\x06digest\x18\x02 \x01(\tR\x06digest\x12\x1d\n" +
|
||||
"\n" +
|
||||
"updated_at\x18\x03 \x01(\tR\tupdatedAt\"x\n" +
|
||||
"\fManifestInfo\x12\x16\n" +
|
||||
"\x06digest\x18\x01 \x01(\tR\x06digest\x12\x1d\n" +
|
||||
"\n" +
|
||||
"media_type\x18\x02 \x01(\tR\tmediaType\x12\x12\n" +
|
||||
"\x04size\x18\x03 \x01(\x03R\x04size\x12\x1d\n" +
|
||||
"\n" +
|
||||
"created_at\x18\x04 \x01(\tR\tcreatedAt\"T\n" +
|
||||
"\x17ListRepositoriesRequest\x129\n" +
|
||||
"\n" +
|
||||
"pagination\x18\x01 \x01(\v2\x19.mcr.v1.PaginationRequestR\n" +
|
||||
"pagination\"Z\n" +
|
||||
"\x18ListRepositoriesResponse\x12>\n" +
|
||||
"\frepositories\x18\x01 \x03(\v2\x1a.mcr.v1.RepositoryMetadataR\frepositories\"*\n" +
|
||||
"\x14GetRepositoryRequest\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\"\xc2\x01\n" +
|
||||
"\x15GetRepositoryResponse\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12#\n" +
|
||||
"\x04tags\x18\x02 \x03(\v2\x0f.mcr.v1.TagInfoR\x04tags\x122\n" +
|
||||
"\tmanifests\x18\x03 \x03(\v2\x14.mcr.v1.ManifestInfoR\tmanifests\x12\x1d\n" +
|
||||
"\n" +
|
||||
"total_size\x18\x04 \x01(\x03R\ttotalSize\x12\x1d\n" +
|
||||
"\n" +
|
||||
"created_at\x18\x05 \x01(\tR\tcreatedAt\"-\n" +
|
||||
"\x17DeleteRepositoryRequest\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\"\x1a\n" +
|
||||
"\x18DeleteRepositoryResponse\"\x17\n" +
|
||||
"\x15GarbageCollectRequest\"(\n" +
|
||||
"\x16GarbageCollectResponse\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\"\x14\n" +
|
||||
"\x12GetGCStatusRequest\"\x93\x01\n" +
|
||||
"\tGCLastRun\x12\x1d\n" +
|
||||
"\n" +
|
||||
"started_at\x18\x01 \x01(\tR\tstartedAt\x12!\n" +
|
||||
"\fcompleted_at\x18\x02 \x01(\tR\vcompletedAt\x12#\n" +
|
||||
"\rblobs_removed\x18\x03 \x01(\x05R\fblobsRemoved\x12\x1f\n" +
|
||||
"\vbytes_freed\x18\x04 \x01(\x03R\n" +
|
||||
"bytesFreed\"]\n" +
|
||||
"\x13GetGCStatusResponse\x12\x18\n" +
|
||||
"\arunning\x18\x01 \x01(\bR\arunning\x12,\n" +
|
||||
"\blast_run\x18\x02 \x01(\v2\x11.mcr.v1.GCLastRunR\alastRun2\xa6\x03\n" +
|
||||
"\x0fRegistryService\x12U\n" +
|
||||
"\x10ListRepositories\x12\x1f.mcr.v1.ListRepositoriesRequest\x1a .mcr.v1.ListRepositoriesResponse\x12L\n" +
|
||||
"\rGetRepository\x12\x1c.mcr.v1.GetRepositoryRequest\x1a\x1d.mcr.v1.GetRepositoryResponse\x12U\n" +
|
||||
"\x10DeleteRepository\x12\x1f.mcr.v1.DeleteRepositoryRequest\x1a .mcr.v1.DeleteRepositoryResponse\x12O\n" +
|
||||
"\x0eGarbageCollect\x12\x1d.mcr.v1.GarbageCollectRequest\x1a\x1e.mcr.v1.GarbageCollectResponse\x12F\n" +
|
||||
"\vGetGCStatus\x12\x1a.mcr.v1.GetGCStatusRequest\x1a\x1b.mcr.v1.GetGCStatusResponseB*Z(git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_mcr_v1_registry_proto_rawDescOnce sync.Once
|
||||
file_mcr_v1_registry_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_mcr_v1_registry_proto_rawDescGZIP() []byte {
|
||||
file_mcr_v1_registry_proto_rawDescOnce.Do(func() {
|
||||
file_mcr_v1_registry_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mcr_v1_registry_proto_rawDesc), len(file_mcr_v1_registry_proto_rawDesc)))
|
||||
})
|
||||
return file_mcr_v1_registry_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_mcr_v1_registry_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
||||
var file_mcr_v1_registry_proto_goTypes = []any{
|
||||
(*RepositoryMetadata)(nil), // 0: mcr.v1.RepositoryMetadata
|
||||
(*TagInfo)(nil), // 1: mcr.v1.TagInfo
|
||||
(*ManifestInfo)(nil), // 2: mcr.v1.ManifestInfo
|
||||
(*ListRepositoriesRequest)(nil), // 3: mcr.v1.ListRepositoriesRequest
|
||||
(*ListRepositoriesResponse)(nil), // 4: mcr.v1.ListRepositoriesResponse
|
||||
(*GetRepositoryRequest)(nil), // 5: mcr.v1.GetRepositoryRequest
|
||||
(*GetRepositoryResponse)(nil), // 6: mcr.v1.GetRepositoryResponse
|
||||
(*DeleteRepositoryRequest)(nil), // 7: mcr.v1.DeleteRepositoryRequest
|
||||
(*DeleteRepositoryResponse)(nil), // 8: mcr.v1.DeleteRepositoryResponse
|
||||
(*GarbageCollectRequest)(nil), // 9: mcr.v1.GarbageCollectRequest
|
||||
(*GarbageCollectResponse)(nil), // 10: mcr.v1.GarbageCollectResponse
|
||||
(*GetGCStatusRequest)(nil), // 11: mcr.v1.GetGCStatusRequest
|
||||
(*GCLastRun)(nil), // 12: mcr.v1.GCLastRun
|
||||
(*GetGCStatusResponse)(nil), // 13: mcr.v1.GetGCStatusResponse
|
||||
(*PaginationRequest)(nil), // 14: mcr.v1.PaginationRequest
|
||||
}
|
||||
var file_mcr_v1_registry_proto_depIdxs = []int32{
|
||||
14, // 0: mcr.v1.ListRepositoriesRequest.pagination:type_name -> mcr.v1.PaginationRequest
|
||||
0, // 1: mcr.v1.ListRepositoriesResponse.repositories:type_name -> mcr.v1.RepositoryMetadata
|
||||
1, // 2: mcr.v1.GetRepositoryResponse.tags:type_name -> mcr.v1.TagInfo
|
||||
2, // 3: mcr.v1.GetRepositoryResponse.manifests:type_name -> mcr.v1.ManifestInfo
|
||||
12, // 4: mcr.v1.GetGCStatusResponse.last_run:type_name -> mcr.v1.GCLastRun
|
||||
3, // 5: mcr.v1.RegistryService.ListRepositories:input_type -> mcr.v1.ListRepositoriesRequest
|
||||
5, // 6: mcr.v1.RegistryService.GetRepository:input_type -> mcr.v1.GetRepositoryRequest
|
||||
7, // 7: mcr.v1.RegistryService.DeleteRepository:input_type -> mcr.v1.DeleteRepositoryRequest
|
||||
9, // 8: mcr.v1.RegistryService.GarbageCollect:input_type -> mcr.v1.GarbageCollectRequest
|
||||
11, // 9: mcr.v1.RegistryService.GetGCStatus:input_type -> mcr.v1.GetGCStatusRequest
|
||||
4, // 10: mcr.v1.RegistryService.ListRepositories:output_type -> mcr.v1.ListRepositoriesResponse
|
||||
6, // 11: mcr.v1.RegistryService.GetRepository:output_type -> mcr.v1.GetRepositoryResponse
|
||||
8, // 12: mcr.v1.RegistryService.DeleteRepository:output_type -> mcr.v1.DeleteRepositoryResponse
|
||||
10, // 13: mcr.v1.RegistryService.GarbageCollect:output_type -> mcr.v1.GarbageCollectResponse
|
||||
13, // 14: mcr.v1.RegistryService.GetGCStatus:output_type -> mcr.v1.GetGCStatusResponse
|
||||
10, // [10:15] is the sub-list for method output_type
|
||||
5, // [5:10] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
5, // [5:5] is the sub-list for extension extendee
|
||||
0, // [0:5] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_mcr_v1_registry_proto_init() }
|
||||
func file_mcr_v1_registry_proto_init() {
|
||||
if File_mcr_v1_registry_proto != nil {
|
||||
return
|
||||
}
|
||||
file_mcr_v1_common_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_mcr_v1_registry_proto_rawDesc), len(file_mcr_v1_registry_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 14,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_mcr_v1_registry_proto_goTypes,
|
||||
DependencyIndexes: file_mcr_v1_registry_proto_depIdxs,
|
||||
MessageInfos: file_mcr_v1_registry_proto_msgTypes,
|
||||
}.Build()
|
||||
File_mcr_v1_registry_proto = out.File
|
||||
file_mcr_v1_registry_proto_goTypes = nil
|
||||
file_mcr_v1_registry_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,178 +1,34 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v6.32.1
|
||||
// source: mcr/v1/registry.proto
|
||||
|
||||
package mcrv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// RegistryServiceServer is the server API for RegistryService.
|
||||
type RegistryServiceServer interface {
|
||||
ListRepositories(context.Context, *ListRepositoriesRequest) (*ListRepositoriesResponse, error)
|
||||
GetRepository(context.Context, *GetRepositoryRequest) (*GetRepositoryResponse, error)
|
||||
DeleteRepository(context.Context, *DeleteRepositoryRequest) (*DeleteRepositoryResponse, error)
|
||||
GarbageCollect(context.Context, *GarbageCollectRequest) (*GarbageCollectResponse, error)
|
||||
GetGCStatus(context.Context, *GetGCStatusRequest) (*GetGCStatusResponse, error)
|
||||
mustEmbedUnimplementedRegistryServiceServer()
|
||||
}
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
// UnimplementedRegistryServiceServer should be embedded to have forward
|
||||
// compatible implementations.
|
||||
type UnimplementedRegistryServiceServer struct{}
|
||||
const (
|
||||
RegistryService_ListRepositories_FullMethodName = "/mcr.v1.RegistryService/ListRepositories"
|
||||
RegistryService_GetRepository_FullMethodName = "/mcr.v1.RegistryService/GetRepository"
|
||||
RegistryService_DeleteRepository_FullMethodName = "/mcr.v1.RegistryService/DeleteRepository"
|
||||
RegistryService_GarbageCollect_FullMethodName = "/mcr.v1.RegistryService/GarbageCollect"
|
||||
RegistryService_GetGCStatus_FullMethodName = "/mcr.v1.RegistryService/GetGCStatus"
|
||||
)
|
||||
|
||||
func (UnimplementedRegistryServiceServer) ListRepositories(context.Context, *ListRepositoriesRequest) (*ListRepositoriesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListRepositories not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedRegistryServiceServer) GetRepository(context.Context, *GetRepositoryRequest) (*GetRepositoryResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetRepository not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedRegistryServiceServer) DeleteRepository(context.Context, *DeleteRepositoryRequest) (*DeleteRepositoryResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteRepository not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedRegistryServiceServer) GarbageCollect(context.Context, *GarbageCollectRequest) (*GarbageCollectResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GarbageCollect not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedRegistryServiceServer) GetGCStatus(context.Context, *GetGCStatusRequest) (*GetGCStatusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetGCStatus not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedRegistryServiceServer) mustEmbedUnimplementedRegistryServiceServer() {}
|
||||
|
||||
// RegisterRegistryServiceServer registers the RegistryServiceServer with the grpc.Server.
|
||||
func RegisterRegistryServiceServer(s grpc.ServiceRegistrar, srv RegistryServiceServer) {
|
||||
s.RegisterService(&RegistryService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func registryServiceListRepositoriesHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(ListRepositoriesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).ListRepositories(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.RegistryService/ListRepositories",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(RegistryServiceServer).ListRepositories(ctx, req.(*ListRepositoriesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func registryServiceGetRepositoryHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(GetRepositoryRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).GetRepository(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.RegistryService/GetRepository",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(RegistryServiceServer).GetRepository(ctx, req.(*GetRepositoryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func registryServiceDeleteRepositoryHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(DeleteRepositoryRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).DeleteRepository(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.RegistryService/DeleteRepository",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(RegistryServiceServer).DeleteRepository(ctx, req.(*DeleteRepositoryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func registryServiceGarbageCollectHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(GarbageCollectRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).GarbageCollect(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.RegistryService/GarbageCollect",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(RegistryServiceServer).GarbageCollect(ctx, req.(*GarbageCollectRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func registryServiceGetGCStatusHandler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(GetGCStatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).GetGCStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/mcr.v1.RegistryService/GetGCStatus",
|
||||
}
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(RegistryServiceServer).GetGCStatus(ctx, req.(*GetGCStatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// RegistryService_ServiceDesc is the grpc.ServiceDesc for RegistryService.
|
||||
var RegistryService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "mcr.v1.RegistryService",
|
||||
HandlerType: (*RegistryServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ListRepositories",
|
||||
Handler: registryServiceListRepositoriesHandler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetRepository",
|
||||
Handler: registryServiceGetRepositoryHandler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteRepository",
|
||||
Handler: registryServiceDeleteRepositoryHandler,
|
||||
},
|
||||
{
|
||||
MethodName: "GarbageCollect",
|
||||
Handler: registryServiceGarbageCollectHandler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetGCStatus",
|
||||
Handler: registryServiceGetGCStatusHandler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "mcr/v1/registry.proto",
|
||||
}
|
||||
|
||||
// RegistryServiceClient is the client API for RegistryService.
|
||||
// RegistryServiceClient is the client API for RegistryService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type RegistryServiceClient interface {
|
||||
ListRepositories(ctx context.Context, in *ListRepositoriesRequest, opts ...grpc.CallOption) (*ListRepositoriesResponse, error)
|
||||
GetRepository(ctx context.Context, in *GetRepositoryRequest, opts ...grpc.CallOption) (*GetRepositoryResponse, error)
|
||||
@@ -185,14 +41,14 @@ type registryServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
// NewRegistryServiceClient creates a new RegistryServiceClient.
|
||||
func NewRegistryServiceClient(cc grpc.ClientConnInterface) RegistryServiceClient {
|
||||
return ®istryServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *registryServiceClient) ListRepositories(ctx context.Context, in *ListRepositoriesRequest, opts ...grpc.CallOption) (*ListRepositoriesResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListRepositoriesResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.RegistryService/ListRepositories", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, RegistryService_ListRepositories_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -200,8 +56,9 @@ func (c *registryServiceClient) ListRepositories(ctx context.Context, in *ListRe
|
||||
}
|
||||
|
||||
func (c *registryServiceClient) GetRepository(ctx context.Context, in *GetRepositoryRequest, opts ...grpc.CallOption) (*GetRepositoryResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetRepositoryResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.RegistryService/GetRepository", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, RegistryService_GetRepository_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,8 +66,9 @@ func (c *registryServiceClient) GetRepository(ctx context.Context, in *GetReposi
|
||||
}
|
||||
|
||||
func (c *registryServiceClient) DeleteRepository(ctx context.Context, in *DeleteRepositoryRequest, opts ...grpc.CallOption) (*DeleteRepositoryResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(DeleteRepositoryResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.RegistryService/DeleteRepository", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, RegistryService_DeleteRepository_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -218,8 +76,9 @@ func (c *registryServiceClient) DeleteRepository(ctx context.Context, in *Delete
|
||||
}
|
||||
|
||||
func (c *registryServiceClient) GarbageCollect(ctx context.Context, in *GarbageCollectRequest, opts ...grpc.CallOption) (*GarbageCollectResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GarbageCollectResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.RegistryService/GarbageCollect", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, RegistryService_GarbageCollect_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -227,10 +86,188 @@ func (c *registryServiceClient) GarbageCollect(ctx context.Context, in *GarbageC
|
||||
}
|
||||
|
||||
func (c *registryServiceClient) GetGCStatus(ctx context.Context, in *GetGCStatusRequest, opts ...grpc.CallOption) (*GetGCStatusResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetGCStatusResponse)
|
||||
err := c.cc.Invoke(ctx, "/mcr.v1.RegistryService/GetGCStatus", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, RegistryService_GetGCStatus_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// RegistryServiceServer is the server API for RegistryService service.
|
||||
// All implementations must embed UnimplementedRegistryServiceServer
|
||||
// for forward compatibility.
|
||||
type RegistryServiceServer interface {
|
||||
ListRepositories(context.Context, *ListRepositoriesRequest) (*ListRepositoriesResponse, error)
|
||||
GetRepository(context.Context, *GetRepositoryRequest) (*GetRepositoryResponse, error)
|
||||
DeleteRepository(context.Context, *DeleteRepositoryRequest) (*DeleteRepositoryResponse, error)
|
||||
GarbageCollect(context.Context, *GarbageCollectRequest) (*GarbageCollectResponse, error)
|
||||
GetGCStatus(context.Context, *GetGCStatusRequest) (*GetGCStatusResponse, error)
|
||||
mustEmbedUnimplementedRegistryServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedRegistryServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedRegistryServiceServer struct{}
|
||||
|
||||
func (UnimplementedRegistryServiceServer) ListRepositories(context.Context, *ListRepositoriesRequest) (*ListRepositoriesResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListRepositories not implemented")
|
||||
}
|
||||
func (UnimplementedRegistryServiceServer) GetRepository(context.Context, *GetRepositoryRequest) (*GetRepositoryResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetRepository not implemented")
|
||||
}
|
||||
func (UnimplementedRegistryServiceServer) DeleteRepository(context.Context, *DeleteRepositoryRequest) (*DeleteRepositoryResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method DeleteRepository not implemented")
|
||||
}
|
||||
func (UnimplementedRegistryServiceServer) GarbageCollect(context.Context, *GarbageCollectRequest) (*GarbageCollectResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GarbageCollect not implemented")
|
||||
}
|
||||
func (UnimplementedRegistryServiceServer) GetGCStatus(context.Context, *GetGCStatusRequest) (*GetGCStatusResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetGCStatus not implemented")
|
||||
}
|
||||
func (UnimplementedRegistryServiceServer) mustEmbedUnimplementedRegistryServiceServer() {}
|
||||
func (UnimplementedRegistryServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeRegistryServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to RegistryServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeRegistryServiceServer interface {
|
||||
mustEmbedUnimplementedRegistryServiceServer()
|
||||
}
|
||||
|
||||
func RegisterRegistryServiceServer(s grpc.ServiceRegistrar, srv RegistryServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedRegistryServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&RegistryService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _RegistryService_ListRepositories_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListRepositoriesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).ListRepositories(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RegistryService_ListRepositories_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServiceServer).ListRepositories(ctx, req.(*ListRepositoriesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RegistryService_GetRepository_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetRepositoryRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).GetRepository(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RegistryService_GetRepository_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServiceServer).GetRepository(ctx, req.(*GetRepositoryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RegistryService_DeleteRepository_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteRepositoryRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).DeleteRepository(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RegistryService_DeleteRepository_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServiceServer).DeleteRepository(ctx, req.(*DeleteRepositoryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RegistryService_GarbageCollect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GarbageCollectRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).GarbageCollect(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RegistryService_GarbageCollect_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServiceServer).GarbageCollect(ctx, req.(*GarbageCollectRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RegistryService_GetGCStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetGCStatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServiceServer).GetGCStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RegistryService_GetGCStatus_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServiceServer).GetGCStatus(ctx, req.(*GetGCStatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// RegistryService_ServiceDesc is the grpc.ServiceDesc for RegistryService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var RegistryService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "mcr.v1.RegistryService",
|
||||
HandlerType: (*RegistryServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ListRepositories",
|
||||
Handler: _RegistryService_ListRepositories_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetRepository",
|
||||
Handler: _RegistryService_GetRepository_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteRepository",
|
||||
Handler: _RegistryService_DeleteRepository_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GarbageCollect",
|
||||
Handler: _RegistryService_GarbageCollect_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetGCStatus",
|
||||
Handler: _RegistryService_GetGCStatus_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "mcr/v1/registry.proto",
|
||||
}
|
||||
|
||||
6
go.mod
6
go.mod
@@ -1,13 +1,14 @@
|
||||
module git.wntrmute.dev/kyle/mcr
|
||||
module git.wntrmute.dev/mc/mcr
|
||||
|
||||
go 1.25.7
|
||||
|
||||
require (
|
||||
git.wntrmute.dev/kyle/mcdsl v1.0.0
|
||||
git.wntrmute.dev/mc/mcdsl v1.2.0
|
||||
github.com/go-chi/chi/v5 v5.2.5
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/spf13/cobra v1.10.2
|
||||
google.golang.org/grpc v1.79.3
|
||||
google.golang.org/protobuf v1.36.11
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -22,7 +23,6 @@ require (
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
modernc.org/libc v1.70.0 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1,5 +1,5 @@
|
||||
git.wntrmute.dev/kyle/mcdsl v1.0.0 h1:YB7dx4gdNYKKcVySpL6UkwHqdCJ9Nl1yS0+eHk0hNtk=
|
||||
git.wntrmute.dev/kyle/mcdsl v1.0.0/go.mod h1:wo0tGfUAxci3XnOe4/rFmR0RjUElKdYUazc+Np986sg=
|
||||
git.wntrmute.dev/mc/mcdsl v1.2.0 h1:41hep7/PNZJfN0SN/nM+rQpyF1GSZcvNNjyVG81DI7U=
|
||||
git.wntrmute.dev/mc/mcdsl v1.2.0/go.mod h1:lXYrAt74ZUix6rx9oVN8d2zH1YJoyp4uxPVKQ+SSxuM=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
|
||||
mcdslauth "git.wntrmute.dev/kyle/mcdsl/auth"
|
||||
mcdslauth "git.wntrmute.dev/mc/mcdsl/auth"
|
||||
)
|
||||
|
||||
// Client communicates with an MCIAS server for authentication and token
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
mcdslconfig "git.wntrmute.dev/kyle/mcdsl/config"
|
||||
mcdslconfig "git.wntrmute.dev/mc/mcdsl/config"
|
||||
)
|
||||
|
||||
// Config is the top-level MCR configuration. It embeds config.Base for
|
||||
@@ -24,9 +24,10 @@ type StorageConfig struct {
|
||||
|
||||
// WebConfig holds the web UI server settings.
|
||||
type WebConfig struct {
|
||||
ListenAddr string `toml:"listen_addr"`
|
||||
GRPCAddr string `toml:"grpc_addr"`
|
||||
CACert string `toml:"ca_cert"`
|
||||
ListenAddr string `toml:"listen_addr"`
|
||||
GRPCAddr string `toml:"grpc_addr"`
|
||||
CACert string `toml:"ca_cert"`
|
||||
TLSServerName string `toml:"tls_server_name"`
|
||||
}
|
||||
|
||||
// Load reads a TOML config file, applies environment variable overrides
|
||||
|
||||
@@ -23,8 +23,9 @@ type RepoMetadata struct {
|
||||
|
||||
// TagInfo is a tag with its manifest digest for repo detail.
|
||||
type TagInfo struct {
|
||||
Name string `json:"name"`
|
||||
Digest string `json:"digest"`
|
||||
Name string `json:"name"`
|
||||
Digest string `json:"digest"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ManifestInfo is a manifest summary for repo detail.
|
||||
@@ -112,7 +113,7 @@ func (d *DB) GetRepositoryDetail(name string) (*RepoDetail, error) {
|
||||
|
||||
// Tags with manifest digests.
|
||||
tagRows, err := d.Query(
|
||||
`SELECT t.name, m.digest
|
||||
`SELECT t.name, m.digest, t.updated_at
|
||||
FROM tags t JOIN manifests m ON m.id = t.manifest_id
|
||||
WHERE t.repository_id = ?
|
||||
ORDER BY t.name ASC`, repoID,
|
||||
@@ -124,7 +125,7 @@ func (d *DB) GetRepositoryDetail(name string) (*RepoDetail, error) {
|
||||
|
||||
for tagRows.Next() {
|
||||
var ti TagInfo
|
||||
if err := tagRows.Scan(&ti.Name, &ti.Digest); err != nil {
|
||||
if err := tagRows.Scan(&ti.Name, &ti.Digest, &ti.UpdatedAt); err != nil {
|
||||
return nil, fmt.Errorf("db: scan tag: %w", err)
|
||||
}
|
||||
detail.Tags = append(detail.Tags, ti)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
mcdsldb "git.wntrmute.dev/kyle/mcdsl/db"
|
||||
mcdsldb "git.wntrmute.dev/mc/mcdsl/db"
|
||||
)
|
||||
|
||||
// DB wraps a SQLite database connection.
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/gc"
|
||||
"git.wntrmute.dev/mc/mcr/internal/gc"
|
||||
)
|
||||
|
||||
// FindAndDeleteUnreferencedBlobs finds all blob rows with no manifest_blobs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
mcdsldb "git.wntrmute.dev/kyle/mcdsl/db"
|
||||
mcdsldb "git.wntrmute.dev/mc/mcdsl/db"
|
||||
)
|
||||
|
||||
// Migrations is the ordered list of MCR schema migrations.
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
// ruleBody is the JSON structure stored in the rule_json column.
|
||||
|
||||
@@ -3,7 +3,7 @@ package db
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
func TestLoadEnabledPolicyRules(t *testing.T) {
|
||||
|
||||
@@ -3,7 +3,7 @@ package grpcserver
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
)
|
||||
|
||||
// adminService implements pb.AdminServiceServer.
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
)
|
||||
|
||||
func TestHealthReturnsOk(t *testing.T) {
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
)
|
||||
|
||||
// auditService implements pb.AuditServiceServer.
|
||||
|
||||
@@ -3,7 +3,7 @@ package grpcserver
|
||||
import (
|
||||
"testing"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
)
|
||||
|
||||
func TestListAuditEventsEmpty(t *testing.T) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
mcdslgrpc "git.wntrmute.dev/kyle/mcdsl/grpcserver"
|
||||
mcdslgrpc "git.wntrmute.dev/mc/mcdsl/grpcserver"
|
||||
)
|
||||
|
||||
// methodMap builds the mcdsl grpcserver.MethodMap for MCR.
|
||||
|
||||
@@ -16,10 +16,10 @@ import (
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
mcdslauth "git.wntrmute.dev/kyle/mcdsl/auth"
|
||||
mcdslauth "git.wntrmute.dev/mc/mcdsl/auth"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
)
|
||||
|
||||
// mockMCIAS starts a fake MCIAS HTTP server for token validation.
|
||||
|
||||
@@ -9,11 +9,11 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
mcdslauth "git.wntrmute.dev/kyle/mcdsl/auth"
|
||||
mcdslauth "git.wntrmute.dev/mc/mcdsl/auth"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
var validActions = map[string]bool{
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
type fakePolicyReloader struct {
|
||||
|
||||
@@ -11,11 +11,11 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
mcdslauth "git.wntrmute.dev/kyle/mcdsl/auth"
|
||||
mcdslauth "git.wntrmute.dev/mc/mcdsl/auth"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/gc"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/gc"
|
||||
)
|
||||
|
||||
// registryService implements pb.RegistryServiceServer.
|
||||
@@ -78,8 +78,9 @@ func (s *registryService) GetRepository(_ context.Context, req *pb.GetRepository
|
||||
}
|
||||
for _, t := range detail.Tags {
|
||||
resp.Tags = append(resp.Tags, &pb.TagInfo{
|
||||
Name: t.Name,
|
||||
Digest: t.Digest,
|
||||
Name: t.Name,
|
||||
Digest: t.Digest,
|
||||
UpdatedAt: t.UpdatedAt,
|
||||
})
|
||||
}
|
||||
for _, m := range detail.Manifests {
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
mcdslauth "git.wntrmute.dev/kyle/mcdsl/auth"
|
||||
mcdslauth "git.wntrmute.dev/mc/mcdsl/auth"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
)
|
||||
|
||||
// testMCIAS is a package-level variable set by adminDeps for reuse.
|
||||
|
||||
@@ -11,13 +11,13 @@ import (
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
mcdslauth "git.wntrmute.dev/kyle/mcdsl/auth"
|
||||
mcdslgrpc "git.wntrmute.dev/kyle/mcdsl/grpcserver"
|
||||
mcdslauth "git.wntrmute.dev/mc/mcdsl/auth"
|
||||
mcdslgrpc "git.wntrmute.dev/mc/mcdsl/grpcserver"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/gc"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
pb "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/gc"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
// AuditFunc is a callback for recording audit events. It follows the same
|
||||
@@ -65,7 +65,7 @@ type Server struct {
|
||||
//
|
||||
// If certFile or keyFile is empty, TLS is skipped (for testing only).
|
||||
func New(certFile, keyFile string, deps Deps, logger *slog.Logger) (*Server, error) {
|
||||
srv, err := mcdslgrpc.New(certFile, keyFile, deps.Authenticator, methodMap(), logger)
|
||||
srv, err := mcdslgrpc.New(certFile, keyFile, deps.Authenticator, methodMap(), logger, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
func (h *Handler) handleBlobGet(w http.ResponseWriter, r *http.Request, repo, digest string) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
type catalogResponse struct {
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
// handleManifestDelete handles DELETE /v2/<name>/manifests/<digest>.
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/storage"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/storage"
|
||||
)
|
||||
|
||||
// DBQuerier provides the database operations needed by OCI handlers.
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/storage"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/storage"
|
||||
)
|
||||
|
||||
// manifestKey uniquely identifies a manifest for test lookup.
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
func (h *Handler) handleManifestGet(w http.ResponseWriter, r *http.Request, repo, reference string) {
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
type tagListResponse struct {
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/storage"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/storage"
|
||||
)
|
||||
|
||||
// uploadManager tracks in-progress blob writers by UUID.
|
||||
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/storage"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/storage"
|
||||
)
|
||||
|
||||
// testHandlerWithStorage creates a handler with real storage in t.TempDir().
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
)
|
||||
|
||||
type adminErrorResponse struct {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
)
|
||||
|
||||
// AdminListAuditHandler handles GET /v1/audit.
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
)
|
||||
|
||||
func TestAdminListAuditEvents(t *testing.T) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
)
|
||||
|
||||
func TestAdminHealthHandler(t *testing.T) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/gc"
|
||||
"git.wntrmute.dev/mc/mcr/internal/gc"
|
||||
)
|
||||
|
||||
// GCLastRun records the result of the last GC run.
|
||||
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
// PolicyReloader can reload policy rules from a store.
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
)
|
||||
|
||||
func TestAdminPolicyCRUDCycle(t *testing.T) {
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
)
|
||||
|
||||
// AdminListReposHandler handles GET /v1/repositories.
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
)
|
||||
|
||||
// seedRepoForAdmin inserts a repository with a manifest and tags into the test DB.
|
||||
|
||||
@@ -3,7 +3,7 @@ package server
|
||||
import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
)
|
||||
|
||||
// AdminDeps holds the dependencies needed by admin routes.
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/db"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/db"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
func openAdminTestDB(t *testing.T) *db.DB {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
)
|
||||
|
||||
// TokenValidator abstracts token validation so the middleware can work
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
)
|
||||
|
||||
type fakeValidator struct {
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
// PolicyEvaluator abstracts the policy engine for testability.
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/kyle/mcr/internal/policy"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/policy"
|
||||
)
|
||||
|
||||
type fakePolicyEvaluator struct {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
)
|
||||
|
||||
func TestRoutesV2Authenticated(t *testing.T) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/internal/auth"
|
||||
"git.wntrmute.dev/mc/mcr/internal/auth"
|
||||
)
|
||||
|
||||
type fakeLoginClient struct {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/hex"
|
||||
"log"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -93,6 +94,31 @@ func (s *Server) handleLoginSubmit(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Validate the token to check roles. Guest accounts are not
|
||||
// permitted to use the web interface.
|
||||
roles, err := s.validateFn(token)
|
||||
if err != nil {
|
||||
log.Printf("login token validation failed for user %q: %v", username, err)
|
||||
csrf := s.generateCSRFToken(w)
|
||||
s.templates.render(w, "login", map[string]any{
|
||||
"Error": "Login failed. Please try again.",
|
||||
"CSRFToken": csrf,
|
||||
"Session": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if slices.Contains(roles, "guest") {
|
||||
log.Printf("login denied for guest user %q", username)
|
||||
csrf := s.generateCSRFToken(w)
|
||||
s.templates.render(w, "login", map[string]any{
|
||||
"Error": "Guest accounts are not permitted to access the web interface.",
|
||||
"CSRFToken": csrf,
|
||||
"Session": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "mcr_session",
|
||||
Value: token,
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
mcrv1 "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
mcrv1 "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
@@ -14,23 +14,27 @@ import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
|
||||
mcrv1 "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/kyle/mcr/web"
|
||||
mcrv1 "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
"git.wntrmute.dev/mc/mcr/web"
|
||||
)
|
||||
|
||||
// LoginFunc authenticates a user and returns a bearer token.
|
||||
type LoginFunc func(username, password string) (token string, expiresIn int, err error)
|
||||
|
||||
// ValidateFunc validates a bearer token and returns the user's roles.
|
||||
type ValidateFunc func(token string) (roles []string, err error)
|
||||
|
||||
// Server is the MCR web UI server.
|
||||
type Server struct {
|
||||
router chi.Router
|
||||
templates *templateSet
|
||||
registry mcrv1.RegistryServiceClient
|
||||
policy mcrv1.PolicyServiceClient
|
||||
audit mcrv1.AuditServiceClient
|
||||
admin mcrv1.AdminServiceClient
|
||||
loginFn LoginFunc
|
||||
csrfKey []byte // 32-byte key for HMAC signing
|
||||
router chi.Router
|
||||
templates *templateSet
|
||||
registry mcrv1.RegistryServiceClient
|
||||
policy mcrv1.PolicyServiceClient
|
||||
audit mcrv1.AuditServiceClient
|
||||
admin mcrv1.AdminServiceClient
|
||||
loginFn LoginFunc
|
||||
validateFn ValidateFunc
|
||||
csrfKey []byte // 32-byte key for HMAC signing
|
||||
}
|
||||
|
||||
// New creates a new web UI server with the given gRPC clients and login function.
|
||||
@@ -40,6 +44,7 @@ func New(
|
||||
audit mcrv1.AuditServiceClient,
|
||||
admin mcrv1.AdminServiceClient,
|
||||
loginFn LoginFunc,
|
||||
validateFn ValidateFunc,
|
||||
csrfKey []byte,
|
||||
) (*Server, error) {
|
||||
tmpl, err := loadTemplates()
|
||||
@@ -48,13 +53,14 @@ func New(
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
templates: tmpl,
|
||||
registry: registry,
|
||||
policy: policy,
|
||||
audit: audit,
|
||||
admin: admin,
|
||||
loginFn: loginFn,
|
||||
csrfKey: csrfKey,
|
||||
templates: tmpl,
|
||||
registry: registry,
|
||||
policy: policy,
|
||||
audit: audit,
|
||||
admin: admin,
|
||||
loginFn: loginFn,
|
||||
validateFn: validateFn,
|
||||
csrfKey: csrfKey,
|
||||
}
|
||||
|
||||
s.router = s.buildRouter()
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
mcrv1 "git.wntrmute.dev/kyle/mcr/gen/mcr/v1"
|
||||
mcrv1 "git.wntrmute.dev/mc/mcr/gen/mcr/v1"
|
||||
)
|
||||
|
||||
// fakeRegistryService implements RegistryServiceServer for testing.
|
||||
@@ -183,15 +183,35 @@ func setupTestEnv(t *testing.T) *testEnv {
|
||||
if username == "admin" && password == "secret" {
|
||||
return "test-token-12345", 3600, nil
|
||||
}
|
||||
if username == "guest" && password == "secret" {
|
||||
return "test-token-guest", 3600, nil
|
||||
}
|
||||
if username == "user" && password == "secret" {
|
||||
return "test-token-user", 3600, nil
|
||||
}
|
||||
return "", 0, fmt.Errorf("invalid credentials")
|
||||
}
|
||||
|
||||
validateFn := func(token string) ([]string, error) {
|
||||
switch token {
|
||||
case "test-token-12345":
|
||||
return []string{"admin"}, nil
|
||||
case "test-token-guest":
|
||||
return []string{"guest"}, nil
|
||||
case "test-token-user":
|
||||
return []string{"user"}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
}
|
||||
}
|
||||
|
||||
srv, err := New(
|
||||
mcrv1.NewRegistryServiceClient(conn),
|
||||
mcrv1.NewPolicyServiceClient(conn),
|
||||
mcrv1.NewAuditServiceClient(conn),
|
||||
mcrv1.NewAdminServiceClient(conn),
|
||||
loginFn,
|
||||
validateFn,
|
||||
csrfKey,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -543,6 +563,59 @@ func TestTruncate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoginDeniesGuest(t *testing.T) {
|
||||
env := setupTestEnv(t)
|
||||
defer env.close()
|
||||
|
||||
// Get CSRF token.
|
||||
getReq := httptest.NewRequest(http.MethodGet, "/login", nil)
|
||||
getRec := httptest.NewRecorder()
|
||||
env.server.Handler().ServeHTTP(getRec, getReq)
|
||||
|
||||
var csrfCookie *http.Cookie
|
||||
for _, c := range getRec.Result().Cookies() {
|
||||
if c.Name == "csrf_token" {
|
||||
csrfCookie = c
|
||||
break
|
||||
}
|
||||
}
|
||||
if csrfCookie == nil {
|
||||
t.Fatal("no csrf_token cookie")
|
||||
}
|
||||
|
||||
parts := strings.SplitN(csrfCookie.Value, ".", 2)
|
||||
csrfToken := parts[0]
|
||||
|
||||
form := url.Values{
|
||||
"username": {"guest"},
|
||||
"password": {"secret"},
|
||||
"_csrf": {csrfToken},
|
||||
}
|
||||
|
||||
postReq := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader(form.Encode()))
|
||||
postReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
postReq.AddCookie(csrfCookie)
|
||||
postRec := httptest.NewRecorder()
|
||||
|
||||
env.server.Handler().ServeHTTP(postRec, postReq)
|
||||
|
||||
if postRec.Code != http.StatusOK {
|
||||
t.Fatalf("POST /login as guest: status %d, want %d", postRec.Code, http.StatusOK)
|
||||
}
|
||||
|
||||
body := postRec.Body.String()
|
||||
if !strings.Contains(body, "Guest accounts are not permitted") {
|
||||
t.Error("response does not contain guest denial message")
|
||||
}
|
||||
|
||||
// Verify no session cookie was set.
|
||||
for _, c := range postRec.Result().Cookies() {
|
||||
if c.Name == "mcr_session" {
|
||||
t.Error("session cookie should not be set for guest login")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoginSuccessSetsCookie(t *testing.T) {
|
||||
env := setupTestEnv(t)
|
||||
defer env.close()
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcr/web"
|
||||
"git.wntrmute.dev/mc/mcr/web"
|
||||
)
|
||||
|
||||
// templateSet wraps parsed templates and provides a render method.
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
option go_package = "git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
service AdminService {
|
||||
rpc Health(HealthRequest) returns (HealthResponse);
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
option go_package = "git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
import "mcr/v1/common.proto";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
option go_package = "git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
// Pagination controls for list RPCs.
|
||||
message PaginationRequest {
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
option go_package = "git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
import "mcr/v1/common.proto";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
option go_package = "git.wntrmute.dev/mc/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
import "mcr/v1/common.proto";
|
||||
|
||||
@@ -25,6 +25,7 @@ message RepositoryMetadata {
|
||||
message TagInfo {
|
||||
string name = 1;
|
||||
string digest = 2;
|
||||
string updated_at = 3;
|
||||
}
|
||||
|
||||
message ManifestInfo {
|
||||
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcdsl/auth"
|
||||
"git.wntrmute.dev/mc/mcdsl/auth"
|
||||
)
|
||||
|
||||
// Base contains the configuration sections common to all Metacircular
|
||||
@@ -144,6 +144,8 @@ func Load[T any](path string, envPrefix string) (*T, error) {
|
||||
applyEnvToStruct(reflect.ValueOf(&cfg).Elem(), envPrefix)
|
||||
}
|
||||
|
||||
applyPortEnv(&cfg)
|
||||
|
||||
applyBaseDefaults(&cfg)
|
||||
|
||||
if err := validateBase(&cfg); err != nil {
|
||||
@@ -239,6 +241,70 @@ func findBase(cfg any) *Base {
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyPortEnv overrides ServerConfig.ListenAddr and ServerConfig.GRPCAddr
|
||||
// from $PORT and $PORT_GRPC respectively. These environment variables are
|
||||
// set by the MCP agent to assign authoritative port bindings, so they take
|
||||
// precedence over both TOML values and generic env overrides.
|
||||
func applyPortEnv(cfg any) {
|
||||
sc := findServerConfig(cfg)
|
||||
if sc == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if port, ok := os.LookupEnv("PORT"); ok {
|
||||
sc.ListenAddr = ":" + port
|
||||
}
|
||||
if port, ok := os.LookupEnv("PORT_GRPC"); ok {
|
||||
sc.GRPCAddr = ":" + port
|
||||
}
|
||||
}
|
||||
|
||||
// findServerConfig returns a pointer to the ServerConfig in the config
|
||||
// struct. It first checks for an embedded Base (which contains Server),
|
||||
// then walks the struct tree via reflection to find any ServerConfig field
|
||||
// directly (e.g., the Metacrypt pattern where ServerConfig is embedded
|
||||
// without Base).
|
||||
func findServerConfig(cfg any) *ServerConfig {
|
||||
if base := findBase(cfg); base != nil {
|
||||
return &base.Server
|
||||
}
|
||||
|
||||
return findServerConfigReflect(reflect.ValueOf(cfg))
|
||||
}
|
||||
|
||||
// findServerConfigReflect walks the struct tree to find a ServerConfig field.
|
||||
func findServerConfigReflect(v reflect.Value) *ServerConfig {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil
|
||||
}
|
||||
|
||||
scType := reflect.TypeOf(ServerConfig{})
|
||||
t := v.Type()
|
||||
for i := range t.NumField() {
|
||||
field := t.Field(i)
|
||||
fv := v.Field(i)
|
||||
|
||||
if field.Type == scType {
|
||||
sc, ok := fv.Addr().Interface().(*ServerConfig)
|
||||
if ok {
|
||||
return sc
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse into embedded or nested structs.
|
||||
if fv.Kind() == reflect.Struct && field.Type != scType {
|
||||
if sc := findServerConfigReflect(fv); sc != nil {
|
||||
return sc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyEnvToStruct recursively walks a struct and overrides field values
|
||||
// from environment variables. The env variable name is built from the
|
||||
// prefix and the toml tag: PREFIX_SECTION_FIELD (uppercased).
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"git.wntrmute.dev/kyle/mcdsl/auth"
|
||||
"git.wntrmute.dev/mc/mcdsl/auth"
|
||||
)
|
||||
|
||||
// MethodMap classifies gRPC methods for access control.
|
||||
@@ -48,21 +48,45 @@ type Server struct {
|
||||
listener net.Listener
|
||||
}
|
||||
|
||||
// Options configures optional behavior for the gRPC server.
|
||||
type Options struct {
|
||||
// PreInterceptors run before the logging and auth interceptors.
|
||||
// Use for lifecycle gates like seal checks that should reject
|
||||
// requests before any auth validation occurs.
|
||||
PreInterceptors []grpc.UnaryServerInterceptor
|
||||
|
||||
// PostInterceptors run after auth but before the handler.
|
||||
// Use for audit logging, rate limiting, or other cross-cutting
|
||||
// concerns that need access to the authenticated identity.
|
||||
PostInterceptors []grpc.UnaryServerInterceptor
|
||||
}
|
||||
|
||||
// New creates a gRPC server with TLS (if certFile and keyFile are
|
||||
// non-empty) and an interceptor chain: logging → auth → handler.
|
||||
// non-empty) and an interceptor chain:
|
||||
//
|
||||
// [pre-interceptors] → logging → auth → [post-interceptors] → handler
|
||||
//
|
||||
// The auth interceptor uses methods to determine the access level for
|
||||
// each RPC. Methods not in any map are denied by default.
|
||||
//
|
||||
// If certFile and keyFile are empty, TLS is skipped (for testing).
|
||||
func New(certFile, keyFile string, authenticator *auth.Authenticator, methods MethodMap, logger *slog.Logger) (*Server, error) {
|
||||
chain := grpc.ChainUnaryInterceptor(
|
||||
// opts is optional; pass nil for the default chain (logging + auth only).
|
||||
func New(certFile, keyFile string, authenticator *auth.Authenticator, methods MethodMap, logger *slog.Logger, opts *Options) (*Server, error) {
|
||||
var interceptors []grpc.UnaryServerInterceptor
|
||||
if opts != nil {
|
||||
interceptors = append(interceptors, opts.PreInterceptors...)
|
||||
}
|
||||
interceptors = append(interceptors,
|
||||
loggingInterceptor(logger),
|
||||
authInterceptor(authenticator, methods),
|
||||
)
|
||||
if opts != nil {
|
||||
interceptors = append(interceptors, opts.PostInterceptors...)
|
||||
}
|
||||
chain := grpc.ChainUnaryInterceptor(interceptors...)
|
||||
|
||||
var opts []grpc.ServerOption
|
||||
opts = append(opts, chain)
|
||||
var serverOpts []grpc.ServerOption
|
||||
serverOpts = append(serverOpts, chain)
|
||||
|
||||
if certFile != "" && keyFile != "" {
|
||||
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
||||
@@ -73,11 +97,11 @@ func New(certFile, keyFile string, authenticator *auth.Authenticator, methods Me
|
||||
Certificates: []tls.Certificate{cert},
|
||||
MinVersion: tls.VersionTLS13,
|
||||
}
|
||||
opts = append(opts, grpc.Creds(credentials.NewTLS(tlsCfg)))
|
||||
serverOpts = append(serverOpts, grpc.Creds(credentials.NewTLS(tlsCfg)))
|
||||
}
|
||||
|
||||
return &Server{
|
||||
GRPCServer: grpc.NewServer(opts...),
|
||||
GRPCServer: grpc.NewServer(serverOpts...),
|
||||
Logger: logger,
|
||||
}, nil
|
||||
}
|
||||
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
@@ -1,9 +1,9 @@
|
||||
# git.wntrmute.dev/kyle/mcdsl v1.0.0
|
||||
# git.wntrmute.dev/mc/mcdsl v1.2.0
|
||||
## explicit; go 1.25.7
|
||||
git.wntrmute.dev/kyle/mcdsl/auth
|
||||
git.wntrmute.dev/kyle/mcdsl/config
|
||||
git.wntrmute.dev/kyle/mcdsl/db
|
||||
git.wntrmute.dev/kyle/mcdsl/grpcserver
|
||||
git.wntrmute.dev/mc/mcdsl/auth
|
||||
git.wntrmute.dev/mc/mcdsl/config
|
||||
git.wntrmute.dev/mc/mcdsl/db
|
||||
git.wntrmute.dev/mc/mcdsl/grpcserver
|
||||
# github.com/dustin/go-humanize v1.0.1
|
||||
## explicit; go 1.16
|
||||
github.com/dustin/go-humanize
|
||||
|
||||
Reference in New Issue
Block a user