Skip to content

Commit

Permalink
refactor: introduce action factory (#2242)
Browse files Browse the repository at this point in the history
Signed-off-by: Charles-Edouard Brétéché <[email protected]>
  • Loading branch information
eddycharly authored Dec 17, 2024
1 parent 9b10855 commit 38c6953
Show file tree
Hide file tree
Showing 24 changed files with 1,172 additions and 731 deletions.
7 changes: 3 additions & 4 deletions pkg/engine/operations/sleep/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@ import (
"time"

"github.com/kyverno/chainsaw/pkg/apis"
"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
"github.com/kyverno/chainsaw/pkg/engine/operations"
"github.com/kyverno/chainsaw/pkg/engine/operations/internal"
"github.com/kyverno/chainsaw/pkg/engine/outputs"
"github.com/kyverno/chainsaw/pkg/logging"
)

type operation struct {
duration v1alpha1.Sleep
duration time.Duration
}

func New(duration v1alpha1.Sleep) operations.Operation {
func New(duration time.Duration) operations.Operation {
return &operation{
duration: duration,
}
Expand All @@ -31,6 +30,6 @@ func (o *operation) Exec(ctx context.Context, _ apis.Bindings) (_ outputs.Output
}

func (o *operation) execute() error {
time.Sleep(o.duration.Duration.Duration)
time.Sleep(o.duration)
return nil
}
11 changes: 3 additions & 8 deletions pkg/engine/operations/sleep/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,22 @@ import (
"testing"
"time"

"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
"github.com/kyverno/chainsaw/pkg/logging"
"github.com/kyverno/chainsaw/pkg/mocks"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func Test_operation_Exec(t *testing.T) {
tests := []struct {
name string
sleep v1alpha1.Sleep
sleep time.Duration
expectedLogs []string
}{{
name: "zero",
sleep: v1alpha1.Sleep{},
expectedLogs: []string{"SLEEP: RUN - []", "SLEEP: DONE - []"},
}, {
name: "1s",
sleep: v1alpha1.Sleep{
Duration: metav1.Duration{Duration: time.Second},
},
name: "1s",
sleep: time.Second,
expectedLogs: []string{"SLEEP: RUN - []", "SLEEP: DONE - []"},
}}
for _, tt := range tests {
Expand Down
74 changes: 74 additions & 0 deletions pkg/runner/operations/apply.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package operations

import (
"context"

"github.com/kyverno/chainsaw/pkg/apis"
"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
"github.com/kyverno/chainsaw/pkg/cleanup/cleaner"
"github.com/kyverno/chainsaw/pkg/engine/namespacer"
opapply "github.com/kyverno/chainsaw/pkg/engine/operations/apply"
"github.com/kyverno/chainsaw/pkg/engine/outputs"
enginecontext "github.com/kyverno/chainsaw/pkg/runner/context"
"github.com/kyverno/kyverno-json/pkg/core/compilers"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

type applyAction struct {
basePath string
namespacer namespacer.Namespacer
op v1alpha1.Apply
resource unstructured.Unstructured
cleaner cleaner.CleanerCollector
}

func (o applyAction) Execute(ctx context.Context, tc enginecontext.TestContext) (outputs.Outputs, error) {
contextData := enginecontext.ContextData{
BasePath: o.basePath,
Cluster: o.op.Cluster,
Clusters: o.op.Clusters,
DryRun: o.op.DryRun,
Templating: o.op.Template,
Timeouts: &v1alpha1.Timeouts{Apply: o.op.Timeout},
}
if tc, err := enginecontext.SetupContextAndBindings(tc, contextData, o.op.Bindings...); err != nil {
return nil, err
} else if err := prepareResource(o.resource, tc); err != nil {
return nil, err
} else if _, client, err := tc.CurrentClusterClient(); err != nil {
return nil, err
} else {
op := opapply.New(
tc.Compilers(),
client,
o.resource,
o.namespacer,
getCleanerOrNil(o.cleaner, tc),
tc.Templating(),
o.op.Expect,
o.op.Outputs,
)
ctx, cancel := context.WithTimeout(ctx, tc.Timeouts().Apply.Duration)
defer cancel()
return op.Exec(ctx, tc.Bindings())
}
}

func applyOperation(compilers compilers.Compilers, basePath string, namespacer namespacer.Namespacer, cleaner cleaner.CleanerCollector, bindings apis.Bindings, op v1alpha1.Apply) ([]Operation, error) {
resources, err := fileRefOrResource(context.TODO(), op.ActionResourceRef, basePath, compilers, bindings)
if err != nil {
return nil, err
}
var ops []Operation
for i := range resources {
resource := resources[i]
ops = append(ops, applyAction{
basePath: basePath,
namespacer: namespacer,
op: op,
resource: resource,
cleaner: cleaner,
})
}
return ops, nil
}
65 changes: 65 additions & 0 deletions pkg/runner/operations/assert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package operations

import (
"context"

"github.com/kyverno/chainsaw/pkg/apis"
"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
"github.com/kyverno/chainsaw/pkg/engine/namespacer"
opassert "github.com/kyverno/chainsaw/pkg/engine/operations/assert"
"github.com/kyverno/chainsaw/pkg/engine/outputs"
enginecontext "github.com/kyverno/chainsaw/pkg/runner/context"
"github.com/kyverno/kyverno-json/pkg/core/compilers"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

type assertAction struct {
basePath string
namespacer namespacer.Namespacer
op v1alpha1.Assert
resource unstructured.Unstructured
}

func (o assertAction) Execute(ctx context.Context, tc enginecontext.TestContext) (outputs.Outputs, error) {
contextData := enginecontext.ContextData{
BasePath: o.basePath,
Cluster: o.op.Cluster,
Clusters: o.op.Clusters,
Templating: o.op.Template,
Timeouts: &v1alpha1.Timeouts{Assert: o.op.Timeout},
}
if tc, err := enginecontext.SetupContextAndBindings(tc, contextData, o.op.Bindings...); err != nil {
return nil, err
} else if _, client, err := tc.CurrentClusterClient(); err != nil {
return nil, err
} else {
op := opassert.New(
tc.Compilers(),
client,
o.resource,
o.namespacer,
tc.Templating(),
)
ctx, cancel := context.WithTimeout(ctx, tc.Timeouts().Assert.Duration)
defer cancel()
return op.Exec(ctx, tc.Bindings())
}
}

func assertOperation(compilers compilers.Compilers, basePath string, namespacer namespacer.Namespacer, bindings apis.Bindings, op v1alpha1.Assert) ([]Operation, error) {
resources, err := fileRefOrCheck(context.TODO(), op.ActionCheckRef, basePath, compilers, bindings)
if err != nil {
return nil, err
}
var ops []Operation
for i := range resources {
resource := resources[i]
ops = append(ops, assertAction{
basePath: basePath,
namespacer: namespacer,
op: op,
resource: resource,
})
}
return ops, nil
}
54 changes: 54 additions & 0 deletions pkg/runner/operations/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package operations

import (
"context"

"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
"github.com/kyverno/chainsaw/pkg/engine/namespacer"
opcommand "github.com/kyverno/chainsaw/pkg/engine/operations/command"
"github.com/kyverno/chainsaw/pkg/engine/outputs"
enginecontext "github.com/kyverno/chainsaw/pkg/runner/context"
)

type commandAction struct {
basePath string
namespacer namespacer.Namespacer
op v1alpha1.Command
}

func (o commandAction) Execute(ctx context.Context, tc enginecontext.TestContext) (outputs.Outputs, error) {
ns := ""
if o.namespacer != nil {
ns = o.namespacer.GetNamespace()
}
contextData := enginecontext.ContextData{
BasePath: o.basePath,
Cluster: o.op.Cluster,
Clusters: o.op.Clusters,
Timeouts: &v1alpha1.Timeouts{Exec: o.op.Timeout},
}
if tc, err := enginecontext.SetupContextAndBindings(tc, contextData, o.op.Bindings...); err != nil {
return nil, err
} else if config, _, err := tc.CurrentClusterClient(); err != nil {
return nil, err
} else {
op := opcommand.New(
tc.Compilers(),
o.op,
o.basePath,
ns,
config,
)
ctx, cancel := context.WithTimeout(ctx, tc.Timeouts().Exec.Duration)
defer cancel()
return op.Exec(ctx, tc.Bindings())
}
}

func commandOperation(basePath string, namespacer namespacer.Namespacer, op v1alpha1.Command) Operation {
return commandAction{
basePath: basePath,
namespacer: namespacer,
op: op,
}
}
74 changes: 74 additions & 0 deletions pkg/runner/operations/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package operations

import (
"context"

"github.com/kyverno/chainsaw/pkg/apis"
"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
"github.com/kyverno/chainsaw/pkg/cleanup/cleaner"
"github.com/kyverno/chainsaw/pkg/engine/namespacer"
opcreate "github.com/kyverno/chainsaw/pkg/engine/operations/create"
"github.com/kyverno/chainsaw/pkg/engine/outputs"
enginecontext "github.com/kyverno/chainsaw/pkg/runner/context"
"github.com/kyverno/kyverno-json/pkg/core/compilers"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

type createAction struct {
basePath string
namespacer namespacer.Namespacer
op v1alpha1.Create
resource unstructured.Unstructured
cleaner cleaner.CleanerCollector
}

func (o createAction) Execute(ctx context.Context, tc enginecontext.TestContext) (outputs.Outputs, error) {
contextData := enginecontext.ContextData{
BasePath: o.basePath,
Cluster: o.op.Cluster,
Clusters: o.op.Clusters,
DryRun: o.op.DryRun,
Templating: o.op.Template,
Timeouts: &v1alpha1.Timeouts{Apply: o.op.Timeout},
}
if tc, err := enginecontext.SetupContextAndBindings(tc, contextData, o.op.Bindings...); err != nil {
return nil, err
} else if err := prepareResource(o.resource, tc); err != nil {
return nil, err
} else if _, client, err := tc.CurrentClusterClient(); err != nil {
return nil, err
} else {
op := opcreate.New(
tc.Compilers(),
client,
o.resource,
o.namespacer,
getCleanerOrNil(o.cleaner, tc),
tc.Templating(),
o.op.Expect,
o.op.Outputs,
)
ctx, cancel := context.WithTimeout(ctx, tc.Timeouts().Apply.Duration)
defer cancel()
return op.Exec(ctx, tc.Bindings())
}
}

func createOperation(compilers compilers.Compilers, basePath string, namespacer namespacer.Namespacer, cleaner cleaner.CleanerCollector, bindings apis.Bindings, op v1alpha1.Create) ([]Operation, error) {
resources, err := fileRefOrResource(context.TODO(), op.ActionResourceRef, basePath, compilers, bindings)
if err != nil {
return nil, err
}
var ops []Operation
for i := range resources {
resource := resources[i]
ops = append(ops, createAction{
basePath: basePath,
namespacer: namespacer,
op: op,
resource: resource,
cleaner: cleaner,
})
}
return ops, nil
}
Loading

0 comments on commit 38c6953

Please sign in to comment.