1// +build !consulent 2 3package consul 4 5import ( 6 "sort" 7 "testing" 8 "time" 9 10 "github.com/hashicorp/consul/agent/structs" 11 "github.com/stretchr/testify/require" 12) 13 14func testLeader_LegacyIntentionMigrationHookEnterprise(_ *testing.T, _ *Server, _ bool) { 15} 16 17func appendLegacyIntentionsForMigrationTestEnterprise(_ *testing.T, _ *Server, ixns []*structs.Intention) []*structs.Intention { 18 return ixns 19} 20 21func TestMigrateIntentionsToConfigEntries(t *testing.T) { 22 compare := func(t *testing.T, got structs.Intentions, expect [][]string) { 23 t.Helper() 24 25 var actual [][]string 26 for _, ixn := range got { 27 actual = append(actual, []string{ 28 ixn.SourceNS, 29 ixn.SourceName, 30 ixn.DestinationNS, 31 ixn.DestinationName, 32 }) 33 } 34 require.ElementsMatch(t, expect, actual) 35 } 36 37 type testCase struct { 38 insert [][]string 39 expect [][]string 40 } 41 42 cases := map[string]testCase{ 43 "no change": { 44 insert: [][]string{ 45 {"default", "foo", "default", "bar"}, 46 {"default", "*", "default", "*"}, 47 }, 48 expect: [][]string{ 49 {"default", "foo", "default", "bar"}, 50 {"default", "*", "default", "*"}, 51 }, 52 }, 53 "non-wildcard deletions": { 54 insert: [][]string{ 55 {"default", "foo", "default", "bar"}, 56 {"alpha", "*", "default", "bar"}, 57 {"default", "foo", "beta", "*"}, 58 {"alpha", "zoo", "beta", "bar"}, 59 }, 60 expect: [][]string{ 61 {"default", "foo", "default", "bar"}, 62 }, 63 }, 64 "updates with no deletions and no collisions": { 65 insert: [][]string{ 66 {"default", "foo", "default", "bar"}, 67 {"default", "foo", "*", "*"}, 68 {"*", "*", "default", "bar"}, 69 {"*", "*", "*", "*"}, 70 }, 71 expect: [][]string{ 72 {"default", "foo", "default", "bar"}, 73 {"default", "foo", "default", "*"}, 74 {"default", "*", "default", "bar"}, 75 {"default", "*", "default", "*"}, 76 }, 77 }, 78 "updates with only collision deletions": { 79 insert: [][]string{ 80 {"default", "foo", "default", "bar"}, 81 {"default", "foo", "default", "*"}, 82 {"default", "foo", "*", "*"}, 83 {"default", "*", "default", "bar"}, 84 {"*", "*", "default", "bar"}, 85 {"default", "*", "default", "*"}, 86 {"*", "*", "*", "*"}, 87 }, 88 expect: [][]string{ 89 {"default", "foo", "default", "bar"}, 90 {"default", "foo", "default", "*"}, 91 {"default", "*", "default", "bar"}, 92 {"default", "*", "default", "*"}, 93 }, 94 }, 95 "a bit of everything": { 96 insert: [][]string{ 97 {"default", "foo", "default", "bar"}, // retained 98 {"default", "foo", "*", "*"}, // upgrade 99 {"default", "*", "default", "bar"}, // retained in collision 100 {"*", "*", "default", "bar"}, // deleted in collision 101 {"default", "*", "default", "*"}, // retained in collision 102 {"*", "*", "*", "*"}, // deleted in collision 103 {"alpha", "*", "default", "bar"}, // deleted 104 {"default", "foo", "beta", "*"}, // deleted 105 {"alpha", "zoo", "beta", "bar"}, // deleted 106 }, 107 expect: [][]string{ 108 {"default", "foo", "default", "bar"}, 109 {"default", "foo", "default", "*"}, 110 {"default", "*", "default", "bar"}, 111 {"default", "*", "default", "*"}, 112 }, 113 }, 114 } 115 for name, tc := range cases { 116 tc := tc 117 t.Run(name, func(t *testing.T) { 118 119 // Do something super evil and directly reach into the FSM to seed it with "bad" data. 120 var ixns structs.Intentions 121 for _, elem := range tc.insert { 122 require.Len(t, elem, 4) 123 ixn := structs.TestIntention(t) 124 ixn.ID = generateUUID() 125 ixn.SourceNS = elem[0] 126 ixn.SourceName = elem[1] 127 ixn.DestinationNS = elem[2] 128 ixn.DestinationName = elem[3] 129 ixn.CreatedAt = time.Now().UTC() 130 ixn.UpdatedAt = ixn.CreatedAt 131 132 ixns = append(ixns, ixn) 133 } 134 135 // Sleep a bit so that the UpdatedAt field will definitely be different 136 time.Sleep(1 * time.Millisecond) 137 138 got := migrateIntentionsToConfigEntries(ixns) 139 140 // Convert them back to the line-item version. 141 var gotIxns structs.Intentions 142 for _, entry := range got { 143 gotIxns = append(gotIxns, entry.ToIntentions()...) 144 } 145 sort.Sort(structs.IntentionPrecedenceSorter(gotIxns)) 146 147 compare(t, gotIxns, tc.expect) 148 }) 149 } 150} 151