fix(panel): streamline system settings and server creation
Use shared action buttons and default to the login space. Allow staff to save startup-only experience settings while running and request a durable restart through the existing operator flow. Grant the API PVC list permission needed to detect retained worlds before server creation, and show internal failures with a request ID. Cover permission, maintenance, restart and UI behavior with regression checks.
This commit is contained in:
34 files changed
+555
-103
No files matched your search
@@ -90,8 +90,8 @@ func ControlPlaneRBAC(p Params) RBAC {
|
||||
// claim. felis-api reads the fleet (velocity's pull, the fleet page, the wake
|
||||
// cap) from an informer cache of minecraftservers, hence watch on that one
|
||||
// resource; everything else goes through a DIRECT client, so it needs no
|
||||
// list/watch beyond the explicit List calls — and the PVC grant is get-only,
|
||||
// mirroring that.
|
||||
// list/watch beyond the explicit List calls. PVC list finds retained world
|
||||
// volumes before creating a server of the same name.
|
||||
//
|
||||
// The read-side grant is deliberately minimal: pods:list + pods/log:get, NOT
|
||||
// pods:get — the streamer lists pods by the server label then reads the chosen
|
||||
@@ -103,9 +103,7 @@ func APIMinecraftRole(p Params) *rbacv1.Role {
|
||||
rules := []rbacv1.PolicyRule{
|
||||
rule([]string{groupFelis}, []string{"minecraftservers"}, []string{"get", "list", "watch", "create", "patch"}),
|
||||
rule([]string{groupCore}, []string{"secrets"}, []string{"get"}),
|
||||
// get-only: WorldVolumeExists does a single direct Get of the world PVC;
|
||||
// nothing in felis-api lists or deletes PVCs.
|
||||
rule([]string{groupCore}, []string{"persistentvolumeclaims"}, []string{"get"}),
|
||||
rule([]string{groupCore}, []string{"persistentvolumeclaims"}, []string{"get", "list"}),
|
||||
// list backs GET /servers/{name}/jobs — the async status outlet reads the
|
||||
// backup/restore Jobs back by the server label — and finds the pending
|
||||
// restore chains; patch settles a chain by relabelling its safety-snapshot
|
||||
|
||||
@@ -127,13 +127,15 @@ func TestAPIRole_MinecraftPowersExact(t *testing.T) {
|
||||
if hasRule(mc, groupCore, "secrets", "list") || hasRule(mc, groupCore, "secrets", "watch") {
|
||||
t.Error("felis-api must NOT list or watch secrets (RCON reads are a direct Get by name)")
|
||||
}
|
||||
// WorldVolumeExists (backup/restore pre-gate) does a single direct PVC Get;
|
||||
// nothing in felis-api lists or deletes claims.
|
||||
// WorldVolumeExists reads a claim and lists retained claims on server creation.
|
||||
if !hasRule(mc, groupCore, "persistentvolumeclaims", "get") {
|
||||
t.Error("felis-api must get the world PVC (persistentvolumeclaims:get) for the backup/restore world-volume gate")
|
||||
}
|
||||
if hasRule(mc, groupCore, "persistentvolumeclaims", "list") || hasRule(mc, groupCore, "persistentvolumeclaims", "delete") {
|
||||
t.Error("felis-api must NOT list or delete PVCs (the gate is a single direct Get)")
|
||||
if !hasRule(mc, groupCore, "persistentvolumeclaims", "list") {
|
||||
t.Error("felis-api must list retained PVCs before creating a server")
|
||||
}
|
||||
if hasRule(mc, groupCore, "persistentvolumeclaims", "watch") || hasRule(mc, groupCore, "persistentvolumeclaims", "delete") {
|
||||
t.Error("felis-api must NOT watch or delete PVCs")
|
||||
}
|
||||
// Read-side console (spec §8 读=pods/log follow): list pods to find the
|
||||
// running pod, then read its log subresource — and nothing wider.
|
||||
|
||||
Reference in new issue
Block a user