Skip to content

Commit

Permalink
Add peerName to ExportedServices. (#1239)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashwin Venkatesh authored and ndhanushkodi committed Jun 15, 2022
1 parent 81bebb9 commit 48d71c2
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 7 deletions.
4 changes: 4 additions & 0 deletions charts/consul/templates/crd-exportedservices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ spec:
description: Partition is the admin partition to export
the service to.
type: string
peerName:
description: PeerName is the name of the peer to export
the service to.
type: string
type: object
type: array
name:
Expand Down
30 changes: 26 additions & 4 deletions control-plane/api/v1alpha1/exportedservices_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ type ExportedService struct {
type ServiceConsumer struct {
// Partition is the admin partition to export the service to.
Partition string `json:"partition,omitempty"`
// PeerName is the name of the peer to export the service to.
PeerName string `json:"peerName,omitempty"`
}

func (in *ExportedServices) GetObjectMeta() metav1.ObjectMeta {
Expand Down Expand Up @@ -164,7 +166,11 @@ func (in *ExportedServices) ToConsul(datacenter string) api.ConfigEntry {
func (in *ExportedService) toConsul() capi.ExportedService {
var consumers []capi.ServiceConsumer
for _, consumer := range in.Consumers {
consumers = append(consumers, capi.ServiceConsumer{Partition: consumer.Partition})
if consumer.PeerName != "" {
consumers = append(consumers, capi.ServiceConsumer{PeerName: consumer.PeerName})
} else {
consumers = append(consumers, capi.ServiceConsumer{Partition: consumer.Partition})
}
}
return capi.ExportedService{
Name: in.Name,
Expand Down Expand Up @@ -199,7 +205,7 @@ func (in *ExportedServices) Validate(consulMeta common.ConsulMeta) error {
}
for i, service := range in.Spec.Services {
if err := service.validate(field.NewPath("spec").Child("services").Index(i)); err != nil {
errs = append(errs, err)
errs = append(errs, err...)
}
}
if len(errs) > 0 {
Expand All @@ -210,9 +216,25 @@ func (in *ExportedServices) Validate(consulMeta common.ConsulMeta) error {
return nil
}

func (in *ExportedService) validate(path *field.Path) *field.Error {
func (in *ExportedService) validate(path *field.Path) field.ErrorList {
var errs field.ErrorList
if len(in.Consumers) == 0 {
return field.Invalid(path, in.Consumers, "service must have at least 1 consumer.")
errs = append(errs, field.Invalid(path, in.Consumers, "service must have at least 1 consumer."))
}
for i, consumer := range in.Consumers {
if err := consumer.validate(path.Child("consumers").Index(i)); err != nil {
errs = append(errs, err)
}
}
return errs
}

func (in *ServiceConsumer) validate(path *field.Path) *field.Error {
if in.Partition != "" && in.PeerName != "" {
return field.Invalid(path, *in, "both partition and peerName cannot be specified.")
}
if in.Partition == "" && in.PeerName == "" {
return field.Invalid(path, *in, "either partition or peerName must be specified.")
}
return nil
}
Expand Down
160 changes: 160 additions & 0 deletions control-plane/api/v1alpha1/exportedservices_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ func TestExportedServices_MatchesConsul(t *testing.T) {
{
Partition: "third",
},
{
PeerName: "second-peer",
},
},
},
{
Expand All @@ -65,6 +68,9 @@ func TestExportedServices_MatchesConsul(t *testing.T) {
{
Partition: "fifth",
},
{
PeerName: "third-peer",
},
},
},
},
Expand All @@ -83,6 +89,9 @@ func TestExportedServices_MatchesConsul(t *testing.T) {
{
Partition: "third",
},
{
PeerName: "second-peer",
},
},
},
{
Expand All @@ -95,6 +104,9 @@ func TestExportedServices_MatchesConsul(t *testing.T) {
{
Partition: "fifth",
},
{
PeerName: "third-peer",
},
},
},
},
Expand Down Expand Up @@ -165,6 +177,9 @@ func TestExportedServices_ToConsul(t *testing.T) {
{
Partition: "third",
},
{
PeerName: "second-peer",
},
},
},
{
Expand All @@ -177,6 +192,9 @@ func TestExportedServices_ToConsul(t *testing.T) {
{
Partition: "fifth",
},
{
PeerName: "third-peer",
},
},
},
},
Expand All @@ -195,6 +213,9 @@ func TestExportedServices_ToConsul(t *testing.T) {
{
Partition: "third",
},
{
PeerName: "second-peer",
},
},
},
{
Expand All @@ -207,6 +228,9 @@ func TestExportedServices_ToConsul(t *testing.T) {
{
Partition: "fifth",
},
{
PeerName: "third-peer",
},
},
},
},
Expand All @@ -227,6 +251,142 @@ func TestExportedServices_ToConsul(t *testing.T) {
}
}

