Skip to content

Commit 944134f

Browse files
committed
HYPERFLEET-971 - feat: reject nodepool create/patch on soft-deleted cluster
1 parent 1d45541 commit 944134f

3 files changed

Lines changed: 349 additions & 8 deletions

File tree

pkg/errors/errors.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const (
5252
// Conflict errors (CNF) - 409
5353
CodeConflictExists = "HYPERFLEET-CNF-001"
5454
CodeConflictVersion = "HYPERFLEET-CNF-002"
55+
CodeConflictState = "HYPERFLEET-CNF-003"
5556

5657
// Rate Limit errors (LMT) - 429
5758
CodeRateLimitExceeded = "HYPERFLEET-LMT-001"
@@ -166,6 +167,10 @@ var errorDefinitions = map[string]errorDefinition{
166167
CodeConflictVersion: {
167168
ErrorTypeConflict, "Version Conflict", "The resource version does not match", http.StatusConflict,
168169
},
170+
CodeConflictState: {
171+
ErrorTypeConflict, "State Conflict",
172+
"Operation not allowed in current resource state", http.StatusConflict,
173+
},
169174

170175
// Rate Limit errors (LMT) - 429
171176
CodeRateLimitExceeded: {
@@ -363,6 +368,10 @@ func Conflict(reason string, values ...interface{}) *ServiceError {
363368
return New(CodeConflictExists, reason, values...)
364369
}
365370

371+
func ConflictState(reason string, values ...interface{}) *ServiceError {
372+
return New(CodeConflictState, reason, values...)
373+
}
374+
366375
func Validation(reason string, values ...interface{}) *ServiceError {
367376
return New(CodeValidationMultiple, reason, values...)
368377
}

pkg/handlers/cluster_nodepools.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,15 @@ func (h ClusterNodePoolsHandler) Patch(w http.ResponseWriter, r *http.Request) {
190190
clusterID := mux.Vars(r)["id"]
191191
nodePoolID := mux.Vars(r)["nodepool_id"]
192192

193-
_, err := h.clusterService.Get(ctx, clusterID)
193+
cluster, err := h.clusterService.Get(ctx, clusterID)
194194
if err != nil {
195195
return nil, err
196196
}
197197

198+
if cluster.DeletedTime != nil {
199+
return nil, errors.ConflictState("Cluster '%s' is marked for deletion", clusterID)
200+
}
201+
198202
found, err := h.nodePoolService.Get(ctx, nodePoolID)
199203
if err != nil {
200204
return nil, err
@@ -204,6 +208,10 @@ func (h ClusterNodePoolsHandler) Patch(w http.ResponseWriter, r *http.Request) {
204208
return nil, errors.NotFound("NodePool '%s' not found for cluster '%s'", nodePoolID, clusterID)
205209
}
206210

211+
if found.DeletedTime != nil {
212+
return nil, errors.ConflictState("NodePool '%s' is marked for deletion", nodePoolID)
213+
}
214+
207215
if patch.Spec != nil {
208216
specJSON, jsonErr := json.Marshal(*patch.Spec)
209217
if jsonErr != nil {
@@ -258,6 +266,10 @@ func (h ClusterNodePoolsHandler) Create(w http.ResponseWriter, r *http.Request)
258266
return nil, err
259267
}
260268

269+
if cluster.DeletedTime != nil {
270+
return nil, errors.ConflictState("Cluster '%s' is marked for deletion", clusterID)
271+
}
272+
261273
// Use the presenters.ConvertNodePool helper to convert the request
262274
nodePoolModel, convErr := presenters.ConvertNodePool(&req, cluster.ID, "system@hyperfleet.local")
263275
if convErr != nil {

0 commit comments

Comments
 (0)