Skip to content

Commit

Permalink
feat: use spec from run II
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe committed Sep 23, 2024
1 parent c147825 commit d4c332c
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 42 deletions.
13 changes: 13 additions & 0 deletions db/playbooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ func FindPlaybooksForEvent(ctx context.Context, eventClass, event string) ([]mod
return playbooks, nil
}

func FindPlaybookRun(ctx context.Context, id uuid.UUID) (*models.PlaybookRun, error) {
var p models.PlaybookRun
if err := ctx.DB().Where("id = ?", id).First(&p).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}

return nil, err
}

return &p, nil
}

func FindPlaybook(ctx context.Context, id uuid.UUID) (*models.Playbook, error) {
var p models.Playbook
if err := ctx.DB().Where("id = ?", id).First(&p).Error; err != nil {
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/containrrr/shoutrrr v0.8.0
github.com/fergusstrange/embedded-postgres v1.25.0 // indirect
github.com/flanksource/commons v1.29.10
github.com/flanksource/duty v1.0.666
github.com/flanksource/duty v1.0.667
github.com/flanksource/gomplate/v3 v3.24.32
github.com/flanksource/kopper v1.0.10
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2
Expand Down Expand Up @@ -359,6 +359,6 @@ require (

// replace github.com/flanksource/commons => /Users/moshe/go/src/github.com/flanksource/commons

replace github.com/flanksource/duty => ../duty
// replace github.com/flanksource/duty => ../duty

// replace github.com/flanksource/gomplate/v3 => /Users/moshe/go/src/github.com/flanksource/gomplate
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -877,8 +877,8 @@ github.com/flanksource/artifacts v1.0.14 h1:Vv70bccsae0MwGaf/uSPp34J5V1/PyKfct9z
github.com/flanksource/artifacts v1.0.14/go.mod h1:qHVCnQu5k50aWNJ5UhpcAKEl7pAzqUrFFKGSm147G70=
github.com/flanksource/commons v1.29.10 h1:T/S95Pl8kASEFvQjQ7fJjTUqeVdhxQXg1vfkULTYFJQ=
github.com/flanksource/commons v1.29.10/go.mod h1:iTbrXOSp3Spv570Nly97D/U9cQjLZoVlmWCXqWzsvRU=
github.com/flanksource/duty v1.0.666 h1:doJ1OBKXHtb9Tlslh/LO7PSoVuqsl4R6B9cuGP+2CWw=
github.com/flanksource/duty v1.0.666/go.mod h1:/dIt7bXnQlVtVikTu1TY1syEcuGCSUBnKyKlxVR5sDw=
github.com/flanksource/duty v1.0.667 h1:um6ppCnvQF3roIduY1n6S9uPv/YkEEicPhzeFBbDzck=
github.com/flanksource/duty v1.0.667/go.mod h1:/dIt7bXnQlVtVikTu1TY1syEcuGCSUBnKyKlxVR5sDw=
github.com/flanksource/gomplate/v3 v3.20.4/go.mod h1:27BNWhzzSjDed1z8YShO6W+z6G9oZXuxfNFGd/iGSdc=
github.com/flanksource/gomplate/v3 v3.24.32 h1:MILauVcjIqBit4nXB5UCN/LZ2z+fiMb8n1Klwjci1Tg=
github.com/flanksource/gomplate/v3 v3.24.32/go.mod h1:FdQHxnyrBSmT5zNJTDq08oXxD+eOqti4ERanSoDmQAU=
Expand Down
48 changes: 21 additions & 27 deletions playbook/approval.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package playbook

import (
"encoding/json"
"net/http"

"github.com/flanksource/commons/collections"
Expand All @@ -19,52 +20,45 @@ func HandlePlaybookRunApproval(c echo.Context) error {
ctx := c.Request().Context().(context.Context)

var (
playbookID = c.Param("playbook_id")
runID = c.Param("run_id")
runID = c.Param("run_id")
)

playbookUUID, err := uuid.Parse(playbookID)
if err != nil {
return c.JSON(http.StatusBadRequest, dutyAPI.HTTPError{Err: err.Error(), Message: "invalid playbook id"})
}

runUUID, err := uuid.Parse(runID)
if err != nil {
return c.JSON(http.StatusBadRequest, dutyAPI.HTTPError{Err: err.Error(), Message: "invalid run id"})
}

if err := ApproveRun(ctx, playbookUUID, runUUID); err != nil {
if err := ApproveRun(ctx, runUUID); err != nil {
return dutyAPI.WriteError(c, err)
}

return c.JSON(http.StatusOK, dutyAPI.HTTPSuccess{Message: "playbook run approved"})
}

func ApproveRun(ctx context.Context, playbookID, runID uuid.UUID) error {
playbook, err := db.FindPlaybook(ctx, playbookID)
func ApproveRun(ctx context.Context, runID uuid.UUID) error {
run, err := db.FindPlaybookRun(ctx, runID)
if err != nil {
return api.Errorf(api.EINTERNAL, "something went wrong while finding playbook(id=%s)", playbookID).WithDebugInfo("db.FindPlaybook(id=%s): %v", playbookID, err)
} else if playbook == nil {
return api.Errorf(api.ENOTFOUND, "playbook(id=%s) not found", playbookID)
return api.Errorf(api.EINTERNAL, "something went wrong while finding run (id=%s)", runID).WithDebugInfo("db.FindPlaybookRun(id=%s): %v", runID, err)
} else if run == nil {
return api.Errorf(api.ENOTFOUND, "playbook run (id=%s) not found", runID)
}

return approveRun(ctx, playbook, runID)
return approveRun(ctx, run)
}

func requiresApproval(playbook *models.Playbook) bool {
playbookV1, _ := v1.PlaybookFromModel(*playbook)
return playbookV1.Spec.Approval != nil && !playbookV1.Spec.Approval.Approvers.Empty()
func requiresApproval(spec v1.PlaybookSpec) bool {
return spec.Approval != nil && !spec.Approval.Approvers.Empty()
}

func approveRun(ctx context.Context, playbook *models.Playbook, runID uuid.UUID) error {
func approveRun(ctx context.Context, run *models.PlaybookRun) error {
approver := ctx.User()

playbookV1, err := v1.PlaybookFromModel(*playbook)
if err != nil {
return api.Errorf(api.EINTERNAL, "something went wrong").WithDebugInfo("v1.PlaybookFromModel: %v", err)
var spec v1.PlaybookSpec
if err := json.Unmarshal(run.Spec, &spec); err != nil {
return err
}

if playbookV1.Spec.Approval == nil || playbookV1.Spec.Approval.Approvers.Empty() {
if spec.Approval == nil || spec.Approval.Approvers.Empty() {
return api.Errorf(api.EINVALID, "this playbook does not require approval")
}

Expand All @@ -73,19 +67,19 @@ func approveRun(ctx context.Context, playbook *models.Playbook, runID uuid.UUID)
}

approval := models.PlaybookApproval{
RunID: runID,
RunID: run.ID,
}

if collections.Contains(playbookV1.Spec.Approval.Approvers.People, approver.Email) {
if collections.Contains(spec.Approval.Approvers.People, approver.Email) {
approval.PersonID = &approver.ID
} else {
teams, err := db.GetTeamsForUser(ctx, approver.ID.String())
if err != nil {
return api.Errorf(api.EINTERNAL, "something went wrong").WithDebugInfo("db.GetTeamIDsForUser(id=%s): %v", approver.ID, err)
return api.Errorf(api.EINTERNAL, "something went wrong").WithDebugInfo("db.GetTeamsForUser(id=%s): %v", approver.ID, err)
}

for _, team := range teams {
if collections.Contains(playbookV1.Spec.Approval.Approvers.Teams, team.Name) {
if collections.Contains(spec.Approval.Approvers.Teams, team.Name) {
approval.TeamID = &team.ID
break
}
Expand All @@ -97,7 +91,7 @@ func approveRun(ctx context.Context, playbook *models.Playbook, runID uuid.UUID)
}

if err := db.SavePlaybookRunApproval(ctx, approval); err != nil {
return api.Errorf(api.EINTERNAL, "something went wrong while approving").WithDebugInfo("db.ApprovePlaybookRun(runID=%s, approverID=%s): %v", runID, approver.ID, err)
return api.Errorf(api.EINTERNAL, "something went wrong while approving").WithDebugInfo("db.SavePlaybookRunApproval(runID=%s, approverID=%s): %v", run.ID, approver.ID, err)
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion playbook/controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func RegisterRoutes(e *echo.Echo) {
runGroup := playbookGroup.Group("/run")
runGroup.POST("", HandlePlaybookRun, rbac.Playbook(rbac.ActionRun))
runGroup.GET("/:id", HandleGetPlaybookRun, rbac.Playbook(rbac.ActionRead))
runGroup.POST("/approve/:playbook_id/:run_id", HandlePlaybookRunApproval, rbac.Playbook(rbac.ActionApprove))
runGroup.POST("/approve/:run_id", HandlePlaybookRunApproval, rbac.Playbook(rbac.ActionApprove))
}

type RunResponse struct {
Expand Down
1 change: 1 addition & 0 deletions playbook/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func (t *playbookScheduler) Handle(ctx context.Context, event models.Event) erro
run := models.PlaybookRun{
PlaybookID: p.ID,
Status: models.PlaybookRunStatusPending,
Spec: p.Spec,
}

if playbook.Spec.Approval == nil || playbook.Spec.Approval.Approvers.Empty() {
Expand Down
12 changes: 8 additions & 4 deletions playbook/playbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func saveRunAsConfigChange(ctx context.Context, playbook *models.Playbook, run m

details := map[string]any{
"parameters": parameters,
"spec": playbook.Spec,
"spec": run.Spec,
}
detailsJSON, err := json.Marshal(details)
if err != nil {
Expand Down Expand Up @@ -215,14 +215,18 @@ func savePlaybookRun(ctx context.Context, playbook *models.Playbook, run *models
defer tx.Rollback()

ctx = ctx.WithDB(tx, ctx.Pool())

if err := ctx.DB().Create(run).Error; err != nil {
return ctx.Oops("db").Wrap(err)
}

if requiresApproval(playbook) {
var spec v1.PlaybookSpec
if err := json.Unmarshal(run.Spec, &spec); err != nil {
return ctx.Oops().Wrap(err)
}

if requiresApproval(spec) {
// Attempt to auto approve run
if err := approveRun(ctx, playbook, run.ID); err != nil {
if err := ApproveRun(ctx, run.ID); err != nil {
switch dutyAPI.ErrorCode(err) {
case dutyAPI.EFORBIDDEN, dutyAPI.EINVALID:
// ignore these errors
Expand Down
2 changes: 1 addition & 1 deletion playbook/runner/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func getActionForAgent(ctx context.Context, agent *models.Agent) (*ActionForAgen
return nil, ctx.Oops().Wrapf(err, "failed to template env")
}

spec, err := getActionSpec(playbook, step.Name)
spec, err := getActionSpec(run, step.Name)
if err != nil {
return nil, ctx.Oops().Wrap(err)
}
Expand Down
9 changes: 5 additions & 4 deletions playbook/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,15 @@ func findNextActionWithFilter(actions []v1.PlaybookAction) *v1.PlaybookAction {
return nil
}

func getActionSpec(playbook *models.Playbook, name string) (*v1.PlaybookAction, error) {
func getActionSpec(run *models.PlaybookRun, name string) (*v1.PlaybookAction, error) {
var spec v1.PlaybookSpec
if err := json.Unmarshal(playbook.Spec, &spec); err != nil {
if err := json.Unmarshal(run.Spec, &spec); err != nil {
return nil, err
}

for _, action := range spec.Actions {
if action.Name == name {
action.PlaybookID = playbook.ID.String()
action.PlaybookID = run.PlaybookID.String()
return &action, nil
}
}
Expand Down Expand Up @@ -197,7 +198,7 @@ func ScheduleRun(ctx context.Context, run models.PlaybookRun) error {
}

var playbookSpec v1.PlaybookSpec
if err := json.Unmarshal(playbook.Spec, &playbookSpec); err != nil {
if err := json.Unmarshal(run.Spec, &playbookSpec); err != nil {
return ctx.Oops().Wrap(err)
}

Expand Down
2 changes: 1 addition & 1 deletion playbook/runner/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func CreateTemplateEnv(ctx context.Context, playbook *models.Playbook, run *mode
oops := oops.With(models.ErrorContext(playbook, run)...)

var spec v1.PlaybookSpec
if err := json.Unmarshal(playbook.Spec, &spec); err != nil {
if err := json.Unmarshal(run.Spec, &spec); err != nil {
return templateEnv, oops.Wrapf(err, "invalid playbook spec")
}

Expand Down

0 comments on commit d4c332c

Please sign in to comment.