- Replace form_urlencoded with RFC 3986 compliant URI encoding - Implement aws_uri_encode() matching AWS SigV4 spec exactly - Unreserved chars (A-Z,a-z,0-9,-,_,.,~) not encoded - All other chars percent-encoded with uppercase hex - Preserve slashes in paths, encode in query params - Normalize empty paths to '/' per AWS spec - Fix test expectations (body hash, HMAC values) - Add comprehensive SigV4 signature determinism test This fixes the canonicalization mismatch that caused signature validation failures in T047. Auth can now be enabled for production. Refs: T058.S1
123 lines
4.9 KiB
YAML
123 lines
4.9 KiB
YAML
id: T045
|
|
name: Service Integration - CreditService Admission Control
|
|
goal: Enforce CreditService quota/billing controls across PlasmaVMC and k8shost
|
|
status: complete
|
|
completed: 2025-12-12 01:39 JST
|
|
priority: P1
|
|
owner: peerB
|
|
created: 2025-12-11
|
|
depends_on: [T042]
|
|
blocks: []
|
|
|
|
context: |
|
|
**Foreman Directive (2025-12-11):**
|
|
CreditService (T042) is complete but not enforced. PlasmaVMC and k8shost
|
|
do not yet check quotas before creating resources.
|
|
|
|
**Integration Pattern (2-Phase Commit):**
|
|
1. check_quota() - Validate balance/quota limits
|
|
2. reserve_credits() - Phase 1: Reserve credits with TTL
|
|
3. [Create Resource] - Actual resource creation
|
|
4. commit_reservation() - Phase 2: Deduct from wallet
|
|
5. release_reservation() - On failure: Release reserved credits
|
|
|
|
acceptance:
|
|
- PlasmaVMC create_vm enforces CreditService admission control
|
|
- Failed VM creation releases reserved credits (rollback)
|
|
- Integration test validates end-to-end flow
|
|
- (Optional) k8shost Pod creation integrates CreditService
|
|
|
|
steps:
|
|
- step: S1
|
|
name: PlasmaVMC CreditService Client Integration
|
|
done: Add creditservice-client dependency, wire into VmServiceImpl
|
|
status: complete
|
|
owner: peerB
|
|
priority: P0
|
|
notes: |
|
|
Files modified:
|
|
- plasmavmc/crates/plasmavmc-server/Cargo.toml (line 35)
|
|
- plasmavmc/crates/plasmavmc-server/src/vm_service.rs (lines 5, 38, 106-124)
|
|
outputs:
|
|
- path: plasmavmc/crates/plasmavmc-server/src/vm_service.rs
|
|
note: CreditService client integration
|
|
|
|
- step: S2
|
|
name: create_vm 2-Phase Commit
|
|
done: Wrap create_vm with reserve→create→commit/release flow
|
|
status: complete
|
|
owner: peerB
|
|
priority: P0
|
|
notes: |
|
|
Implementation at vm_service.rs:586-667:
|
|
- Phase 0: check_quota() validates balance/quota limits (lines 594-606)
|
|
- Phase 1: reserve_credits() with TTL (lines 609-629)
|
|
- VM creation (lines 634-648)
|
|
- Rollback on failure: release_reservation (lines 637-646)
|
|
- Phase 2: commit_reservation on success (lines 654-667)
|
|
outputs:
|
|
- path: plasmavmc/crates/plasmavmc-server/src/vm_service.rs
|
|
note: 2-phase commit implementation (~80L)
|
|
|
|
- step: S3
|
|
name: Integration Test
|
|
done: E2E test validates admission control flow
|
|
status: complete
|
|
owner: peerB
|
|
priority: P0
|
|
outputs:
|
|
- path: plasmavmc/crates/plasmavmc-server/tests/creditservice_integration.rs
|
|
note: 3 tests - deny (insufficient balance), allow (sufficient), smoke (client API)
|
|
notes: |
|
|
Tests:
|
|
- creditservice_admission_control_deny: Tests denial with 0 balance
|
|
- creditservice_admission_control_allow: Tests full E2E with VM creation
|
|
- creditservice_client_integration_smoke: Tests client API (no QEMU needed)
|
|
|
|
- step: S4
|
|
name: k8shost Integration
|
|
done: Pod creation checks CreditService quotas
|
|
status: complete
|
|
completed: 2025-12-12 01:39 JST
|
|
owner: peerB
|
|
priority: P1
|
|
notes: |
|
|
**COMPLETED 2025-12-12 (Unblocked after T041 resolution)**
|
|
|
|
Implementation (k8shost/crates/k8shost-server/src/services/pod.rs):
|
|
- Added credit_service field to PodServiceImpl
|
|
- Implemented new_with_credit_service() constructor (CREDITSERVICE_ENDPOINT env var)
|
|
- Added Pod cost calculation: calculate_pod_cost(), parse_cpu(), parse_memory()
|
|
- 2-phase commit in create_pod() (lines 338-424):
|
|
* Phase 0: check_quota(ResourceType::K8sNode)
|
|
* Phase 1: reserve_credits("PodInstance", 300s TTL)
|
|
* Create: storage.put_pod()
|
|
* Rollback: release_reservation on failure
|
|
* Phase 2: commit_reservation on success
|
|
- Pricing: 10 credits/vCPU + 5 credits/GB (same as PlasmaVMC)
|
|
|
|
Tests (k8shost/crates/k8shost-server/tests/creditservice_pod_integration.rs):
|
|
- 3 tests (363L): deny, allow, smoke
|
|
- Smoke test passing: ✓ 0.11s
|
|
|
|
Pattern consistent with PlasmaVMC vm_service.rs:586-667
|
|
|
|
evidence:
|
|
- cmd: "cargo test --test creditservice_integration creditservice_client_integration_smoke"
|
|
result: "1 passed; 0 failed (PlasmaVMC)"
|
|
- cmd: "cargo test --package k8shost-server --test creditservice_pod_integration creditservice_pod_client_integration_smoke"
|
|
result: "1 passed; 0 failed; 0 ignored; 2 filtered out; finished in 0.11s (k8shost)"
|
|
- cmd: "cargo check --package k8shost-server"
|
|
result: "Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.41s"
|
|
notes: |
|
|
**T045 COMPLETE (2025-12-12) by PeerB:**
|
|
- S1-S3: PlasmaVMC CreditService integration (2025-12-11)
|
|
- S4: k8shost CreditService integration (2025-12-12, unblocked after T041)
|
|
- Total: ~763L implementation + tests
|
|
- Pattern consistent across PlasmaVMC and k8shost
|
|
|
|
**Implementation Pattern:**
|
|
- CREDITSERVICE_ENDPOINT env var enables admission control
|
|
- Simple pricing: vcpus * 10 + memory_gb * 5
|
|
- Graceful degradation: if CreditService unavailable, continues without quota check
|
|
- 2-phase commit: check_quota → reserve → create → commit/rollback
|