| // Copyright Istio Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package trustdomain |
| |
| import ( |
| "reflect" |
| "testing" |
| ) |
| |
| func TestReplaceTrustDomainAliases(t *testing.T) { |
| testCases := []struct { |
| name string |
| trustDomainBundle Bundle |
| principals []string |
| expect []string |
| }{ |
| { |
| name: "No trust domain aliases (no change in trust domain)", |
| trustDomainBundle: NewBundle("cluster.local", nil), |
| principals: []string{"cluster.local/ns/foo/sa/bar"}, |
| expect: []string{"cluster.local/ns/foo/sa/bar"}, |
| }, |
| { |
| name: "Principal with *", |
| trustDomainBundle: NewBundle("cluster.local", nil), |
| principals: []string{"*"}, |
| expect: []string{"*"}, |
| }, |
| { |
| name: "Principal with * prefix", |
| trustDomainBundle: NewBundle("cluster.local", nil), |
| principals: []string{"*/ns/foo/sa/bar"}, |
| expect: []string{"*/ns/foo/sa/bar"}, |
| }, |
| { |
| name: "One trust domain alias, one principal", |
| trustDomainBundle: NewBundle("td2", []string{"td1"}), |
| principals: []string{"td1/ns/foo/sa/bar"}, |
| expect: []string{"td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar"}, |
| }, |
| { |
| name: "One trust domain alias, two principals", |
| trustDomainBundle: NewBundle("td1", []string{"cluster.local"}), |
| principals: []string{"cluster.local/ns/foo/sa/bar", "cluster.local/ns/yyy/sa/zzz"}, |
| expect: []string{"td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz"}, |
| }, |
| { |
| name: "One trust domain alias, principals with * as-is", |
| trustDomainBundle: NewBundle("td1", []string{"cluster.local"}), |
| principals: []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"}, |
| expect: []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"}, |
| }, |
| { |
| name: "Two trust domain aliases, two principals", |
| trustDomainBundle: NewBundle("td2", []string{"td1", "cluster.local"}), |
| principals: []string{"cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz"}, |
| expect: []string{ |
| "td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar", |
| "td2/ns/yyy/sa/zzz", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz", |
| }, |
| }, |
| { |
| name: "Two trust domain aliases with * prefix in trust domain", |
| trustDomainBundle: NewBundle("td2", []string{"foo-td1", "cluster.local"}), |
| principals: []string{"*-td1/ns/foo/sa/bar"}, |
| expect: []string{"td2/ns/foo/sa/bar", "*-td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar"}, |
| }, |
| { |
| name: "Principals not match any trust domains", |
| trustDomainBundle: NewBundle("td1", []string{"td2"}), |
| principals: []string{"some-td/ns/foo/sa/bar"}, |
| expect: []string{"some-td/ns/foo/sa/bar"}, |
| }, |
| { |
| name: "Principals match one alias", |
| trustDomainBundle: NewBundle("td1", []string{"td2", "some-td"}), |
| principals: []string{"some-td/ns/foo/sa/bar"}, |
| expect: []string{"td1/ns/foo/sa/bar", "td2/ns/foo/sa/bar", "some-td/ns/foo/sa/bar"}, |
| }, |
| { |
| name: "One principal match one alias", |
| trustDomainBundle: NewBundle("new-td", []string{"td2", "td3"}), |
| principals: []string{"td1/ns/some-ns/sa/some-sa", "td2/ns/foo/sa/bar"}, |
| expect: []string{ |
| "td1/ns/some-ns/sa/some-sa", "new-td/ns/foo/sa/bar", |
| "td2/ns/foo/sa/bar", "td3/ns/foo/sa/bar", |
| }, |
| }, |
| { |
| name: "Trust domain is empty string", |
| trustDomainBundle: NewBundle("new-td", []string{"td2", "td3"}), |
| principals: []string{"/ns/some-ns/sa/some-sa"}, |
| expect: []string{"/ns/some-ns/sa/some-sa"}, |
| }, |
| { |
| name: "No duplicated principals for prefix", |
| trustDomainBundle: NewBundle("new-td", []string{"old-td"}), |
| principals: []string{"*-td/ns/some-ns/sa/some-sa"}, |
| // Rather than output *-td/ns/some-ns/sa/some-sa once for each trust domain. |
| expect: []string{"*-td/ns/some-ns/sa/some-sa"}, |
| }, |
| } |
| |
| for _, tc := range testCases { |
| got := tc.trustDomainBundle.ReplaceTrustDomainAliases(tc.principals) |
| if !reflect.DeepEqual(got, tc.expect) { |
| t.Errorf("%s failed. Expect: %s. Got: %s", tc.name, tc.expect, got) |
| } |
| } |
| } |
| |
| func TestReplaceTrustDomainInPrincipal(t *testing.T) { |
| cases := []struct { |
| name string |
| trustDomainIn string |
| principal string |
| out string |
| expectedError string |
| }{ |
| { |
| name: "Principal in wrong format with SPIFFE:// prefix", |
| principal: "spiffe://cluster.local/ns/foo/sa/bar", |
| out: "", |
| expectedError: "wrong SPIFFE format: spiffe://cluster.local/ns/foo/sa/bar", |
| }, |
| { |
| name: "Principal in wrong format with less components", |
| principal: "sa/test-sa/ns/default", |
| out: "", |
| expectedError: "wrong SPIFFE format: sa/test-sa/ns/default", |
| }, |
| { |
| name: "Replace td with domain name in principal", |
| trustDomainIn: "td", |
| principal: "cluster.local/ns/foo/sa/bar", |
| out: "td/ns/foo/sa/bar", |
| expectedError: "", |
| }, |
| { |
| name: "Replace td without domain name in principal", |
| trustDomainIn: "abc", |
| principal: "xyz/ns/foo/sa/bar", |
| out: "abc/ns/foo/sa/bar", |
| expectedError: "", |
| }, |
| } |
| |
| for _, c := range cases { |
| got, err := replaceTrustDomainInPrincipal(c.trustDomainIn, c.principal) |
| if err != nil { |
| if c.expectedError == "" { |
| t.Errorf("%s: replace trust domain in principal error: %v", c.name, err) |
| } |
| if got != "" { |
| t.Errorf("%s: Expected empty SPIFFE ID but obtained a non-empty one: %s.", c.name, got) |
| } |
| if err.Error() != c.expectedError { |
| t.Errorf("%s: Expected error: %s but got error: %s.", c.name, c.expectedError, err.Error()) |
| } |
| continue |
| } |
| |
| if got != c.out { |
| t.Errorf("%s failed. Expect %s, but got %s", c.name, c.out, got) |
| } |
| } |
| } |
| |
| func TestGetTrustDomainFromSpiffeIdentity(t *testing.T) { |
| cases := []struct { |
| principal string |
| out string |
| }{ |
| {principal: "spiffe://cluster.local/ns/foo/sa/bar", out: ""}, |
| {principal: "sa/test-sa/ns/default", out: ""}, |
| {principal: "cluster.local/ns/foo/sa/bar", out: "cluster.local"}, |
| {principal: "xyz/ns/foo/sa/bar", out: "xyz"}, |
| } |
| |
| for _, c := range cases { |
| got, _ := getTrustDomainFromSpiffeIdentity(c.principal) |
| if got != c.out { |
| t.Errorf("expect %s, but got %s", c.out, got) |
| } |
| } |
| } |
| |
| func TestIsTrustDomainBeingEnforced(t *testing.T) { |
| cases := []struct { |
| principal string |
| want bool |
| }{ |
| {principal: "cluster.local/ns/foo/sa/bar", want: true}, |
| {principal: "*/ns/foo/sa/bar", want: false}, |
| {principal: "*-td/ns/foo/sa/bar", want: true}, |
| {principal: "*/sa/bar", want: false}, |
| {principal: "*", want: false}, |
| {principal: "/ns/foo/sa/bar", want: true}, |
| } |
| |
| for _, c := range cases { |
| got := isTrustDomainBeingEnforced(c.principal) |
| if got != c.want { |
| t.Errorf("expect %v, but got %v", c.want, got) |
| } |
| } |
| } |