istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/security/trustdomain/bundle_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package trustdomain 16 17 import ( 18 "reflect" 19 "testing" 20 ) 21 22 func TestReplaceTrustDomainAliases(t *testing.T) { 23 testCases := []struct { 24 name string 25 trustDomainBundle Bundle 26 principals []string 27 expect []string 28 }{ 29 { 30 name: "No trust domain aliases (no change in trust domain)", 31 trustDomainBundle: NewBundle("cluster.local", nil), 32 principals: []string{"cluster.local/ns/foo/sa/bar"}, 33 expect: []string{"cluster.local/ns/foo/sa/bar"}, 34 }, 35 { 36 name: "Principal with *", 37 trustDomainBundle: NewBundle("cluster.local", nil), 38 principals: []string{"*"}, 39 expect: []string{"*"}, 40 }, 41 { 42 name: "Principal with * prefix", 43 trustDomainBundle: NewBundle("cluster.local", nil), 44 principals: []string{"*/ns/foo/sa/bar"}, 45 expect: []string{"*/ns/foo/sa/bar"}, 46 }, 47 { 48 name: "One trust domain alias, one principal", 49 trustDomainBundle: NewBundle("td2", []string{"td1"}), 50 principals: []string{"td1/ns/foo/sa/bar"}, 51 expect: []string{"td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar"}, 52 }, 53 { 54 name: "One trust domain alias, two principals", 55 trustDomainBundle: NewBundle("td1", []string{"cluster.local"}), 56 principals: []string{"cluster.local/ns/foo/sa/bar", "cluster.local/ns/yyy/sa/zzz"}, 57 expect: []string{"td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz"}, 58 }, 59 { 60 name: "One trust domain alias, principals with * as-is", 61 trustDomainBundle: NewBundle("td1", []string{"cluster.local"}), 62 principals: []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"}, 63 expect: []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"}, 64 }, 65 { 66 name: "Two trust domain aliases, two principals", 67 trustDomainBundle: NewBundle("td2", []string{"td1", "cluster.local"}), 68 principals: []string{"cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz"}, 69 expect: []string{ 70 "td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar", 71 "td2/ns/yyy/sa/zzz", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz", 72 }, 73 }, 74 { 75 name: "Two trust domain aliases with * prefix in trust domain", 76 trustDomainBundle: NewBundle("td2", []string{"foo-td1", "cluster.local"}), 77 principals: []string{"*-td1/ns/foo/sa/bar"}, 78 expect: []string{"td2/ns/foo/sa/bar", "*-td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar"}, 79 }, 80 { 81 name: "Principals not match any trust domains", 82 trustDomainBundle: NewBundle("td1", []string{"td2"}), 83 principals: []string{"some-td/ns/foo/sa/bar"}, 84 expect: []string{"some-td/ns/foo/sa/bar"}, 85 }, 86 { 87 name: "Principals match one alias", 88 trustDomainBundle: NewBundle("td1", []string{"td2", "some-td"}), 89 principals: []string{"some-td/ns/foo/sa/bar"}, 90 expect: []string{"td1/ns/foo/sa/bar", "td2/ns/foo/sa/bar", "some-td/ns/foo/sa/bar"}, 91 }, 92 { 93 name: "One principal match one alias", 94 trustDomainBundle: NewBundle("new-td", []string{"td2", "td3"}), 95 principals: []string{"td1/ns/some-ns/sa/some-sa", "td2/ns/foo/sa/bar"}, 96 expect: []string{ 97 "td1/ns/some-ns/sa/some-sa", "new-td/ns/foo/sa/bar", 98 "td2/ns/foo/sa/bar", "td3/ns/foo/sa/bar", 99 }, 100 }, 101 { 102 name: "Trust domain is empty string", 103 trustDomainBundle: NewBundle("new-td", []string{"td2", "td3"}), 104 principals: []string{"/ns/some-ns/sa/some-sa"}, 105 expect: []string{"/ns/some-ns/sa/some-sa"}, 106 }, 107 { 108 name: "No duplicated principals for prefix", 109 trustDomainBundle: NewBundle("new-td", []string{"old-td"}), 110 principals: []string{"*-td/ns/some-ns/sa/some-sa"}, 111 // Rather than output *-td/ns/some-ns/sa/some-sa once for each trust domain. 112 expect: []string{"*-td/ns/some-ns/sa/some-sa"}, 113 }, 114 } 115 116 for _, tc := range testCases { 117 got := tc.trustDomainBundle.ReplaceTrustDomainAliases(tc.principals) 118 if !reflect.DeepEqual(got, tc.expect) { 119 t.Errorf("%s failed. Expect: %s. Got: %s", tc.name, tc.expect, got) 120 } 121 } 122 } 123 124 func TestReplaceTrustDomainInPrincipal(t *testing.T) { 125 cases := []struct { 126 name string 127 trustDomainIn string 128 principal string 129 out string 130 expectedError string 131 }{ 132 { 133 name: "Principal in wrong format with SPIFFE:// prefix", 134 principal: "spiffe://cluster.local/ns/foo/sa/bar", 135 out: "", 136 expectedError: "wrong SPIFFE format: spiffe://cluster.local/ns/foo/sa/bar", 137 }, 138 { 139 name: "Principal in wrong format with less components", 140 principal: "sa/test-sa/ns/default", 141 out: "", 142 expectedError: "wrong SPIFFE format: sa/test-sa/ns/default", 143 }, 144 { 145 name: "Replace td with domain name in principal", 146 trustDomainIn: "td", 147 principal: "cluster.local/ns/foo/sa/bar", 148 out: "td/ns/foo/sa/bar", 149 expectedError: "", 150 }, 151 { 152 name: "Replace td without domain name in principal", 153 trustDomainIn: "abc", 154 principal: "xyz/ns/foo/sa/bar", 155 out: "abc/ns/foo/sa/bar", 156 expectedError: "", 157 }, 158 } 159 160 for _, c := range cases { 161 got, err := replaceTrustDomainInPrincipal(c.trustDomainIn, c.principal) 162 if err != nil { 163 if c.expectedError == "" { 164 t.Errorf("%s: replace trust domain in principal error: %v", c.name, err) 165 } 166 if got != "" { 167 t.Errorf("%s: Expected empty SPIFFE ID but obtained a non-empty one: %s.", c.name, got) 168 } 169 if err.Error() != c.expectedError { 170 t.Errorf("%s: Expected error: %s but got error: %s.", c.name, c.expectedError, err.Error()) 171 } 172 continue 173 } 174 175 if got != c.out { 176 t.Errorf("%s failed. Expect %s, but got %s", c.name, c.out, got) 177 } 178 } 179 } 180 181 func TestGetTrustDomainFromSpiffeIdentity(t *testing.T) { 182 cases := []struct { 183 principal string 184 out string 185 }{ 186 {principal: "spiffe://cluster.local/ns/foo/sa/bar", out: ""}, 187 {principal: "sa/test-sa/ns/default", out: ""}, 188 {principal: "cluster.local/ns/foo/sa/bar", out: "cluster.local"}, 189 {principal: "xyz/ns/foo/sa/bar", out: "xyz"}, 190 } 191 192 for _, c := range cases { 193 got, _ := getTrustDomainFromSpiffeIdentity(c.principal) 194 if got != c.out { 195 t.Errorf("expect %s, but got %s", c.out, got) 196 } 197 } 198 } 199 200 func TestIsTrustDomainBeingEnforced(t *testing.T) { 201 cases := []struct { 202 principal string 203 want bool 204 }{ 205 {principal: "cluster.local/ns/foo/sa/bar", want: true}, 206 {principal: "*/ns/foo/sa/bar", want: false}, 207 {principal: "*-td/ns/foo/sa/bar", want: true}, 208 {principal: "*/sa/bar", want: false}, 209 {principal: "*", want: false}, 210 {principal: "/ns/foo/sa/bar", want: true}, 211 } 212 213 for _, c := range cases { 214 got := isTrustDomainBeingEnforced(c.principal) 215 if got != c.want { 216 t.Errorf("expect %v, but got %v", c.want, got) 217 } 218 } 219 }