github.com/looshlee/cilium@v1.6.12/test/runtime/memcache.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  package RuntimeTest
    16  
    17  import (
    18  	"fmt"
    19  	. "github.com/cilium/cilium/test/ginkgo-ext"
    20  	"github.com/cilium/cilium/test/helpers"
    21  	"github.com/cilium/cilium/test/helpers/constants"
    22  
    23  	. "github.com/onsi/gomega"
    24  )
    25  
    26  var _ = Describe("RuntimeMemcache", func() {
    27  
    28  	var (
    29  		vm         *helpers.SSHMeta
    30  		memcacheIP string
    31  	)
    32  
    33  	containers := func(mode string) {
    34  
    35  		images := map[string]string{
    36  			"memcache":             constants.MemcacheDImage,
    37  			"memcache-bin-client":  constants.MemcacheBinClient,
    38  			"memcache-text-client": constants.AlpineImage,
    39  		}
    40  		cmds := map[string][]string{
    41  			"memcache-bin-client":  {"sleep", "10000"},
    42  			"memcache-text-client": {"sleep", "10000"},
    43  		}
    44  
    45  		switch mode {
    46  		case "create":
    47  			for k, v := range images {
    48  				cmd, ok := cmds[k]
    49  				var res *helpers.CmdRes
    50  				if ok {
    51  					// client containers
    52  					res = vm.ContainerCreate(k, v, helpers.CiliumDockerNetwork, "-l memcache-client", cmd...)
    53  				} else {
    54  					res = vm.ContainerCreate(k, v, helpers.CiliumDockerNetwork, fmt.Sprintf("-l id.%s", k))
    55  				}
    56  				res.ExpectSuccess("failed to create container %s", k)
    57  			}
    58  			memcache, err := vm.ContainerInspectNet("memcache")
    59  			Expect(err).Should(BeNil(), "Could not get memcache network")
    60  			memcacheIP = memcache["IPv4"]
    61  
    62  		case "delete":
    63  			for k := range images {
    64  				vm.ContainerRm(k)
    65  			}
    66  		}
    67  	}
    68  
    69  	setKeyBinary := func(key, value string) *helpers.CmdRes {
    70  		logger.Infof("Setting %s as %s", key, value)
    71  		res := vm.ContainerExec("memcache-bin-client", fmt.Sprintf(
    72  			`python -c 'import bmemcached; client = bmemcached.Client(("%s:11211", )); print(client.set("%s", "%s"))'`, memcacheIP, key, value))
    73  		return res
    74  	}
    75  
    76  	getKeyBinary := func(key string) *helpers.CmdRes {
    77  		logger.Infof("Getting %s", key)
    78  		res := vm.ContainerExec("memcache-bin-client", fmt.Sprintf(
    79  			`python -c 'import bmemcached; client = bmemcached.Client(("%s:11211", )); print(client.get("%s"))'`, memcacheIP, key))
    80  		return res
    81  	}
    82  
    83  	runWithClientBinary := func(code string) *helpers.CmdRes {
    84  		logger.Infof("Executing %s", code)
    85  		res := vm.ContainerExec("memcache-bin-client", fmt.Sprintf(
    86  			`python -c 'import bmemcached; client = bmemcached.Client(("%s:11211", )); %s'`, memcacheIP, code))
    87  		return res
    88  	}
    89  
    90  	flush := func() *helpers.CmdRes {
    91  		logger.Infof("flushing memcached")
    92  		cmd := fmt.Sprintf(
    93  			`sh -c 'echo -en "flush_all\r\nquit\r\n" | nc %s 11211'`, memcacheIP)
    94  		res := vm.ContainerExec("memcache-text-client", cmd)
    95  		return res
    96  	}
    97  
    98  	BeforeAll(func() {
    99  		vm = helpers.InitRuntimeHelper(helpers.Runtime, logger)
   100  
   101  		ExpectCiliumReady(vm)
   102  
   103  		containers("create")
   104  		epsReady := vm.WaitEndpointsReady()
   105  		Expect(epsReady).Should(BeTrue(), "Endpoints are not ready after timeout")
   106  	})
   107  
   108  	AfterEach(func() {
   109  		vm.PolicyDelAll()
   110  		flush().ExpectContains("OK", "Unable to flush memcache")
   111  	})
   112  
   113  	AfterAll(func() {
   114  		containers("delete")
   115  		vm.CloseSSHClient()
   116  	})
   117  
   118  	JustAfterEach(func() {
   119  		vm.ValidateNoErrorsInLogs(CurrentGinkgoTestDescription().Duration)
   120  	})
   121  
   122  	AfterFailed(func() {
   123  		containers("delete")
   124  		vm.ReportFailed("cilium policy get")
   125  	})
   126  
   127  	Context("Testing binary memcache", func() {
   128  		It("Tests basic memcache operation", func() {
   129  			key := "test1"
   130  			value := "value1"
   131  			By("Setting memcache value")
   132  			r := setKeyBinary(key, value)
   133  
   134  			r.ExpectSuccess("Unable to set key %s", key)
   135  
   136  			By("getting memcache value")
   137  			r = getKeyBinary(key)
   138  			r.ExpectSuccess("Unable to get key %s", key)
   139  			r.ExpectContains(value, "Value mismatch on get")
   140  		})
   141  
   142  		It("Tests policy allowing all actions", func() {
   143  			_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-memcache-allow.json"), helpers.HelperTimeout)
   144  			Expect(err).Should(BeNil(), "Failed to import policy")
   145  
   146  			key := "test2"
   147  			value := "value2"
   148  			By("Setting memcache value")
   149  			r := setKeyBinary(key, value)
   150  			r.ExpectSuccess("Unable to set key %s", key)
   151  
   152  			By("getting memcache value")
   153  			r = getKeyBinary(key)
   154  			r.ExpectSuccess("Unable to get key %s", key)
   155  			r.ExpectContains(value, "Value mismatch for key %s", key)
   156  		})
   157  
   158  		It("Tests policy disallowing set action", func() {
   159  			By("Setting key before disallowing set")
   160  			keyBeforePolicy := "before"
   161  			valBeforePolicy := "beforeval"
   162  			r := setKeyBinary(keyBeforePolicy, valBeforePolicy)
   163  			r.ExpectSuccess("Unable to set key %q without policy loaded", keyBeforePolicy)
   164  
   165  			By("Importing policy disallowing set")
   166  			_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-memcache-disallow-set.json"), helpers.HelperTimeout)
   167  			Expect(err).Should(BeNil(), "Failed to import policy")
   168  
   169  			By("Trying to set new key")
   170  			key := "keyAfterPolicy"
   171  			value := "valAfterPolicy"
   172  
   173  			By("Setting memcache value")
   174  			r = setKeyBinary(key, value)
   175  			r.ExpectFail("Set key should be prohibited by policy")
   176  
   177  			By("getting memcache value")
   178  			r = getKeyBinary(keyBeforePolicy)
   179  			r.ExpectSuccess("Unable to get key set before applying policy")
   180  			r.ExpectContains(valBeforePolicy, "Value mismatch on get")
   181  		})
   182  
   183  		It("Tests policy allowing actions only for key", func() {
   184  			By("Importing key-specific policy")
   185  			_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-memcache-allow-key.json"), helpers.HelperTimeout)
   186  			Expect(err).Should(BeNil(), "Failed to import policy")
   187  
   188  			key := "allowed"
   189  			value := "value"
   190  			By("Setting memcache allowed key")
   191  			r := setKeyBinary(key, value)
   192  			r.ExpectSuccess("Unable to set allowed key")
   193  			By("Getting memcache allowed key")
   194  			r = getKeyBinary(key)
   195  			r.ExpectSuccess("Unable to get allowed key")
   196  
   197  			key = "disallowed"
   198  			By("Setting memcache disallowed key")
   199  			r = setKeyBinary(key, value)
   200  			r.ExpectFail("Able to set disallowed key")
   201  		})
   202  
   203  		It("Tests multi-get from a disallowed and allowed keys set", func() {
   204  			By("Setting value to both keys")
   205  			r := setKeyBinary("allowed", "value")
   206  			r.ExpectSuccess("Unable to set allowed value")
   207  			r = setKeyBinary("disallowed", "value")
   208  			r.ExpectSuccess("Unable to set disallowed value")
   209  
   210  			By("Importing key-specific policy")
   211  			_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-memcache-allow-key-get.json"), helpers.HelperTimeout)
   212  			Expect(err).Should(BeNil(), "Failed to import policy")
   213  
   214  			By("Getting multiple keys")
   215  			code := "print(client.get_multi([\"allowed\", \"disallowed\"]))"
   216  			r = runWithClientBinary(code)
   217  
   218  			r.ExpectFail("Able to get multiple keys with disallowed")
   219  		})
   220  	})
   221  
   222  	setKeyText := func(key, value string) *helpers.CmdRes {
   223  		logger.Infof("Setting %s as %s", key, value)
   224  		cmd := fmt.Sprintf(
   225  			`sh -c 'echo -en "set %s 0 500 %d\r\n%s\r\nquit\r\n" | nc %s 11211'`, key, len(value), value, memcacheIP)
   226  		res := vm.ContainerExec("memcache-text-client", cmd)
   227  		return res
   228  	}
   229  
   230  	getKeyText := func(key string) *helpers.CmdRes {
   231  		logger.Infof("Getting %s", key)
   232  		res := vm.ContainerExec("memcache-text-client", fmt.Sprintf(
   233  			`sh -c 'echo -en "get %s\r\nquit\r\n" | nc %s 11211'`, key, memcacheIP))
   234  		return res
   235  	}
   236  
   237  	Context("Testing text memcache", func() {
   238  		It("Tests basic memcache operation", func() {
   239  			key := "test1"
   240  			value := "value1"
   241  			By("Setting memcache value")
   242  			r := setKeyText(key, value)
   243  			r.ExpectSuccess("Unable to set key %s", key)
   244  			r.ExpectContains("STORED", "value not stored")
   245  
   246  			By("getting memcache value")
   247  			r = getKeyText(key)
   248  			r.ExpectSuccess("Unable to get key %s", key)
   249  			r.ExpectContains(value, "Value mismatch on get")
   250  			r.ExpectContains("VALUE", "Did not have text VALUE header")
   251  		})
   252  
   253  		It("Tests policy allowing all actions", func() {
   254  			_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-memcache-allow.json"), helpers.HelperTimeout)
   255  			Expect(err).Should(BeNil(), "Failed to import policy")
   256  
   257  			key := "test2"
   258  			value := "value2"
   259  			By("Setting memcache value")
   260  			r := setKeyText(key, value)
   261  			r.ExpectSuccess("Unable to set key, %s", key)
   262  			r.ExpectContains("STORED", "value not stored")
   263  
   264  			By("getting memcache value")
   265  			r = getKeyText(key)
   266  			r.ExpectSuccess("Unable to get key, %s", key)
   267  			r.ExpectContains(value, "memcache key %s value mismatch", key)
   268  			r.ExpectContains("VALUE", "Did not have text VALUE header")
   269  		})
   270  
   271  		It("Tests policy disallowing set action", func() {
   272  			By("Setting key before disallowing set")
   273  			keyBeforePolicy := "before"
   274  			valBeforePolicy := "beforeval"
   275  			r := setKeyText(keyBeforePolicy, valBeforePolicy)
   276  			r.ExpectSuccess("Unable to set key %q without policy loaded", keyBeforePolicy)
   277  			r.ExpectContains("STORED", "value not stored")
   278  
   279  			By("Importing policy disallowing set")
   280  			_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-memcache-disallow-set.json"), helpers.HelperTimeout)
   281  			Expect(err).Should(BeNil(), "Failed to import policy")
   282  
   283  			By("Trying to set new key")
   284  			key := "keyAfterPolicy"
   285  			value := "valAfterPolicy"
   286  
   287  			By("Setting memcache value")
   288  			r = setKeyText(key, value)
   289  			r.ExpectSuccess("Unable to set key %s", key)
   290  			r.ExpectContains("access denied", "did not get access denied message")
   291  
   292  			By("getting memcache value")
   293  			r = getKeyText(keyBeforePolicy)
   294  			r.ExpectSuccess("Unable to get key set before applying policy")
   295  			r.ExpectContains(valBeforePolicy, "Value mismatch on get")
   296  		})
   297  
   298  		It("Tests policy allowing actions only for allowed key", func() {
   299  			By("Importing key-specific policy")
   300  			_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-memcache-allow-key.json"), helpers.HelperTimeout)
   301  			Expect(err).Should(BeNil(), "Failed to import policy")
   302  
   303  			key := "allowed"
   304  			value := "value"
   305  			By("Setting memcache allowed key")
   306  			r := setKeyText(key, value)
   307  			r.ExpectSuccess("Unable to set allowed key")
   308  			By("Getting memcache allowed key")
   309  			r = getKeyText(key)
   310  			r.ExpectSuccess("Unable to get allowed key")
   311  
   312  			key = "disallowed"
   313  			By("Setting memcache disallowed key")
   314  			r = setKeyText(key, value)
   315  			r.ExpectSuccess("Unable to set key %s", key)
   316  			r.ExpectContains("access denied", "did not get access denied message")
   317  		})
   318  	})
   319  })