Skip to content
This repository was archived by the owner on Mar 10, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions manager/domain/enums.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const (
PermissionRead PermissionKey = "permission.read"
ScheduleStrategyCreate PermissionKey = "schedule_strategy.create"
ScheduleStrategyRead PermissionKey = "schedule_strategy.read"
ScheduleStrategyUpdate PermissionKey = "schedule_strategy.update"
ScheduleStrategyDelete PermissionKey = "schedule_strategy.delete"
ScheduleIntentRead PermissionKey = "schedule_intent.read"
ScheduleIntentDelete PermissionKey = "schedule_intent.delete"
Expand Down
2 changes: 2 additions & 0 deletions manager/domain/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type Repository interface {
BatchUpdateIntentsState(ctx context.Context, intentIDs []bson.ObjectID, newState IntentState) error
QueryStrategies(ctx context.Context, opt *QueryStrategyOptions) error
QueryIntents(ctx context.Context, opt *QueryIntentOptions) error
UpdateStrategy(ctx context.Context, strategyID bson.ObjectID, update bson.M) error
DeleteStrategy(ctx context.Context, strategyID bson.ObjectID) error
DeleteIntents(ctx context.Context, intentIDs []bson.ObjectID) error
DeleteIntentsByStrategyID(ctx context.Context, strategyID bson.ObjectID) error
Expand All @@ -91,6 +92,7 @@ type Service interface {
CreateScheduleStrategy(ctx context.Context, operator *Claims, strategy *ScheduleStrategy) error
ListScheduleStrategies(ctx context.Context, filterOpts *QueryStrategyOptions) error
ListScheduleIntents(ctx context.Context, filterOpts *QueryIntentOptions) error
UpdateScheduleStrategy(ctx context.Context, operator *Claims, strategyID string, strategy *ScheduleStrategy) error
DeleteScheduleStrategy(ctx context.Context, operator *Claims, strategyID string) error
DeleteScheduleIntents(ctx context.Context, operator *Claims, intentIDs []string) error
GetPodPIDMapping(ctx context.Context, nodeID string) (*PodPIDMappingResponse, error)
Expand Down
132 changes: 132 additions & 0 deletions manager/domain/mock_domain.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[
{
"update": "roles",
"updates": [
{
"q": { "name": "admin" },
"u": {
"$pull": {
"policies": { "permissionKey": "schedule_strategy.update" }
}
}
}
]
},
{
"delete": "permissions",
"deletes": [
{
"q": { "key": "schedule_strategy.update" },
"limit": 1
}
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[
{
"insert": "permissions",
"documents": [
{
"key": "schedule_strategy.update",
"resource": "schedule_strategy",
"action": "update",
"description": "Update schedule strategies"
}
]
},
{
"update": "roles",
"updates": [
{
"q": { "name": "admin" },
"u": {
"$push": {
"policies": { "permissionKey": "schedule_strategy.update", "self": false }
}
}
}
]
}
]
8 changes: 8 additions & 0 deletions manager/repository/strategy_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ func (r *repo) DeleteStrategy(ctx context.Context, strategyID bson.ObjectID) err
return err
}

func (r *repo) UpdateStrategy(ctx context.Context, strategyID bson.ObjectID, update bson.M) error {
if update == nil {
return errors.New("nil update")
}
_, err := r.db.Collection(scheduleStrategyCollection).UpdateOne(ctx, bson.M{"_id": strategyID}, update)
return err
}
Comment on lines +161 to +167
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UpdateStrategy repository method doesn't validate that the update was successful. Unlike UpdateUser in repo_rbac.go which checks res.MatchedCount == 0 and returns domain.ErrNotFound, this method doesn't verify whether any document was actually modified. This could silently fail if the strategyID doesn't exist in the database (though the service layer does pre-validate).

Copilot uses AI. Check for mistakes.

func (r *repo) DeleteIntents(ctx context.Context, intentIDs []bson.ObjectID) error {
if len(intentIDs) == 0 {
return nil
Expand Down
1 change: 1 addition & 0 deletions manager/rest/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func (h *Handler) SetupRoutes(engine *echo.Echo) {

// strategy routes
apiV1.POST("/strategies", h.echoHandler(h.CreateScheduleStrategy), echo.WrapMiddleware(h.GetAuthMiddleware(domain.ScheduleStrategyCreate)))
apiV1.PUT("/strategies", h.echoHandler(h.UpdateScheduleStrategy), echo.WrapMiddleware(h.GetAuthMiddleware(domain.ScheduleStrategyUpdate)))
apiV1.GET("/strategies/self", h.echoHandler(h.ListSelfScheduleStrategies), echo.WrapMiddleware(h.GetAuthMiddleware(domain.ScheduleStrategyRead)))
apiV1.DELETE("/strategies", h.echoHandler(h.DeleteScheduleStrategy), echo.WrapMiddleware(h.GetAuthMiddleware(domain.ScheduleStrategyDelete)))
apiV1.GET("/intents/self", h.echoHandler(h.ListSelfScheduleIntents), echo.WrapMiddleware(h.GetAuthMiddleware(domain.ScheduleIntentRead)))
Expand Down
67 changes: 67 additions & 0 deletions manager/rest/strategy_hdl.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ type CreateScheduleStrategyRequest struct {
ExecutionTime int64 `json:"executionTime,omitempty"`
}

type UpdateScheduleStrategyRequest struct {
StrategyID string `json:"strategyId"`
StrategyNamespace string `json:"strategyNamespace,omitempty"`
LabelSelectors []LabelSelector `json:"labelSelectors,omitempty"`
K8sNamespace []string `json:"k8sNamespace,omitempty"`
CommandRegex string `json:"commandRegex,omitempty"`
Priority int `json:"priority,omitempty"`
ExecutionTime int64 `json:"executionTime,omitempty"`
}

// CreateScheduleStrategy godoc
// @Summary Create schedule strategy
// @Description Create a new schedule strategy.
Expand Down Expand Up @@ -75,6 +85,63 @@ func (h *Handler) CreateScheduleStrategy(w http.ResponseWriter, r *http.Request)
h.JSONResponse(ctx, w, http.StatusOK, response)
}

// UpdateScheduleStrategy godoc
// @Summary Update schedule strategy
// @Description Update an existing schedule strategy.
// @Tags Strategies
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body UpdateScheduleStrategyRequest true "Schedule strategy payload"
// @Success 200 {object} SuccessResponse[EmptyResponse]
// @Failure 400 {object} ErrorResponse
// @Failure 401 {object} ErrorResponse
// @Failure 403 {object} ErrorResponse
// @Failure 404 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /api/v1/strategies [put]
func (h *Handler) UpdateScheduleStrategy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req UpdateScheduleStrategyRequest
if err := h.JSONBind(r, &req); err != nil {
h.ErrorResponse(ctx, w, http.StatusBadRequest, "Invalid request body", err)
return
}
if req.StrategyID == "" {
h.ErrorResponse(ctx, w, http.StatusBadRequest, "Strategy ID is required", nil)
return
}

strategy := &domain.ScheduleStrategy{
StrategyNamespace: req.StrategyNamespace,
LabelSelectors: make([]domain.LabelSelector, len(req.LabelSelectors)),
K8sNamespace: req.K8sNamespace,
CommandRegex: req.CommandRegex,
Priority: req.Priority,
ExecutionTime: req.ExecutionTime,
}
for i, ls := range req.LabelSelectors {
strategy.LabelSelectors[i] = domain.LabelSelector{
Key: ls.Key,
Value: ls.Value,
}
}

claims, ok := h.GetClaimsFromContext(ctx)
if !ok {
h.ErrorResponse(ctx, w, http.StatusUnauthorized, "Unauthorized", nil)
return
}

if err := h.Svc.UpdateScheduleStrategy(ctx, &claims, req.StrategyID, strategy); err != nil {
h.HandleError(ctx, w, err)
return
}

response := NewSuccessResponse[string](nil)
h.JSONResponse(ctx, w, http.StatusOK, response)
}

type ListSchedulerStrategiesResponse struct {
Strategies []*ScheduleStrategy `json:"strategies"`
}
Expand Down
Loading