Skip to content

Commit

Permalink
Conversion functions from assign / assignmetadata to Mutator.
Browse files Browse the repository at this point in the history
We expose a generic MutatorFor(o Object) to build a mutator instance
that wraps the cr.

Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
  • Loading branch information
fedepaol committed Nov 18, 2020
1 parent f3ec64a commit d98f7af
Show file tree
Hide file tree
Showing 4 changed files with 441 additions and 2 deletions.
117 changes: 117 additions & 0 deletions pkg/mutation/assign_mutator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package mutation

import (
"github.com/google/go-cmp/cmp"
mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1alpha1"
"github.com/open-policy-agent/gatekeeper/pkg/mutation/path"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

// AssignMutator is a mutator object built out of a
// Assign instance.
type AssignMutator struct {
id ID
assign *mutationsv1alpha1.Assign
path []path.Entry
bindings []SchemaBinding
}

// AssignMutator implements mutatorWithSchema
var _ MutatorWithSchema = &AssignMutator{}

func (m *AssignMutator) Matches(obj metav1.Object, ns *corev1.Namespace) bool {
// TODO implement using matches function
return false
}

func (m *AssignMutator) Mutate(obj *unstructured.Unstructured) error {
// TODO implement
return nil
}
func (m *AssignMutator) ID() ID {
return m.id
}

func (m *AssignMutator) SchemaBindings() []SchemaBinding {
return m.bindings
}

func (m *AssignMutator) HasDiff(mutator Mutator) bool {
toCheck, ok := mutator.(*AssignMutator)
if !ok { // different types, different
return true
}

if !cmp.Equal(toCheck.id, m.id) {
return true
}
if !cmp.Equal(toCheck.path, m.path) {
return true
}
if !cmp.Equal(toCheck.bindings, m.bindings) {
return true
}

// any difference in spec may be enough
if !cmp.Equal(toCheck.assign.Spec, m.assign.Spec) {
return true
}

return false
}

func (m *AssignMutator) Path() []path.Entry {
return m.path
}

func (m *AssignMutator) DeepCopy() Mutator {
res := &AssignMutator{
id: m.id,
assign: m.assign.DeepCopy(),
path: make([]path.Entry, len(m.path)),
bindings: make([]SchemaBinding, len(m.bindings)),
}
copy(res.path, m.path)
copy(res.bindings, m.bindings)
return res
}

// MutatorForAssign returns an AssignMutator built from
// the given assign instance.
func MutatorForAssign(assign *mutationsv1alpha1.Assign) (*AssignMutator, error) {
id, err := MakeID(assign)
if err != nil {
return nil, errors.Wrapf(err, "Failed to retrieve id for assign type")
}
return &AssignMutator{
id: id,
assign: assign.DeepCopy(),
bindings: applyToToBindings(assign.Spec.ApplyTo),
path: nil, // TODO fill when the parsing is done
}, nil
}

func applyToToBindings(applyTos []mutationsv1alpha1.ApplyTo) []SchemaBinding {
res := []SchemaBinding{}
for _, applyTo := range applyTos {
binding := SchemaBinding{
Groups: make([]string, len(applyTo.Groups)),
Kinds: make([]string, len(applyTo.Kinds)),
Versions: make([]string, len(applyTo.Versions)),
}
for i, g := range applyTo.Groups {
binding.Groups[i] = g
}
for i, k := range applyTo.Kinds {
binding.Kinds[i] = k
}
for i, v := range applyTo.Versions {
binding.Versions[i] = v
}
res = append(res, binding)
}
return res
}
70 changes: 70 additions & 0 deletions pkg/mutation/assignmeta_mutator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package mutation

import (
"github.com/google/go-cmp/cmp"
mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1alpha1"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

//AssignMetadataMutator is a mutator built out of an
// AssignMeta instance.
type AssignMetadataMutator struct {
id ID
assignMetadata *mutationsv1alpha1.AssignMetadata
}

// assignMetadataMutator implements mutator
var _ Mutator = &AssignMetadataMutator{}

func (m *AssignMetadataMutator) Matches(obj metav1.Object, ns *corev1.Namespace) bool {
// TODO implement using matches function
return false
}

func (m *AssignMetadataMutator) Mutate(obj *unstructured.Unstructured) error {
// TODO implement
return nil
}
func (m *AssignMetadataMutator) ID() ID {
return m.id
}

func (m *AssignMetadataMutator) HasDiff(mutator Mutator) bool {
toCheck, ok := mutator.(*AssignMetadataMutator)
if !ok { // different types, different
return true
}

if !cmp.Equal(toCheck.id, m.id) {
return true
}
// any difference in spec may be enough
if !cmp.Equal(toCheck.assignMetadata.Spec, m.assignMetadata.Spec) {
return true
}

return false
}

func (m *AssignMetadataMutator) DeepCopy() Mutator {
res := &AssignMetadataMutator{
id: m.id,
assignMetadata: m.assignMetadata.DeepCopy(),
}
return res
}

// MutatorForAssignMetadata builds an AssignMetadataMutator from the given AssignMetadata object.
func MutatorForAssignMetadata(assignMeta *mutationsv1alpha1.AssignMetadata) (*AssignMetadataMutator, error) {
id, err := MakeID(assignMeta)
if err != nil {
return nil, errors.Wrapf(err, "Failed to retrieve id for assignMetadata type")
}
return &AssignMetadataMutator{
id: id,
assignMetadata: assignMeta.DeepCopy(),
}, nil
}
Loading

0 comments on commit d98f7af

Please sign in to comment.