// VerifyBootstrapConfig sanity-checks the initial config and returns an error // for things that should never happen. func (c *ServerConfig) VerifyBootstrapConfig() error { m := c.Cluster.MemberByName(c.Name) // Make sure the cluster at least contains the local server. if m == nil { return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name) } if uint64(m.ID) == raft.None { return fmt.Errorf("cannot use %x as member id", raft.None) } if c.DiscoveryURL == "" && !c.NewCluster { return fmt.Errorf("initial cluster state unset and no wal or discovery URL found") } // No identical IPs in the cluster peer list urlMap := make(map[string]bool) for _, m := range c.Cluster.Members() { for _, url := range m.PeerURLs { if urlMap[url] { return fmt.Errorf("duplicate url %v in cluster config", url) } urlMap[url] = true } } // Advertised peer URLs must match those in the cluster peer list // TODO: Remove URLStringsEqual after improvement of using hostnames #2150 #2123 apurls := c.PeerURLs.StringSlice() sort.Strings(apurls) if !netutil.URLStringsEqual(apurls, m.PeerURLs) { return fmt.Errorf("%s has different advertised URLs in the cluster and advertised peer URLs list", c.Name) } return nil }
// verifyLocalMember verifies the configured member is in configured // cluster. If strict is set, it also verifies the configured member // has the same peer urls as configured advertised peer urls. func (c *ServerConfig) verifyLocalMember(strict bool) error { urls := c.InitialPeerURLsMap[c.Name] // Make sure the cluster at least contains the local server. if urls == nil { return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name) } // Advertised peer URLs must match those in the cluster peer list apurls := c.PeerURLs.StringSlice() sort.Strings(apurls) urls.Sort() if strict { if !netutil.URLStringsEqual(apurls, urls.StringSlice()) { return fmt.Errorf("advertise URLs of %q do not match in --initial-advertise-peer-urls %s and --initial-cluster %s", c.Name, apurls, urls.StringSlice()) } } return nil }
// verifyLocalMember verifies the configured member is in configured // cluster. If strict is set, it also verifies the configured member // has the same peer urls as configured advertised peer urls. func (c *ServerConfig) verifyLocalMember(strict bool) error { urls := c.InitialPeerURLsMap[c.Name] // Make sure the cluster at least contains the local server. if urls == nil { return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name) } // Advertised peer URLs must match those in the cluster peer list apurls := c.PeerURLs.StringSlice() sort.Strings(apurls) urls.Sort() if strict { if !netutil.URLStringsEqual(apurls, urls.StringSlice()) { umap := map[string]types.URLs{c.Name: c.PeerURLs} return fmt.Errorf("--initial-cluster must include %s given --initial-advertise-peer-urls=%s", types.URLsMap(umap).String(), strings.Join(apurls, ",")) } } return nil }
// ValidateClusterAndAssignIDs validates the local cluster by matching the PeerURLs // with the existing cluster. If the validation succeeds, it assigns the IDs // from the existing cluster to the local cluster. // If the validation fails, an error will be returned. func ValidateClusterAndAssignIDs(local *cluster, existing *cluster) error { ems := existing.Members() lms := local.Members() if len(ems) != len(lms) { return fmt.Errorf("member count is unequal") } sort.Sort(MembersByPeerURLs(ems)) sort.Sort(MembersByPeerURLs(lms)) for i := range ems { if !netutil.URLStringsEqual(ems[i].PeerURLs, lms[i].PeerURLs) { return fmt.Errorf("unmatched member while checking PeerURLs") } lms[i].ID = ems[i].ID } local.members = make(map[types.ID]*Member) for _, m := range lms { local.members[m.ID] = m } return nil }
// verifyLocalMember verifies the configured member is in configured // cluster. If strict is set, it also verifies the configured member // has the same peer urls as configured advertised peer urls. func (c *ServerConfig) verifyLocalMember(strict bool) error { m := c.Cluster.MemberByName(c.Name) // Make sure the cluster at least contains the local server. if m == nil { return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name) } if uint64(m.ID) == raft.None { return fmt.Errorf("cannot use %x as member id", raft.None) } // Advertised peer URLs must match those in the cluster peer list // TODO: Remove URLStringsEqual after improvement of using hostnames #2150 #2123 apurls := c.PeerURLs.StringSlice() sort.Strings(apurls) if strict { if !netutil.URLStringsEqual(apurls, m.PeerURLs) { return fmt.Errorf("%s has different advertised URLs in the cluster and advertised peer URLs list", c.Name) } } return nil }
// ValidateClusterAndAssignIDs validates the local cluster by matching the PeerURLs // with the existing cluster. If the validation succeeds, it assigns the IDs // from the existing cluster to the local cluster. // If the validation fails, an error will be returned. func ValidateClusterAndAssignIDs(local *Cluster, existing *Cluster) error { ems := existing.Members() lms := local.Members() if len(ems) != len(lms) { return fmt.Errorf("member count is unequal") } sort.Sort(SortableMemberSliceByPeerURLs(ems)) sort.Sort(SortableMemberSliceByPeerURLs(lms)) for i := range ems { // TODO: Remove URLStringsEqual after improvement of using hostnames #2150 #2123 if !netutil.URLStringsEqual(ems[i].PeerURLs, lms[i].PeerURLs) { return fmt.Errorf("unmatched member while checking PeerURLs") } lms[i].ID = ems[i].ID } local.members = make(map[types.ID]*Member) for _, m := range lms { local.members[m.ID] = m } return nil }