Add List/Relist Catalog Restrictions#1773
Add List/Relist Catalog Restrictions#1773carolynvs merged 53 commits intokubernetes-retired:masterfrom
Conversation
pkg/apis/servicecatalog/types.go
Outdated
| type ClusterServiceClassRequirements string | ||
|
|
||
| type ServiceClassCatalogRestrictions struct { | ||
| ServicePlan ClusterServicePlanRequirements |
There was a problem hiding this comment.
It's not clear to me how I would say:
- From this broker, create resources only for service X
- From this broker, create resources for all services but Y
There was a problem hiding this comment.
I have added some more comments to help you understand.
Is there any reason to do this in an Admission Controller instead of in API validation? |
whichever. If you think that API validation is better then yeah lets do that. I have not touched that area of the code yet so I am ignorant of the correct way. |
staebler
left a comment
There was a problem hiding this comment.
Looks to me like a reasonably approach to filtering.
| // Solution: restrictions := ServiceClassCatalogRestrictions{ | ||
| // ServiceClass: "externalName in (FooService, BarService)", | ||
| // } | ||
| // This is an example of a whitelist on service externalName. |
There was a problem hiding this comment.
This is a blacklist not a whitelist, right? It is explicit blocking FooService and BarService.
There was a problem hiding this comment.
I think this could be interpreted in a couple ways: either "Allow all services that are NOT Foo/BarService", which would be an allowance rule and a whitelist. However, ultimately what you're saying here is "Block FooService and BarService", which sounds much more like a blacklist to me.
There was a problem hiding this comment.
The comment may be confusing, I am staying the previous solution is the whitelist.
Above example is whitelist: "externalName in (FooService, BarService)"
Below example is a blacklist: "externalName notin (FooService, BarService)",
in means the thing must be contained in the following list to pass the predicate.
notin means the thing must not be contained in the following list to pass the predicate.
I hope it is just confusion around the Goal, Solution, and English Description format. I can fix that.
There was a problem hiding this comment.
Or you folks are getting caught up on the restrictions name. In that case, I am open to other names that are allowed to house both white and black lists together, example: "externalName in (Demo),name not in (AABBCC)"
There was a problem hiding this comment.
@n3wscott this is getting kind of pedantic, but I interpret a blacklist as "allow everything but these", compared to a whitelist that is "Allow nothing, but pass these". The distinction being a default allowing everything, or nothing. Given that definition, your examples are exactly correct, and the comment is describing a blacklist.
There was a problem hiding this comment.
@n3wscott OK. The confusion for me was the ordering of the comments. I read it to apply to the following rather than the preceding. An empty line between each example would have made it less confusing for me.
There was a problem hiding this comment.
@n3wscott And, for what it's worth, I had no problem understanding the examples. I don't think that there is a need to change the restrictions name.
There was a problem hiding this comment.
Ok updated to hopefully clear this up.
this is getting kind of pedantic
:D
@eriknelson we are staying the same thing and we agree. I updated the comment order and added whitespace to clear this up.
| // } | ||
| type ServiceClassCatalogRestrictions struct { | ||
| // ServiceClass represents a selector for plans, used to filter catalog re-lists. | ||
| ServiceClass ClusterServiceClassRequirements `json:"serviceClass,omitempty"` |
There was a problem hiding this comment.
This should probably be an array
There was a problem hiding this comment.
We will need to be able to translate these strings between API versions, so you might consider whether it would be easier to have a structured definition of a restriction than a string that has to be parsed.
There was a problem hiding this comment.
I could do an array, makes it less easy to fat finger a long string.
As for the structured definition, k8s does both. The object that this turns into is non-trivial because it is pretty powerful and then we either leak the fact we are using label selectors or we have to duplicate the label selector code.
I vote array of strings for now, if that pleases you
There was a problem hiding this comment.
Array of strings is fine for me.
| type ClusterServicePlanRequirements string | ||
|
|
||
| // ServiceClassCatalogRestrictions contains the restrictions used to on catalog re-list. | ||
| // Some examples of this object are as follows: |
There was a problem hiding this comment.
It needs to be more clear that the restriction expressions are in terms of the k8s API resources. It would also be more correct to say spec.externalName than externalName.
There was a problem hiding this comment.
Yes, good call. I think we should make that clear. I had this with field selectors and it got lost when I was attempting label selectors. I can add it back. Then free = true makes a lot more sense when it is next to spec.externalName
|
|
||
| // CatalogRestrictions allows adding restrictions onto Class/Plans on relist. | ||
| // +optional | ||
| CatalogRestrictions *ServiceClassCatalogRestrictions `json:"catalogRestrictions,omitempty"` |
There was a problem hiding this comment.
Why not just make these arrays instead of pointer to typedef?
There was a problem hiding this comment.
ServiceClassCatalogRestrictions is a struct that has arrays for class and plan. So this is a pointer to a struct, not a pointer to a typedef'ed array.
There was a problem hiding this comment.
Now looking at it, I did not mean for this to contain "Class", this type is suppose to be ServiceCatalogRestrictions
I will update.
…g and orphan mitigation) (kubernetes-retired#1803)" This reverts commit 4b5d159.
pmorie
left a comment
There was a problem hiding this comment.
Looking really good, just a few things
| return serviceClasses, servicePlans, nil | ||
| } | ||
|
|
||
| func convertAndFilterCatalog(in *osb.CatalogResponse, restrictions *v1beta1.CatalogRestrictions) ([]*v1beta1.ClusterServiceClass, []*v1beta1.ClusterServicePlan, error) { |
There was a problem hiding this comment.
In the future, we could make this just work with CommonService(Class|Plan)Spec, and have wrappers that built the right types for cluster and ns-scoped. WDYT?
There was a problem hiding this comment.
this currently uses the parent service class name in part of the plan query to aid in the filtering. We are going to need a general strategy on how to deal with this all over the place in the codebase.
There was a problem hiding this comment.
also why I did not just copy/paste yet, I wanted to look into seeing if I can make it work as you asked.
pkg/features/features.go
Outdated
| // alpha: v0.1.6 | ||
| PodPreset utilfeature.Feature = "PodPreset" | ||
|
|
||
| // CatalogRestrictions controls whether the ClusterServiceBroker will use |
There was a problem hiding this comment.
Can we change the verbiage here around "control which services and plans have k8s resources created for them" ?
pkg/filter/predicate.go
Outdated
| ) | ||
|
|
||
| // Want to filter the allowed labels. | ||
| // want to use only |
There was a problem hiding this comment.
I did not mean to leave that in... removed.
pkg/filter/predicate.go
Outdated
| // NotIn Operator = "notin" | ||
| //) | ||
|
|
||
| // Predicate is used to test if this rule accepts the properties given. |
pmorie
left a comment
There was a problem hiding this comment.
Just a couple nits on godoc stuff, but would you also add a simple integration test?
| // +optional | ||
| RelistRequests int64 `json:"relistRequests"` | ||
|
|
||
| // CatalogRestrictions allows adding restrictions onto Class/Plans on relist. |
There was a problem hiding this comment.
bump - can we change the wording here?
| // can be manually incremented by a user to manually trigger a relist. | ||
| RelistRequests int64 | ||
|
|
||
| // CatalogRestrictions is a set of restrictions on which of a broker's services |
There was a problem hiding this comment.
Need to put the same godoc as v1beta1 here.
There was a problem hiding this comment.
ok updated. too much codez... (will push soon)
| spec.CatalogRestrictions.ServiceClass, err.Error())) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
One thing I just thought of: I think we should not allow you to set these fields if the feature gate isn't enabled.
There was a problem hiding this comment.
meh, I am not sure about that. I could see a use for setting this up then turning on or off the feature.
There was a problem hiding this comment.
It's conventional not to allow fields for a feature that isn't enabled.
There was a problem hiding this comment.
If you accept the fields, users will expect them to work.
There was a problem hiding this comment.
the flag has been removed.
charts/catalog/values.yaml
Outdated
| originatingIdentityEnabled: false | ||
| # Whether the AsyncBindingOperations alpha feature should be enabled | ||
| asyncBindingOperationsEnabled: false | ||
| # Whether the CatalogRestrictions alpha feature should be enabled |
There was a problem hiding this comment.
Do we still need this flag, since the feature gate has been removed?
|
Looks like CI failure was a flake - I bounced it. |
|
/retest |
|
Dear Travis, You suck. Sincerely, |
|
Sorted it out, I had old compiled generators locally giving me different things than master expected. PTAL. |
|
This is cool! I'm excited to see this make it in! LGTM. |
| if len(errs) != 0 && tc.valid { | ||
| t.Errorf("%v: unexpected error: %v", tc.name, errs) | ||
| continue | ||
| return |
In this PR I am wrapping the functionality of label selectors to allow us to apply the label selector query/matching syntax for service classes and service plans. This will allow us to create whitelists or blacklists for either class or plan to give lots of control to the cluster operator on which items end up in the catalog.
As a follow-up I will add the needed namespaced version of the added Cluster* methods to be able to do the same work on the new ns objects.
Seeing if we can use labels.Selector to filter the catalog.
Things to do:
[x] Services that are filtered out need to remove their plans.
[x] Services that have all their plans filtered out should be removed.
[x] Testing needs a fuller catalog to test real filtering.
[x] Add filtering behind a feature flag.
[x] API validation should validate the filter string.
[X] Confirm the storage format is ok for the filter.
[X] ---> Internal representation might need to be the processed labels.Selector.Requirements object?
fixes #1604