Skip to content

Index metadata.name for cluster-name label #740

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

Merged

Conversation

vincepri
Copy link
Member

@vincepri vincepri commented Feb 11, 2019

Signed-off-by: Vince Prignano [email protected]

What this PR does / why we need it:

#728 introduced a bug where the metadata.name field cannot be queried because the client uses a cached-index implementation to retrieve results. This bug prevents providers to successfully spin up clusters when using the Cluster resource.

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #

Special notes for your reviewer:
The branch has been successfully tested on the AWS and vSphere providers.

Release note:


@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Feb 11, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: vincepri

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 11, 2019
@vincepri vincepri force-pushed the cluster-name-index-field branch from 3cd9513 to 0617f27 Compare February 11, 2019 20:31
@vincepri
Copy link
Member Author

/assign @detiber

@@ -58,6 +58,10 @@ func newReconciler(mgr manager.Manager, actuator Actuator) reconcile.Reconciler
actuator: actuator,
}

mgr.GetFieldIndexer().IndexField(&clusterv1.Cluster{}, "metadata.name", func(obj runtime.Object) []string {
Copy link
Member

@detiber detiber Feb 11, 2019

Choose a reason for hiding this comment

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

Does it matter that IndexerFunc is meant to be unique across namespaces?

// IndexerFunc knows how to take an object and turn it into a series
// of (non-namespaced) keys for that object.
type IndexerFunc func(runtime.Object) []string

Copy link
Member Author

Choose a reason for hiding this comment

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

I believe that's taken care of in this wrapper

func (ip *informerCache) IndexField(obj runtime.Object, field string, extractValue client.IndexerFunc) error {
informer, err := ip.GetInformer(obj)
if err != nil {
return err
}
return indexByField(informer.GetIndexer(), field, extractValue)
}
func indexByField(indexer cache.Indexer, field string, extractor client.IndexerFunc) error {
indexFunc := func(objRaw interface{}) ([]string, error) {
// TODO(directxman12): check if this is the correct type?
obj, isObj := objRaw.(runtime.Object)
if !isObj {
return nil, fmt.Errorf("object of type %T is not an Object", objRaw)
}
meta, err := apimeta.Accessor(obj)
if err != nil {
return nil, err
}
ns := meta.GetNamespace()
rawVals := extractor(obj)
var vals []string
if ns == "" {
// if we're not doubling the keys for the namespaced case, just re-use what was returned to us
vals = rawVals
} else {
// if we need to add non-namespaced versions too, double the length
vals = make([]string, len(rawVals)*2)
}
for i, rawVal := range rawVals {
// save a namespaced variant, so that we can ask
// "what are all the object matching a given index *in a given namespace*"
vals[i] = internal.KeyToNamespacedKey(ns, rawVal)
if ns != "" {
// if we have a namespace, also inject a special index key for listing
// regardless of the object namespace
vals[i+len(rawVals)] = internal.KeyToNamespacedKey("", rawVal)
}
}
return vals, nil
}
return indexer.AddIndexers(cache.Indexers{internal.FieldIndexName(field): indexFunc})
}

Copy link
Member

Choose a reason for hiding this comment

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

@vincepri From the looks of it, that field indexes both the namespaced and non-namespaced keys for each value, so wouldn't there be a collision for the non-namespaced value of two clusters with the same name in different namespaces?

@davidewatson
Copy link
Contributor

davidewatson commented Feb 11, 2019

Modulo @detiber's comments, plus one from me. I'd like if the Cluster object were the user interface for managing clusters.

@@ -58,6 +58,10 @@ func newReconciler(mgr manager.Manager, actuator Actuator) reconcile.Reconciler
actuator: actuator,
}

mgr.GetFieldIndexer().IndexField(&clusterv1.Cluster{}, "metadata.name", func(obj runtime.Object) []string {
Copy link
Contributor

Choose a reason for hiding this comment

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

there is another option to filter cluster object by using LabelSelector,
it does require adding a new label to cluster object.

// ListOptions contains options for limitting or filtering results.
// It's generally a subset of metav1.ListOptions, with support for
// pre-parsed selectors (since generally, selectors will be executed
// against the cache).
type ListOptions struct {
	// LabelSelector filters results by label.  Use SetLabelSelector to
	// set from raw string form.
	LabelSelector labels.Selector
	// FieldSelector filters results by a particular field.  In order
	// to use this with cache-based implementations, restrict usage to
	// a single field-value pair that's been added to the indexers.
	FieldSelector fields.Selector

have you considered this?
i guess my point is to avoid this extra indexing logic.

Copy link
Member Author

Choose a reason for hiding this comment

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

The problem that I see using labels is that it doesn't guarantee uniqueness and if we duplicate the name there we'd need to keep it in sync, which isn't ideal

@figo
Copy link
Contributor

figo commented Feb 12, 2019

/lgtm

@k8s-ci-robot
Copy link
Contributor

@figo: changing LGTM is restricted to assignees, and only kubernetes-sigs/cluster-api repo collaborators may be assigned issues.

In response to this:

/lgtm

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@detiber
Copy link
Member

detiber commented Feb 12, 2019

@figo since you are already a member of the kubernetes org, you can request to be added to kubernetes-sigs as well, which will give you the ability to be assigned issues in this repo: https://github.com/kubernetes/community/blob/master/community-membership.md#kubernetes-ecosystem

@detiber
Copy link
Member

detiber commented Feb 12, 2019

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Feb 12, 2019
@k8s-ci-robot k8s-ci-robot merged commit 4b4ec3b into kubernetes-sigs:master Feb 12, 2019
@vincepri vincepri deleted the cluster-name-index-field branch July 26, 2019 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants