github.com/fafucoder/cilium@v1.6.11/cilium/cmd/helpers_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 cmd
    18  
    19  import (
    20  	"bytes"
    21  	"path"
    22  	"sort"
    23  	"testing"
    24  
    25  	"github.com/cilium/cilium/pkg/checker"
    26  	"github.com/cilium/cilium/pkg/labels"
    27  	"github.com/cilium/cilium/pkg/policy/trafficdirection"
    28  	"github.com/cilium/cilium/pkg/u8proto"
    29  
    30  	. "gopkg.in/check.v1"
    31  )
    32  
    33  func Test(t *testing.T) { TestingT(t) }
    34  
    35  type CMDHelpersSuite struct{}
    36  
    37  var _ = Suite(&CMDHelpersSuite{})
    38  
    39  func (s *CMDHelpersSuite) TestExpandNestedJSON(c *C) {
    40  	buf := bytes.NewBufferString("not json at all")
    41  	res, err := expandNestedJSON(*buf)
    42  	c.Assert(err, IsNil)
    43  	c.Assert(string(res.Bytes()), Equals, `not json at all`)
    44  
    45  	buf = bytes.NewBufferString(`{\n\"notEscapedJson\": \"foo\"}`)
    46  	res, err = expandNestedJSON(*buf)
    47  	c.Assert(err, IsNil)
    48  	c.Assert(string(res.Bytes()), Equals, `{\n\"notEscapedJson\": \"foo\"}`)
    49  
    50  	buf = bytes.NewBufferString(`nonjson={\n\"notEscapedJson\": \"foo\"}`)
    51  	res, err = expandNestedJSON(*buf)
    52  	c.Assert(err, IsNil)
    53  	c.Assert(string(res.Bytes()), Equals, `nonjson={\n\"notEscapedJson\": \"foo\"}`)
    54  
    55  	buf = bytes.NewBufferString(`nonjson:morenonjson={\n\"notEscapedJson\": \"foo\"}`)
    56  	res, err = expandNestedJSON(*buf)
    57  	c.Assert(err, IsNil)
    58  	c.Assert(string(res.Bytes()), Equals, `nonjson:morenonjson={\n\"notEscapedJson\": \"foo\"}`)
    59  
    60  	buf = bytes.NewBufferString(`{"foo": ["{\n  \"port\": 8080,\n  \"protocol\": \"TCP\"\n}"]}`)
    61  	res, err = expandNestedJSON(*buf)
    62  	c.Assert(err, IsNil)
    63  	c.Assert(string(res.Bytes()), Equals, `{"foo": [{
    64    "port": 8080,
    65    "protocol": "TCP"
    66  }]}`)
    67  
    68  	buf = bytes.NewBufferString(`"foo": [
    69    "bar:baz/alice={\"bob\":{\"charlie\":4}}\n"
    70  ]`)
    71  	res, err = expandNestedJSON(*buf)
    72  	c.Assert(err, IsNil)
    73  	c.Assert(string(res.Bytes()), Equals, `"foo": [
    74    bar:baz/alice={
    75  				  "bob": {
    76  				    "charlie": 4
    77  				  }
    78  				}
    79  
    80  ]`)
    81  
    82  	buf = bytes.NewBufferString(`"foo": [
    83    "bar:baz/alice={\n\"bob\":\n{\n\"charlie\":\n4\n}\n}\n"
    84  ]`)
    85  	res, err = expandNestedJSON(*buf)
    86  	c.Assert(err, IsNil)
    87  	c.Assert(string(res.Bytes()), Equals, `"foo": [
    88    bar:baz/alice={
    89  				  "bob": {
    90  				    "charlie": 4
    91  				  }
    92  				}
    93  
    94  ]`)
    95  
    96  	buf = bytes.NewBufferString(`[
    97    {
    98      "id": 2669,
    99      "spec": {
   100        "label-configuration": {},
   101        "options": {
   102          "Conntrack": "Enabled",
   103          "ConntrackAccounting": "Enabled",
   104          "ConntrackLocal": "Disabled",
   105          "Debug": "Enabled",
   106          "DebugLB": "Enabled",
   107          "DropNotification": "Enabled",
   108          "MonitorAggregationLevel": "None",
   109          "NAT46": "Disabled",
   110          "TraceNotification": "Enabled"
   111        }
   112      },
   113      "status": {
   114        "controllers": [
   115          {
   116            "configuration": {
   117              "error-retry": true,
   118              "interval": "5m0s"
   119            },
   120            "name": "resolve-identity-2669",
   121            "status": {
   122              "last-failure-timestamp": "0001-01-01T00:00:00.000Z",
   123              "last-success-timestamp": "2019-06-10T19:36:42.497Z",
   124              "success-count": 4
   125            },
   126            "uuid": "aba643d9-8bb5-11e9-9be2-080027486be3"
   127          },
   128          {
   129            "configuration": {
   130              "error-retry": true,
   131              "interval": "5m0s"
   132            },
   133            "name": "sync-IPv4-identity-mapping (2669)",
   134            "status": {
   135              "last-failure-timestamp": "0001-01-01T00:00:00.000Z",
   136              "last-success-timestamp": "2019-06-10T19:36:42.529Z",
   137              "success-count": 4
   138            },
   139            "uuid": "aba631c3-8bb5-11e9-9be2-080027486be3"
   140          },
   141          {
   142            "configuration": {
   143              "error-retry": true,
   144              "interval": "5m0s"
   145            },
   146            "name": "sync-IPv6-identity-mapping (2669)",
   147            "status": {
   148              "last-failure-timestamp": "0001-01-01T00:00:00.000Z",
   149              "last-success-timestamp": "2019-06-10T19:36:42.529Z",
   150              "success-count": 4
   151            },
   152            "uuid": "aba637e9-8bb5-11e9-9be2-080027486be3"
   153          },
   154          {
   155            "configuration": {
   156              "error-retry": true,
   157              "interval": "1m0s"
   158            },
   159            "name": "sync-policymap-2669",
   160            "status": {
   161              "last-failure-timestamp": "0001-01-01T00:00:00.000Z",
   162              "last-success-timestamp": "2019-06-10T19:39:43.974Z",
   163              "success-count": 16
   164            },
   165            "uuid": "ad0a1388-8bb5-11e9-9be2-080027486be3"
   166          }
   167        ],
   168        "external-identifiers": {
   169          "container-id": "1968a48396a0e42f3faad360a7ffa23d8629faddee7f828408bf177d3eeac47a",
   170          "container-name": "client",
   171          "docker-endpoint-id": "05a27bef9f339e5ae25a191108b91ee1e7fdc2696d2c46908645157a62438ccd",
   172          "docker-network-id": "e3ea8f2e1df2250df6702fd802ea0d3706091c1b374db998d48e7327bf9bd0fe",
   173          "pod-name": "/"
   174        },
   175        "health": {
   176          "bpf": "OK",
   177          "connected": true,
   178          "overallHealth": "OK",
   179          "policy": "OK"
   180        },
   181        "identity": {
   182          "id": 62004,
   183          "labels": [
   184            "container:id.client"
   185          ],
   186          "labelsSHA256": "c2e7b3482b5e9e1abca840b8cc5568ff876c7524d723b3068683f539008537dc"
   187        },
   188        "labels": {
   189          "realized": {},
   190          "security-relevant": [
   191            "container:id.client"
   192          ]
   193        },
   194        "log": [
   195          {
   196            "code": "OK",
   197            "message": "Successfully regenerated endpoint program (Reason: policy rules added)",
   198            "state": "ready",
   199            "timestamp": "2019-06-10T19:26:43Z"
   200          }
   201        ],
   202        "networking": {
   203          "addressing": [
   204            {
   205              "ipv4": "10.11.212.174",
   206              "ipv6": "f00d::a0b:0:0:8cdf"
   207            }
   208          ],
   209          "host-mac": "1a:c9:b9:4f:98:65",
   210          "interface-index": 250,
   211          "interface-name": "lxca8e38e6f627e",
   212          "mac": "7e:41:1b:fd:02:81"
   213        },
   214        "policy": {
   215          "proxy-policy-revision": 48,
   216          "proxy-statistics": [
   217            {
   218              "allocated-proxy-port": 15814,
   219              "location": "egress",
   220              "port": 80,
   221              "protocol": "http",
   222              "statistics": {
   223                "requests": {
   224                  "denied": 2,
   225                  "forwarded": 2,
   226                  "received": 4
   227                },
   228                "responses": {
   229                  "forwarded": 2,
   230                  "received": 2
   231                }
   232              }
   233            }
   234          ],
   235          "realized": {
   236            "allowed-egress-identities": [],
   237            "allowed-ingress-identities": [
   238              0,
   239              1
   240            ],
   241            "build": 48,
   242            "cidr-policy": {
   243              "egress": [],
   244              "ingress": []
   245            },
   246            "id": 62004,
   247            "l4": {
   248              "egress": [
   249                {
   250                  "derived-from-rules": [
   251                    []
   252                  ],
   253                  "rule": "{\n  \"port\": 80,\n  \"protocol\": \"TCP\",\n  \"l7-rules\": [\n    {\n      \"\\u0026LabelSelector{MatchLabels:map[string]string{},MatchExpressions:[],}\": {\n        \"http\": [\n          {\n            \"path\": \"/public\",\n            \"method\": \"GET\"\n          }\n        ]\n      }\n    }\n  ]\n}"
   254                }
   255              ],
   256              "ingress": []
   257            },
   258            "policy-enabled": "egress",
   259            "policy-revision": 48
   260          },
   261          "spec": {
   262            "allowed-egress-identities": [],
   263            "allowed-ingress-identities": [
   264              0,
   265              1
   266            ],
   267            "build": 48,
   268            "cidr-policy": {
   269              "egress": [],
   270              "ingress": []
   271            },
   272            "id": 62004,
   273            "l4": {
   274              "egress": [
   275                {
   276                  "derived-from-rules": [
   277                    []
   278                  ],
   279                  "rule": "{\n  \"port\": 80,\n  \"protocol\": \"TCP\",\n  \"l7-rules\": [\n    {\n      \"\\u0026LabelSelector{MatchLabels:map[string]string{},MatchExpressions:[],}\": {\n        \"http\": [\n          {\n            \"path\": \"/public\",\n            \"method\": \"GET\"\n          }\n        ]\n      }\n    }\n  ]\n}"
   280                }
   281              ],
   282              "ingress": []
   283            },
   284            "policy-enabled": "egress",
   285            "policy-revision": 48
   286          }
   287        },
   288        "realized": {
   289          "label-configuration": {},
   290          "options": {
   291            "Conntrack": "Enabled",
   292            "ConntrackAccounting": "Enabled",
   293            "ConntrackLocal": "Disabled",
   294            "Debug": "Enabled",
   295            "DebugLB": "Enabled",
   296            "DropNotification": "Enabled",
   297            "MonitorAggregationLevel": "None",
   298            "NAT46": "Disabled",
   299            "TraceNotification": "Enabled"
   300          }
   301        },
   302        "state": "ready"
   303      }
   304    }
   305  ]`)
   306  	res, err = expandNestedJSON(*buf)
   307  	c.Assert(err, IsNil)
   308  	c.Assert(string(res.Bytes()), Equals, `[
   309    {
   310      "id": 2669,
   311      "spec": {
   312        "label-configuration": {},
   313        "options": {
   314          "Conntrack": "Enabled",
   315          "ConntrackAccounting": "Enabled",
   316          "ConntrackLocal": "Disabled",
   317          "Debug": "Enabled",
   318          "DebugLB": "Enabled",
   319          "DropNotification": "Enabled",
   320          "MonitorAggregationLevel": "None",
   321          "NAT46": "Disabled",
   322          "TraceNotification": "Enabled"
   323        }
   324      },
   325      "status": {
   326        "controllers": [
   327          {
   328            "configuration": {
   329              "error-retry": true,
   330              "interval": "5m0s"
   331            },
   332            "name": "resolve-identity-2669",
   333            "status": {
   334              "last-failure-timestamp": "0001-01-01T00:00:00.000Z",
   335              "last-success-timestamp": "2019-06-10T19:36:42.497Z",
   336              "success-count": 4
   337            },
   338            "uuid": "aba643d9-8bb5-11e9-9be2-080027486be3"
   339          },
   340          {
   341            "configuration": {
   342              "error-retry": true,
   343              "interval": "5m0s"
   344            },
   345            "name": "sync-IPv4-identity-mapping (2669)",
   346            "status": {
   347              "last-failure-timestamp": "0001-01-01T00:00:00.000Z",
   348              "last-success-timestamp": "2019-06-10T19:36:42.529Z",
   349              "success-count": 4
   350            },
   351            "uuid": "aba631c3-8bb5-11e9-9be2-080027486be3"
   352          },
   353          {
   354            "configuration": {
   355              "error-retry": true,
   356              "interval": "5m0s"
   357            },
   358            "name": "sync-IPv6-identity-mapping (2669)",
   359            "status": {
   360              "last-failure-timestamp": "0001-01-01T00:00:00.000Z",
   361              "last-success-timestamp": "2019-06-10T19:36:42.529Z",
   362              "success-count": 4
   363            },
   364            "uuid": "aba637e9-8bb5-11e9-9be2-080027486be3"
   365          },
   366          {
   367            "configuration": {
   368              "error-retry": true,
   369              "interval": "1m0s"
   370            },
   371            "name": "sync-policymap-2669",
   372            "status": {
   373              "last-failure-timestamp": "0001-01-01T00:00:00.000Z",
   374              "last-success-timestamp": "2019-06-10T19:39:43.974Z",
   375              "success-count": 16
   376            },
   377            "uuid": "ad0a1388-8bb5-11e9-9be2-080027486be3"
   378          }
   379        ],
   380        "external-identifiers": {
   381          "container-id": "1968a48396a0e42f3faad360a7ffa23d8629faddee7f828408bf177d3eeac47a",
   382          "container-name": "client",
   383          "docker-endpoint-id": "05a27bef9f339e5ae25a191108b91ee1e7fdc2696d2c46908645157a62438ccd",
   384          "docker-network-id": "e3ea8f2e1df2250df6702fd802ea0d3706091c1b374db998d48e7327bf9bd0fe",
   385          "pod-name": "/"
   386        },
   387        "health": {
   388          "bpf": "OK",
   389          "connected": true,
   390          "overallHealth": "OK",
   391          "policy": "OK"
   392        },
   393        "identity": {
   394          "id": 62004,
   395          "labels": [
   396            "container:id.client"
   397          ],
   398          "labelsSHA256": "c2e7b3482b5e9e1abca840b8cc5568ff876c7524d723b3068683f539008537dc"
   399        },
   400        "labels": {
   401          "realized": {},
   402          "security-relevant": [
   403            "container:id.client"
   404          ]
   405        },
   406        "log": [
   407          {
   408            "code": "OK",
   409            "message": "Successfully regenerated endpoint program (Reason: policy rules added)",
   410            "state": "ready",
   411            "timestamp": "2019-06-10T19:26:43Z"
   412          }
   413        ],
   414        "networking": {
   415          "addressing": [
   416            {
   417              "ipv4": "10.11.212.174",
   418              "ipv6": "f00d::a0b:0:0:8cdf"
   419            }
   420          ],
   421          "host-mac": "1a:c9:b9:4f:98:65",
   422          "interface-index": 250,
   423          "interface-name": "lxca8e38e6f627e",
   424          "mac": "7e:41:1b:fd:02:81"
   425        },
   426        "policy": {
   427          "proxy-policy-revision": 48,
   428          "proxy-statistics": [
   429            {
   430              "allocated-proxy-port": 15814,
   431              "location": "egress",
   432              "port": 80,
   433              "protocol": "http",
   434              "statistics": {
   435                "requests": {
   436                  "denied": 2,
   437                  "forwarded": 2,
   438                  "received": 4
   439                },
   440                "responses": {
   441                  "forwarded": 2,
   442                  "received": 2
   443                }
   444              }
   445            }
   446          ],
   447          "realized": {
   448            "allowed-egress-identities": [],
   449            "allowed-ingress-identities": [
   450              0,
   451              1
   452            ],
   453            "build": 48,
   454            "cidr-policy": {
   455              "egress": [],
   456              "ingress": []
   457            },
   458            "id": 62004,
   459            "l4": {
   460              "egress": [
   461                {
   462                  "derived-from-rules": [
   463                    []
   464                  ],
   465                  "rule": {
   466  		  "l7-rules": [
   467  		    {
   468  		      "\u0026LabelSelector{MatchLabels:map[string]string{},MatchExpressions:[],}": {
   469  		        "http": [
   470  		          {
   471  		            "method": "GET",
   472  		            "path": "/public"
   473  		          }
   474  		        ]
   475  		      }
   476  		    }
   477  		  ],
   478  		  "port": 80,
   479  		  "protocol": "TCP"
   480  		}
   481                }
   482              ],
   483              "ingress": []
   484            },
   485            "policy-enabled": "egress",
   486            "policy-revision": 48
   487          },
   488          "spec": {
   489            "allowed-egress-identities": [],
   490            "allowed-ingress-identities": [
   491              0,
   492              1
   493            ],
   494            "build": 48,
   495            "cidr-policy": {
   496              "egress": [],
   497              "ingress": []
   498            },
   499            "id": 62004,
   500            "l4": {
   501              "egress": [
   502                {
   503                  "derived-from-rules": [
   504                    []
   505                  ],
   506                  "rule": {
   507  		  "l7-rules": [
   508  		    {
   509  		      "\u0026LabelSelector{MatchLabels:map[string]string{},MatchExpressions:[],}": {
   510  		        "http": [
   511  		          {
   512  		            "method": "GET",
   513  		            "path": "/public"
   514  		          }
   515  		        ]
   516  		      }
   517  		    }
   518  		  ],
   519  		  "port": 80,
   520  		  "protocol": "TCP"
   521  		}
   522                }
   523              ],
   524              "ingress": []
   525            },
   526            "policy-enabled": "egress",
   527            "policy-revision": 48
   528          }
   529        },
   530        "realized": {
   531          "label-configuration": {},
   532          "options": {
   533            "Conntrack": "Enabled",
   534            "ConntrackAccounting": "Enabled",
   535            "ConntrackLocal": "Disabled",
   536            "Debug": "Enabled",
   537            "DebugLB": "Enabled",
   538            "DropNotification": "Enabled",
   539            "MonitorAggregationLevel": "None",
   540            "NAT46": "Disabled",
   541            "TraceNotification": "Enabled"
   542          }
   543        },
   544        "state": "ready"
   545      }
   546    }
   547  ]`)
   548  
   549  }
   550  
   551  func (s *CMDHelpersSuite) TestParseTrafficString(c *C) {
   552  
   553  	validIngressCases := []string{"ingress", "Ingress", "InGrEss"}
   554  	validEgressCases := []string{"egress", "Egress", "EGrEss"}
   555  
   556  	invalidStr := "getItDoneMan"
   557  
   558  	for _, validCase := range validIngressCases {
   559  		ingressDir, err := parseTrafficString(validCase)
   560  		c.Assert(ingressDir, Equals, trafficdirection.Ingress)
   561  		c.Assert(err, IsNil)
   562  	}
   563  
   564  	for _, validCase := range validEgressCases {
   565  		egressDir, err := parseTrafficString(validCase)
   566  		c.Assert(egressDir, Equals, trafficdirection.Egress)
   567  		c.Assert(err, IsNil)
   568  	}
   569  
   570  	invalid, err := parseTrafficString(invalidStr)
   571  	c.Assert(invalid, Equals, trafficdirection.Invalid)
   572  	c.Assert(err, Not(IsNil))
   573  
   574  }
   575  
   576  func (s *CMDHelpersSuite) TestParsePolicyUpdateArgsHelper(c *C) {
   577  	sortProtos := func(ints []uint8) {
   578  		sort.Slice(ints, func(i, j int) bool {
   579  			return ints[i] < ints[j]
   580  		})
   581  	}
   582  
   583  	allProtos := []uint8{}
   584  	for _, proto := range u8proto.ProtoIDs {
   585  		allProtos = append(allProtos, uint8(proto))
   586  	}
   587  
   588  	tests := []struct {
   589  		args             []string
   590  		invalid          bool
   591  		mapBaseName      string
   592  		trafficDirection trafficdirection.TrafficDirection
   593  		peerLbl          uint32
   594  		port             uint16
   595  		protos           []uint8
   596  	}{
   597  		{
   598  			args:             []string{labels.IDNameHost, "ingress", "12345"},
   599  			invalid:          false,
   600  			mapBaseName:      "cilium_policy_reserved_1",
   601  			trafficDirection: trafficdirection.Ingress,
   602  			peerLbl:          12345,
   603  			port:             0,
   604  			protos:           []uint8{0},
   605  		},
   606  		{
   607  			args:             []string{"123", "egress", "12345", "1/tcp"},
   608  			invalid:          false,
   609  			mapBaseName:      "cilium_policy_00123",
   610  			trafficDirection: trafficdirection.Egress,
   611  			peerLbl:          12345,
   612  			port:             1,
   613  			protos:           []uint8{uint8(u8proto.TCP)},
   614  		},
   615  		{
   616  			args:             []string{"123", "ingress", "12345", "1"},
   617  			invalid:          false,
   618  			mapBaseName:      "cilium_policy_00123",
   619  			trafficDirection: trafficdirection.Ingress,
   620  			peerLbl:          12345,
   621  			port:             1,
   622  			protos:           allProtos,
   623  		},
   624  		{
   625  			// Invalid traffic direction.
   626  			args:    []string{"123", "invalid", "12345"},
   627  			invalid: true,
   628  		},
   629  		{
   630  			// Invalid protocol.
   631  			args:    []string{"123", "invalid", "1/udt"},
   632  			invalid: true,
   633  		},
   634  	}
   635  
   636  	for _, tt := range tests {
   637  		args, err := parsePolicyUpdateArgsHelper(tt.args)
   638  
   639  		if tt.invalid {
   640  			c.Assert(err, NotNil)
   641  		} else {
   642  			c.Assert(err, IsNil)
   643  
   644  			c.Assert(path.Base(args.path), Equals, tt.mapBaseName)
   645  			c.Assert(args.trafficDirection, Equals, tt.trafficDirection)
   646  			c.Assert(args.label, Equals, tt.peerLbl)
   647  			c.Assert(args.port, Equals, tt.port)
   648  
   649  			sortProtos(args.protocols)
   650  			sortProtos(tt.protos)
   651  			c.Assert(args.protocols, checker.DeepEquals, tt.protos)
   652  		}
   653  	}
   654  }