1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00
kyverno/pkg/engine/context/deferred.go
Jim Bugwadia b98c0775f2
Fix deferred loading (#7597)
* handle nested contexts

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add feature flag

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add kuttl tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix linter issues

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix CLI regclient

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix: token permissions on report vulns workflow (#7611)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix: token permissions (#7619)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix: update the flag descriptions of the reports-controller (#7617)

Signed-off-by: emmanuel-ferdman <emmanuelferdman@gmail.com>

* fix: panic if env var not defined (#7613)

* fix: panic if env var not defined

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* use toggles instead of a flag

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update toggle name

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update toggle name

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix roles

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix role

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update manifests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove extra unlock

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix loader reset

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* propagate context

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* cm resolver

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* level management

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* address review comments

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add enableDeferredLoading to other controllers

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* re-enable ACR credhelper

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* improve tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove image registry client init

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* check for invalid reset/restore

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* recursive kuttl test

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* add pre/post queries

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add check for a recursive match

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* new test suite

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* eval loaders at creation level

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* kuttl test

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* add an index for resolving deps in order

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* improve comment

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* extract remove method

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* merge main

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* flags

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* feature flag

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix flag

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* update unit tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* two rules kuttl test

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* update unit tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* revert

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* per rule checkpoint

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix mutate chained rules

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* per rule checpoint/restore

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* log error

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

---------

Signed-off-by: Jim Bugwadia <jim@nirmata.com>
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
Signed-off-by: emmanuel-ferdman <emmanuelferdman@gmail.com>
Signed-off-by: ShutingZhao <shuting@nirmata.com>
Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
Co-authored-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
2023-06-27 09:58:50 -07:00

177 lines
3.6 KiB
Go

package context
import (
"regexp"
)
type deferredLoader struct {
name string
matcher regexp.Regexp
loader Loader
}
func NewDeferredLoader(name string, loader Loader) (DeferredLoader, error) {
// match on ASCII word boundaries except do not allow starting with a `.`
// this allows `x` to match `x.y` but not `y.x` or `y.x.z`
matcher, err := regexp.Compile(`(?:\A|\z|\s|[^.0-9A-Za-z])` + name + `\b`)
if err != nil {
return nil, err
}
return &deferredLoader{
name: name,
matcher: *matcher,
loader: loader,
}, nil
}
func (dl *deferredLoader) Name() string {
return dl.name
}
func (dl *deferredLoader) HasLoaded() bool {
return dl.loader.HasLoaded()
}
func (dl *deferredLoader) LoadData() error {
return dl.loader.LoadData()
}
func (d *deferredLoader) Matches(query string) bool {
return d.matcher.MatchString(query)
}
type leveledLoader struct {
level int
matched bool
loader DeferredLoader
}
func (cl *leveledLoader) Level() int {
return cl.level
}
func (cl *leveledLoader) Name() string {
return cl.loader.Name()
}
func (cl *leveledLoader) Matches(query string) bool {
return cl.loader.Matches(query)
}
func (cl *leveledLoader) HasLoaded() bool {
return cl.loader.HasLoaded()
}
func (cl *leveledLoader) LoadData() error {
return cl.loader.LoadData()
}
type deferredLoaders struct {
level int
index int
loaders []*leveledLoader
}
func NewDeferredLoaders() DeferredLoaders {
return &deferredLoaders{
loaders: make([]*leveledLoader, 0),
level: -1,
index: -1,
}
}
func (d *deferredLoaders) Add(dl DeferredLoader, level int) {
d.loaders = append(d.loaders, &leveledLoader{level, false, dl})
}
func (d *deferredLoaders) Reset(restore bool, level int) {
d.clearMatches()
for i := 0; i < len(d.loaders); i++ {
l := d.loaders[i]
if l.level > level {
i = d.removeLoader(i)
} else {
if l.loader.HasLoaded() {
// reload data into the current context for restore, and
// for a reset but only if loader is at a prior level
if restore || (l.level < level) {
if err := d.loadData(l, i); err != nil {
logger.Error(err, "failed to reload context entry", "name", l.loader.Name())
}
}
if l.level == level {
i = d.removeLoader(i)
}
} else if !restore {
if l.level == level {
i = d.removeLoader(i)
}
}
}
}
}
// removeLoader removes loader at the specified index
// and returns the prior index
func (d *deferredLoaders) removeLoader(i int) int {
d.loaders = append(d.loaders[:i], d.loaders[i+1:]...)
return i - 1
}
func (d *deferredLoaders) clearMatches() {
for _, dl := range d.loaders {
dl.matched = false
}
}
func (d *deferredLoaders) LoadMatching(query string, level int) error {
if d.level >= 0 {
level = d.level
}
index := len(d.loaders)
if d.index >= 0 {
index = d.index
}
for l, idx := d.match(query, level, index); l != nil; l, idx = d.match(query, level, index) {
if err := d.loadData(l, idx); err != nil {
return nil
}
}
return nil
}
func (d *deferredLoaders) loadData(l *leveledLoader, index int) error {
d.setLevelAndIndex(l.level, index)
defer d.setLevelAndIndex(-1, -1)
if err := l.LoadData(); err != nil {
return err
}
return nil
}
func (d *deferredLoaders) setLevelAndIndex(level, index int) {
d.level = level
d.index = index
}
func (d *deferredLoaders) match(query string, level, index int) (*leveledLoader, int) {
for i := 0; i < index; i++ {
dl := d.loaders[i]
if dl.matched || dl.loader.HasLoaded() {
continue
}
if dl.Matches(query) && dl.level <= level {
idx := i
d.loaders[i].matched = true
return dl, idx
}
}
return nil, -1
}