Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closes #2378: Filtering of watched resources #3275

Merged
merged 1 commit into from
Jul 1, 2020
Merged

Closes #2378: Filtering of watched resources #3275

merged 1 commit into from
Jul 1, 2020

Conversation

VenkatRamaraju
Copy link
Contributor

Description of the change:
Added a predicate that will filter resources by labels based on the selectors that are specified in watches.yaml

Motivation for the #change:
Avoid having to do an Ansible initialization before skipping an event.
Fixes the issue: #2378

@openshift-ci-robot openshift-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 22, 2020
entries:
- description: >
Added predicate filtering function for labels based on selectors specified in watches.yaml.
Added temporary structs to watches.go for yaml parsing in UnmarshalYAML
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 4 is kinda implementation detail not meant to surface as user facing change logs?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, what you should put here is a brief description of the feature from the user's perspective, no need to talk about the code base directly


migration:
header:
body: >
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .DS_Store file below was added by mistake.

if err := c.Watch(&source.Kind{Type: u}, &crthandler.EnqueueRequestForObject{},
predicate.GenerationChangedPredicate{}); err != nil {
predicate.GenerationChangedPredicate{},
predicate.ResourceFilterPredicate{Selector: options.Selector}); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest we add some vars as arguments to c.Watch() because readability of this whole line is important as well.

@@ -141,6 +141,7 @@ func Run(flags *aoflags.AnsibleOperatorFlags) error {
AnsibleDebugLogs: getAnsibleDebugLog(),
MaxWorkers: w.MaxWorkers,
ReconcilePeriod: w.ReconcilePeriod,
Selector: w.Selector,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this indentation is weird ... forgot to go fmt your code?


// these are overridden by cmdline flags
maxWorkersDefault = 1
ansibleVerbosityDefault = 2
)

// Creates, populates and returns Label Selector object during UnmarshalYAML
func parseTemp(dls tempLabelSelector) metav1.LabelSelector {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any alternative function names in mind?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving forward ... this label filtering can be used for other types of operator as well?
Pls ignore this question if we already have this for helm or go.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, would be good to make it clearer that this is for parsing the label selectors.

wrt the second question, currently this will not be exposed to other operator types, but it could be exposed eventually

@@ -304,6 +342,8 @@ func Load(path string, maxWorkers, ansibleVerbosity int) ([]Watch, error) {
log.Error(err, fmt.Sprintf("Watch with GVK %v failed validation", watch.GroupVersionKind.String()))
return nil, err
}

fmt.Printf("%+v", watch)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revise this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah looks like a leftover debug print, should be removed

Copy link
Member

@fabianvf fabianvf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice first PR! Few changes that should be dropped from the PR, stylistic nits and some best practices, plus tests and docs, but implementation looks sound to me

entries:
- description: >
Added predicate filtering function for labels based on selectors specified in watches.yaml.
Added temporary structs to watches.go for yaml parsing in UnmarshalYAML
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, what you should put here is a brief description of the feature from the user's perspective, no need to talk about the code base directly

go.mod Outdated
@@ -30,8 +30,9 @@ require (
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.5.1
go.uber.org/zap v1.14.1
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file shouldn't be changed in this PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this change to go.mod

go.sum Outdated
@@ -91,6 +91,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with this file


// these are overridden by cmdline flags
maxWorkersDefault = 1
ansibleVerbosityDefault = 2
)

// Creates, populates and returns Label Selector object during UnmarshalYAML
func parseTemp(dls tempLabelSelector) metav1.LabelSelector {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, would be good to make it clearer that this is for parsing the label selectors.

wrt the second question, currently this will not be exposed to other operator types, but it could be exposed eventually


return nil
}

// addRolePlaybookPaths will add the full path based on the current dir
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think you meant to delete this word

@@ -304,6 +342,8 @@ func Load(path string, maxWorkers, ansibleVerbosity int) ([]Watch, error) {
log.Error(err, fmt.Sprintf("Watch with GVK %v failed validation", watch.GroupVersionKind.String()))
return nil, err
}

fmt.Printf("%+v", watch)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah looks like a leftover debug print, should be removed

@@ -51,3 +58,37 @@ func (GenerationChangedPredicate) Update(e event.UpdateEvent) bool {
}
return true
}

