2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2021-11-16 18:04:01 +00:00
|
|
|
//go:build !consulent
|
2020-06-26 21:59:15 +00:00
|
|
|
// +build !consulent
|
|
|
|
|
|
|
|
package consul
|
|
|
|
|
|
|
|
import (
|
2020-10-06 18:24:05 +00:00
|
|
|
"sort"
|
2020-06-26 21:59:15 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2020-11-13 19:56:41 +00:00
|
|
|
func testLeader_LegacyIntentionMigrationHookEnterprise(_ *testing.T, _ *Server, _ bool) {
|
|
|
|
}
|
|
|
|
|
|
|
|
func appendLegacyIntentionsForMigrationTestEnterprise(_ *testing.T, _ *Server, ixns []*structs.Intention) []*structs.Intention {
|
|
|
|
return ixns
|
|
|
|
}
|
|
|
|
|
2020-10-06 18:24:05 +00:00
|
|
|
func TestMigrateIntentionsToConfigEntries(t *testing.T) {
|
|
|
|
compare := func(t *testing.T, got structs.Intentions, expect [][]string) {
|
2020-06-26 21:59:15 +00:00
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
var actual [][]string
|
2020-10-06 18:24:05 +00:00
|
|
|
for _, ixn := range got {
|
2020-06-26 21:59:15 +00:00
|
|
|
actual = append(actual, []string{
|
|
|
|
ixn.SourceNS,
|
|
|
|
ixn.SourceName,
|
|
|
|
ixn.DestinationNS,
|
|
|
|
ixn.DestinationName,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
require.ElementsMatch(t, expect, actual)
|
|
|
|
}
|
|
|
|
|
|
|
|
type testCase struct {
|
|
|
|
insert [][]string
|
|
|
|
expect [][]string
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := map[string]testCase{
|
|
|
|
"no change": {
|
|
|
|
insert: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
{"default", "*", "default", "*"},
|
|
|
|
},
|
|
|
|
expect: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
{"default", "*", "default", "*"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"non-wildcard deletions": {
|
|
|
|
insert: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
{"alpha", "*", "default", "bar"},
|
|
|
|
{"default", "foo", "beta", "*"},
|
|
|
|
{"alpha", "zoo", "beta", "bar"},
|
|
|
|
},
|
|
|
|
expect: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"updates with no deletions and no collisions": {
|
|
|
|
insert: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
{"default", "foo", "*", "*"},
|
|
|
|
{"*", "*", "default", "bar"},
|
|
|
|
{"*", "*", "*", "*"},
|
|
|
|
},
|
|
|
|
expect: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
{"default", "foo", "default", "*"},
|
|
|
|
{"default", "*", "default", "bar"},
|
|
|
|
{"default", "*", "default", "*"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"updates with only collision deletions": {
|
|
|
|
insert: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
{"default", "foo", "default", "*"},
|
|
|
|
{"default", "foo", "*", "*"},
|
|
|
|
{"default", "*", "default", "bar"},
|
|
|
|
{"*", "*", "default", "bar"},
|
|
|
|
{"default", "*", "default", "*"},
|
|
|
|
{"*", "*", "*", "*"},
|
|
|
|
},
|
|
|
|
expect: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
{"default", "foo", "default", "*"},
|
|
|
|
{"default", "*", "default", "bar"},
|
|
|
|
{"default", "*", "default", "*"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"a bit of everything": {
|
|
|
|
insert: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"}, // retained
|
|
|
|
{"default", "foo", "*", "*"}, // upgrade
|
|
|
|
{"default", "*", "default", "bar"}, // retained in collision
|
|
|
|
{"*", "*", "default", "bar"}, // deleted in collision
|
|
|
|
{"default", "*", "default", "*"}, // retained in collision
|
|
|
|
{"*", "*", "*", "*"}, // deleted in collision
|
|
|
|
{"alpha", "*", "default", "bar"}, // deleted
|
|
|
|
{"default", "foo", "beta", "*"}, // deleted
|
|
|
|
{"alpha", "zoo", "beta", "bar"}, // deleted
|
|
|
|
},
|
|
|
|
expect: [][]string{
|
|
|
|
{"default", "foo", "default", "bar"},
|
|
|
|
{"default", "foo", "default", "*"},
|
|
|
|
{"default", "*", "default", "bar"},
|
|
|
|
{"default", "*", "default", "*"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, tc := range cases {
|
|
|
|
tc := tc
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
|
|
|
|
// Do something super evil and directly reach into the FSM to seed it with "bad" data.
|
2020-10-06 18:24:05 +00:00
|
|
|
var ixns structs.Intentions
|
2020-06-26 21:59:15 +00:00
|
|
|
for _, elem := range tc.insert {
|
|
|
|
require.Len(t, elem, 4)
|
|
|
|
ixn := structs.TestIntention(t)
|
|
|
|
ixn.ID = generateUUID()
|
|
|
|
ixn.SourceNS = elem[0]
|
|
|
|
ixn.SourceName = elem[1]
|
|
|
|
ixn.DestinationNS = elem[2]
|
|
|
|
ixn.DestinationName = elem[3]
|
|
|
|
ixn.CreatedAt = time.Now().UTC()
|
|
|
|
ixn.UpdatedAt = ixn.CreatedAt
|
2020-10-06 18:24:05 +00:00
|
|
|
|
|
|
|
ixns = append(ixns, ixn)
|
2020-06-26 21:59:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sleep a bit so that the UpdatedAt field will definitely be different
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
|
2020-10-06 18:24:05 +00:00
|
|
|
got := migrateIntentionsToConfigEntries(ixns)
|
2020-06-26 21:59:15 +00:00
|
|
|
|
2020-10-06 18:24:05 +00:00
|
|
|
// Convert them back to the line-item version.
|
|
|
|
var gotIxns structs.Intentions
|
|
|
|
for _, entry := range got {
|
|
|
|
gotIxns = append(gotIxns, entry.ToIntentions()...)
|
|
|
|
}
|
|
|
|
sort.Sort(structs.IntentionPrecedenceSorter(gotIxns))
|
2020-06-26 21:59:15 +00:00
|
|
|
|
2020-10-06 18:24:05 +00:00
|
|
|
compare(t, gotIxns, tc.expect)
|
2020-06-26 21:59:15 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|