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

feat: generate fallback cache snapshot excluding affected objects #6047

Merged
merged 1 commit into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,11 @@ Adding a new version? You'll need three changes:
[#5982](https://github.com/Kong/kubernetes-ingress-controller/pull/5982)
[#6006](https://github.com/Kong/kubernetes-ingress-controller/pull/6006)
- Added `FallbackConfiguration` feature gate to enable the controller to generate a fallback configuration
for Kong when it fails to apply the configuration. The feature gate is disabled by default.
for Kong when it fails to apply the original one. The feature gate is disabled by default.
[#5993](https://github.com/Kong/kubernetes-ingress-controller/pull/5993)
[#6010](https://github.com/Kong/kubernetes-ingress-controller/pull/6010)
[#6047](https://github.com/Kong/kubernetes-ingress-controller/pull/6047)

- Add support for Kubernetes Gateway API v1.1:
- add a flag `--enable-controller-gwapi-grpcroute` to control whether enable or disable GRPCRoute controller.
- add support for `GRPCRoute` v1, which requires users to upgrade the Gateway API's CRD to v1.1.
Expand Down
62 changes: 62 additions & 0 deletions internal/dataplane/fallback/cache_to_graph.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package fallback

import (
"errors"
"fmt"

"github.com/dominikbraun/graph"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/kong/kubernetes-ingress-controller/v3/internal/store"
)

// DefaultCacheGraphProvider is a default implementation of the CacheGraphProvider interface.
type DefaultCacheGraphProvider struct{}

func NewDefaultCacheGraphProvider() *DefaultCacheGraphProvider {
return &DefaultCacheGraphProvider{}
}

// CacheToGraph creates a new ConfigGraph from the given cache stores. It adds all objects
// from the cache stores to the graph as vertices as well as edges between objects and their dependencies
// resolved by the ResolveDependencies function.
func (p DefaultCacheGraphProvider) CacheToGraph(c store.CacheStores) (*ConfigGraph, error) {
g := NewConfigGraph()

for _, s := range c.ListAllStores() {
for _, o := range s.List() {
obj, ok := o.(client.Object)
if !ok {
// Should not happen since all objects in the cache are client.Objects, but better safe than sorry.
return nil, fmt.Errorf("expected client.Object, got %T", o)
}
// Add the object to the graph. It can happen that the object is already in the graph (i.e. was already added
// as a dependency of another object), in which case we ignore the error.
if err := g.AddVertex(obj); err != nil && !errors.Is(err, graph.ErrVertexAlreadyExists) {
return nil, fmt.Errorf("failed to add %s to the graph: %w", GetObjectHash(obj), err)
}

deps, err := ResolveDependencies(c, obj)
if err != nil {
return nil, fmt.Errorf("failed to resolve dependencies for %s: %w", GetObjectHash(obj), err)
}
// Add the object's dependencies to the graph.
for _, dep := range deps {
// Add the dependency to the graph in case it wasn't added before. If it was added before, we ignore the
// error.
if err := g.AddVertex(dep); err != nil && !errors.Is(err, graph.ErrVertexAlreadyExists) {
return nil, fmt.Errorf("failed to add %s to the graph: %w", GetObjectHash(obj), err)
}

// Add an edge from a dependency to the object. If the edge was already added before, we ignore the error.
// It's on purpose that we add the edge from the dependency to the object, as it makes it easier to traverse
// the graph from the object to its dependants once it is broken.
if err := g.AddEdge(GetObjectHash(dep), GetObjectHash(obj)); err != nil && !errors.Is(err, graph.ErrEdgeAlreadyExists) {
return nil, fmt.Errorf("failed to add edge from %s to %s: %w", GetObjectHash(obj), GetObjectHash(dep), err)
}
}
}
}

return g, nil
}
Loading
Loading