Skip to content

Commit

Permalink
fix(kuma-cp): fix Zone{In|E}gress sync when no mesh (#8129)
Browse files Browse the repository at this point in the history
- Add ZoneEgresses to AggregatetMeshContexts when there is no mesh.
- Sync ZoneIngresses and ZoneEgresses only when the hash changes.
- Return an error with the correct resource type (ZoneEgress) when
  a ZoneEgress cannot be found.

Signed-off-by: Bart Smykla <bartek@smykla.com>
  • Loading branch information
bartsmykla authored and kumahq[bot] committed Oct 25, 2023
1 parent 3851164 commit 7cc5b0e
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 5 deletions.
70 changes: 70 additions & 0 deletions pkg/xds/context/aggregate_mesh_context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package context

import (
"context"

core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
"github.com/kumahq/kuma/pkg/core/resources/manager"
core_store "github.com/kumahq/kuma/pkg/core/resources/store"
"github.com/kumahq/kuma/pkg/xds/cache/sha256"
)

type meshContextFetcher = func(ctx context.Context, meshName string) (MeshContext, error)

func AggregateMeshContexts(
ctx context.Context,
resManager manager.ReadOnlyResourceManager,
fetcher meshContextFetcher,
) (AggregatedMeshContexts, error) {
var meshList core_mesh.MeshResourceList
if err := resManager.List(ctx, &meshList, core_store.ListOrdered()); err != nil {
return AggregatedMeshContexts{}, err
}

var meshContexts []MeshContext
meshContextsByName := map[string]MeshContext{}
for _, mesh := range meshList.Items {
meshCtx, err := fetcher(ctx, mesh.GetMeta().GetName())
if err != nil {
return AggregatedMeshContexts{}, err
}
meshContexts = append(meshContexts, meshCtx)
meshContextsByName[mesh.Meta.GetName()] = meshCtx
}

hash := aggregatedHash(meshContexts)

egressByName := map[string]*core_mesh.ZoneEgressResource{}
if len(meshContexts) > 0 {
for _, egress := range meshContexts[0].Resources.ZoneEgresses().Items {
egressByName[egress.Meta.GetName()] = egress
}
} else {
var egressList core_mesh.ZoneEgressResourceList
if err := resManager.List(ctx, &egressList, core_store.ListOrdered()); err != nil {
return AggregatedMeshContexts{}, err
}

for _, egress := range egressList.GetItems() {
egressByName[egress.GetMeta().GetName()] = egress.(*core_mesh.ZoneEgressResource)
}

hash = sha256.Hash(hashResources(egressList.GetItems()...))
}

result := AggregatedMeshContexts{
Hash: hash,
Meshes: meshList.Items,
MeshContextsByName: meshContextsByName,
ZoneEgressByName: egressByName,
}
return result, nil
}

func aggregatedHash(meshContexts []MeshContext) string {
var hash string
for _, meshCtx := range meshContexts {
hash += meshCtx.Hash
}
return sha256.Hash(hash)
}
10 changes: 5 additions & 5 deletions pkg/xds/context/mesh_context_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,19 +329,19 @@ func (m *meshContextBuilder) hash(mesh *core_mesh.MeshResource, resources Resour
allResources = append(allResources, rl.GetItems()...)
}
}
return sha256.Hash(m.hashResources(allResources...))
return sha256.Hash(hashResources(allResources...))
}

func (m *meshContextBuilder) hashResources(rs ...core_model.Resource) string {
hashes := []string{}
func hashResources(rs ...core_model.Resource) string {
var hashes []string
for _, r := range rs {
hashes = append(hashes, m.hashResource(r))
hashes = append(hashes, hashResource(r))
}
sort.Strings(hashes)
return strings.Join(hashes, ",")
}

func (m *meshContextBuilder) hashResource(r core_model.Resource) string {
func hashResource(r core_model.Resource) string {
switch v := r.(type) {
// In case of hashing Dataplane we are also adding '.Spec.Networking.Address' and `.Spec.Networking.Ingress.PublicAddress` into hash.
// The address could be a domain name and right now we resolve it right after fetching
Expand Down
34 changes: 34 additions & 0 deletions pkg/xds/sync/dataplane_watchdog.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,24 @@ func (d *DataplaneWatchdog) syncIngress(ctx context.Context, metadata *core_xds.
if err != nil {
return err
}
<<<<<<< HEAD
envoyAdminMTLS, err := d.getEnvoyAdminMTLS(ctx, proxy.ZoneIngressProxy.ZoneIngressResource.Spec.GetNetworking().GetAddress())
=======

result := SyncResult{
ProxyType: mesh_proto.IngressProxyType,
}
syncForConfig := aggregatedMeshCtxs.Hash != d.lastHash
if !syncForConfig {
result.Status = SkipStatus
return result, nil
}

d.log.V(1).Info("snapshot hash updated, reconcile", "prev", d.lastHash, "current", aggregatedMeshCtxs.Hash)
d.lastHash = aggregatedMeshCtxs.Hash

proxy, err := d.IngressProxyBuilder.Build(ctx, d.key, aggregatedMeshCtxs)
>>>>>>> 1912999c9 (fix(kuma-cp): fix Zone{In|E}gress sync when no mesh (#8129))
if err != nil {
return errors.Wrap(err, "could not get Envoy Admin mTLS certs")
}
Expand All @@ -165,7 +182,24 @@ func (d *DataplaneWatchdog) syncEgress(ctx context.Context, metadata *core_xds.D
if err != nil {
return err
}
<<<<<<< HEAD
envoyAdminMTLS, err := d.getEnvoyAdminMTLS(ctx, proxy.ZoneEgressProxy.ZoneEgressResource.Spec.Networking.Address)
=======

result := SyncResult{
ProxyType: mesh_proto.EgressProxyType,
}
syncForConfig := aggregatedMeshCtxs.Hash != d.lastHash
if !syncForConfig {
result.Status = SkipStatus
return result, nil
}

d.log.V(1).Info("snapshot hash updated, reconcile", "prev", d.lastHash, "current", aggregatedMeshCtxs.Hash)
d.lastHash = aggregatedMeshCtxs.Hash

proxy, err := d.EgressProxyBuilder.Build(ctx, d.key, aggregatedMeshCtxs)
>>>>>>> 1912999c9 (fix(kuma-cp): fix Zone{In|E}gress sync when no mesh (#8129))
if err != nil {
return errors.Wrap(err, "could not get Envoy Admin mTLS certs")
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/xds/sync/egress_proxy_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (p *EgressProxyBuilder) Build(
ctx context.Context,
key core_model.ResourceKey,
) (*core_xds.Proxy, error) {
<<<<<<< HEAD
zoneEgress := core_mesh.NewZoneEgressResource()

if err := p.ReadOnlyResManager.Get(
Expand All @@ -49,6 +50,11 @@ func (p *EgressProxyBuilder) Build(
var meshList core_mesh.MeshResourceList
if err := p.ReadOnlyResManager.List(ctx, &meshList); err != nil {
return nil, err
=======
zoneEgress, ok := aggregatedMeshCtxs.ZoneEgressByName[key.Name]
if !ok {
return nil, core_store.ErrorResourceNotFound(core_mesh.ZoneEgressType, key.Name, key.Mesh)
>>>>>>> 1912999c9 (fix(kuma-cp): fix Zone{In|E}gress sync when no mesh (#8129))
}

// As egress is using SNI to identify the services, we need to filter out
Expand Down

0 comments on commit 7cc5b0e

Please sign in to comment.