github.com/imran-kn/cilium-fork@v1.6.9/pkg/k8s/apis/cilium.io/utils/utils_test.go (about)

     1  // Copyright 2018-2019 Authors of Cilium
     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  // +build !privileged_tests
    16  
    17  package utils
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/cilium/cilium/pkg/checker"
    24  	k8sConst "github.com/cilium/cilium/pkg/k8s/apis/cilium.io"
    25  	"github.com/cilium/cilium/pkg/labels"
    26  	"github.com/cilium/cilium/pkg/policy/api"
    27  
    28  	. "gopkg.in/check.v1"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  	"k8s.io/apimachinery/pkg/types"
    31  )
    32  
    33  // Hook up gocheck into the "go test" runner.
    34  func Test(t *testing.T) {
    35  	TestingT(t)
    36  }
    37  
    38  type CiliumUtilsSuite struct{}
    39  
    40  var _ = Suite(&CiliumUtilsSuite{})
    41  
    42  func (s *CiliumUtilsSuite) Test_namespacesAreValid(c *C) {
    43  	c.Assert(namespacesAreValid("default", []string{}), Equals, true)
    44  	c.Assert(namespacesAreValid("default", []string{"default"}), Equals, true)
    45  	c.Assert(namespacesAreValid("default", []string{"foo"}), Equals, false)
    46  	c.Assert(namespacesAreValid("default", []string{"default", "foo"}), Equals, false)
    47  }
    48  
    49  func Test_ParseToCiliumRule(t *testing.T) {
    50  	role := fmt.Sprintf("%s.role", labels.LabelSourceAny)
    51  	namespace := fmt.Sprintf("%s.%s", labels.LabelSourceK8s, k8sConst.PodNamespaceLabel)
    52  	uuid := types.UID("11bba160-ddca-11e8-b697-0800273b04ff")
    53  	type args struct {
    54  		namespace string
    55  		rule      *api.Rule
    56  		uid       types.UID
    57  	}
    58  	tests := []struct {
    59  		name string
    60  		args args
    61  		want *api.Rule
    62  	}{
    63  		{
    64  			// When the rule has no namespace match, the namespace
    65  			// is inherited from the namespace where the rule is
    66  			// added.
    67  			name: "parse-in-namespace",
    68  			args: args{
    69  				namespace: metav1.NamespaceDefault,
    70  				uid:       uuid,
    71  				rule: &api.Rule{
    72  					EndpointSelector: api.NewESFromMatchRequirements(
    73  						map[string]string{
    74  							role: "backend",
    75  						},
    76  						nil,
    77  					),
    78  				},
    79  			},
    80  			want: api.NewRule().WithEndpointSelector(
    81  				api.NewESFromMatchRequirements(
    82  					map[string]string{
    83  						role:      "backend",
    84  						namespace: "default",
    85  					},
    86  					nil,
    87  				),
    88  			).WithLabels(
    89  				labels.LabelArray{
    90  					{
    91  						Key:    "io.cilium.k8s.policy.derived-from",
    92  						Value:  "CiliumNetworkPolicy",
    93  						Source: labels.LabelSourceK8s,
    94  					},
    95  					{
    96  						Key:    "io.cilium.k8s.policy.name",
    97  						Value:  "parse-in-namespace",
    98  						Source: labels.LabelSourceK8s,
    99  					},
   100  					{
   101  						Key:    "io.cilium.k8s.policy.namespace",
   102  						Value:  "default",
   103  						Source: labels.LabelSourceK8s,
   104  					},
   105  					{
   106  						Key:    "io.cilium.k8s.policy.uid",
   107  						Value:  string(uuid),
   108  						Source: labels.LabelSourceK8s,
   109  					},
   110  				},
   111  			),
   112  		},
   113  		{
   114  			// When the rule specifies a namespace, it is overridden
   115  			// by the namespace where the rule was inserted.
   116  			name: "parse-in-namespace-with-ns-selector",
   117  			args: args{
   118  				namespace: metav1.NamespaceDefault,
   119  				uid:       uuid,
   120  				rule: &api.Rule{
   121  					EndpointSelector: api.NewESFromMatchRequirements(
   122  						map[string]string{
   123  							role:      "backend",
   124  							namespace: "foo",
   125  						},
   126  						nil,
   127  					),
   128  				},
   129  			},
   130  			want: api.NewRule().WithEndpointSelector(
   131  				api.NewESFromMatchRequirements(
   132  					map[string]string{
   133  						role:      "backend",
   134  						namespace: "default",
   135  					},
   136  					nil,
   137  				),
   138  			).WithLabels(
   139  				labels.LabelArray{
   140  					{
   141  						Key:    "io.cilium.k8s.policy.derived-from",
   142  						Value:  "CiliumNetworkPolicy",
   143  						Source: labels.LabelSourceK8s,
   144  					},
   145  					{
   146  						Key:    "io.cilium.k8s.policy.name",
   147  						Value:  "parse-in-namespace-with-ns-selector",
   148  						Source: labels.LabelSourceK8s,
   149  					},
   150  					{
   151  						Key:    "io.cilium.k8s.policy.namespace",
   152  						Value:  "default",
   153  						Source: labels.LabelSourceK8s,
   154  					},
   155  					{
   156  						Key:    "io.cilium.k8s.policy.uid",
   157  						Value:  string(uuid),
   158  						Source: labels.LabelSourceK8s,
   159  					},
   160  				},
   161  			),
   162  		},
   163  		{
   164  			// Don't insert a namespace selection when the rule
   165  			// is for init policies.
   166  			name: "parse-init-policy",
   167  			args: args{
   168  				namespace: metav1.NamespaceDefault,
   169  				uid:       uuid,
   170  				rule: &api.Rule{
   171  					EndpointSelector: api.NewESFromMatchRequirements(
   172  						map[string]string{
   173  							role:       "backend",
   174  							podInitLbl: "",
   175  						},
   176  						nil,
   177  					),
   178  				},
   179  			},
   180  			want: api.NewRule().WithEndpointSelector(
   181  				api.NewESFromMatchRequirements(
   182  					map[string]string{
   183  						role:       "backend",
   184  						podInitLbl: "",
   185  						// No namespace because it's init.
   186  						// namespace: "default",
   187  					},
   188  					nil,
   189  				),
   190  			).WithLabels(
   191  				labels.LabelArray{
   192  					{
   193  						Key:    "io.cilium.k8s.policy.derived-from",
   194  						Value:  "CiliumNetworkPolicy",
   195  						Source: labels.LabelSourceK8s,
   196  					},
   197  					{
   198  						Key:    "io.cilium.k8s.policy.name",
   199  						Value:  "parse-init-policy",
   200  						Source: labels.LabelSourceK8s,
   201  					},
   202  					{
   203  						Key:    "io.cilium.k8s.policy.namespace",
   204  						Value:  "default",
   205  						Source: labels.LabelSourceK8s,
   206  					},
   207  					{
   208  						Key:    "io.cilium.k8s.policy.uid",
   209  						Value:  string(uuid),
   210  						Source: labels.LabelSourceK8s,
   211  					},
   212  				},
   213  			),
   214  		},
   215  		{
   216  			name: "set-any-source-for-namespace",
   217  			args: args{
   218  				namespace: metav1.NamespaceDefault,
   219  				uid:       uuid,
   220  				rule: &api.Rule{
   221  					EndpointSelector: api.NewESFromMatchRequirements(
   222  						map[string]string{
   223  							role: "backend",
   224  						},
   225  						nil,
   226  					),
   227  					Ingress: []api.IngressRule{
   228  						{
   229  							FromEndpoints: []api.EndpointSelector{
   230  								{
   231  									LabelSelector: &metav1.LabelSelector{
   232  										MatchLabels: map[string]string{
   233  											podAnyPrefixLbl: "ns-2",
   234  										},
   235  									},
   236  								},
   237  							},
   238  						},
   239  					},
   240  				},
   241  			},
   242  			want: api.NewRule().WithEndpointSelector(
   243  				api.NewESFromMatchRequirements(
   244  					map[string]string{
   245  						role:      "backend",
   246  						namespace: "default",
   247  					},
   248  					nil,
   249  				),
   250  			).WithIngressRules(
   251  				[]api.IngressRule{
   252  					{
   253  						FromEndpoints: []api.EndpointSelector{
   254  							api.NewESFromK8sLabelSelector(
   255  								labels.LabelSourceAnyKeyPrefix,
   256  								&metav1.LabelSelector{
   257  									MatchLabels: map[string]string{
   258  										k8sConst.PodNamespaceLabel: "ns-2",
   259  									},
   260  								}),
   261  						},
   262  					},
   263  				},
   264  			).WithLabels(
   265  				labels.LabelArray{
   266  					{
   267  						Key:    "io.cilium.k8s.policy.derived-from",
   268  						Value:  "CiliumNetworkPolicy",
   269  						Source: labels.LabelSourceK8s,
   270  					},
   271  					{
   272  						Key:    "io.cilium.k8s.policy.name",
   273  						Value:  "set-any-source-for-namespace",
   274  						Source: labels.LabelSourceK8s,
   275  					},
   276  					{
   277  						Key:    "io.cilium.k8s.policy.namespace",
   278  						Value:  "default",
   279  						Source: labels.LabelSourceK8s,
   280  					},
   281  					{
   282  						Key:    "io.cilium.k8s.policy.uid",
   283  						Value:  string(uuid),
   284  						Source: labels.LabelSourceK8s,
   285  					},
   286  				},
   287  			),
   288  		},
   289  	}
   290  	for _, tt := range tests {
   291  		t.Run(tt.name, func(t *testing.T) {
   292  			got := ParseToCiliumRule(tt.args.namespace, tt.name, tt.args.uid, tt.args.rule)
   293  
   294  			// Sanitize to set aggregatedSelectors field.
   295  			tt.want.Sanitize()
   296  			args := []interface{}{got, tt.want}
   297  			names := []string{"obtained", "expected"}
   298  			if equal, err := checker.DeepEquals.Check(args, names); !equal {
   299  				t.Errorf("Failed to ParseToCiliumRule():\n%s", err)
   300  			}
   301  		})
   302  	}
   303  }
   304  
   305  func (s *CiliumUtilsSuite) TestParseToCiliumLabels(c *C) {
   306  
   307  	uuid := types.UID("11bba160-ddca-11e8-b697-0800273b04ff")
   308  	type args struct {
   309  		namespace string
   310  		name      string
   311  		uid       types.UID
   312  		ruleLbs   labels.LabelArray
   313  	}
   314  	tests := []struct {
   315  		name string
   316  		args args
   317  		want labels.LabelArray
   318  	}{
   319  		{
   320  			name: "parse labels",
   321  			args: args{
   322  				name:      "foo",
   323  				namespace: "bar",
   324  				uid:       uuid,
   325  				ruleLbs: labels.LabelArray{
   326  					{
   327  						Key:    "hello",
   328  						Value:  "world",
   329  						Source: labels.LabelSourceK8s,
   330  					},
   331  				},
   332  			},
   333  			want: labels.LabelArray{
   334  				{
   335  					Key:    "hello",
   336  					Value:  "world",
   337  					Source: labels.LabelSourceK8s,
   338  				},
   339  				{
   340  					Key:    "io.cilium.k8s.policy.derived-from",
   341  					Value:  "CiliumNetworkPolicy",
   342  					Source: labels.LabelSourceK8s,
   343  				},
   344  				{
   345  					Key:    "io.cilium.k8s.policy.name",
   346  					Value:  "foo",
   347  					Source: labels.LabelSourceK8s,
   348  				},
   349  				{
   350  					Key:    "io.cilium.k8s.policy.namespace",
   351  					Value:  "bar",
   352  					Source: labels.LabelSourceK8s,
   353  				},
   354  				{
   355  					Key:    "io.cilium.k8s.policy.uid",
   356  					Value:  string(uuid),
   357  					Source: labels.LabelSourceK8s,
   358  				},
   359  			},
   360  		},
   361  	}
   362  	for _, tt := range tests {
   363  		got := ParseToCiliumLabels(tt.args.namespace, tt.args.name, tt.args.uid, tt.args.ruleLbs)
   364  		c.Assert(got, checker.DeepEquals, tt.want, Commentf("Test Name: %s", tt.name))
   365  	}
   366  }