Skip to content

Commit

Permalink
complete
Browse files Browse the repository at this point in the history
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
  • Loading branch information
eddycharly committed Feb 23, 2024
1 parent d49b603 commit af5549d
Show file tree
Hide file tree
Showing 30 changed files with 305 additions and 245 deletions.
5 changes: 2 additions & 3 deletions pkg/commands/assert/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"io"
"time"

"github.com/jmespath-community/go-jmespath/pkg/binding"
"github.com/kyverno/chainsaw/pkg/apis/v1alpha1"
ctrlClient "github.com/kyverno/chainsaw/pkg/client"
tclient "github.com/kyverno/chainsaw/pkg/client/testing"
Expand Down Expand Up @@ -135,6 +134,6 @@ func runE(opts options, cmd *cobra.Command, client ctrlClient.Client, namespacer
func assert(opts options, client ctrlClient.Client, resource unstructured.Unstructured, namespacer nspacer.Namespacer) error {
ctx, cancel := context.WithTimeout(context.Background(), opts.timeout.Duration)
defer cancel()
op := opassert.New(client, resource, namespacer, binding.NewBindings(), false)
return op.Exec(ctx)
op := opassert.New(client, resource, namespacer, false)
return op.Exec(ctx, nil)
}
36 changes: 16 additions & 20 deletions pkg/runner/operations/apply/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ type operation struct {
base unstructured.Unstructured
namespacer namespacer.Namespacer
cleaner cleanup.Cleaner
bindings binding.Bindings
template bool
expect []v1alpha1.Expectation
}
Expand All @@ -36,25 +35,23 @@ func New(
obj unstructured.Unstructured,
namespacer namespacer.Namespacer,
cleaner cleanup.Cleaner,
bindings binding.Bindings,
template bool,
expect []v1alpha1.Expectation,
) operations.Operation {
if bindings == nil {
bindings = binding.NewBindings()
}
return &operation{
client: client,
base: obj,
namespacer: namespacer,
cleaner: cleaner,
bindings: bindings,
template: template,
expect: expect,
}
}

func (o *operation) Exec(ctx context.Context) (err error) {
func (o *operation) Exec(ctx context.Context, bindings binding.Bindings) (err error) {
if bindings == nil {
bindings = binding.NewBindings()
}
obj := o.base
logger := internal.GetLogger(ctx, &obj)
defer func() {
Expand All @@ -64,7 +61,7 @@ func (o *operation) Exec(ctx context.Context) (err error) {
template := v1alpha1.Any{
Value: obj.UnstructuredContent(),
}
if merged, err := mutate.Merge(ctx, obj, o.bindings, template); err != nil {
if merged, err := mutate.Merge(ctx, obj, bindings, template); err != nil {
return err
} else {
obj = merged
Expand All @@ -74,13 +71,13 @@ func (o *operation) Exec(ctx context.Context) (err error) {
return err
}
internal.LogStart(logger, logging.Apply)
return o.execute(ctx, obj)
return o.execute(ctx, bindings, obj)
}

func (o *operation) execute(ctx context.Context, obj unstructured.Unstructured) error {
func (o *operation) execute(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured) error {
var lastErr error
err := wait.PollUntilContextCancel(ctx, internal.PollInterval, false, func(ctx context.Context) (bool, error) {
lastErr = o.tryApplyResource(ctx, obj)
lastErr = o.tryApplyResource(ctx, bindings, obj)
// TODO: determine if the error can be retried
return lastErr == nil, nil
})
Expand All @@ -93,20 +90,20 @@ func (o *operation) execute(ctx context.Context, obj unstructured.Unstructured)
return err
}

func (o *operation) tryApplyResource(ctx context.Context, obj unstructured.Unstructured) error {
func (o *operation) tryApplyResource(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured) error {
var actual unstructured.Unstructured
actual.SetGroupVersionKind(obj.GetObjectKind().GroupVersionKind())
err := o.client.Get(ctx, client.ObjectKey(&obj), &actual)
if err == nil {
return o.updateResource(ctx, &actual, obj)
return o.updateResource(ctx, bindings, &actual, obj)
}
if kerrors.IsNotFound(err) {
return o.createResource(ctx, obj)
return o.createResource(ctx, bindings, obj)
}
return err
}

func (o *operation) updateResource(ctx context.Context, actual *unstructured.Unstructured, obj unstructured.Unstructured) error {
func (o *operation) updateResource(ctx context.Context, bindings binding.Bindings, actual *unstructured.Unstructured, obj unstructured.Unstructured) error {
patched, err := client.PatchObject(actual, &obj)
if err != nil {
return err
Expand All @@ -115,19 +112,18 @@ func (o *operation) updateResource(ctx context.Context, actual *unstructured.Uns
if err != nil {
return err
}
return o.handleCheck(ctx, obj, o.client.Patch(ctx, actual, ctrlclient.RawPatch(types.MergePatchType, bytes)))
return o.handleCheck(ctx, bindings, obj, o.client.Patch(ctx, actual, ctrlclient.RawPatch(types.MergePatchType, bytes)))
}

func (o *operation) createResource(ctx context.Context, obj unstructured.Unstructured) error {
func (o *operation) createResource(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured) error {
err := o.client.Create(ctx, &obj)
if err == nil && o.cleaner != nil {
o.cleaner(obj, o.client)
}
return o.handleCheck(ctx, obj, err)
return o.handleCheck(ctx, bindings, obj, err)
}

func (o *operation) handleCheck(ctx context.Context, obj unstructured.Unstructured, err error) error {
bindings := o.bindings
func (o *operation) handleCheck(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured, err error) error {
if err == nil {
bindings = bindings.Register("$error", binding.NewBinding(nil))
} else {
Expand Down
3 changes: 1 addition & 2 deletions pkg/runner/operations/apply/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,10 @@ func Test_apply(t *testing.T) {
tt.object,
nil,
nil,
nil,
false,
tt.expect,
)
err := operation.Exec(ctx)
err := operation.Exec(ctx, nil)
if tt.expectedErr != nil {
assert.EqualError(t, err, tt.expectedErr.Error())
} else {
Expand Down
18 changes: 7 additions & 11 deletions pkg/runner/operations/assert/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,34 @@ type operation struct {
client client.Client
base unstructured.Unstructured
namespacer namespacer.Namespacer
bindings binding.Bindings
template bool
}

func New(
client client.Client,
expected unstructured.Unstructured,
namespacer namespacer.Namespacer,
bindings binding.Bindings,
template bool,
) operations.Operation {
if bindings == nil {
bindings = binding.NewBindings()
}
return &operation{
client: client,
base: expected,
namespacer: namespacer,
bindings: bindings,
template: template,
}
}

func (o *operation) Exec(ctx context.Context) (err error) {
func (o *operation) Exec(ctx context.Context, bindings binding.Bindings) (err error) {
if bindings == nil {
bindings = binding.NewBindings()
}
obj := o.base
logger := internal.GetLogger(ctx, &obj)
defer func() {
internal.LogEnd(logger, logging.Assert, err)
}()
if o.template {
if err := template.ResourceRef(ctx, &obj, o.bindings); err != nil {
if err := template.ResourceRef(ctx, &obj, bindings); err != nil {
return err
}
}
Expand All @@ -64,12 +61,11 @@ func (o *operation) Exec(ctx context.Context) (err error) {
}
}
internal.LogStart(logger, logging.Assert)
return o.execute(ctx, obj)
return o.execute(ctx, bindings, obj)
}

func (o *operation) execute(ctx context.Context, obj unstructured.Unstructured) error {
func (o *operation) execute(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured) error {
var lastErrs []error
bindings := o.bindings
err := wait.PollUntilContextCancel(ctx, internal.PollInterval, false, func(ctx context.Context) (_ bool, err error) {
var errs []error
defer func() {
Expand Down
3 changes: 1 addition & 2 deletions pkg/runner/operations/assert/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,10 @@ func Test_operationAssert(t *testing.T) {
tt.client,
tt.expected,
nspacer,
nil,
false,
)
logger := &tlogging.FakeLogger{}
err := operation.Exec(ttesting.IntoContext(logging.IntoContext(ctx, logger), t))
err := operation.Exec(ttesting.IntoContext(logging.IntoContext(ctx, logger), t), nil)
if tt.expectErr {
assert.NotNil(t, err)
} else {
Expand Down
17 changes: 7 additions & 10 deletions pkg/runner/operations/command/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,27 @@ type operation struct {
command v1alpha1.Command
basePath string
namespace string
bindings binding.Bindings
cfg *rest.Config
}

func New(
command v1alpha1.Command,
basePath string,
namespace string,
bindings binding.Bindings,
cfg *rest.Config,
) operations.Operation {
if bindings == nil {
bindings = binding.NewBindings()
}
return &operation{
command: command,
basePath: basePath,
namespace: namespace,
bindings: bindings,
cfg: cfg,
}
}

func (o *operation) Exec(ctx context.Context) (_err error) {
func (o *operation) Exec(ctx context.Context, bindings binding.Bindings) (_err error) {
if bindings == nil {
bindings = binding.NewBindings()
}
logger := internal.GetLogger(ctx, nil)
defer func() {
internal.LogEnd(logger, logging.Command, _err)
Expand All @@ -59,7 +56,7 @@ func (o *operation) Exec(ctx context.Context) (_err error) {
return err
}
internal.LogStart(logger, logging.Command, logging.Section("COMMAND", cmd.String()))
return o.execute(ctx, cmd)
return o.execute(ctx, bindings, cmd)
}

func (o *operation) createCommand(ctx context.Context) (*exec.Cmd, context.CancelFunc, error) {
Expand Down Expand Up @@ -99,7 +96,7 @@ func (o *operation) createCommand(ctx context.Context) (*exec.Cmd, context.Cance
return cmd, cancel, nil
}

func (o *operation) execute(ctx context.Context, cmd *exec.Cmd) error {
func (o *operation) execute(ctx context.Context, bindings binding.Bindings, cmd *exec.Cmd) error {
logger := logging.FromContext(ctx)
var output internal.CommandOutput
if !o.command.SkipLogOutput {
Expand All @@ -115,7 +112,7 @@ func (o *operation) execute(ctx context.Context, cmd *exec.Cmd) error {
if o.command.Check == nil || o.command.Check.Value == nil {
return err
}
bindings := o.bindings.Register("$stdout", binding.NewBinding(output.Out()))
bindings = bindings.Register("$stdout", binding.NewBinding(output.Out()))
bindings = bindings.Register("$stderr", binding.NewBinding(output.Err()))
if err == nil {
bindings = bindings.Register("$error", binding.NewBinding(nil))
Expand Down
3 changes: 1 addition & 2 deletions pkg/runner/operations/command/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,8 @@ func Test_operationCommand(t *testing.T) {
tt.basePath,
tt.namespace,
nil,
nil,
)
err := operation.Exec(ctx)
err := operation.Exec(ctx, nil)
if tt.wantErr {
assert.Error(t, err)
} else {
Expand Down
30 changes: 13 additions & 17 deletions pkg/runner/operations/create/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ type operation struct {
base unstructured.Unstructured
namespacer namespacer.Namespacer
cleaner cleanup.Cleaner
bindings binding.Bindings
template bool
expect []v1alpha1.Expectation
}
Expand All @@ -34,25 +33,23 @@ func New(
obj unstructured.Unstructured,
namespacer namespacer.Namespacer,
cleaner cleanup.Cleaner,
bindings binding.Bindings,
template bool,
expect []v1alpha1.Expectation,
) operations.Operation {
if bindings == nil {
bindings = binding.NewBindings()
}
return &operation{
client: client,
base: obj,
namespacer: namespacer,
cleaner: cleaner,
bindings: bindings,
template: template,
expect: expect,
}
}

func (o *operation) Exec(ctx context.Context) (err error) {
func (o *operation) Exec(ctx context.Context, bindings binding.Bindings) (err error) {
if bindings == nil {
bindings = binding.NewBindings()
}
obj := o.base
logger := internal.GetLogger(ctx, &obj)
defer func() {
Expand All @@ -61,7 +58,7 @@ func (o *operation) Exec(ctx context.Context) (err error) {
selfModifier := v1alpha1.Any{
Value: obj.UnstructuredContent(),
}
if merged, err := mutate.Merge(ctx, obj, o.bindings, selfModifier); err != nil {
if merged, err := mutate.Merge(ctx, obj, bindings, selfModifier); err != nil {
return err
} else {
obj = merged
Expand All @@ -70,13 +67,13 @@ func (o *operation) Exec(ctx context.Context) (err error) {
return err
}
internal.LogStart(logger, logging.Create)
return o.execute(ctx, obj)
return o.execute(ctx, bindings, obj)
}

func (o *operation) execute(ctx context.Context, obj unstructured.Unstructured) error {
func (o *operation) execute(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured) error {
var lastErr error
err := wait.PollUntilContextCancel(ctx, internal.PollInterval, false, func(ctx context.Context) (bool, error) {
lastErr = o.tryCreateResource(ctx, obj)
lastErr = o.tryCreateResource(ctx, bindings, obj)
// TODO: determine if the error can be retried
return lastErr == nil, nil
})
Expand All @@ -90,29 +87,28 @@ func (o *operation) execute(ctx context.Context, obj unstructured.Unstructured)
}

// TODO: could be replaced by checking the already exists error
func (o *operation) tryCreateResource(ctx context.Context, obj unstructured.Unstructured) error {
func (o *operation) tryCreateResource(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured) error {
var actual unstructured.Unstructured
actual.SetGroupVersionKind(obj.GetObjectKind().GroupVersionKind())
err := o.client.Get(ctx, client.ObjectKey(&obj), &actual)
if err == nil {
return errors.New("the resource already exists in the cluster")
}
if kerrors.IsNotFound(err) {
return o.createResource(ctx, obj)
return o.createResource(ctx, bindings, obj)
}
return err
}

func (o *operation) createResource(ctx context.Context, obj unstructured.Unstructured) error {
func (o *operation) createResource(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured) error {
err := o.client.Create(ctx, &obj)
if err == nil && o.cleaner != nil {
o.cleaner(obj, o.client)
}
return o.handleCheck(ctx, obj, err)
return o.handleCheck(ctx, bindings, obj, err)
}

func (o *operation) handleCheck(ctx context.Context, obj unstructured.Unstructured, err error) error {
bindings := o.bindings
func (o *operation) handleCheck(ctx context.Context, bindings binding.Bindings, obj unstructured.Unstructured, err error) error {
if err == nil {
bindings = bindings.Register("$error", binding.NewBinding(nil))
} else {
Expand Down
3 changes: 1 addition & 2 deletions pkg/runner/operations/create/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,10 @@ func Test_create(t *testing.T) {
tt.object,
nil,
tt.cleaner,
nil,
false,
tt.expect,
)
err := operation.Exec(ctx)
err := operation.Exec(ctx, nil)
if tt.expectedErr != nil {
assert.EqualError(t, err, tt.expectedErr.Error())
} else {
Expand Down
Loading

0 comments on commit af5549d

Please sign in to comment.