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

Fix Service object remove from resource map from route controller #549

Merged
merged 7 commits into from
Oct 18, 2022

Conversation

chauhanshubham
Copy link
Member

This commit fetches the services that were referenced by the route which has now been deleted, and removes those objects from the resource map. In order to facilitate this, the commit introduces a provider cache for kubernetes that stores mappings between kubernetes objects - for now it stores the map between [tls/http]route -> backend service references.
So that once the [tls/http]route is deleted we have the services that it referenced.
Fixes: #536

Signed-off-by: Shubham Chauhan shubham@tetrate.io

This commit fetches the services that were referenced by the route
which has now been deleted, and removes those objects from the
resource map. In order to facilitate this, the commit introduces
a provider cache for kubernetes that stores mappings between
kubernetes objects - for now it stores the map between
[tls/http]route -> backend service references.
So that once the [tls/http]route is deleted we have the services that
it referenced.

Signed-off-by: Shubham Chauhan <shubham@tetrate.io>
@chauhanshubham chauhanshubham requested a review from a team as a code owner October 12, 2022 09:16
@chauhanshubham chauhanshubham marked this pull request as draft October 12, 2022 09:17
@codecov-commenter
Copy link

codecov-commenter commented Oct 12, 2022

Codecov Report

Merging #549 (fb48c25) into main (2fb3ca8) will decrease coverage by 0.36%.
The diff coverage is 74.68%.

@@            Coverage Diff             @@
##             main     #549      +/-   ##
==========================================
- Coverage   60.98%   60.61%   -0.37%     
==========================================
  Files          45       47       +2     
  Lines        5564     5721     +157     
==========================================
+ Hits         3393     3468      +75     
- Misses       1968     2034      +66     
- Partials      203      219      +16     
Impacted Files Coverage Δ
internal/provider/kubernetes/kubernetes.go 50.94% <50.00%> (+2.94%) ⬆️
internal/provider/kubernetes/tlsroute.go 51.98% <54.54%> (-14.69%) ⬇️
internal/provider/kubernetes/httproute.go 57.61% <55.55%> (-8.48%) ⬇️
internal/provider/kubernetes/store.go 100.00% <100.00%> (ø)
internal/infrastructure/kubernetes/configmap.go 75.86% <0.00%> (-6.60%) ⬇️
...ternal/infrastructure/kubernetes/serviceaccount.go 77.96% <0.00%> (-4.80%) ⬇️
internal/xds/translator/listener.go 81.42% <0.00%> (-4.40%) ⬇️
internal/gatewayapi/contexts.go 76.02% <0.00%> (-4.12%) ⬇️
... and 11 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@chauhanshubham chauhanshubham marked this pull request as ready for review October 12, 2022 10:25
@danehans danehans added the provider/kubernetes Issues related to the Kubernetes provider label Oct 12, 2022
@danehans danehans added this to the 0.2.0 milestone Oct 12, 2022
@danehans danehans added the kind/bug Something isn't working label Oct 13, 2022
@arkodg
Copy link
Contributor

arkodg commented Oct 13, 2022

thanks for working on this !
this functionality will most likely not be needed once #413 is in since it will always build out SoTW from scratch, using the controller runtime cache, but it might make sense to introduce this PR if we want to support RefereneGrant in 0.2.0 since #539 (a much more severe consequence of not removing the resource) will leverage the same library introduced in this PR

@chauhanshubham
Copy link
Member Author

chauhanshubham commented Oct 13, 2022

Will there not be a need to store Service objects any more in the resource map post 413?
Could we try fetching the Services from the controller cache right now itself? doesn't seem to depend on 413. Maybe I'm missing something.
We'll have to pass on the client to the gatewayapi/translator for fetching these objects.

I'm looking at

