feat(operator): 状态迁移、超时、自动重建、空闲停机与 RCON Secret 创建写 Event 和结构化日志,RBAC 增加 events create/patch
This commit is contained in:
5 files changed
+206
-9
No files matched your search
@@ -155,8 +155,9 @@ func APIBuildRole(p Params) *rbacv1.Role {
|
||||
// the operator checks that no restore/backup/file-write Job holds its world
|
||||
// (internal/maintenance). Pods are delete-only: a start that timed out is retried
|
||||
// by deleting its pod for the StatefulSet to recreate (bounded, three attempts;
|
||||
// internal/operator.recoverFailedStart). It never touches PVCs, Events, or
|
||||
// finalizers, so none appear here.
|
||||
// internal/operator.recoverFailedStart). Events are create/patch only, for the
|
||||
// timeline it records on each server. It never touches PVCs or finalizers, so
|
||||
// none appear here.
|
||||
func OperatorRole(p Params) *rbacv1.Role {
|
||||
p = p.withDefaults()
|
||||
return role(p.MinecraftNamespace, "felis-operator", ComponentOperator, []rbacv1.PolicyRule{
|
||||
@@ -177,6 +178,10 @@ func OperatorRole(p Params) *rbacv1.Role {
|
||||
// delete only, through the direct client: no read of pods is needed to
|
||||
// remove the one named <server>-0.
|
||||
rule([]string{groupCore}, []string{"pods"}, []string{"delete"}),
|
||||
// The Events the reconciler records on MinecraftServers (phase changes,
|
||||
// pod recreation, idle stop): the recorder creates one and patches its
|
||||
// count when the same Event repeats.
|
||||
rule([]string{groupCore}, []string{"events"}, []string{"create", "patch"}),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -189,9 +189,18 @@ func TestOperatorRole_ScopeExact(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// Hard exclusions.
|
||||
for _, res := range []string{"persistentvolumeclaims", "events"} {
|
||||
if grantsResource(op, groupCore, res) {
|
||||
t.Errorf("operator must NOT touch core/%s", res)
|
||||
if grantsResource(op, groupCore, "persistentvolumeclaims") {
|
||||
t.Error("operator must NOT touch core/persistentvolumeclaims")
|
||||
}
|
||||
// Events: the recorder creates one and patches its count on a repeat.
|
||||
for _, v := range []string{"create", "patch"} {
|
||||
if !hasRule(op, groupCore, "events", v) {
|
||||
t.Errorf("operator must have events:%s (the server timeline)", v)
|
||||
}
|
||||
}
|
||||
for _, v := range []string{"get", "list", "watch", "update", "delete", "deletecollection", "*"} {
|
||||
if hasRule(op, groupCore, "events", v) {
|
||||
t.Errorf("operator events rule must be create+patch only, found %s", v)
|
||||
}
|
||||
}
|
||||
// RCON Secrets are read by name through the uncached reader and created once;
|
||||
|
||||
Reference in new issue
Block a user