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

kuma-cp: add a custom version of SnapshotCache that supports arbitrary xDS resources #528

Merged
merged 3 commits into from
Jan 10, 2020
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

Changes:

* feature: add a custom version of SnapshotCache that supports arbitrary xDS resources
[#528](https://github.com/Kong/kuma/pull/528)
* feature: add proto definition for Monitoring Assignment Discovery Service (MADS)
[#525](https://github.com/Kong/kuma/pull/525)
* feature: enable Envoy Admin API by default with an option to opt out
Expand Down
13 changes: 13 additions & 0 deletions pkg/mads/cache/cache_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cache_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestCache(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Cache Suite")
}
79 changes: 79 additions & 0 deletions pkg/mads/cache/snapshot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package cache

import (
"github.com/pkg/errors"

envoy_cache "github.com/envoyproxy/go-control-plane/pkg/cache"

"github.com/Kong/kuma/pkg/mads"
util_xds "github.com/Kong/kuma/pkg/util/xds"
)

// NewSnapshot creates a snapshot from response types and a version.
func NewSnapshot(version string, assignments map[string]envoy_cache.Resource) *Snapshot {
return &Snapshot{
MonitoringAssignments: envoy_cache.Resources{Version: version, Items: assignments},
}
}

// Snapshot is an internally consistent snapshot of xDS resources.
type Snapshot struct {
MonitoringAssignments envoy_cache.Resources
}

var _ util_xds.Snapshot = &Snapshot{}

// GetSupportedTypes returns a list of xDS types supported by this snapshot.
func (s *Snapshot) GetSupportedTypes() []string {
return []string{mads.MonitoringAssignmentType}
}

// Consistent check verifies that the dependent resources are exactly listed in the
// snapshot.
func (s *Snapshot) Consistent() error {
if s == nil {
return errors.New("nil snapshot")
}
return nil
}

// GetResources selects snapshot resources by type.
func (s *Snapshot) GetResources(typ string) map[string]envoy_cache.Resource {
if s == nil {
return nil
}
switch typ {
case mads.MonitoringAssignmentType:
return s.MonitoringAssignments.Items
}
return nil
}

// GetVersion returns the version for a resource type.
func (s *Snapshot) GetVersion(typ string) string {
if s == nil {
return ""
}
switch typ {
case mads.MonitoringAssignmentType:
return s.MonitoringAssignments.Version
}
return ""
}

// WithVersion creates a new snapshot with a different version for a given resource type.
func (s *Snapshot) WithVersion(typ string, version string) util_xds.Snapshot {
if s == nil {
return nil
}
if s.GetVersion(typ) == version {
return s
}
switch typ {
case mads.MonitoringAssignmentType:
return &Snapshot{
MonitoringAssignments: envoy_cache.Resources{Version: version, Items: s.MonitoringAssignments.Items},
}
}
return s
}
185 changes: 185 additions & 0 deletions pkg/mads/cache/snapshot_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package cache_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

envoy_cache "github.com/envoyproxy/go-control-plane/pkg/cache"

. "github.com/Kong/kuma/pkg/mads/cache"

observability_proto "github.com/Kong/kuma/api/observability/v1alpha1"
)

var _ = Describe("Snapshot", func() {

expectedType := "type.googleapis.com/kuma.observability.v1alpha1.MonitoringAssignment"

Describe("GetSupportedTypes()", func() {
It("should always return ['type.googleapis.com/kuma.observability.v1alpha1.MonitoringAssignment']", func() {
// when
var snapshot *Snapshot
// then
Expect(snapshot.GetSupportedTypes()).To(Equal([]string{expectedType}))

// when
snapshot = &Snapshot{}
// then
Expect(snapshot.GetSupportedTypes()).To(Equal([]string{expectedType}))
})
})

Describe("Consistent()", func() {
It("should handle `nil`", func() {
// when
var snapshot *Snapshot
// then
Expect(snapshot.Consistent()).To(MatchError("nil snapshot"))
})

It("non-`nil` snapshot should be always consistet", func() {
// when
snapshot := NewSnapshot("v1", nil)
// then
Expect(snapshot.Consistent()).To(BeNil())

// when
snapshot = NewSnapshot("v2", map[string]envoy_cache.Resource{
"backend": &observability_proto.MonitoringAssignment{
Name: "/meshes/default/dataplanes/backend",
},
})
// then
Expect(snapshot.Consistent()).To(BeNil())
})
})

Describe("GetResources()", func() {
It("should handle `nil`", func() {
// when
var snapshot *Snapshot
// then
Expect(snapshot.GetResources(expectedType)).To(BeNil())
})

It("should return MonitoringAssignments", func() {
// given
assignments := map[string]envoy_cache.Resource{
"backend": &observability_proto.MonitoringAssignment{
Name: "/meshes/default/dataplanes/backend",
},
}
// when
snapshot := NewSnapshot("v1", assignments)
// then
Expect(snapshot.GetResources(expectedType)).To(Equal(assignments))
})

It("should return `nil` for unsupported resource types", func() {
// given
assignments := map[string]envoy_cache.Resource{
"backend": &observability_proto.MonitoringAssignment{
Name: "/meshes/default/dataplanes/backend",
},
}
// when
snapshot := NewSnapshot("v1", assignments)
// then
Expect(snapshot.GetResources("unsupported type")).To(BeNil())
})
})

Describe("GetVersion()", func() {
It("should handle `nil`", func() {
// when
var snapshot *Snapshot
// then
Expect(snapshot.GetVersion(expectedType)).To(Equal(""))
})

It("should return proper version for a supported resource type", func() {
// given
assignments := map[string]envoy_cache.Resource{
"backend": &observability_proto.MonitoringAssignment{
Name: "/meshes/default/dataplanes/backend",
},
}
// when
snapshot := NewSnapshot("v1", assignments)
// then
Expect(snapshot.GetVersion(expectedType)).To(Equal("v1"))
})

It("should return an empty string for unsupported resource type", func() {
// given
assignments := map[string]envoy_cache.Resource{
"backend": &observability_proto.MonitoringAssignment{
Name: "/meshes/default/dataplanes/backend",
},
}
// when
snapshot := NewSnapshot("v1", assignments)
// then
Expect(snapshot.GetVersion("unsupported type")).To(Equal(""))
})
})

Describe("WithVersion()", func() {
It("should handle `nil`", func() {
// given
var snapshot *Snapshot
// when
actual := snapshot.WithVersion(expectedType, "v1")
// then
Expect(actual).To(BeNil())
})

It("should return a new snapshot if version has changed", func() {
// given
assignments := map[string]envoy_cache.Resource{
"backend": &observability_proto.MonitoringAssignment{
Name: "/meshes/default/dataplanes/backend",
},
}
snapshot := NewSnapshot("v1", assignments)
// when
actual := snapshot.WithVersion(expectedType, "v2")
// then
Expect(actual.GetVersion(expectedType)).To(Equal("v2"))
// and
Expect(actual).To(Equal(NewSnapshot("v2", assignments)))
})

It("should return the same snapshot if version has not changed", func() {
// given
assignments := map[string]envoy_cache.Resource{
"backend": &observability_proto.MonitoringAssignment{
Name: "/meshes/default/dataplanes/backend",
},
}
snapshot := NewSnapshot("v1", assignments)
// when
actual := snapshot.WithVersion(expectedType, "v1")
// then
Expect(actual.GetVersion(expectedType)).To(Equal("v1"))
// and
Expect(actual).To(BeIdenticalTo(snapshot))
})

It("should return the same snapshot if resource type is not supported", func() {
// given
assignments := map[string]envoy_cache.Resource{
"backend": &observability_proto.MonitoringAssignment{
Name: "/meshes/default/dataplanes/backend",
},
}
snapshot := NewSnapshot("v1", assignments)
// when
actual := snapshot.WithVersion("unsupported type", "v2")
// then
Expect(actual.GetVersion(expectedType)).To(Equal("v1"))
// and
Expect(actual).To(BeIdenticalTo(snapshot))
})
})
})
5 changes: 5 additions & 0 deletions pkg/mads/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package mads

const (
MonitoringAssignmentType = "type.googleapis.com/kuma.observability.v1alpha1.MonitoringAssignment"
)
Loading