// Skips events that have labels matching a selector defined in watches.yaml
func EventFilter(eventLabels map[string]string, r ResourceFilterPredicate) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be func (r ResourceFilterPredicate) Event filter(eventLabels map[string]string) bool

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also should probably be lowercase eventFilter, this is an implementation detail and not something we should expose outside of this package


if err != nil {
log.Error(nil, "Unable to retrieve requirement", err)
return false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, if we're unable to parse the requirement should our behavior be to reconcile or not? My inclination is to reconcile in this case but curious what others think


// Predicate functions that call the EventFilter Function
func (r ResourceFilterPredicate) Update(e event.UpdateEvent) bool {
return EventFilter(e.MetaNew.GetLabels(), r)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the signature above, these would turn into r.EventFilter(e.Meta.GetLabels())

@fabianvf fabianvf changed the title [WIP] Closes #2378: Filtering of watched resources Closes #2378: Filtering of watched resources Jun 30, 2020
@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 30, 2020
Copy link
Member

@fabianvf fabianvf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .DS_STORE and cmd/.DS_STORE files should not be committed. Few other comments, but getting close

that: cm.data.hello == 'world'
vars:
cm: "{{ q('k8s', api_version='v1', kind='ConfigMap', namespace=namespace,
resource_name='selector-test').0 }}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably have a second test case where we create a SelectorTest sans label and verify it doesn't reconcile

}

func NewResourceFilterPredicate(s metav1.LabelSelector) (ResourceFilterPredicate, error) {
// fmt.Println(s)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These commented lines should be removed, and there probably doesn't need to be so many newlines (wouldn't normally even comment on that but since you'll be changing the file anyway figured I'd mention it)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed on both counts

filterPredicate, err := predicate.NewResourceFilterPredicate(options.Selector)

if err != nil {
log.Error(nil, "Unable to retreieve requirement", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first argument here should be the error, and the message should make it a little more clear why it exited. The user won't know what you mean by requirement, you need to make it clear that it's an issue with the selector they defined

go.sum Outdated
@@ -91,6 +91,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file should be left unchanged

go.mod Outdated
@@ -30,8 +30,9 @@ require (
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.5.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file should be left unchanged

Copy link
Member

@jmrodri jmrodri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor changes. The biggest one is remove the .DS_Store file from this PR. We do not want that in the repo.

go.mod Outdated
@@ -30,8 +30,9 @@ require (
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.5.1
go.uber.org/zap v1.14.1
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this change to go.mod

u := &unstructured.Unstructured{}
u.SetGroupVersionKind(options.GVK)

filterPredicate, err := predicate.NewResourceFilterPredicate(options.Selector)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the blank line, this makes it more clear that the err check is for the predicate error.

Comment on lines 92 to 95
requirement := metav1.LabelSelectorRequirement{}
requirement.Key = v.Key
requirement.Operator = v.Operator
requirement.Values = v.Values
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any specific reason you chose to initialize the variable like this? Normally I do it as one statement:

requirement := metav1.LabelSelectorRequirement{
    Key: v.Key,
    Operator: v.Operator,
    Values: v.Values,
}

@@ -278,6 +315,7 @@ func Load(path string, maxWorkers, ansibleVerbosity int) ([]Watch, error) {
maxWorkersDefault = maxWorkers
ansibleVerbosityDefault = ansibleVerbosity
b, err := ioutil.ReadFile(path)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this blank line that was added

}

func NewResourceFilterPredicate(s metav1.LabelSelector) (ResourceFilterPredicate, error) {
// fmt.Println(s)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed on both counts

@VenkatRamaraju
Copy link
Contributor Author

Made all the changes.

Copy link
Member

@jmrodri jmrodri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jul 1, 2020
Copy link
Member

@fabianvf fabianvf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@fabianvf fabianvf merged commit d8b7a33 into operator-framework:master Jul 1, 2020
@drewwells
Copy link

This would be useful for the go operator too. Adding labels from cli args is tricky b/c the manager.go/manager.Options code is vendored

@joelanford joelanford added the language/ansible Issue is related to an Ansible operator project label Aug 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
language/ansible Issue is related to an Ansible operator project lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants