Skip to content

Commit

Permalink
fix: Delete unused status keys from watchable (envoyproxy#2782)
Browse files Browse the repository at this point in the history
* Delete unused status keys in gatewayapi-runner

Signed-off-by: Yuneui Jeong <uniglot@proton.me>

* Delete unused status keys in xds-translator runner

Signed-off-by: Yuneui Jeong <uniglot@proton.me>

* Add tests and fix code to pass all tests

Signed-off-by: Yuneui Jeong <uniglot@proton.me>

* Cover more

Signed-off-by: Yuneui <uniglot@proton.me>

* Change struct's name and other minor fixes

Signed-off-by: Yuneui Jeong <uniglot@proton.me>

---------

Signed-off-by: Yuneui Jeong <uniglot@proton.me>
Signed-off-by: Yuneui <uniglot@proton.me>
  • Loading branch information
uniglot authored and Xunzhuo committed Mar 13, 2024
1 parent fc04eed commit 2ad0e89
Show file tree
Hide file tree
Showing 4 changed files with 382 additions and 18 deletions.
192 changes: 181 additions & 11 deletions internal/gatewayapi/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"context"

"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
v1 "sigs.k8s.io/gateway-api/apis/v1"

"github.com/envoyproxy/gateway/api/v1alpha1"
Expand Down Expand Up @@ -56,15 +57,23 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
// so when a delete is triggered, delete all IR keys
if update.Delete || val == nil {
r.deleteAllIRKeys()
r.deleteAllStatusKeys()
return
}

var curKeys, newKeys []string
// IR keys for watchable
var curIRKeys, newIRKeys []string

// Get current IR keys
for key := range r.InfraIR.LoadAll() {
curKeys = append(curKeys, key)
curIRKeys = append(curIRKeys, key)
}

// Get all status keys from watchable and save them in this StatusesToDelete structure.
// Iterating through the controller resources, any valid keys will be removed from statusesToDelete.
// Remaining keys will be deleted from watchable before we exit this function.
statusesToDelete := r.getAllStatuses()

for _, resources := range *val {
// Translate and publish IRs.
t := &gatewayapi.Translator{
Expand Down Expand Up @@ -95,7 +104,7 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
errChan <- err
} else {
r.InfraIR.Store(key, val)
newKeys = append(newKeys, key)
newIRKeys = append(newIRKeys, key)
}
}

Expand All @@ -114,61 +123,75 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
gateway := gateway
key := utils.NamespacedName(gateway)
r.ProviderResources.GatewayStatuses.Store(key, &gateway.Status)
delete(statusesToDelete.GatewayStatusKeys, key)
}
for _, httpRoute := range result.HTTPRoutes {
httpRoute := httpRoute
key := utils.NamespacedName(httpRoute)
r.ProviderResources.HTTPRouteStatuses.Store(key, &httpRoute.Status)
delete(statusesToDelete.HTTPRouteStatusKeys, key)
}
for _, grpcRoute := range result.GRPCRoutes {
grpcRoute := grpcRoute
key := utils.NamespacedName(grpcRoute)
r.ProviderResources.GRPCRouteStatuses.Store(key, &grpcRoute.Status)
delete(statusesToDelete.GRPCRouteStatusKeys, key)
}

for _, tlsRoute := range result.TLSRoutes {
tlsRoute := tlsRoute
key := utils.NamespacedName(tlsRoute)
r.ProviderResources.TLSRouteStatuses.Store(key, &tlsRoute.Status)
delete(statusesToDelete.TLSRouteStatusKeys, key)
}
for _, tcpRoute := range result.TCPRoutes {
tcpRoute := tcpRoute
key := utils.NamespacedName(tcpRoute)
r.ProviderResources.TCPRouteStatuses.Store(key, &tcpRoute.Status)
delete(statusesToDelete.TCPRouteStatusKeys, key)
}
for _, udpRoute := range result.UDPRoutes {
udpRoute := udpRoute
key := utils.NamespacedName(udpRoute)
r.ProviderResources.UDPRouteStatuses.Store(key, &udpRoute.Status)
delete(statusesToDelete.UDPRouteStatusKeys, key)
}
for _, backendTLSPolicy := range result.BackendTLSPolicies {
backendTLSPolicy := backendTLSPolicy
key := utils.NamespacedName(backendTLSPolicy)
r.ProviderResources.BackendTLSPolicyStatuses.Store(key, &backendTLSPolicy.Status)
delete(statusesToDelete.BackendTLSPolicyStatusKeys, key)
}