func (r *Resources) GetService(namespace, name string) *v1.Service {

The GetNamespace, GetService, and GetSecret functions here, that try fetching it from the Resources struct, instead we could read it from the controller cache perhaps? We can add a similar GetReferenceGrant too.

@arkodg
Copy link
Contributor

arkodg commented Oct 13, 2022

Will there not be a need to store Service objects any more in the resource map post 413? Could we try fetching the Services from the controller cache right now itself? doesn't seem to depend on 413. Maybe I'm missing something. We'll have to pass on the client to the gatewayapi/translator for fetching these objects.

I'm looking at

func (r *Resources) GetService(namespace, name string) *v1.Service {

The GetNamespace, GetService, and GetSecret functions here, that try fetching it from the Resources struct, instead we could read it from the controller cache perhaps? We can add a similar GetReferenceGrant too.

I was referring to the fact that we won't need to handle delete logic anymore with #413 .

  • Any changes to gatewayclasses, gateways, httproutes, services .... will trigger a reconcile
  • the function would build all the resource state from scratch starting from the accepted GatewayClass
type resource struct {
GatewayClass string
Gateways []*v1b1.Gateway
HTTPRoutes []*v1b1.HTTPRoute
....

and update the watchable map with the same key, so we dont need to deal with deletes in the provider anymore

  • if we want to add watches for specific services, namespaces etc. we might need to handle delete logic there

arkodg
arkodg previously approved these changes Oct 13, 2022
Copy link
Contributor

@arkodg arkodg left a comment

Choose a reason for hiding this comment

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

🚀

LukeShu
LukeShu previously approved these changes Oct 17, 2022
Copy link
Contributor

@LukeShu LukeShu left a comment

Choose a reason for hiding this comment

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

There are some things I think should be changed, but if we want to get this in to 0.2.0, I'm OK merging as-is and cleaning it up later.

Comment on lines 15 to 19
// routeToServicesMappings maintains a mapping of a Route object,
// and the Services it references. For instance
// HTTPRoute/ns1/route1 -> { ns1/svc1, ns1/svc2, ns2/svc1 }
// TLSRoute/ns1/route1 -> { ns1/svc1, ns2/svc2 }
routeToServicesMappings map[string]sets.String
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use typed structs, instead of having to wrangle strings?

type routeIdentifier struct {
    Kind      string
    Namespace string
    Name      string
}

routeToServicesMappings map[routeIdentifier]Set[types.NamespacedName]

(it's easy enough to write a type-parametarized Set[T] (example) but if we don't want to do that, map[types.NamespacedName]struct{} would do in a pinch)

// providerCache maintains additional mappings related to Kubernetes provider
// resources. The mappings are regularly updated from the reconcilers based
// on the existence of the object in the Kubernetes datastore.
type providerCache struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

Calling this a "cache" is misleading. It isn't really a cache, it's a reference-counting machine.

Comment on lines 56 to 66
func (p *providerCache) isServiceReferredByRoutes(service string) bool {
p.mu.Lock()
defer p.mu.Unlock()

for _, svcs := range p.routeToServicesMappings {
if svcs.Has(service) {
return true
}
}
return false
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is O(n), and that makes me uneasy. Would it make sense to have the primary key be the service, rather than the route?

Copy link
Member Author

@chauhanshubham chauhanshubham Oct 18, 2022

Choose a reason for hiding this comment

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

It will probably get uglier if we use the reverse mapping with the service as P.K.
As we need to query this primarily - Find all services for a Route r1 which was deleted, while reconciling the deleted Route r1. With service as the P.K. we'll have to traverse all the Services (and find a route match) which will be more than the number of TLS/HTTP Routes. (Note that with route as the P.K we are filtering based on kind too)

I started off by adding multiple mappings like route-to-services and service-to-routes, but seemed like we're optimizing at the cost of double the memory, so stuck with the route-to-services mapping only.

Signed-off-by: Shubham Chauhan <shubham@tetrate.io>
@chauhanshubham chauhanshubham dismissed stale reviews from LukeShu and arkodg via b9f6843 October 18, 2022 08:41
Signed-off-by: Shubham Chauhan <shubham@tetrate.io>
@arkodg
Copy link
Contributor

arkodg commented Oct 18, 2022

hey @chauhanshubham can you rm the docs/user/tls-passthrough.md changes from this PR :)

Signed-off-by: Shubham Chauhan <shubham@tetrate.io>
Signed-off-by: Shubham Chauhan <shubham@tetrate.io>
Signed-off-by: Shubham Chauhan <shubham@tetrate.io>
Signed-off-by: Shubham Chauhan <shubham@tetrate.io>
@LukeShu LukeShu self-requested a review October 18, 2022 17:07
Copy link
Contributor

@LukeShu LukeShu left a comment

Choose a reason for hiding this comment

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

Thanks!

@arkodg arkodg merged commit 9ab00f2 into envoyproxy:main Oct 18, 2022
danehans pushed a commit to danehans/gateway that referenced this pull request Nov 3, 2022
…voyproxy#549)

* Fix Service object remove from resource map from route controller

This commit fetches the services that were referenced by the route
which has now been deleted, and removes those objects from the
resource map. In order to facilitate this, the commit introduces
a provider cache for kubernetes that stores mappings between
kubernetes objects - for now it stores the map between
[tls/http]route -> backend service references.
So that once the [tls/http]route is deleted we have the services that
it referenced.

Signed-off-by: Shubham Chauhan <shubham@tetrate.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working provider/kubernetes Issues related to the Kubernetes provider
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix logic for deleting Services from ProviderResources
5 participants