github.phpd.cn/cilium/cilium@v1.6.12/test/runtime/cassandra.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("RuntimeCassandra", func() {
    27  
    28  	var (
    29  		vm          *helpers.SSHMeta
    30  		cassandraIP string
    31  	)
    32  
    33  	containers := func(mode string) {
    34  
    35  		images := map[string]string{
    36  			"cass-server": constants.CassandraImage,
    37  			"cass-client": constants.CassandraImage,
    38  		}
    39  		cmds := map[string][]string{
    40  			"cass-client": {"sleep", "10000"},
    41  		}
    42  
    43  		switch mode {
    44  		case "create":
    45  			for k, v := range images {
    46  				cmd, ok := cmds[k]
    47  				var res *helpers.CmdRes
    48  				if ok {
    49  					res = vm.ContainerCreate(k, v, helpers.CiliumDockerNetwork, fmt.Sprintf("-l id.%s", k), cmd...)
    50  				} else {
    51  					res = vm.ContainerCreate(k, v, helpers.CiliumDockerNetwork, fmt.Sprintf("-l id.%s", k))
    52  				}
    53  				res.ExpectSuccess("failed to create container %s", k)
    54  			}
    55  			cassServer, err := vm.ContainerInspectNet("cass-server")
    56  			Expect(err).Should(BeNil(), "Could not get cass-server network info")
    57  			cassandraIP = cassServer["IPv4"]
    58  
    59  		case "delete":
    60  			for k := range images {
    61  				vm.ContainerRm(k)
    62  			}
    63  		}
    64  	}
    65  
    66  	runCqlsh := func(cmd string) *helpers.CmdRes {
    67  		logger.Infof("Executing command '%s'", cmd)
    68  		res := vm.ContainerExec("cass-client", fmt.Sprintf(
    69  			`cqlsh %s --connect-timeout=200 -e "%s"`, cassandraIP, cmd))
    70  		return res
    71  	}
    72  
    73  	setupPostsTable := func() {
    74  		r := runCqlsh("CREATE KEYSPACE posts_db WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'datacenter1' : 2 };")
    75  		r.ExpectSuccess("Unable to create keyspace 'posts_db'")
    76  
    77  		r = runCqlsh("CREATE TABLE posts_db.posts (username varchar, creation timeuuid, content varchar, PRIMARY KEY ((username), creation));")
    78  		r.ExpectSuccess("Unable to create 'posts' table")
    79  
    80  		r = runCqlsh("INSERT INTO posts_db.posts (username, creation, content) values ('dan', now(), 'Cilium Rocks!');")
    81  		r.ExpectSuccess("Unable to insert into 'posts' table")
    82  	}
    83  
    84  	// Waits for the server to be ready, by executing
    85  	// a command repeatedly until it succeeds, or a timeout occurs
    86  	waitForCassandraServer := func() error {
    87  		body := func() bool {
    88  			res := runCqlsh("SELECT * from system.local")
    89  			return res.WasSuccessful()
    90  		}
    91  		err := helpers.WithTimeout(body, "Cassandra server not ready", &helpers.TimeoutConfig{Timeout: helpers.HelperTimeout})
    92  		return err
    93  	}
    94  
    95  	BeforeAll(func() {
    96  		vm = helpers.InitRuntimeHelper(helpers.Runtime, logger)
    97  
    98  		ExpectCiliumReady(vm)
    99  
   100  		containers("create")
   101  		epsReady := vm.WaitEndpointsReady()
   102  		Expect(epsReady).Should(BeTrue(), "Endpoints are not ready after timeout")
   103  
   104  		err := waitForCassandraServer()
   105  		Expect(err).To(BeNil(), "Cassandra Server failed to come up")
   106  
   107  		// create keyspace, table, and do one insert
   108  		// with no policy in place
   109  		setupPostsTable()
   110  	})
   111  
   112  	AfterEach(func() {
   113  		vm.PolicyDelAll()
   114  	})
   115  
   116  	AfterAll(func() {
   117  		containers("delete")
   118  		vm.CloseSSHClient()
   119  	})
   120  
   121  	JustAfterEach(func() {
   122  		vm.ValidateNoErrorsInLogs(CurrentGinkgoTestDescription().Duration)
   123  	})
   124  
   125  	AfterFailed(func() {
   126  		vm.ReportFailed("cilium policy get")
   127  	})
   128  
   129  	It("Tests policy allowing all actions", func() {
   130  		_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-cassandra-allow-all.json"), helpers.HelperTimeout)
   131  		Expect(err).Should(BeNil(), "Failed to import policy")
   132  
   133  		endPoints, err := vm.PolicyEndpointsSummary()
   134  		Expect(err).Should(BeNil(), "Cannot get endpoint list")
   135  		Expect(endPoints[helpers.Enabled]).To(Equal(1),
   136  			"Check number of endpoints with policy enforcement enabled")
   137  		Expect(endPoints[helpers.Disabled]).To(Equal(1),
   138  			"Check number of endpoints with policy enforcement disabled")
   139  
   140  		By("Inserting Value into Cassandra (no policy)")
   141  		r := runCqlsh("INSERT INTO posts_db.posts (username, creation, content) values ('alice', now(), 'Hello');")
   142  		r.ExpectSuccess("Unable to insert into 'posts_db.posts' table")
   143  
   144  		By("Reading values from Cassandra (no policy)")
   145  		r = runCqlsh("SELECT * FROM posts_db.posts;")
   146  		r.ExpectSuccess("Unable to select from 'posts' table")
   147  		r.ExpectContains("alice", "Did not get inserted data in select")
   148  	})
   149  
   150  	It("Tests policy disallowing Insert action", func() {
   151  
   152  		_, err := vm.PolicyImportAndWait(vm.GetFullPath("Policies-cassandra-no-insert-posts.json"), helpers.HelperTimeout)
   153  		Expect(err).Should(BeNil(), "Failed to import policy")
   154  
   155  		endPoints, err := vm.PolicyEndpointsSummary()
   156  		Expect(err).Should(BeNil(), "Cannot get endpoint list")
   157  		Expect(endPoints[helpers.Enabled]).To(Equal(1),
   158  			"Check number of endpoints with policy enforcement enabled")
   159  		Expect(endPoints[helpers.Disabled]).To(Equal(1),
   160  			"Check number of endpoints with policy enforcement disabled")
   161  
   162  		By("Inserting Value into Cassandra (denied by policy)")
   163  		r := runCqlsh("INSERT INTO posts_db.posts (username, creation, content) values ('bob', now(), 'Goodbye');")
   164  		r.ExpectFail("Able to insert into 'posts_db.posts' table, which should be denied by policy")
   165  
   166  		By("Reading values from Cassandra (allowed by policy)")
   167  		r = runCqlsh("SELECT * FROM posts_db.posts;")
   168  		r.ExpectSuccess("Unable to select from 'posts' table")
   169  		r.ExpectContains("alice", "Did not get inserted data in select")
   170  		r.ExpectDoesNotContain("bob", "Got value on select that should not have been inserted")
   171  	})
   172  
   173  })