Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
CDimonaco committed Oct 8, 2024
1 parent b08ae45 commit a7dd26b
Show file tree
Hide file tree
Showing 13 changed files with 515 additions and 175 deletions.
62 changes: 62 additions & 0 deletions cmd/execute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package cmd

import (
"context"
"encoding/json"
"fmt"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/trento-project/workbench/pkg/operator"
)

var arguments string

var executeCmd = &cobra.Command{
Use: "execute",
Short: "execute an operator providing operator name and arguments",
Long: `
workbench execute <operator name> --arguments <json object>
Example
worbench execute saptunesolutionapply --arguments "{"solution": "HANA"}"
`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
logger := logrus.StandardLogger()
if verbose {
logger.SetLevel(logrus.DebugLevel)
}

solution := args[0]
if solution != "saptunesolutionapply" {
return fmt.Errorf("solution %s provided as argument, is invalid", solution)
}

opArgs := make(operator.OperatorArguments)
err := json.Unmarshal([]byte(arguments), &opArgs)
if err != nil {
return fmt.Errorf("could not unmarhsal %s into arguments", arguments)
}

op := operator.NewSaptuneApplySolution(opArgs, "test-cli", operator.OperatorOptions[operator.SaptuneApplySolution]{

Check failure on line 43 in cmd/execute.go

View workflow job for this annotation

GitHub Actions / static-analysis

undefined: operator.SaptuneApplySolution

Check failure on line 43 in cmd/execute.go

View workflow job for this annotation

GitHub Actions / test

undefined: operator.SaptuneApplySolution
BaseOperatorOptions: []operator.BaseOption{operator.WithLogger(logger)},

Check failure on line 44 in cmd/execute.go

View workflow job for this annotation

GitHub Actions / static-analysis

undefined: operator.BaseOption

Check failure on line 44 in cmd/execute.go

View workflow job for this annotation

GitHub Actions / static-analysis

undefined: operator.WithLogger

Check failure on line 44 in cmd/execute.go

View workflow job for this annotation

GitHub Actions / test

undefined: operator.BaseOption

Check failure on line 44 in cmd/execute.go

View workflow job for this annotation

GitHub Actions / test

undefined: operator.WithLogger
})

report := op.Run(context.Background())
if report.Error != nil {
return fmt.Errorf("operation execution error, phase: %s, reason: %s",
report.Error.ErrorPhase,
report.Error.Message,
)
}

logger.Infof("exeuction succeded in phase: %s, diff: before: %s, after: %s",
report.Success.LastPhase,
report.Success.Diff["before"],
report.Success.Diff["after"],
)
return nil
},
}
28 changes: 28 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

var verbose bool

var rootCmd = &cobra.Command{
Use: "workbench",
Short: "Workbench allow run trento operator directly",
}

