-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
Targets
field to service resolver failovers. (#14162)
This field will be used for cluster peering failover.
- Loading branch information
1 parent
d46b515
commit 1a73b0c
Showing
11 changed files
with
1,080 additions
and
459 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
```release-note:improvement | ||
config-entry: Validate that service-resolver `Failover`s and `Redirect`s only | ||
specify `Partition` and `Namespace` on Consul Enterprise. This prevents scenarios | ||
where OSS Consul would save service-resolvers that require Consul Enterprise. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
//go:build !consulent | ||
// +build !consulent | ||
|
||
package structs | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestServiceResolverConfigEntry_OSS(t *testing.T) { | ||
type testcase struct { | ||
name string | ||
entry *ServiceResolverConfigEntry | ||
normalizeErr string | ||
validateErr string | ||
// check is called between normalize and validate | ||
check func(t *testing.T, entry *ServiceResolverConfigEntry) | ||
} | ||
|
||
cases := []testcase{ | ||
{ | ||
name: "failover with a namespace on OSS", | ||
entry: &ServiceResolverConfigEntry{ | ||
Kind: ServiceResolver, | ||
Name: "test", | ||
Failover: map[string]ServiceResolverFailover{ | ||
"*": { | ||
Service: "backup", | ||
Namespace: "ns1", | ||
}, | ||
}, | ||
}, | ||
validateErr: `Bad Failover["*"]: Setting Namespace requires Consul Enterprise`, | ||
}, | ||
{ | ||
name: "failover Targets cannot set Namespace on OSS", | ||
entry: &ServiceResolverConfigEntry{ | ||
Kind: ServiceResolver, | ||
Name: "test", | ||
Failover: map[string]ServiceResolverFailover{ | ||
"*": { | ||
Targets: []ServiceResolverFailoverTarget{{Namespace: "ns1"}}, | ||
}, | ||
}, | ||
}, | ||
validateErr: `Bad Failover["*"].Targets[0]: Setting Namespace requires Consul Enterprise`, | ||
}, | ||
{ | ||
name: "failover Targets cannot set Partition on OSS", | ||
entry: &ServiceResolverConfigEntry{ | ||
Kind: ServiceResolver, | ||
Name: "test", | ||
Failover: map[string]ServiceResolverFailover{ | ||
"*": { | ||
Targets: []ServiceResolverFailoverTarget{{Partition: "ap1"}}, | ||
}, | ||
}, | ||
}, | ||
validateErr: `Bad Failover["*"].Targets[0]: Setting Partition requires Consul Enterprise`, | ||
}, | ||
{ | ||
name: "setting failover Namespace on OSS", | ||
entry: &ServiceResolverConfigEntry{ | ||
Kind: ServiceResolver, | ||
Name: "test", | ||
Failover: map[string]ServiceResolverFailover{ | ||
"*": {Namespace: "ns1"}, | ||
}, | ||
}, | ||
validateErr: `Bad Failover["*"]: Setting Namespace requires Consul Enterprise`, | ||
}, | ||
} | ||
|
||
// Bulk add a bunch of similar validation cases. | ||
for _, invalidSubset := range invalidSubsetNames { | ||
tc := testcase{ | ||
name: "invalid subset name: " + invalidSubset, | ||
entry: &ServiceResolverConfigEntry{ | ||
Kind: ServiceResolver, | ||
Name: "test", | ||
Subsets: map[string]ServiceResolverSubset{ | ||
invalidSubset: {OnlyPassing: true}, | ||
}, | ||
}, | ||
validateErr: fmt.Sprintf("Subset %q is invalid", invalidSubset), | ||
} | ||
cases = append(cases, tc) | ||
} | ||
|
||
for _, goodSubset := range validSubsetNames { | ||
tc := testcase{ | ||
name: "valid subset name: " + goodSubset, | ||
entry: &ServiceResolverConfigEntry{ | ||
Kind: ServiceResolver, | ||
Name: "test", | ||
Subsets: map[string]ServiceResolverSubset{ | ||
goodSubset: {OnlyPassing: true}, | ||
}, | ||
}, | ||
} | ||
cases = append(cases, tc) | ||
} | ||
|
||
for _, tc := range cases { | ||
tc := tc | ||
t.Run(tc.name, func(t *testing.T) { | ||
err := tc.entry.Normalize() | ||
if tc.normalizeErr != "" { | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), tc.normalizeErr) | ||
return | ||
} | ||
require.NoError(t, err) | ||
|
||
if tc.check != nil { | ||
tc.check(t, tc.entry) | ||
} | ||
|
||
err = tc.entry.Validate() | ||
if tc.validateErr != "" { | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), tc.validateErr) | ||
return | ||
} | ||
require.NoError(t, err) | ||
}) | ||
} | ||
} |
Oops, something went wrong.