diff --git a/pkg/member/member_control.go b/pkg/member/member_control.go index a4384f903..6e965ecbb 100644 --- a/pkg/member/member_control.go +++ b/pkg/member/member_control.go @@ -113,7 +113,9 @@ func NewMemberControl(etcdConnConfig *brtypes.EtcdConnectionConfig) Control { // AddMemberAsLearner add a member as a learner to the etcd cluster func (m *memberControl) AddMemberAsLearner(ctx context.Context) error { //Add member as learner to cluster - memberURL, err := getMemberPeerURL(m.configFile, m.podName) + // TODO: Need to handle multiple peer URLs once etcd config is updated to support it. + // It is required in the context of Gardener usecase to support live control plane migration. + memberURL, err := miscellaneous.GetAdvertisePeerURLs(m.configFile) if err != nil { m.logger.Fatalf("Error fetching etcd member URL : %v", err) } @@ -198,28 +200,13 @@ func (m *memberControl) IsMemberInCluster(ctx context.Context) (bool, error) { return false, nil } -func getMemberPeerURL(configFile string, podName string) (string, error) { - config, err := miscellaneous.ReadConfigFileAsMap(configFile) - if err != nil { - return "", err - } - initAdPeerURL := config["initial-advertise-peer-urls"] - if initAdPeerURL == nil { - return "", errors.New("initial-advertise-peer-urls must be set in etcd config") - } - peerURL, err := miscellaneous.ParsePeerURL(initAdPeerURL.(string), podName) - if err != nil { - return "", fmt.Errorf("could not parse peer URL from the config file : %v", err) - } - return peerURL, nil -} - // doUpdateMemberPeerAddress updated the peer address of a specified etcd member func (m *memberControl) doUpdateMemberPeerAddress(ctx context.Context, cli etcdClient.ClusterCloser, id uint64) error { // Already existing clusters or cluster after restoration have `http://localhost:2380` as the peer address. This needs to explicitly updated to the correct peer address. m.logger.Infof("Updating member peer URL for %s", m.podName) - - memberPeerURL, err := getMemberPeerURL(m.configFile, m.podName) + // TODO: Need to handle multiple peer URLs once etcd config is updated to support it. + // It is required in the context of Gardener usecase to support live control plane migration. + memberPeerURL, err := miscellaneous.GetAdvertisePeerURLs(m.configFile) if err != nil { return fmt.Errorf("could not fetch member URL : %v", err) } diff --git a/pkg/member/member_control_test.go b/pkg/member/member_control_test.go index d0d19d2ab..8c004480f 100644 --- a/pkg/member/member_control_test.go +++ b/pkg/member/member_control_test.go @@ -47,20 +47,23 @@ var _ = Describe("Membercontrol", func() { outfile := "/tmp/etcd.conf.yaml" etcdConfigYaml := `# Human-readable name for this member. - name: etcd1 - data-dir: ` + os.Getenv("ETCD_DATA_DIR") + ` - metrics: extensive - snapshot-count: 75000 - enable-v2: false - quota-backend-bytes: 1073741824 - listen-client-urls: http://0.0.0.0:2379 - advertise-client-urls: http://0.0.0.0:2379 - initial-advertise-peer-urls: http@etcd-main-peer@default@2380 - initial-cluster: etcd1=http://0.0.0.0:2380 - initial-cluster-token: new - initial-cluster-state: new - auto-compaction-mode: periodic - auto-compaction-retention: 30m` +name: etcd1 +data-dir: ` + os.Getenv("ETCD_DATA_DIR") + ` +metrics: extensive +snapshot-count: 75000 +enable-v2: false +quota-backend-bytes: 1073741824 +listen-client-urls: http://0.0.0.0:2379 +advertise-client-urls: + ` + podName + `: http://0.0.0.0:2379 +initial-advertise-peer-urls: + ` + podName + `: + - http://etcd-main-peer.default:2380 +initial-cluster: etcd1=http://0.0.0.0:2380 +initial-cluster-token: new +initial-cluster-state: new +auto-compaction-mode: periodic +auto-compaction-retention: 30m` err := os.WriteFile(outfile, []byte(etcdConfigYaml), 0755) Expect(err).ShouldNot(HaveOccurred()) diff --git a/pkg/miscellaneous/miscellaneous.go b/pkg/miscellaneous/miscellaneous.go index 40ecc77e3..daf65af15 100644 --- a/pkg/miscellaneous/miscellaneous.go +++ b/pkg/miscellaneous/miscellaneous.go @@ -529,41 +529,100 @@ func ReadConfigFileAsMap(path string) (map[string]interface{}, error) { return c, nil } -// ParsePeerURL forms a PeerURL, given podName by parsing the initial-advertise-peer-urls -func ParsePeerURL(initialAdvertisePeerURLs, podName string) (string, error) { - tokens := strings.Split(initialAdvertisePeerURLs, "@") - if len(tokens) < 4 { - return "", fmt.Errorf("invalid peer URL : %s", initialAdvertisePeerURLs) +// GetAdvertisePeerURLs returns the advertise peer URLs for the etcd member. +func GetAdvertisePeerURLs(configFile string) (string, error) { + memberName, err := GetEnvVarOrError("POD_NAME") + if err != nil { + return "", err } - domaiName := fmt.Sprintf("%s.%s.%s", tokens[1], tokens[2], "svc") - return fmt.Sprintf("%s://%s.%s:%s", tokens[0], podName, domaiName, tokens[3]), nil -} - -// IsPeerURLTLSEnabled checks whether the peer address is TLS enabled or not. -func IsPeerURLTLSEnabled() (bool, error) { - podName, err := GetEnvVarOrError("POD_NAME") + config, err := ReadConfigFileAsMap(configFile) if err != nil { - return false, err + return "", err + } + initAdPeerURL := config["initial-advertise-peer-urls"] + if initAdPeerURL == nil { + return "", fmt.Errorf("initial-advertise-peer-urls must be set in etcd config") } - configFile := GetConfigFilePath() + peerUrlsMap, ok := initAdPeerURL.(map[interface{}]interface{}) + if !ok { + return "", fmt.Errorf("initial-advertise-peer-urls is not in the expected format") + } + resultMap := make(map[string][]string) + for pod, urls := range peerUrlsMap { + podName, ok := pod.(string) + if !ok { + return "", fmt.Errorf("pod name is not a string") + } + urlsList, ok := urls.([]interface{}) + if !ok { + return "", fmt.Errorf("urls is not a list") + } + for _, url := range urlsList { + urlStr, ok := url.(string) + if !ok { + return "", fmt.Errorf("url is not a string") + } + resultMap[podName] = append(resultMap[podName], urlStr) + } + } + peerUrls, ok := resultMap[memberName] + if !ok { + return "", fmt.Errorf("peer url not found for pod %s", memberName) + } + return strings.Join(peerUrls, ","), nil +} +// GetAdvertiseClientURL returns the advertise client URL for the etcd member. +func GetAdvertiseClientURL(configFile string) (string, error) { + memberName, err := GetEnvVarOrError("POD_NAME") + if err != nil { + return "", err + } config, err := ReadConfigFileAsMap(configFile) if err != nil { - return false, err + return "", err } - initAdPeerURL := config["initial-advertise-peer-urls"] + initAdClientURL := config["advertise-client-urls"] + if initAdClientURL == nil { + return "", fmt.Errorf("advertise-client-urls must be set in etcd config") + } + clientUrlsMap, ok := initAdClientURL.(map[interface{}]interface{}) + if !ok { + return "", fmt.Errorf("advertise-client-urls is not in the expected format") + } + resultMap := make(map[string]string) + for pod, url := range clientUrlsMap { + podName, ok := pod.(string) + if !ok { + return "", fmt.Errorf("pod name is not a string") + } + urlStr, ok := url.(string) + if !ok { + return "", fmt.Errorf("url is not a string") + } + resultMap[podName] = urlStr + } + clientURL, ok := resultMap[memberName] + if !ok { + return "", fmt.Errorf("client url not found for pod %s", memberName) + } + return clientURL, nil +} - memberPeerURL, err := ParsePeerURL(initAdPeerURL.(string), podName) +// IsPeerURLTLSEnabled checks whether the peer address is TLS enabled or not. +func IsPeerURLTLSEnabled() (bool, error) { + configFile := GetConfigFilePath() + // TODO: Need to handle multiple peer URLs once etcd config is updated to support it. + // It is required in the context of Gardener usecase to support live control plane migration. + memberPeerURL, err := GetAdvertisePeerURLs(configFile) if err != nil { return false, err } - peerURL, err := url.Parse(memberPeerURL) if err != nil { return false, err } - return peerURL.Scheme == https, nil } diff --git a/pkg/miscellaneous/miscellaneous_test.go b/pkg/miscellaneous/miscellaneous_test.go index 1d5554747..1e52c35fc 100644 --- a/pkg/miscellaneous/miscellaneous_test.go +++ b/pkg/miscellaneous/miscellaneous_test.go @@ -11,12 +11,14 @@ import ( "os" "path/filepath" "reflect" + "strings" "time" mockfactory "github.com/gardener/etcd-backup-restore/pkg/mock/etcdutil/client" "github.com/gardener/etcd-backup-restore/pkg/snapstore" brtypes "github.com/gardener/etcd-backup-restore/pkg/types" "github.com/golang/mock/gomock" + "sigs.k8s.io/yaml" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -586,28 +588,224 @@ var _ = Describe("Miscellaneous Tests", func() { }) }) - Describe("parse peer urls config", func() { - var ( - initialAdPeerURL string - podName string + Describe("GetAdvertisePeerURLs", func() { + const ( + configFile = "/tmp/etcd-config.yaml" + podName = "test-pod" ) + Context("When POD_NAME environment variable is not set", func() { + It("should return an error", func() { + _, err := GetAdvertisePeerURLs(configFile) + Expect(err).NotTo(BeNil()) + }) + }) - BeforeEach(func() { - podName = "etcd-test-pod-0" + Context("When POD_NAME environment variable is set", func() { + BeforeEach(func() { + Expect(os.Setenv("POD_NAME", podName)).To(Succeed()) + Expect(os.Setenv("ETCD_CONF", configFile)).To(Succeed()) + }) + AfterEach(func() { + Expect(os.Unsetenv("POD_NAME")).To(Succeed()) + Expect(os.Unsetenv("ETCD_CONF")).To(Succeed()) + }) + + Context("When the config file cannot be read", func() { + It("should return an error", func() { + _, err := GetAdvertisePeerURLs(configFile) + Expect(err).NotTo(BeNil()) + }) + }) + + Context("When initial-advertise-peer-urls is not set in the config file", func() { + var config map[string]interface{} + + BeforeEach(func() { + config = map[string]interface{}{ + "name": "etcd-test", + } + writeConfigToFile(configFile, config) + }) + + AfterEach(func() { + Expect(os.Remove(configFile)).To(Succeed()) + }) + + It("should return an error", func() { + _, err := GetAdvertisePeerURLs(configFile) + Expect(err).NotTo(BeNil()) + }) + }) + + Context("When initial-advertise-peer-urls is set in the config file", func() { + var config map[string]interface{} + podUrlsMap := make(map[string]interface{}) + + AfterEach(func() { + Expect(os.Remove(configFile)).To(Succeed()) + }) + + Context("When the initial-advertise-peer-urls is not in the expected format", func() { + BeforeEach(func() { + config = map[string]interface{}{ + "name": "etcd-test", + "initial-advertise-peer-urls": "invalid-format", + } + writeConfigToFile(configFile, config) + }) + + It("should return an error", func() { + _, err := GetAdvertisePeerURLs(configFile) + Expect(err).NotTo(BeNil()) + }) + }) + + Context("When the pod name is not present in the config file", func() { + BeforeEach(func() { + otherPodPeerURLs := []string{"http://pod1:2380", "http://pod1:2381"} + podUrlsMap["other-pod"] = otherPodPeerURLs + + config = map[string]interface{}{ + "name": "etcd-test", + "initial-advertise-peer-urls": podUrlsMap, + } + writeConfigToFile(configFile, config) + }) + + It("should return an error", func() { + _, err := GetAdvertisePeerURLs(configFile) + Expect(err).NotTo(BeNil()) + }) + }) + + Context("When the pod name is present in the config file", func() { + var podPeerURLs []string + BeforeEach(func() { + podPeerURLs = []string{"http://pod:2380", "http://pod:2381"} + podUrlsMap[podName] = podPeerURLs + + config = map[string]interface{}{ + "name": "etcd-test", + "initial-advertise-peer-urls": podUrlsMap, + } + writeConfigToFile(configFile, config) + }) + + It("should return the peer URLs", func() { + peerURLs, err := GetAdvertisePeerURLs(configFile) + Expect(err).NotTo(HaveOccurred()) + Expect(peerURLs).To(Equal(strings.Join(podPeerURLs, ","))) + }) + }) + }) }) - Context("parse peer url", func() { - It("parsing well-defined initial-advertise-peer-urls", func() { - initialAdPeerURL = "https@etcd-events-peer@shoot--dev--test@2380" - peerURL, err := ParsePeerURL(initialAdPeerURL, podName) - Expect(err).To(BeNil()) - Expect(peerURL).To(Equal("https://etcd-test-pod-0.etcd-events-peer.shoot--dev--test.svc:2380")) + }) + + Describe("GetAdvertiseClientURL", func() { + const ( + configFile = "/tmp/etcd-config.yaml" + podName = "test-pod" + ) + + Context("When POD_NAME environment variable is not set", func() { + It("should return an error", func() { + url, err := GetAdvertiseClientURL(configFile) + Expect(err).To(HaveOccurred()) + Expect(url).To(BeEmpty()) + }) + }) + + Context("When POD_NAME environment variable is set", func() { + BeforeEach(func() { + Expect(os.Setenv("POD_NAME", podName)).To(Succeed()) + Expect(os.Setenv("ETCD_CONF", configFile)).To(Succeed()) }) - It("parsing malformed initial-advertise-peer-urls", func() { - initialAdPeerURL = "https@etcd-events-peer@shoot--dev--test" - _, err := ParsePeerURL(initialAdPeerURL, podName) - Expect(err).ToNot(BeNil()) + AfterEach(func() { + Expect(os.Unsetenv("POD_NAME")).To(Succeed()) + Expect(os.Unsetenv("ETCD_CONF")).To(Succeed()) + }) + + Context("When the config file cannot be read", func() { + It("should return an error", func() { + _, err := GetAdvertiseClientURL(configFile) + Expect(err).To(Not(BeNil())) + }) + }) + + Context("When advertise-client-urls is not set in the etcd config", func() { + BeforeEach(func() { + config := map[string]interface{}{ + "name": "etcd-test", + } + writeConfigToFile(configFile, config) + }) + + AfterEach(func() { + Expect(os.Remove(configFile)).To(Succeed()) + }) + + It("should return an error", func() { + url, err := GetAdvertiseClientURL(configFile) + Expect(err).To(HaveOccurred()) + Expect(url).To(BeEmpty()) + }) + }) + + Context("When advertise-client-urls is set in the etcd config", func() { + podUrlsMap := make(map[string]interface{}) + AfterEach(func() { + Expect(os.Remove(configFile)).To(Succeed()) + }) + + Context("When advertise-client-urls is not in the expected format", func() { + BeforeEach(func() { + config := map[string]interface{}{ + "name": "etcd-test", + "advertise-client-urls": "invalid-format", + } + writeConfigToFile(configFile, config) + }) + + It("should return an error", func() { + url, err := GetAdvertiseClientURL(configFile) + Expect(err).To(HaveOccurred()) + Expect(url).To(BeEmpty()) + }) + }) + + Context("When the client URL is not found for the pod", func() { + BeforeEach(func() { + podUrlsMap["other-pod"] = "http://localhost:2379" + config := map[string]interface{}{ + "advertise-client-urls": podUrlsMap, + } + writeConfigToFile(configFile, config) + }) + + It("should return an error", func() { + url, err := GetAdvertiseClientURL(configFile) + Expect(err).To(HaveOccurred()) + Expect(url).To(BeEmpty()) + }) + }) + + Context("When the client URL is found for the pod", func() { + BeforeEach(func() { + podUrlsMap[podName] = "http://localhost:2379" + config := map[string]interface{}{ + "advertise-client-urls": podUrlsMap, + } + writeConfigToFile(configFile, config) + }) + + It("should return the client URL", func() { + url, err := GetAdvertiseClientURL(configFile) + Expect(err).ToNot(HaveOccurred()) + Expect(url).To(Equal("http://localhost:2379")) + }) + }) }) }) }) @@ -714,7 +912,16 @@ var _ = Describe("Miscellaneous Tests", func() { Context("with non-TLS enabled peer url", func() { BeforeEach(func() { etcdConfigYaml := `name: etcd1 -initial-advertise-peer-urls: http@etcd-main-peer@default@2380 +initial-advertise-peer-urls: + test_pod: + - http://etcd-main-peer.default:2380 + - http://etcd-main-peer.default:2381 + test_pod2: + - http://etcd-main-peer.default:2380 + - http://etcd-main-peer.default:2381 + test_pod3: + - http://etcd-main-peer.default:2380 + - http://etcd-main-peer.default:2381 initial-cluster: etcd1=http://0.0.0.0:2380` err := os.WriteFile(outfile, []byte(etcdConfigYaml), 0755) Expect(err).ShouldNot(HaveOccurred()) @@ -730,7 +937,16 @@ initial-cluster: etcd1=http://0.0.0.0:2380` Context("with TLS enabled peer url", func() { BeforeEach(func() { etcdConfigYaml := `name: etcd1 -initial-advertise-peer-urls: https@etcd-main-peer@default@2380 +initial-advertise-peer-urls: + test_pod: + - https://etcd-main-peer.default:2380 + - https://etcd-main-peer.default:2381 + test_pod2: + - https://etcd-main-peer.default:2380 + - https://etcd-main-peer.default:2381 + test_pod3: + - https://etcd-main-peer.default:2380 + - https://etcd-main-peer.default:2381 initial-cluster: etcd1=https://0.0.0.0:2380` err := os.WriteFile(outfile, []byte(etcdConfigYaml), 0755) Expect(err).ShouldNot(HaveOccurred()) @@ -832,3 +1048,11 @@ func (ds *DummyStore) Save(snap brtypes.Snapshot, rc io.ReadCloser) error { func (ds *DummyStore) Fetch(snap brtypes.Snapshot) (io.ReadCloser, error) { return nil, nil } + +func writeConfigToFile(configFile string, config map[string]interface{}) { + byteSlice, err := yaml.Marshal(config) + Expect(err).NotTo(HaveOccurred()) + + err = os.WriteFile(configFile, byteSlice, 0644) + Expect(err).NotTo(HaveOccurred()) +} diff --git a/pkg/miscellaneous/testdata/valid_config.yaml b/pkg/miscellaneous/testdata/valid_config.yaml index f711d5ccd..dbf6437da 100644 --- a/pkg/miscellaneous/testdata/valid_config.yaml +++ b/pkg/miscellaneous/testdata/valid_config.yaml @@ -31,7 +31,10 @@ listen-client-urls: https://0.0.0.0:2379 # List of this member's client URLs to advertise to the public. # The URLs needed to be a comma-separated list. -advertise-client-urls: https@etcd-events-peer@shoot--dev--test@2379 +advertise-client-urls: + etcd-events-0: https://etcd-events-0.etcd-events-peer.shoot--dev--test.svc:2379 + etcd-events-1: https://etcd-events-1.etcd-events-peer.shoot--dev--test.svc:2379 + etcd-events-2: https://etcd-events-2.etcd-events-peer.shoot--dev--test.svc:2379 peer-transport-security: # Path to the peer server TLS cert file. cert-file: /var/etcd/ssl/peer/server/tls.crt @@ -52,7 +55,13 @@ listen-peer-urls: https://0.0.0.0:2380 # List of this member's peer URLs to advertise to the public. # The URLs needed to be a comma-separated list. -initial-advertise-peer-urls: https@etcd-events-peer@shoot--dev--test@2380 +initial-advertise-peer-urls: + etcd-events-0: + - https://etcd-events-0.etcd-events-peer.shoot--dev--test.svc:2380 + etcd-events-1: + - https://etcd-events-1.etcd-events-peer.shoot--dev--test.svc:2380 + etcd-events-2: + - https://etcd-events-2.etcd-events-peer.shoot--dev--test.svc:2380 # Initial cluster token for the etcd cluster during bootstrap. initial-cluster-token: etcd-cluster diff --git a/pkg/server/httpAPI.go b/pkg/server/httpAPI.go index 714bb717c..c9d4a1faa 100644 --- a/pkg/server/httpAPI.go +++ b/pkg/server/httpAPI.go @@ -428,25 +428,23 @@ func (h *HTTPHandler) serveConfig(rw http.ResponseWriter, req *http.Request) { config["name"] = podName - initAdPeerURL := config["initial-advertise-peer-urls"] - protocol, svcName, namespace, peerPort, err := parsePeerURL(fmt.Sprint(initAdPeerURL)) + // fetch initial-advertise-peer-urls from etcd config file + initAdPeerURL, err := miscellaneous.GetAdvertisePeerURLs(inputFileName) if err != nil { - h.Logger.Warnf("Unable to determine service name, namespace, peer port from advertise peer urls : %v", err) + h.Logger.Warnf("Unable to get initial-advertise-peer-urls from etcd config file: %v", err) rw.WriteHeader(http.StatusInternalServerError) return } - domaiName := fmt.Sprintf("%s.%s.%s", svcName, namespace, "svc") - config["initial-advertise-peer-urls"] = fmt.Sprintf("%s://%s.%s:%s", protocol, podName, domaiName, peerPort) + config["initial-advertise-peer-urls"] = initAdPeerURL - advClientURL := config["advertise-client-urls"] - protocol, svcName, namespace, clientPort, err := parseAdvClientURL(fmt.Sprint(advClientURL)) + // fetch advertise-client-urls from etcd config file + advClientURL, err := miscellaneous.GetAdvertiseClientURL(inputFileName) if err != nil { - h.Logger.Warnf("Unable to determine service name, namespace, peer port from advertise client url : %v", err) + h.Logger.Warnf("Unable to get advertise-client-urls : %v", err) rw.WriteHeader(http.StatusInternalServerError) return } - domaiName = fmt.Sprintf("%s.%s.%s", svcName, namespace, "svc") - config["advertise-client-urls"] = fmt.Sprintf("%s://%s.%s:%s", protocol, podName, domaiName, clientPort) + config["advertise-client-urls"] = advClientURL config["initial-cluster"] = getInitialCluster(req.Context(), fmt.Sprint(config["initial-cluster"]), *h.EtcdConnectionConfig, *h.Logger, podName) @@ -568,22 +566,6 @@ func getInitialCluster(ctx context.Context, initialCluster string, etcdConn brty return initialCluster } -func parsePeerURL(peerURL string) (string, string, string, string, error) { - tokens := strings.Split(peerURL, "@") - if len(tokens) < 4 { - return "", "", "", "", fmt.Errorf("total length of tokens is less than four") - } - return tokens[0], tokens[1], tokens[2], tokens[3], nil -} - -func parseAdvClientURL(advClientURL string) (string, string, string, string, error) { - tokens := strings.Split(advClientURL, "@") - if len(tokens) < 4 { - return "", "", "", "", fmt.Errorf("total length of tokens is less than four") - } - return tokens[0], tokens[1], tokens[2], tokens[3], nil -} - // delegateReqToLeader forwards the incoming http/https request to BackupLeader. func (h *HTTPHandler) delegateReqToLeader(rw http.ResponseWriter, req *http.Request) { // Get the BackupLeader URL diff --git a/test/e2e/integration/cloud_backup_test.go b/test/e2e/integration/cloud_backup_test.go index a81a04c4a..825e30a22 100644 --- a/test/e2e/integration/cloud_backup_test.go +++ b/test/e2e/integration/cloud_backup_test.go @@ -118,6 +118,11 @@ var _ = Describe("CloudBackup", func() { Container: os.Getenv("TEST_ID"), Prefix: path.Join("v2"), } + // Required as the config file for embedded ETCD fetches ETCD instance name from the POD_NAME variable + podName := "etcd1" + podNamespace := "etcd-test" + Expect(os.Setenv("POD_NAME", podName)).To(Succeed()) + Expect(os.Setenv("POD_NAMESPACE", podNamespace)).To(Succeed()) // Create and place a ETCD config yaml outfile := "/tmp/etcd.conf.yaml" etcdConfigYaml := `# Human-readable name for this member. @@ -128,8 +133,11 @@ snapshot-count: 75000 enable-v2: false quota-backend-bytes: 1073741824 listen-client-urls: http://0.0.0.0:2379 -advertise-client-urls: http://0.0.0.0:2379 -initial-advertise-peer-urls: http@etcd-main-peer@default@2380 +advertise-client-urls: + ` + podName + `: http://0.0.0.0:2379 +initial-advertise-peer-urls: + ` + podName + `: + - http://etcd-main-peer.default:2380 initial-cluster: etcd1=http://0.0.0.0:2380 initial-cluster-token: new initial-cluster-state: new @@ -139,9 +147,6 @@ auto-compaction-retention: 30m` err := os.WriteFile(outfile, []byte(etcdConfigYaml), 0755) Expect(err).ShouldNot(HaveOccurred()) Expect(os.Setenv("ETCD_CONF", outfile)).To(Succeed()) - // Required as the config file for embedded ETCD fetches ETCD instance name from the POD_NAME variable - Expect(os.Setenv("POD_NAME", "etcd1")).To(Succeed()) - Expect(os.Setenv("POD_NAMESPACE", "etcd-test")).To(Succeed()) }) Describe("Regular backups", func() {