for _, clientTrafficPolicy := range result.ClientTrafficPolicies {
clientTrafficPolicy := clientTrafficPolicy
key := utils.NamespacedName(clientTrafficPolicy)
r.ProviderResources.ClientTrafficPolicyStatuses.Store(key, &clientTrafficPolicy.Status)
delete(statusesToDelete.ClientTrafficPolicyStatusKeys, key)
}
for _, backendTrafficPolicy := range result.BackendTrafficPolicies {
backendTrafficPolicy := backendTrafficPolicy
key := utils.NamespacedName(backendTrafficPolicy)
r.ProviderResources.BackendTrafficPolicyStatuses.Store(key, &backendTrafficPolicy.Status)
delete(statusesToDelete.BackendTrafficPolicyStatusKeys, key)
}
for _, securityPolicy := range result.SecurityPolicies {
securityPolicy := securityPolicy
key := utils.NamespacedName(securityPolicy)
r.ProviderResources.SecurityPolicyStatuses.Store(key, &securityPolicy.Status)
}
for _, backendTLSPolicy := range result.BackendTLSPolicies {
backendTLSPolicy := backendTLSPolicy
key := utils.NamespacedName(backendTLSPolicy)
r.ProviderResources.BackendTLSPolicyStatuses.Store(key, &backendTLSPolicy.Status)
delete(statusesToDelete.SecurityPolicyStatusKeys, key)
}
}
// Delete keys

// Delete IR keys
// There is a 1:1 mapping between infra and xds IR keys
delKeys := getIRKeysToDelete(curKeys, newKeys)
delKeys := getIRKeysToDelete(curIRKeys, newIRKeys)
for _, key := range delKeys {
r.InfraIR.Delete(key)
r.XdsIR.Delete(key)
}

// Delete status keys
r.deleteStatusKeys(statusesToDelete)
},
)
r.Logger.Info("shutting down")
Expand All @@ -182,6 +205,153 @@ func (r *Runner) deleteAllIRKeys() {
}
}

type StatusesToDelete struct {
GatewayStatusKeys map[types.NamespacedName]bool
HTTPRouteStatusKeys map[types.NamespacedName]bool
GRPCRouteStatusKeys map[types.NamespacedName]bool
TLSRouteStatusKeys map[types.NamespacedName]bool
TCPRouteStatusKeys map[types.NamespacedName]bool
UDPRouteStatusKeys map[types.NamespacedName]bool
BackendTLSPolicyStatusKeys map[types.NamespacedName]bool

ClientTrafficPolicyStatusKeys map[types.NamespacedName]bool
BackendTrafficPolicyStatusKeys map[types.NamespacedName]bool
SecurityPolicyStatusKeys map[types.NamespacedName]bool
}

func (r *Runner) getAllStatuses() *StatusesToDelete {
// Maps storing status keys to be deleted
ds := &StatusesToDelete{
GatewayStatusKeys: make(map[types.NamespacedName]bool),
HTTPRouteStatusKeys: make(map[types.NamespacedName]bool),
GRPCRouteStatusKeys: make(map[types.NamespacedName]bool),
TLSRouteStatusKeys: make(map[types.NamespacedName]bool),
TCPRouteStatusKeys: make(map[types.NamespacedName]bool),
UDPRouteStatusKeys: make(map[types.NamespacedName]bool),

ClientTrafficPolicyStatusKeys: make(map[types.NamespacedName]bool),
BackendTrafficPolicyStatusKeys: make(map[types.NamespacedName]bool),
SecurityPolicyStatusKeys: make(map[types.NamespacedName]bool),
BackendTLSPolicyStatusKeys: make(map[types.NamespacedName]bool),
}

// Get current status keys
for key := range r.ProviderResources.GatewayStatuses.LoadAll() {
ds.GatewayStatusKeys[key] = true
}
for key := range r.ProviderResources.HTTPRouteStatuses.LoadAll() {
ds.HTTPRouteStatusKeys[key] = true
}
for key := range r.ProviderResources.GRPCRouteStatuses.LoadAll() {
ds.GRPCRouteStatusKeys[key] = true
}
for key := range r.ProviderResources.TLSRouteStatuses.LoadAll() {
ds.TLSRouteStatusKeys[key] = true
}
for key := range r.ProviderResources.TCPRouteStatuses.LoadAll() {
ds.TCPRouteStatusKeys[key] = true
}
for key := range r.ProviderResources.UDPRouteStatuses.LoadAll() {
ds.UDPRouteStatusKeys[key] = true
}
for key := range r.ProviderResources.BackendTLSPolicyStatuses.LoadAll() {
ds.BackendTLSPolicyStatusKeys[key] = true
}

for key := range r.ProviderResources.ClientTrafficPolicyStatuses.LoadAll() {
ds.ClientTrafficPolicyStatusKeys[key] = true
}
for key := range r.ProviderResources.BackendTrafficPolicyStatuses.LoadAll() {
ds.BackendTrafficPolicyStatusKeys[key] = true
}
for key := range r.ProviderResources.SecurityPolicyStatuses.LoadAll() {
ds.SecurityPolicyStatusKeys[key] = true
}

return ds
}

