Skip to content

Commit

Permalink
fix: context variables
Browse files Browse the repository at this point in the history
Signed-off-by: ShutingZhao <[email protected]>
  • Loading branch information
realshuting committed Aug 16, 2024
1 parent f941f81 commit 937b6fc
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 31 deletions.
22 changes: 10 additions & 12 deletions pkg/background/generate/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func manageClone(log logr.Logger, target, sourceSpec kyvernov1.ResourceSpec, severSideApply bool, rule kyvernov1.Rule, client dclient.Interface) generateResponse {
func manageClone(log logr.Logger, target, sourceSpec kyvernov1.ResourceSpec, severSideApply bool, pattern kyvernov1.GeneratePatterns, client dclient.Interface) generateResponse {
source := sourceSpec
clone := rule.Generation
if clone.Clone.Name != "" {
if pattern.Clone.Name != "" {
source = kyvernov1.ResourceSpec{
APIVersion: target.GetAPIVersion(),
Kind: target.GetKind(),
Namespace: clone.Clone.Namespace,
Name: clone.Clone.Name,
Namespace: pattern.Clone.Namespace,
Name: pattern.Clone.Name,
}
}

Expand Down Expand Up @@ -80,14 +79,13 @@ func manageClone(log logr.Logger, target, sourceSpec kyvernov1.ResourceSpec, sev
return newCreateGenerateResponse(sourceObjCopy.UnstructuredContent(), target, nil)
}

func manageCloneList(log logr.Logger, targetNamespace string, severSideApply bool, rule kyvernov1.Rule, client dclient.Interface) []generateResponse {
func manageCloneList(log logr.Logger, targetNamespace string, severSideApply bool, pattern kyvernov1.GeneratePatterns, client dclient.Interface) []generateResponse {
var responses []generateResponse
cloneList := rule.Generation.CloneList
sourceNamespace := cloneList.Namespace
kinds := cloneList.Kinds
sourceNamespace := pattern.CloneList.Namespace
kinds := pattern.CloneList.Kinds
for _, kind := range kinds {
apiVersion, kind := kubeutils.GetKindFromGVK(kind)
sources, err := client.ListResource(context.TODO(), apiVersion, kind, sourceNamespace, cloneList.Selector)
sources, err := client.ListResource(context.TODO(), apiVersion, kind, sourceNamespace, pattern.CloneList.Selector)
if err != nil {
responses = append(responses,
newSkipGenerateResponse(
Expand All @@ -101,13 +99,13 @@ func manageCloneList(log logr.Logger, targetNamespace string, severSideApply boo
for _, source := range sources.Items {
target := newResourceSpec(source.GetAPIVersion(), source.GetKind(), targetNamespace, source.GetName())

if (cloneList.Kinds != nil) && (source.GetNamespace() == target.GetNamespace()) {
if (pattern.CloneList.Kinds != nil) && (source.GetNamespace() == target.GetNamespace()) {
log.V(4).Info("skip resource self-clone")
responses = append(responses, newSkipGenerateResponse(nil, target, nil))
continue
}
responses = append(responses,
manageClone(log, target, newResourceSpec(source.GetAPIVersion(), source.GetKind(), source.GetNamespace(), source.GetName()), severSideApply, rule, client))
manageClone(log, target, newResourceSpec(source.GetAPIVersion(), source.GetKind(), source.GetNamespace(), source.GetName()), severSideApply, pattern, client))
}
}
return responses
Expand Down
15 changes: 10 additions & 5 deletions pkg/background/generate/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/go-logr/logr"
gojmespath "github.com/kyverno/go-jmespath"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
"github.com/kyverno/kyverno/pkg/background/common"
Expand Down Expand Up @@ -311,16 +312,20 @@ func (c *GenerateController) ApplyGeneratePolicy(log logr.Logger, policyContext
}
logger := log.WithValues("rule", rule.Name)
contextLoader := c.engine.ContextLoader(policy, rule)
// if rule, err = variables.SubstituteAllInRule(log, policyContext.JSONContext(), rule); err != nil {
// log.Error(err, "variable substitution failed for rule", "rule", rule.Name)
// return nil, err
// }
if err := contextLoader(context.TODO(), rule.Context, policyContext.JSONContext()); err != nil {
if _, ok := err.(gojmespath.NotFoundError); ok {
logger.V(3).Info("failed to load rule level context", "reason", err.Error())
} else {
logger.Error(err, "failed to load rule level context")
}
return nil, fmt.Errorf("failed to load rule level context: %v", err)
}

if rule.Generation.ForEachGeneration != nil {
g := newForeachGenerator(c.client, logger, policyContext, policy, rule, rule.Context, rule.GetAnyAllConditions(), policyContext.NewResource(), rule.Generation.ForEachGeneration, contextLoader)
genResource, err = g.generateForeach()
} else {
g := newGenerator(c.client, logger, policyContext, policy, rule, rule.Context, rule.GetAnyAllConditions(), policyContext.NewResource(), contextLoader)
g := newGenerator(c.client, logger, policyContext, policy, rule, rule.Context, rule.GetAnyAllConditions(), policyContext.NewResource(), rule.Generation.GeneratePatterns, contextLoader)
genResource, err = g.generate()
}

Expand Down
40 changes: 26 additions & 14 deletions pkg/background/generate/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type generator struct {
anyAllConditions any
trigger unstructured.Unstructured
forEach []kyvernov1.ForEachGeneration
pattern kyvernov1.GeneratePatterns
contextLoader engineapi.EngineContextLoader
}

Expand All @@ -39,6 +40,7 @@ func newGenerator(client dclient.Interface,
contextEntries []kyvernov1.ContextEntry,
anyAllConditions any,
trigger unstructured.Unstructured,
pattern kyvernov1.GeneratePatterns,
contextLoader engineapi.EngineContextLoader,
) *generator {
return &generator{
Expand All @@ -50,6 +52,7 @@ func newGenerator(client dclient.Interface,
contextEntries: contextEntries,
anyAllConditions: anyAllConditions,
trigger: trigger,
pattern: pattern,
contextLoader: contextLoader,
}
}
Expand All @@ -65,10 +68,18 @@ func newForeachGenerator(client dclient.Interface,
forEach []kyvernov1.ForEachGeneration,
contextLoader engineapi.EngineContextLoader,
) *generator {

g := newGenerator(client, logger, policyContext, policy, rule, contextEntries, anyAllConditions, trigger, contextLoader)
g.forEach = forEach
return g
return &generator{
client: client,
logger: logger,
policyContext: policyContext,
policy: policy,
rule: rule,
contextEntries: contextEntries,
anyAllConditions: anyAllConditions,
trigger: trigger,
forEach: forEach,
contextLoader: contextLoader,
}
}

func (g *generator) generate() ([]kyvernov1.ResourceSpec, error) {
Expand All @@ -95,22 +106,22 @@ func (g *generator) generate() ([]kyvernov1.ResourceSpec, error) {
return newGenResources, nil
}

rule, err := variables.SubstituteAllInRule(g.logger, g.policyContext.JSONContext(), g.rule)
pattern, err := variables.SubstituteAllInType(g.logger, g.policyContext.JSONContext(), &g.pattern)
if err != nil {
g.logger.Error(err, "variable substitution failed for rule", "rule", rule.Name)
g.logger.Error(err, "variable substitution failed for rule", "rule", g.rule.Name)
return nil, err
}

target := rule.Generation.ResourceSpec
target := pattern.ResourceSpec
logger := g.logger.WithValues("target", target.String())

if rule.Generation.Clone.Name != "" {
resp := manageClone(logger.WithValues("type", "clone"), target, kyvernov1.ResourceSpec{}, g.policy.GetSpec().UseServerSideApply, rule, g.client)
if pattern.Clone.Name != "" {
resp := manageClone(logger.WithValues("type", "clone"), target, kyvernov1.ResourceSpec{}, g.policy.GetSpec().UseServerSideApply, *pattern, g.client)
responses = append(responses, resp)
} else if len(rule.Generation.CloneList.Kinds) != 0 {
responses = manageCloneList(logger.WithValues("type", "cloneList"), target.GetNamespace(), g.policy.GetSpec().UseServerSideApply, rule, g.client)
} else if len(pattern.CloneList.Kinds) != 0 {
responses = manageCloneList(logger.WithValues("type", "cloneList"), target.GetNamespace(), g.policy.GetSpec().UseServerSideApply, *pattern, g.client)
} else {
resp := manageData(logger.WithValues("type", "data"), target, rule.Generation.RawData, rule.Generation.Synchronize, g.client)
resp := manageData(logger.WithValues("type", "data"), target, pattern.RawData, g.rule.Generation.Synchronize, g.client)
responses = append(responses, resp)
}

Expand Down Expand Up @@ -140,7 +151,7 @@ func (g *generator) generate() ([]kyvernov1.ResourceSpec, error) {
}

newResource.SetAPIVersion(targetMeta.GetAPIVersion())
common.ManageLabels(newResource, g.trigger, g.policy, rule.Name)
common.ManageLabels(newResource, g.trigger, g.policy, g.rule.Name)
if response.GetAction() == Create {
newResource.SetResourceVersion("")
if g.policy.GetSpec().UseServerSideApply {
Expand Down Expand Up @@ -169,7 +180,7 @@ func (g *generator) generate() ([]kyvernov1.ResourceSpec, error) {
}
newGenResources = append(newGenResources, targetMeta)
} else {
if !rule.Generation.Synchronize {
if !g.rule.Generation.Synchronize {
logger.V(4).Info("synchronize disabled, skip syncing changes")
continue
}
Expand Down Expand Up @@ -253,6 +264,7 @@ func (g *generator) generateElements(foreach kyvernov1.ForEachGeneration, elemen
foreach.Context,
foreach.AnyAllConditions,
g.trigger,
foreach.GeneratePatterns,
g.contextLoader).
generate()
if err != nil {
Expand Down

0 comments on commit 937b6fc

Please sign in to comment.