func TestExportedServices_Validate(t *testing.T) {
cases := map[string]struct {
input *ExportedServices
expectedErrMsgs []string
}{
"valid": {
input: &ExportedServices{
ObjectMeta: metav1.ObjectMeta{
Name: common.DefaultConsulPartition,
},
Spec: ExportedServicesSpec{
Services: []ExportedService{
{
Name: "service-frontend",
Namespace: "frontend",
Consumers: []ServiceConsumer{
{
Partition: "second",
},
{
PeerName: "second-peer",
},
},
},
},
},
},
expectedErrMsgs: []string{},
},
"no consumers specified": {
input: &ExportedServices{
ObjectMeta: metav1.ObjectMeta{
Name: common.DefaultConsulPartition,
},
Spec: ExportedServicesSpec{
Services: []ExportedService{
{
Name: "service-frontend",
Namespace: "frontend",
Consumers: []ServiceConsumer{},
},
},
},
},
expectedErrMsgs: []string{
`spec.services[0]: Invalid value: []v1alpha1.ServiceConsumer{}: service must have at least 1 consumer.`,
},
},
"both partition and peer name specified": {
input: &ExportedServices{
ObjectMeta: metav1.ObjectMeta{
Name: common.DefaultConsulPartition,
},
Spec: ExportedServicesSpec{
Services: []ExportedService{
{
Name: "service-frontend",
Namespace: "frontend",
Consumers: []ServiceConsumer{
{
Partition: "second",
PeerName: "second-peer",
},
},
},
},
},
},
expectedErrMsgs: []string{
`spec.services[0].consumers[0]: Invalid value: v1alpha1.ServiceConsumer{Partition:"second", PeerName:"second-peer"}: both partition and peerName cannot be specified.`,
},
},
"neither partition nor peer name specified": {
input: &ExportedServices{
ObjectMeta: metav1.ObjectMeta{
Name: common.DefaultConsulPartition,
},
Spec: ExportedServicesSpec{
Services: []ExportedService{
{
Name: "service-frontend",
Namespace: "frontend",
Consumers: []ServiceConsumer{
{},
},
},
},
},
},
expectedErrMsgs: []string{
`spec.services[0].consumers[0]: Invalid value: v1alpha1.ServiceConsumer{Partition:"", PeerName:""}: either partition or peerName must be specified.`,
},
},
"multiple errors": {
input: &ExportedServices{
ObjectMeta: metav1.ObjectMeta{
Name: common.DefaultConsulPartition,
},
Spec: ExportedServicesSpec{
Services: []ExportedService{
{
Name: "service-frontend",
Namespace: "frontend",
Consumers: []ServiceConsumer{
{
Partition: "second",
PeerName: "second-peer",
},
{},
},
},
},
},
},
expectedErrMsgs: []string{
`spec.services[0].consumers[0]: Invalid value: v1alpha1.ServiceConsumer{Partition:"second", PeerName:"second-peer"}: both partition and peerName cannot be specified.`,
`spec.services[0].consumers[1]: Invalid value: v1alpha1.ServiceConsumer{Partition:"", PeerName:""}: either partition or peerName must be specified.`,
},
},
}

for name, testCase := range cases {
t.Run(name, func(t *testing.T) {
err := testCase.input.Validate(common.ConsulMeta{NamespacesEnabled: true, PartitionsEnabled: true, Partition: common.DefaultConsulPartition})
if len(testCase.expectedErrMsgs) != 0 {
require.Error(t, err)
for _, s := range testCase.expectedErrMsgs {
require.Contains(t, err.Error(), s)
}
} else {
require.NoError(t, err)
}
})
}
}

func TestExportedServices_AddFinalizer(t *testing.T) {
exportedServices := &ExportedServices{}
exportedServices.AddFinalizer("finalizer")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ spec:
description: Partition is the admin partition to export
the service to.
type: string
peerName:
description: PeerName is the name of the peer to export
the service to.
type: string
type: object
type: array
name:
Expand Down
2 changes: 1 addition & 1 deletion control-plane/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/go-logr/logr v0.4.0
github.com/google/go-cmp v0.5.7
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/hashicorp/consul/api v1.10.1-0.20220425143126-6d0162a58a94
github.com/hashicorp/consul/api v1.10.1-0.20220519230759-6167400b28c9
github.com/hashicorp/consul/sdk v0.9.0
github.com/hashicorp/go-discover v0.0.0-20200812215701-c4b85f6ed31f
github.com/hashicorp/go-hclog v0.16.1
Expand Down
4 changes: 2 additions & 2 deletions control-plane/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.10.1-0.20220425143126-6d0162a58a94 h1:mPhpaeGO4BmD0Fi9gmevT7kYDyDml1kNjf0HKCFF5xM=
github.com/hashicorp/consul/api v1.10.1-0.20220425143126-6d0162a58a94/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
github.com/hashicorp/consul/api v1.10.1-0.20220519230759-6167400b28c9 h1:HWXZXOMz3EXKtpE+ETagwEtppdCywlcQ799oEpdxfxc=
github.com/hashicorp/consul/api v1.10.1-0.20220519230759-6167400b28c9/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.4.1-0.20220214194852-80dfcb1bcd68 h1:yw3OXf1OUgfnitE8rwnr+zaT9VluSgvrCHQGwSvA7V4=
github.com/hashicorp/consul/sdk v0.4.1-0.20220214194852-80dfcb1bcd68/go.mod h1:K9S7H8bLBwkBb2I4hq0Ddm4LCVGuhtenfzSTx2Y36RM=
Expand Down

0 comments on commit 48d71c2

Please sign in to comment.