go.ligato.io/vpp-agent/v3@v3.5.0/tests/e2e/e2etest/etcd.go (about) 1 // Copyright (c) 2020 Cisco and/or its affiliates. 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 e2etest 16 17 import ( 18 "path/filepath" 19 20 docker "github.com/fsouza/go-dockerclient" 21 "github.com/go-errors/errors" 22 ) 23 24 const ( 25 etcdImage = "gcr.io/etcd-development/etcd:v3.5.5" 26 etcdStopTimeout = 1 // seconds 27 ) 28 29 // Etcd is represents running ETCD 30 type Etcd struct { 31 ComponentRuntime 32 ctx *TestCtx 33 } 34 35 // NewEtcd creates and starts new ETCD container 36 func NewEtcd(ctx *TestCtx, optMods ...EtcdOptModifier) (*Etcd, error) { 37 // compute options 38 opts := DefaultEtcdOpt(ctx) 39 for _, mod := range optMods { 40 mod(opts) 41 } 42 43 // create struct for ETCD server 44 etcd := &Etcd{ 45 ComponentRuntime: opts.Runtime, 46 ctx: ctx, 47 } 48 49 // get runtime specific options and start ETCD in runtime environment 50 startOpts, err := opts.RuntimeStartOptions(ctx, opts) 51 if err != nil { 52 return nil, errors.Errorf("can't get ETCD start option for runtime due to: %v", err) 53 } 54 err = etcd.Start(startOpts) 55 if err != nil { 56 return nil, errors.Errorf("can't start ETCD due to: %v", err) 57 } 58 return etcd, nil 59 } 60 61 // Put inserts key-value pair into the ETCD inside its running docker container 62 func (ec *Etcd) Put(key string, value string) error { 63 _, _, err := ec.ExecCmd("etcdctl", "put", key, value) 64 return err 65 } 66 67 // Get retrieves value for the key from the ETCD that is running in its docker container 68 func (ec *Etcd) Get(key string) (string, error) { 69 stdout, _, err := ec.ExecCmd("etcdctl", "get", key) 70 return stdout, err 71 } 72 73 // GetAll retrieves all key-value pairs from the ETCD that is running in its docker container 74 func (ec *Etcd) GetAll() (string, error) { 75 stdout, _, err := ec.ExecCmd("etcdctl", "get", "", "--prefix=true") 76 return stdout, err 77 } 78 79 // ETCDStartOptionsForContainerRuntime translates EtcdOpt to options for ComponentRuntime.Start(option) 80 // method implemented by ContainerRuntime 81 func ETCDStartOptionsForContainerRuntime(ctx *TestCtx, options interface{}) (interface{}, error) { 82 opts, ok := options.(*EtcdOpt) 83 if !ok { 84 return nil, errors.Errorf("expected EtcdOpt but got %+v", options) 85 } 86 87 // construct command string and container host config 88 cmd := []string{ 89 "/usr/local/bin/etcd", 90 } 91 hostConfig := &docker.HostConfig{} 92 if opts.UseHTTPS { 93 cmd = append(cmd, 94 "--client-cert-auth", 95 "--trusted-ca-file=/etc/certs/ca.pem", 96 "--cert-file=/etc/certs/cert1.pem", 97 "--key-file=/etc/certs/cert1-key.pem", 98 "--advertise-client-urls=https://127.0.0.1:2379", 99 "--listen-client-urls=https://127.0.0.1:2379", 100 ) 101 hostConfig.Binds = []string{filepath.Join(ctx.DataDir, "certs") + ":/etc/certs:ro"} 102 } else { // HTTP connection 103 cmd = append(cmd, 104 "--advertise-client-urls=http://0.0.0.0:2379", 105 "--listen-client-urls=http://0.0.0.0:2379", 106 ) 107 } 108 if opts.UseTestContainerForNetworking { 109 hostConfig.NetworkMode = "container:vpp-agent-e2e-test" 110 } else { // separate container networking (default) 111 hostConfig.PortBindings = map[docker.Port][]docker.PortBinding{ 112 "2379/tcp": {{HostIP: "0.0.0.0", HostPort: "2379"}}, 113 } 114 } 115 containerOptions := &docker.CreateContainerOptions{ 116 Name: "e2e-test-etcd", 117 Config: &docker.Config{ 118 Env: []string{"ETCDCTL_API=3"}, 119 Image: etcdImage, 120 Cmd: cmd, 121 }, 122 HostConfig: hostConfig, 123 } 124 125 return &ContainerStartOptions{ 126 ContainerOptions: containerOptions, 127 Pull: true, 128 }, nil 129 }