func Execute() {
executeCmd.Flags().StringVarP(&arguments, "arguments", "a", "", "arguments as json object (required)")
executeCmd.MarkFlagRequired("arguments")

rootCmd.AddCommand(executeCmd)
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")

if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
13 changes: 11 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@ module github.com/trento-project/workbench

go 1.22.5

require github.com/stretchr/testify v1.9.0
require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
github.com/tidwall/gjson v1.18.0
golang.org/x/mod v0.21.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
golang.org/x/sys v0.25.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
17 changes: 17 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
Expand Down
6 changes: 4 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import "fmt"
import (
"github.com/trento-project/workbench/cmd"
)

func main() {
fmt.Println("hello moto")
cmd.Execute()
}
87 changes: 23 additions & 64 deletions pkg/operator/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,32 @@ package operator

import (
"context"
"errors"
"fmt"

"github.com/sirupsen/logrus"
)

type BaseOption Option[base]

type errUnimplementedPhase struct {
phase OPERATION_PHASES
}

func (e errUnimplementedPhase) Error() string {
return fmt.Sprintf("phase function: %s not implemented", e.phase)
}
const (
beforeDiffField = "before"
afterFieldDiff = "after"
)

func WithLogger(logger *logrus.Logger) BaseOption {
return func(b *base) {
b.logger = logger
}
}
type BaseOperationOption Option[baseOperation]

type base struct {
operationID string
arguments OperatorArguments
currentPhase OPERATION_PHASES
planResources map[string]any
logger *logrus.Logger
type baseOperation struct {
arguments OperatorArguments
resources map[string]any
logger *logrus.Entry
}

func newBaseOperator(operationID string, arguments OperatorArguments, options ...BaseOption) base {
base := &base{
operationID: operationID,
arguments: arguments,
planResources: make(map[string]any),
logger: logrus.StandardLogger(),
func newBaseOperator(
operationID string,
arguments OperatorArguments,
options ...BaseOperationOption,
) baseOperation {
base := &baseOperation{
arguments: arguments,
resources: make(map[string]any),
logger: logrus.StandardLogger().WithField("operation_id", operationID),
}

for _, opt := range options {
Expand All @@ -47,41 +37,10 @@ func newBaseOperator(operationID string, arguments OperatorArguments, options ..
return *base
}

func (sa *base) plan(_ context.Context) error {
return errUnimplementedPhase{phase: PLAN}
}

func (sa *base) commit(_ context.Context) error {
return errUnimplementedPhase{phase: COMMIT}
}

func (sa *base) verify(_ context.Context) error {
return errUnimplementedPhase{phase: VERIFY}
}

func (sa *base) rollback(_ context.Context) error {
return errUnimplementedPhase{phase: ROLLBACK}
}

func (sa *base) wrapRollbackError(phaseError error, rollbackError error) error {
return errors.Join(rollbackError, phaseError)
}
func (b *baseOperation) standardDiff(_ context.Context) map[string]any {
diff := make(map[string]any)
diff["before"] = b.resources[beforeDiffField]
diff["after"] = b.resources[afterFieldDiff]

func (sa *base) reportError(error error) *ExecutionReport {
return &ExecutionReport{
OperationID: sa.operationID,
Error: &ExecutionError{
Message: error.Error(),
ErrorPhase: sa.currentPhase,
},
}
}

func (sa *base) reportSuccess(diff map[string]string) *ExecutionReport {
return &ExecutionReport{
OperationID: sa.operationID,
Success: &ExecutionSuccess{
Diff: diff,
},
}
return nil
}
27 changes: 25 additions & 2 deletions pkg/operator/execution.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package operator

import "fmt"
import (
"fmt"
)

type ExecutionError struct {
ErrorPhase OPERATION_PHASES
Expand All @@ -16,11 +18,32 @@ func (e ExecutionError) Error() string {
}

type ExecutionSuccess struct {
Diff map[string]string
Diff map[string]any
LastPhase OPERATION_PHASES
}

type ExecutionReport struct {
OperationID string
Success *ExecutionSuccess
Error *ExecutionError
}

func executionReportWithError(error error, phase OPERATION_PHASES, operationID string) *ExecutionReport {
return &ExecutionReport{
OperationID: operationID,
Error: &ExecutionError{
Message: error.Error(),
ErrorPhase: phase,
},
}
}

func executionReportWithSuccess(diff map[string]any, phase OPERATION_PHASES, operationID string) *ExecutionReport {
return &ExecutionReport{
OperationID: operationID,
Success: &ExecutionSuccess{
Diff: diff,
LastPhase: phase,
},
}
}
68 changes: 68 additions & 0 deletions pkg/operator/executor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package operator

import (
"context"
"errors"
)

type phaser interface {
plan(ctx context.Context) error
commit(ctx context.Context) error
rollback(ctx context.Context) error
verify(ctx context.Context) error
operationDiff(ctx context.Context) map[string]any
}

type Executor struct {
currentPhase OPERATION_PHASES
phaser phaser
operationID string
}

func (e *Executor) Run(ctx context.Context) *ExecutionReport {
e.currentPhase = PLAN
err := e.phaser.plan(ctx)
if err != nil {
return executionReportWithError(err, e.currentPhase, e.operationID)
}

e.currentPhase = COMMIT

err = e.phaser.commit(ctx)
if err != nil {
e.currentPhase = ROLLBACK
rollbackError := e.phaser.rollback(ctx)
if rollbackError != nil {
return executionReportWithError(
wrapRollbackError(err, rollbackError),
e.currentPhase,
e.operationID,
)

}
return executionReportWithError(err, e.currentPhase, e.operationID)
}

e.currentPhase = VERIFY
err = e.phaser.verify(ctx)
if err != nil {
e.currentPhase = ROLLBACK
rollbackError := e.phaser.rollback(ctx)
if rollbackError != nil {
return executionReportWithError(
wrapRollbackError(err, rollbackError),
e.currentPhase,
e.operationID,
)
}
return executionReportWithError(err, e.currentPhase, e.operationID)
}

diff := e.phaser.operationDiff(ctx)

return executionReportWithSuccess(diff, e.currentPhase, e.operationID)
}

func wrapRollbackError(phaseError error, rollbackError error) error {
return errors.Join(rollbackError, phaseError)
}
Loading

0 comments on commit a7dd26b

Please sign in to comment.