func (r *Runner) deleteStatusKeys(ds *StatusesToDelete) {
for key := range ds.GatewayStatusKeys {
r.ProviderResources.GatewayStatuses.Delete(key)
delete(ds.GatewayStatusKeys, key)
}
for key := range ds.HTTPRouteStatusKeys {
r.ProviderResources.HTTPRouteStatuses.Delete(key)
delete(ds.HTTPRouteStatusKeys, key)
}
for key := range ds.GRPCRouteStatusKeys {
r.ProviderResources.GRPCRouteStatuses.Delete(key)
delete(ds.GRPCRouteStatusKeys, key)
}
for key := range ds.TLSRouteStatusKeys {
r.ProviderResources.TLSRouteStatuses.Delete(key)
delete(ds.TLSRouteStatusKeys, key)
}
for key := range ds.TCPRouteStatusKeys {
r.ProviderResources.TCPRouteStatuses.Delete(key)
delete(ds.TCPRouteStatusKeys, key)
}
for key := range ds.UDPRouteStatusKeys {
r.ProviderResources.UDPRouteStatuses.Delete(key)
delete(ds.UDPRouteStatusKeys, key)
}

for key := range ds.ClientTrafficPolicyStatusKeys {
r.ProviderResources.ClientTrafficPolicyStatuses.Delete(key)
delete(ds.ClientTrafficPolicyStatusKeys, key)
}
for key := range ds.BackendTrafficPolicyStatusKeys {
r.ProviderResources.BackendTrafficPolicyStatuses.Delete(key)
delete(ds.BackendTrafficPolicyStatusKeys, key)
}
for key := range ds.SecurityPolicyStatusKeys {
r.ProviderResources.SecurityPolicyStatuses.Delete(key)
delete(ds.SecurityPolicyStatusKeys, key)
}
for key := range ds.BackendTLSPolicyStatusKeys {
r.ProviderResources.BackendTLSPolicyStatuses.Delete(key)
delete(ds.BackendTLSPolicyStatusKeys, key)
}
}

// deleteAllStatusKeys deletes all status keys stored by the subscriber.
func (r *Runner) deleteAllStatusKeys() {
// Fields of GatewayAPIStatuses
for key := range r.ProviderResources.GatewayStatuses.LoadAll() {
r.ProviderResources.GatewayStatuses.Delete(key)
}
for key := range r.ProviderResources.HTTPRouteStatuses.LoadAll() {
r.ProviderResources.HTTPRouteStatuses.Delete(key)
}
for key := range r.ProviderResources.GRPCRouteStatuses.LoadAll() {
r.ProviderResources.GRPCRouteStatuses.Delete(key)
}
for key := range r.ProviderResources.TLSRouteStatuses.LoadAll() {
r.ProviderResources.TLSRouteStatuses.Delete(key)
}
for key := range r.ProviderResources.TCPRouteStatuses.LoadAll() {
r.ProviderResources.TCPRouteStatuses.Delete(key)
}
for key := range r.ProviderResources.UDPRouteStatuses.LoadAll() {
r.ProviderResources.UDPRouteStatuses.Delete(key)
}
for key := range r.ProviderResources.BackendTLSPolicyStatuses.LoadAll() {
r.ProviderResources.BackendTLSPolicyStatuses.Delete(key)
}

// Fields of PolicyStatuses
for key := range r.ProviderResources.ClientTrafficPolicyStatuses.LoadAll() {
r.ProviderResources.ClientTrafficPolicyStatuses.Delete(key)
}
for key := range r.ProviderResources.BackendTrafficPolicyStatuses.LoadAll() {
r.ProviderResources.BackendTrafficPolicyStatuses.Delete(key)
}
for key := range r.ProviderResources.SecurityPolicyStatuses.LoadAll() {
r.ProviderResources.SecurityPolicyStatuses.Delete(key)
}
}

// getIRKeysToDelete returns the list of IR keys to delete
// based on the difference between the current keys and the
// new keys parameters passed to the function.
Expand Down
Loading

0 comments on commit 2ad0e89

Please sign in to comment.