mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-06 17:57:51 +00:00
Add vendor folder to git
This commit is contained in:
parent
66cf5eaafb
commit
183585f56f
6916 changed files with 2629581 additions and 1 deletions
414
vendor/github.com/coreos/etcd/embed/config.go
generated
vendored
Normal file
414
vendor/github.com/coreos/etcd/embed/config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,414 @@
|
|||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package embed
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/etcd/discovery"
|
||||
"github.com/coreos/etcd/etcdserver"
|
||||
"github.com/coreos/etcd/pkg/cors"
|
||||
"github.com/coreos/etcd/pkg/netutil"
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"github.com/coreos/etcd/pkg/types"
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
const (
|
||||
ClusterStateFlagNew = "new"
|
||||
ClusterStateFlagExisting = "existing"
|
||||
|
||||
DefaultName = "default"
|
||||
DefaultMaxSnapshots = 5
|
||||
DefaultMaxWALs = 5
|
||||
|
||||
DefaultListenPeerURLs = "http://localhost:2380"
|
||||
DefaultListenClientURLs = "http://localhost:2379"
|
||||
|
||||
// maxElectionMs specifies the maximum value of election timeout.
|
||||
// More details are listed in ../Documentation/tuning.md#time-parameters.
|
||||
maxElectionMs = 50000
|
||||
)
|
||||
|
||||
var (
|
||||
ErrConflictBootstrapFlags = fmt.Errorf("multiple discovery or bootstrap flags are set. " +
|
||||
"Choose one of \"initial-cluster\", \"discovery\" or \"discovery-srv\"")
|
||||
ErrUnsetAdvertiseClientURLsFlag = fmt.Errorf("--advertise-client-urls is required when --listen-client-urls is set explicitly")
|
||||
|
||||
DefaultInitialAdvertisePeerURLs = "http://localhost:2380"
|
||||
DefaultAdvertiseClientURLs = "http://localhost:2379"
|
||||
|
||||
defaultHostname string
|
||||
defaultHostStatus error
|
||||
)
|
||||
|
||||
func init() {
|
||||
defaultHostname, defaultHostStatus = netutil.GetDefaultHost()
|
||||
}
|
||||
|
||||
// Config holds the arguments for configuring an etcd server.
|
||||
type Config struct {
|
||||
// member
|
||||
|
||||
CorsInfo *cors.CORSInfo
|
||||
LPUrls, LCUrls []url.URL
|
||||
Dir string `json:"data-dir"`
|
||||
WalDir string `json:"wal-dir"`
|
||||
MaxSnapFiles uint `json:"max-snapshots"`
|
||||
MaxWalFiles uint `json:"max-wals"`
|
||||
Name string `json:"name"`
|
||||
SnapCount uint64 `json:"snapshot-count"`
|
||||
AutoCompactionRetention int `json:"auto-compaction-retention"`
|
||||
|
||||
// TickMs is the number of milliseconds between heartbeat ticks.
|
||||
// TODO: decouple tickMs and heartbeat tick (current heartbeat tick = 1).
|
||||
// make ticks a cluster wide configuration.
|
||||
TickMs uint `json:"heartbeat-interval"`
|
||||
ElectionMs uint `json:"election-timeout"`
|
||||
QuotaBackendBytes int64 `json:"quota-backend-bytes"`
|
||||
|
||||
// clustering
|
||||
|
||||
APUrls, ACUrls []url.URL
|
||||
ClusterState string `json:"initial-cluster-state"`
|
||||
DNSCluster string `json:"discovery-srv"`
|
||||
Dproxy string `json:"discovery-proxy"`
|
||||
Durl string `json:"discovery"`
|
||||
InitialCluster string `json:"initial-cluster"`
|
||||
InitialClusterToken string `json:"initial-cluster-token"`
|
||||
StrictReconfigCheck bool `json:"strict-reconfig-check"`
|
||||
|
||||
// security
|
||||
|
||||
ClientTLSInfo transport.TLSInfo
|
||||
ClientAutoTLS bool
|
||||
PeerTLSInfo transport.TLSInfo
|
||||
PeerAutoTLS bool
|
||||
|
||||
// debug
|
||||
|
||||
Debug bool `json:"debug"`
|
||||
LogPkgLevels string `json:"log-package-levels"`
|
||||
EnablePprof bool
|
||||
Metrics string `json:"metrics"`
|
||||
|
||||
// ForceNewCluster starts a new cluster even if previously started; unsafe.
|
||||
ForceNewCluster bool `json:"force-new-cluster"`
|
||||
|
||||
// UserHandlers is for registering users handlers and only used for
|
||||
// embedding etcd into other applications.
|
||||
// The map key is the route path for the handler, and
|
||||
// you must ensure it can't be conflicted with etcd's.
|
||||
UserHandlers map[string]http.Handler `json:"-"`
|
||||
}
|
||||
|
||||
// configYAML holds the config suitable for yaml parsing
|
||||
type configYAML struct {
|
||||
Config
|
||||
configJSON
|
||||
}
|
||||
|
||||
// configJSON has file options that are translated into Config options
|
||||
type configJSON struct {
|
||||
LPUrlsJSON string `json:"listen-peer-urls"`
|
||||
LCUrlsJSON string `json:"listen-client-urls"`
|
||||
CorsJSON string `json:"cors"`
|
||||
APUrlsJSON string `json:"initial-advertise-peer-urls"`
|
||||
ACUrlsJSON string `json:"advertise-client-urls"`
|
||||
ClientSecurityJSON securityConfig `json:"client-transport-security"`
|
||||
PeerSecurityJSON securityConfig `json:"peer-transport-security"`
|
||||
}
|
||||
|
||||
type securityConfig struct {
|
||||
CAFile string `json:"ca-file"`
|
||||
CertFile string `json:"cert-file"`
|
||||
KeyFile string `json:"key-file"`
|
||||
CertAuth bool `json:"client-cert-auth"`
|
||||
TrustedCAFile string `json:"trusted-ca-file"`
|
||||
AutoTLS bool `json:"auto-tls"`
|
||||
}
|
||||
|
||||
// NewConfig creates a new Config populated with default values.
|
||||
func NewConfig() *Config {
|
||||
lpurl, _ := url.Parse(DefaultListenPeerURLs)
|
||||
apurl, _ := url.Parse(DefaultInitialAdvertisePeerURLs)
|
||||
lcurl, _ := url.Parse(DefaultListenClientURLs)
|
||||
acurl, _ := url.Parse(DefaultAdvertiseClientURLs)
|
||||
cfg := &Config{
|
||||
CorsInfo: &cors.CORSInfo{},
|
||||
MaxSnapFiles: DefaultMaxSnapshots,
|
||||
MaxWalFiles: DefaultMaxWALs,
|
||||
Name: DefaultName,
|
||||
SnapCount: etcdserver.DefaultSnapCount,
|
||||
TickMs: 100,
|
||||
ElectionMs: 1000,
|
||||
LPUrls: []url.URL{*lpurl},
|
||||
LCUrls: []url.URL{*lcurl},
|
||||
APUrls: []url.URL{*apurl},
|
||||
ACUrls: []url.URL{*acurl},
|
||||
ClusterState: ClusterStateFlagNew,
|
||||
InitialClusterToken: "etcd-cluster",
|
||||
StrictReconfigCheck: true,
|
||||
Metrics: "basic",
|
||||
}
|
||||
cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
|
||||
return cfg
|
||||
}
|
||||
|
||||
func ConfigFromFile(path string) (*Config, error) {
|
||||
cfg := &configYAML{Config: *NewConfig()}
|
||||
if err := cfg.configFromFile(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cfg.Config, nil
|
||||
}
|
||||
|
||||
func (cfg *configYAML) configFromFile(path string) error {
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(b, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.LPUrlsJSON != "" {
|
||||
u, err := types.NewURLs(strings.Split(cfg.LPUrlsJSON, ","))
|
||||
if err != nil {
|
||||
plog.Fatalf("unexpected error setting up listen-peer-urls: %v", err)
|
||||
}
|
||||
cfg.LPUrls = []url.URL(u)
|
||||
}
|
||||
|
||||
if cfg.LCUrlsJSON != "" {
|
||||
u, err := types.NewURLs(strings.Split(cfg.LCUrlsJSON, ","))
|
||||
if err != nil {
|
||||
plog.Fatalf("unexpected error setting up listen-client-urls: %v", err)
|
||||
}
|
||||
cfg.LCUrls = []url.URL(u)
|
||||
}
|
||||
|
||||
if cfg.CorsJSON != "" {
|
||||
if err := cfg.CorsInfo.Set(cfg.CorsJSON); err != nil {
|
||||
plog.Panicf("unexpected error setting up cors: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.APUrlsJSON != "" {
|
||||
u, err := types.NewURLs(strings.Split(cfg.APUrlsJSON, ","))
|
||||
if err != nil {
|
||||
plog.Fatalf("unexpected error setting up initial-advertise-peer-urls: %v", err)
|
||||
}
|
||||
cfg.APUrls = []url.URL(u)
|
||||
}
|
||||
|
||||
if cfg.ACUrlsJSON != "" {
|
||||
u, err := types.NewURLs(strings.Split(cfg.ACUrlsJSON, ","))
|
||||
if err != nil {
|
||||
plog.Fatalf("unexpected error setting up advertise-peer-urls: %v", err)
|
||||
}
|
||||
cfg.ACUrls = []url.URL(u)
|
||||
}
|
||||
|
||||
if (cfg.Durl != "" || cfg.DNSCluster != "") && cfg.InitialCluster == cfg.InitialClusterFromName(cfg.Name) {
|
||||
cfg.InitialCluster = ""
|
||||
}
|
||||
if cfg.ClusterState == "" {
|
||||
cfg.ClusterState = ClusterStateFlagNew
|
||||
}
|
||||
|
||||
copySecurityDetails := func(tls *transport.TLSInfo, ysc *securityConfig) {
|
||||
tls.CAFile = ysc.CAFile
|
||||
tls.CertFile = ysc.CertFile
|
||||
tls.KeyFile = ysc.KeyFile
|
||||
tls.ClientCertAuth = ysc.CertAuth
|
||||
tls.TrustedCAFile = ysc.TrustedCAFile
|
||||
}
|
||||
copySecurityDetails(&cfg.ClientTLSInfo, &cfg.ClientSecurityJSON)
|
||||
copySecurityDetails(&cfg.PeerTLSInfo, &cfg.PeerSecurityJSON)
|
||||
cfg.ClientAutoTLS = cfg.ClientSecurityJSON.AutoTLS
|
||||
cfg.PeerAutoTLS = cfg.PeerSecurityJSON.AutoTLS
|
||||
|
||||
return cfg.Validate()
|
||||
}
|
||||
|
||||
func (cfg *Config) Validate() error {
|
||||
if err := checkBindURLs(cfg.LPUrls); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkBindURLs(cfg.LCUrls); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if conflicting flags are passed.
|
||||
nSet := 0
|
||||
for _, v := range []bool{cfg.Durl != "", cfg.InitialCluster != "", cfg.DNSCluster != ""} {
|
||||
if v {
|
||||
nSet++
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.ClusterState != ClusterStateFlagNew && cfg.ClusterState != ClusterStateFlagExisting {
|
||||
return fmt.Errorf("unexpected clusterState %q", cfg.ClusterState)
|
||||
}
|
||||
|
||||
if nSet > 1 {
|
||||
return ErrConflictBootstrapFlags
|
||||
}
|
||||
|
||||
if 5*cfg.TickMs > cfg.ElectionMs {
|
||||
return fmt.Errorf("--election-timeout[%vms] should be at least as 5 times as --heartbeat-interval[%vms]", cfg.ElectionMs, cfg.TickMs)
|
||||
}
|
||||
if cfg.ElectionMs > maxElectionMs {
|
||||
return fmt.Errorf("--election-timeout[%vms] is too long, and should be set less than %vms", cfg.ElectionMs, maxElectionMs)
|
||||
}
|
||||
|
||||
// check this last since proxying in etcdmain may make this OK
|
||||
if cfg.LCUrls != nil && cfg.ACUrls == nil {
|
||||
return ErrUnsetAdvertiseClientURLsFlag
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PeerURLsMapAndToken sets up an initial peer URLsMap and cluster token for bootstrap or discovery.
|
||||
func (cfg *Config) PeerURLsMapAndToken(which string) (urlsmap types.URLsMap, token string, err error) {
|
||||
switch {
|
||||
case cfg.Durl != "":
|
||||
urlsmap = types.URLsMap{}
|
||||
// If using discovery, generate a temporary cluster based on
|
||||
// self's advertised peer URLs
|
||||
urlsmap[cfg.Name] = cfg.APUrls
|
||||
token = cfg.Durl
|
||||
case cfg.DNSCluster != "":
|
||||
var clusterStr string
|
||||
clusterStr, token, err = discovery.SRVGetCluster(cfg.Name, cfg.DNSCluster, cfg.InitialClusterToken, cfg.APUrls)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if strings.Contains(clusterStr, "https://") && cfg.PeerTLSInfo.CAFile == "" {
|
||||
cfg.PeerTLSInfo.ServerName = cfg.DNSCluster
|
||||
}
|
||||
urlsmap, err = types.NewURLsMap(clusterStr)
|
||||
// only etcd member must belong to the discovered cluster.
|
||||
// proxy does not need to belong to the discovered cluster.
|
||||
if which == "etcd" {
|
||||
if _, ok := urlsmap[cfg.Name]; !ok {
|
||||
return nil, "", fmt.Errorf("cannot find local etcd member %q in SRV records", cfg.Name)
|
||||
}
|
||||
}
|
||||
default:
|
||||
// We're statically configured, and cluster has appropriately been set.
|
||||
urlsmap, err = types.NewURLsMap(cfg.InitialCluster)
|
||||
token = cfg.InitialClusterToken
|
||||
}
|
||||
return urlsmap, token, err
|
||||
}
|
||||
|
||||
func (cfg Config) InitialClusterFromName(name string) (ret string) {
|
||||
if len(cfg.APUrls) == 0 {
|
||||
return ""
|
||||
}
|
||||
n := name
|
||||
if name == "" {
|
||||
n = DefaultName
|
||||
}
|
||||
for i := range cfg.APUrls {
|
||||
ret = ret + "," + n + "=" + cfg.APUrls[i].String()
|
||||
}
|
||||
return ret[1:]
|
||||
}
|
||||
|
||||
func (cfg Config) IsNewCluster() bool { return cfg.ClusterState == ClusterStateFlagNew }
|
||||
func (cfg Config) ElectionTicks() int { return int(cfg.ElectionMs / cfg.TickMs) }
|
||||
|
||||
func (cfg Config) defaultPeerHost() bool {
|
||||
return len(cfg.APUrls) == 1 && cfg.APUrls[0].String() == DefaultInitialAdvertisePeerURLs
|
||||
}
|
||||
|
||||
func (cfg Config) defaultClientHost() bool {
|
||||
return len(cfg.ACUrls) == 1 && cfg.ACUrls[0].String() == DefaultAdvertiseClientURLs
|
||||
}
|
||||
|
||||
// UpdateDefaultClusterFromName updates cluster advertise URLs with, if available, default host,
|
||||
// if advertise URLs are default values(localhost:2379,2380) AND if listen URL is 0.0.0.0.
|
||||
// e.g. advertise peer URL localhost:2380 or listen peer URL 0.0.0.0:2380
|
||||
// then the advertise peer host would be updated with machine's default host,
|
||||
// while keeping the listen URL's port.
|
||||
// User can work around this by explicitly setting URL with 127.0.0.1.
|
||||
// It returns the default hostname, if used, and the error, if any, from getting the machine's default host.
|
||||
// TODO: check whether fields are set instead of whether fields have default value
|
||||
func (cfg *Config) UpdateDefaultClusterFromName(defaultInitialCluster string) (string, error) {
|
||||
if defaultHostname == "" || defaultHostStatus != nil {
|
||||
// update 'initial-cluster' when only the name is specified (e.g. 'etcd --name=abc')
|
||||
if cfg.Name != DefaultName && cfg.InitialCluster == defaultInitialCluster {
|
||||
cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
|
||||
}
|
||||
return "", defaultHostStatus
|
||||
}
|
||||
|
||||
used := false
|
||||
pip, pport, _ := net.SplitHostPort(cfg.LPUrls[0].Host)
|
||||
if cfg.defaultPeerHost() && pip == "0.0.0.0" {
|
||||
cfg.APUrls[0] = url.URL{Scheme: cfg.APUrls[0].Scheme, Host: fmt.Sprintf("%s:%s", defaultHostname, pport)}
|
||||
used = true
|
||||
}
|
||||
// update 'initial-cluster' when only the name is specified (e.g. 'etcd --name=abc')
|
||||
if cfg.Name != DefaultName && cfg.InitialCluster == defaultInitialCluster {
|
||||
cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
|
||||
}
|
||||
|
||||
cip, cport, _ := net.SplitHostPort(cfg.LCUrls[0].Host)
|
||||
if cfg.defaultClientHost() && cip == "0.0.0.0" {
|
||||
cfg.ACUrls[0] = url.URL{Scheme: cfg.ACUrls[0].Scheme, Host: fmt.Sprintf("%s:%s", defaultHostname, cport)}
|
||||
used = true
|
||||
}
|
||||
dhost := defaultHostname
|
||||
if !used {
|
||||
dhost = ""
|
||||
}
|
||||
return dhost, defaultHostStatus
|
||||
}
|
||||
|
||||
// checkBindURLs returns an error if any URL uses a domain name.
|
||||
// TODO: return error in 3.2.0
|
||||
func checkBindURLs(urls []url.URL) error {
|
||||
for _, url := range urls {
|
||||
if url.Scheme == "unix" || url.Scheme == "unixs" {
|
||||
continue
|
||||
}
|
||||
host, _, err := net.SplitHostPort(url.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if host == "localhost" {
|
||||
// special case for local address
|
||||
// TODO: support /etc/hosts ?
|
||||
continue
|
||||
}
|
||||
if net.ParseIP(host) == nil {
|
||||
err := fmt.Errorf("expected IP in URL for binding (%s)", url.String())
|
||||
plog.Warning(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
151
vendor/github.com/coreos/etcd/embed/config_test.go
generated
vendored
Normal file
151
vendor/github.com/coreos/etcd/embed/config_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package embed
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
func TestConfigFileOtherFields(t *testing.T) {
|
||||
ctls := securityConfig{CAFile: "cca", CertFile: "ccert", KeyFile: "ckey"}
|
||||
ptls := securityConfig{CAFile: "pca", CertFile: "pcert", KeyFile: "pkey"}
|
||||
yc := struct {
|
||||
ClientSecurityCfgFile securityConfig `json:"client-transport-security"`
|
||||
PeerSecurityCfgFile securityConfig `json:"peer-transport-security"`
|
||||
ForceNewCluster bool `json:"force-new-cluster"`
|
||||
}{
|
||||
ctls,
|
||||
ptls,
|
||||
true,
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(&yc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tmpfile := mustCreateCfgFile(t, b)
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
cfg, err := ConfigFromFile(tmpfile.Name())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !cfg.ForceNewCluster {
|
||||
t.Errorf("ForceNewCluster = %v, want %v", cfg.ForceNewCluster, true)
|
||||
}
|
||||
|
||||
if !ctls.equals(&cfg.ClientTLSInfo) {
|
||||
t.Errorf("ClientTLS = %v, want %v", cfg.ClientTLSInfo, ctls)
|
||||
}
|
||||
if !ptls.equals(&cfg.PeerTLSInfo) {
|
||||
t.Errorf("PeerTLS = %v, want %v", cfg.PeerTLSInfo, ptls)
|
||||
}
|
||||
}
|
||||
|
||||
// TestUpdateDefaultClusterFromName ensures that etcd can start with 'etcd --name=abc'.
|
||||
func TestUpdateDefaultClusterFromName(t *testing.T) {
|
||||
cfg := NewConfig()
|
||||
defaultInitialCluster := cfg.InitialCluster
|
||||
oldscheme := cfg.APUrls[0].Scheme
|
||||
origpeer := cfg.APUrls[0].String()
|
||||
origadvc := cfg.ACUrls[0].String()
|
||||
|
||||
cfg.Name = "abc"
|
||||
_, lpport, _ := net.SplitHostPort(cfg.LPUrls[0].Host)
|
||||
|
||||
// in case of 'etcd --name=abc'
|
||||
exp := fmt.Sprintf("%s=%s://localhost:%s", cfg.Name, oldscheme, lpport)
|
||||
cfg.UpdateDefaultClusterFromName(defaultInitialCluster)
|
||||
if exp != cfg.InitialCluster {
|
||||
t.Fatalf("initial-cluster expected %q, got %q", exp, cfg.InitialCluster)
|
||||
}
|
||||
// advertise peer URL should not be affected
|
||||
if origpeer != cfg.APUrls[0].String() {
|
||||
t.Fatalf("advertise peer url expected %q, got %q", origadvc, cfg.APUrls[0].String())
|
||||
}
|
||||
// advertise client URL should not be affected
|
||||
if origadvc != cfg.ACUrls[0].String() {
|
||||
t.Fatalf("advertise client url expected %q, got %q", origadvc, cfg.ACUrls[0].String())
|
||||
}
|
||||
}
|
||||
|
||||
// TestUpdateDefaultClusterFromNameOverwrite ensures that machine's default host is only used
|
||||
// if advertise URLs are default values(localhost:2379,2380) AND if listen URL is 0.0.0.0.
|
||||
func TestUpdateDefaultClusterFromNameOverwrite(t *testing.T) {
|
||||
if defaultHostname == "" {
|
||||
t.Skip("machine's default host not found")
|
||||
}
|
||||
|
||||
cfg := NewConfig()
|
||||
defaultInitialCluster := cfg.InitialCluster
|
||||
oldscheme := cfg.APUrls[0].Scheme
|
||||
origadvc := cfg.ACUrls[0].String()
|
||||
|
||||
cfg.Name = "abc"
|
||||
_, lpport, _ := net.SplitHostPort(cfg.LPUrls[0].Host)
|
||||
cfg.LPUrls[0] = url.URL{Scheme: cfg.LPUrls[0].Scheme, Host: fmt.Sprintf("0.0.0.0:%s", lpport)}
|
||||
dhost, _ := cfg.UpdateDefaultClusterFromName(defaultInitialCluster)
|
||||
if dhost != defaultHostname {
|
||||
t.Fatalf("expected default host %q, got %q", defaultHostname, dhost)
|
||||
}
|
||||
aphost, apport, _ := net.SplitHostPort(cfg.APUrls[0].Host)
|
||||
if apport != lpport {
|
||||
t.Fatalf("advertise peer url got different port %s, expected %s", apport, lpport)
|
||||
}
|
||||
if aphost != defaultHostname {
|
||||
t.Fatalf("advertise peer url expected machine default host %q, got %q", defaultHostname, aphost)
|
||||
}
|
||||
expected := fmt.Sprintf("%s=%s://%s:%s", cfg.Name, oldscheme, defaultHostname, lpport)
|
||||
if expected != cfg.InitialCluster {
|
||||
t.Fatalf("initial-cluster expected %q, got %q", expected, cfg.InitialCluster)
|
||||
}
|
||||
|
||||
// advertise client URL should not be affected
|
||||
if origadvc != cfg.ACUrls[0].String() {
|
||||
t.Fatalf("advertise-client-url expected %q, got %q", origadvc, cfg.ACUrls[0].String())
|
||||
}
|
||||
}
|
||||
|
||||
func (s *securityConfig) equals(t *transport.TLSInfo) bool {
|
||||
return s.CAFile == t.CAFile &&
|
||||
s.CertFile == t.CertFile &&
|
||||
s.CertAuth == t.ClientCertAuth &&
|
||||
s.TrustedCAFile == t.TrustedCAFile
|
||||
}
|
||||
|
||||
func mustCreateCfgFile(t *testing.T, b []byte) *os.File {
|
||||
tmpfile, err := ioutil.TempFile("", "servercfg")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err = tmpfile.Write(b); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = tmpfile.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return tmpfile
|
||||
}
|
||||
45
vendor/github.com/coreos/etcd/embed/doc.go
generated
vendored
Normal file
45
vendor/github.com/coreos/etcd/embed/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
Package embed provides bindings for embedding an etcd server in a program.
|
||||
|
||||
Launch an embedded etcd server using the configuration defaults:
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/embed"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := embed.NewConfig()
|
||||
cfg.Dir = "default.etcd"
|
||||
e, err := embed.StartEtcd(cfg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer e.Close()
|
||||
select {
|
||||
case <-e.Server.ReadyNotify():
|
||||
log.Printf("Server is ready!")
|
||||
case <-time.After(60 * time.Second):
|
||||
e.Server.Stop() // trigger a shutdown
|
||||
log.Printf("Server took too long to start!")
|
||||
}
|
||||
log.Fatal(<-e.Err())
|
||||
}
|
||||
*/
|
||||
package embed
|
||||
334
vendor/github.com/coreos/etcd/embed/etcd.go
generated
vendored
Normal file
334
vendor/github.com/coreos/etcd/embed/etcd.go
generated
vendored
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package embed
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver"
|
||||
"github.com/coreos/etcd/etcdserver/api/v2http"
|
||||
"github.com/coreos/etcd/pkg/cors"
|
||||
runtimeutil "github.com/coreos/etcd/pkg/runtime"
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"github.com/coreos/etcd/pkg/types"
|
||||
"github.com/coreos/etcd/rafthttp"
|
||||
"github.com/coreos/pkg/capnslog"
|
||||
)
|
||||
|
||||
var plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "embed")
|
||||
|
||||
const (
|
||||
// internal fd usage includes disk usage and transport usage.
|
||||
// To read/write snapshot, snap pkg needs 1. In normal case, wal pkg needs
|
||||
// at most 2 to read/lock/write WALs. One case that it needs to 2 is to
|
||||
// read all logs after some snapshot index, which locates at the end of
|
||||
// the second last and the head of the last. For purging, it needs to read
|
||||
// directory, so it needs 1. For fd monitor, it needs 1.
|
||||
// For transport, rafthttp builds two long-polling connections and at most
|
||||
// four temporary connections with each member. There are at most 9 members
|
||||
// in a cluster, so it should reserve 96.
|
||||
// For the safety, we set the total reserved number to 150.
|
||||
reservedInternalFDNum = 150
|
||||
)
|
||||
|
||||
// Etcd contains a running etcd server and its listeners.
|
||||
type Etcd struct {
|
||||
Peers []net.Listener
|
||||
Clients []net.Listener
|
||||
Server *etcdserver.EtcdServer
|
||||
|
||||
cfg Config
|
||||
errc chan error
|
||||
sctxs map[string]*serveCtx
|
||||
}
|
||||
|
||||
// StartEtcd launches the etcd server and HTTP handlers for client/server communication.
|
||||
// The returned Etcd.Server is not guaranteed to have joined the cluster. Wait
|
||||
// on the Etcd.Server.ReadyNotify() channel to know when it completes and is ready for use.
|
||||
func StartEtcd(inCfg *Config) (e *Etcd, err error) {
|
||||
if err = inCfg.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e = &Etcd{cfg: *inCfg}
|
||||
cfg := &e.cfg
|
||||
defer func() {
|
||||
if e != nil && err != nil {
|
||||
e.Close()
|
||||
e = nil
|
||||
}
|
||||
}()
|
||||
|
||||
if e.Peers, err = startPeerListeners(cfg); err != nil {
|
||||
return
|
||||
}
|
||||
if e.sctxs, err = startClientListeners(cfg); err != nil {
|
||||
return
|
||||
}
|
||||
for _, sctx := range e.sctxs {
|
||||
e.Clients = append(e.Clients, sctx.l)
|
||||
}
|
||||
|
||||
var (
|
||||
urlsmap types.URLsMap
|
||||
token string
|
||||
)
|
||||
|
||||
if !isMemberInitialized(cfg) {
|
||||
urlsmap, token, err = cfg.PeerURLsMapAndToken("etcd")
|
||||
if err != nil {
|
||||
return e, fmt.Errorf("error setting up initial cluster: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
srvcfg := &etcdserver.ServerConfig{
|
||||
Name: cfg.Name,
|
||||
ClientURLs: cfg.ACUrls,
|
||||
PeerURLs: cfg.APUrls,
|
||||
DataDir: cfg.Dir,
|
||||
DedicatedWALDir: cfg.WalDir,
|
||||
SnapCount: cfg.SnapCount,
|
||||
MaxSnapFiles: cfg.MaxSnapFiles,
|
||||
MaxWALFiles: cfg.MaxWalFiles,
|
||||
InitialPeerURLsMap: urlsmap,
|
||||
InitialClusterToken: token,
|
||||
DiscoveryURL: cfg.Durl,
|
||||
DiscoveryProxy: cfg.Dproxy,
|
||||
NewCluster: cfg.IsNewCluster(),
|
||||
ForceNewCluster: cfg.ForceNewCluster,
|
||||
PeerTLSInfo: cfg.PeerTLSInfo,
|
||||
TickMs: cfg.TickMs,
|
||||
ElectionTicks: cfg.ElectionTicks(),
|
||||
AutoCompactionRetention: cfg.AutoCompactionRetention,
|
||||
QuotaBackendBytes: cfg.QuotaBackendBytes,
|
||||
StrictReconfigCheck: cfg.StrictReconfigCheck,
|
||||
ClientCertAuthEnabled: cfg.ClientTLSInfo.ClientCertAuth,
|
||||
}
|
||||
|
||||
if e.Server, err = etcdserver.NewServer(srvcfg); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// buffer channel so goroutines on closed connections won't wait forever
|
||||
e.errc = make(chan error, len(e.Peers)+len(e.Clients)+2*len(e.sctxs))
|
||||
|
||||
e.Server.Start()
|
||||
if err = e.serve(); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Config returns the current configuration.
|
||||
func (e *Etcd) Config() Config {
|
||||
return e.cfg
|
||||
}
|
||||
|
||||
func (e *Etcd) Close() {
|
||||
for _, sctx := range e.sctxs {
|
||||
sctx.cancel()
|
||||
}
|
||||
for i := range e.Peers {
|
||||
if e.Peers[i] != nil {
|
||||
e.Peers[i].Close()
|
||||
}
|
||||
}
|
||||
for i := range e.Clients {
|
||||
if e.Clients[i] != nil {
|
||||
e.Clients[i].Close()
|
||||
}
|
||||
}
|
||||
if e.Server != nil {
|
||||
e.Server.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Etcd) Err() <-chan error { return e.errc }
|
||||
|
||||
func startPeerListeners(cfg *Config) (plns []net.Listener, err error) {
|
||||
if cfg.PeerAutoTLS && cfg.PeerTLSInfo.Empty() {
|
||||
phosts := make([]string, len(cfg.LPUrls))
|
||||
for i, u := range cfg.LPUrls {
|
||||
phosts[i] = u.Host
|
||||
}
|
||||
cfg.PeerTLSInfo, err = transport.SelfCert(filepath.Join(cfg.Dir, "fixtures", "peer"), phosts)
|
||||
if err != nil {
|
||||
plog.Fatalf("could not get certs (%v)", err)
|
||||
}
|
||||
} else if cfg.PeerAutoTLS {
|
||||
plog.Warningf("ignoring peer auto TLS since certs given")
|
||||
}
|
||||
|
||||
if !cfg.PeerTLSInfo.Empty() {
|
||||
plog.Infof("peerTLS: %s", cfg.PeerTLSInfo)
|
||||
}
|
||||
|
||||
plns = make([]net.Listener, len(cfg.LPUrls))
|
||||
defer func() {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
for i := range plns {
|
||||
if plns[i] == nil {
|
||||
continue
|
||||
}
|
||||
plns[i].Close()
|
||||
plog.Info("stopping listening for peers on ", cfg.LPUrls[i].String())
|
||||
}
|
||||
}()
|
||||
|
||||
for i, u := range cfg.LPUrls {
|
||||
var tlscfg *tls.Config
|
||||
if u.Scheme == "http" {
|
||||
if !cfg.PeerTLSInfo.Empty() {
|
||||
plog.Warningf("The scheme of peer url %s is HTTP while peer key/cert files are presented. Ignored peer key/cert files.", u.String())
|
||||
}
|
||||
if cfg.PeerTLSInfo.ClientCertAuth {
|
||||
plog.Warningf("The scheme of peer url %s is HTTP while client cert auth (--peer-client-cert-auth) is enabled. Ignored client cert auth for this url.", u.String())
|
||||
}
|
||||
}
|
||||
if !cfg.PeerTLSInfo.Empty() {
|
||||
if tlscfg, err = cfg.PeerTLSInfo.ServerConfig(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if plns[i], err = rafthttp.NewListener(u, tlscfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
plog.Info("listening for peers on ", u.String())
|
||||
}
|
||||
return plns, nil
|
||||
}
|
||||
|
||||
func startClientListeners(cfg *Config) (sctxs map[string]*serveCtx, err error) {
|
||||
if cfg.ClientAutoTLS && cfg.ClientTLSInfo.Empty() {
|
||||
chosts := make([]string, len(cfg.LCUrls))
|
||||
for i, u := range cfg.LCUrls {
|
||||
chosts[i] = u.Host
|
||||
}
|
||||
cfg.ClientTLSInfo, err = transport.SelfCert(filepath.Join(cfg.Dir, "fixtures", "client"), chosts)
|
||||
if err != nil {
|
||||
plog.Fatalf("could not get certs (%v)", err)
|
||||
}
|
||||
} else if cfg.ClientAutoTLS {
|
||||
plog.Warningf("ignoring client auto TLS since certs given")
|
||||
}
|
||||
|
||||
if cfg.EnablePprof {
|
||||
plog.Infof("pprof is enabled under %s", pprofPrefix)
|
||||
}
|
||||
|
||||
sctxs = make(map[string]*serveCtx)
|
||||
for _, u := range cfg.LCUrls {
|
||||
sctx := newServeCtx()
|
||||
|
||||
if u.Scheme == "http" || u.Scheme == "unix" {
|
||||
if !cfg.ClientTLSInfo.Empty() {
|
||||
plog.Warningf("The scheme of client url %s is HTTP while peer key/cert files are presented. Ignored key/cert files.", u.String())
|
||||
}
|
||||
if cfg.ClientTLSInfo.ClientCertAuth {
|
||||
plog.Warningf("The scheme of client url %s is HTTP while client cert auth (--client-cert-auth) is enabled. Ignored client cert auth for this url.", u.String())
|
||||
}
|
||||
}
|
||||
if (u.Scheme == "https" || u.Scheme == "unixs") && cfg.ClientTLSInfo.Empty() {
|
||||
return nil, fmt.Errorf("TLS key/cert (--cert-file, --key-file) must be provided for client url %s with HTTPs scheme", u.String())
|
||||
}
|
||||
|
||||
proto := "tcp"
|
||||
if u.Scheme == "unix" || u.Scheme == "unixs" {
|
||||
proto = "unix"
|
||||
}
|
||||
|
||||
sctx.secure = u.Scheme == "https" || u.Scheme == "unixs"
|
||||
sctx.insecure = !sctx.secure
|
||||
if oldctx := sctxs[u.Host]; oldctx != nil {
|
||||
oldctx.secure = oldctx.secure || sctx.secure
|
||||
oldctx.insecure = oldctx.insecure || sctx.insecure
|
||||
continue
|
||||
}
|
||||
|
||||
if sctx.l, err = net.Listen(proto, u.Host); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fdLimit, fderr := runtimeutil.FDLimit(); fderr == nil {
|
||||
if fdLimit <= reservedInternalFDNum {
|
||||
plog.Fatalf("file descriptor limit[%d] of etcd process is too low, and should be set higher than %d to ensure internal usage", fdLimit, reservedInternalFDNum)
|
||||
}
|
||||
sctx.l = transport.LimitListener(sctx.l, int(fdLimit-reservedInternalFDNum))
|
||||
}
|
||||
|
||||
if proto == "tcp" {
|
||||
if sctx.l, err = transport.NewKeepAliveListener(sctx.l, "tcp", nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
plog.Info("listening for client requests on ", u.Host)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
sctx.l.Close()
|
||||
plog.Info("stopping listening for client requests on ", u.Host)
|
||||
}
|
||||
}()
|
||||
for k := range cfg.UserHandlers {
|
||||
sctx.userHandlers[k] = cfg.UserHandlers[k]
|
||||
}
|
||||
if cfg.EnablePprof {
|
||||
sctx.registerPprof()
|
||||
}
|
||||
sctxs[u.Host] = sctx
|
||||
}
|
||||
return sctxs, nil
|
||||
}
|
||||
|
||||
func (e *Etcd) serve() (err error) {
|
||||
var ctlscfg *tls.Config
|
||||
if !e.cfg.ClientTLSInfo.Empty() {
|
||||
plog.Infof("ClientTLS: %s", e.cfg.ClientTLSInfo)
|
||||
if ctlscfg, err = e.cfg.ClientTLSInfo.ServerConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if e.cfg.CorsInfo.String() != "" {
|
||||
plog.Infof("cors = %s", e.cfg.CorsInfo)
|
||||
}
|
||||
|
||||
// Start the peer server in a goroutine
|
||||
ph := v2http.NewPeerHandler(e.Server)
|
||||
for _, l := range e.Peers {
|
||||
go func(l net.Listener) {
|
||||
e.errc <- servePeerHTTP(l, ph)
|
||||
}(l)
|
||||
}
|
||||
|
||||
// Start a client server goroutine for each listen address
|
||||
ch := http.Handler(&cors.CORSHandler{
|
||||
Handler: v2http.NewClientHandler(e.Server, e.Server.Cfg.ReqTimeout()),
|
||||
Info: e.cfg.CorsInfo,
|
||||
})
|
||||
for _, sctx := range e.sctxs {
|
||||
// read timeout does not work with http close notify
|
||||
// TODO: https://github.com/golang/go/issues/9524
|
||||
go func(s *serveCtx) {
|
||||
e.errc <- s.serve(e.Server, ctlscfg, ch, e.errc)
|
||||
}(sctx)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
206
vendor/github.com/coreos/etcd/embed/serve.go
generated
vendored
Normal file
206
vendor/github.com/coreos/etcd/embed/serve.go
generated
vendored
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package embed
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"io/ioutil"
|
||||
defaultLog "log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver"
|
||||
"github.com/coreos/etcd/etcdserver/api/v3rpc"
|
||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
|
||||
"github.com/cockroachdb/cmux"
|
||||
gw "github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const pprofPrefix = "/debug/pprof"
|
||||
|
||||
type serveCtx struct {
|
||||
l net.Listener
|
||||
secure bool
|
||||
insecure bool
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
|
||||
userHandlers map[string]http.Handler
|
||||
}
|
||||
|
||||
func newServeCtx() *serveCtx {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &serveCtx{ctx: ctx, cancel: cancel, userHandlers: make(map[string]http.Handler)}
|
||||
}
|
||||
|
||||
// serve accepts incoming connections on the listener l,
|
||||
// creating a new service goroutine for each. The service goroutines
|
||||
// read requests and then call handler to reply to them.
|
||||
func (sctx *serveCtx) serve(s *etcdserver.EtcdServer, tlscfg *tls.Config, handler http.Handler, errc chan<- error) error {
|
||||
logger := defaultLog.New(ioutil.Discard, "etcdhttp", 0)
|
||||
<-s.ReadyNotify()
|
||||
plog.Info("ready to serve client requests")
|
||||
|
||||
m := cmux.New(sctx.l)
|
||||
|
||||
if sctx.insecure {
|
||||
gs := v3rpc.Server(s, nil)
|
||||
grpcl := m.Match(cmux.HTTP2())
|
||||
go func() { errc <- gs.Serve(grpcl) }()
|
||||
|
||||
opts := []grpc.DialOption{
|
||||
grpc.WithInsecure(),
|
||||
}
|
||||
gwmux, err := sctx.registerGateway(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
httpmux := sctx.createMux(gwmux, handler)
|
||||
|
||||
srvhttp := &http.Server{
|
||||
Handler: httpmux,
|
||||
ErrorLog: logger, // do not log user error
|
||||
}
|
||||
httpl := m.Match(cmux.HTTP1())
|
||||
go func() { errc <- srvhttp.Serve(httpl) }()
|
||||
plog.Noticef("serving insecure client requests on %s, this is strongly discouraged!", sctx.l.Addr().String())
|
||||
}
|
||||
|
||||
if sctx.secure {
|
||||
gs := v3rpc.Server(s, tlscfg)
|
||||
handler = grpcHandlerFunc(gs, handler)
|
||||
|
||||
dtls := transport.ShallowCopyTLSConfig(tlscfg)
|
||||
// trust local server
|
||||
dtls.InsecureSkipVerify = true
|
||||
creds := credentials.NewTLS(dtls)
|
||||
opts := []grpc.DialOption{grpc.WithTransportCredentials(creds)}
|
||||
gwmux, err := sctx.registerGateway(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tlsl := tls.NewListener(m.Match(cmux.Any()), tlscfg)
|
||||
// TODO: add debug flag; enable logging when debug flag is set
|
||||
httpmux := sctx.createMux(gwmux, handler)
|
||||
|
||||
srv := &http.Server{
|
||||
Handler: httpmux,
|
||||
TLSConfig: tlscfg,
|
||||
ErrorLog: logger, // do not log user error
|
||||
}
|
||||
go func() { errc <- srv.Serve(tlsl) }()
|
||||
|
||||
plog.Infof("serving client requests on %s", sctx.l.Addr().String())
|
||||
}
|
||||
|
||||
return m.Serve()
|
||||
}
|
||||
|
||||
// grpcHandlerFunc returns an http.Handler that delegates to grpcServer on incoming gRPC
|
||||
// connections or otherHandler otherwise. Copied from cockroachdb.
|
||||
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
|
||||
grpcServer.ServeHTTP(w, r)
|
||||
} else {
|
||||
otherHandler.ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func servePeerHTTP(l net.Listener, handler http.Handler) error {
|
||||
logger := defaultLog.New(ioutil.Discard, "etcdhttp", 0)
|
||||
// TODO: add debug flag; enable logging when debug flag is set
|
||||
srv := &http.Server{
|
||||
Handler: handler,
|
||||
ReadTimeout: 5 * time.Minute,
|
||||
ErrorLog: logger, // do not log user error
|
||||
}
|
||||
return srv.Serve(l)
|
||||
}
|
||||
|
||||
func (sctx *serveCtx) registerGateway(opts []grpc.DialOption) (*gw.ServeMux, error) {
|
||||
ctx := sctx.ctx
|
||||
addr := sctx.l.Addr().String()
|
||||
gwmux := gw.NewServeMux()
|
||||
|
||||
err := pb.RegisterKVHandlerFromEndpoint(ctx, gwmux, addr, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = pb.RegisterWatchHandlerFromEndpoint(ctx, gwmux, addr, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = pb.RegisterLeaseHandlerFromEndpoint(ctx, gwmux, addr, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = pb.RegisterClusterHandlerFromEndpoint(ctx, gwmux, addr, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = pb.RegisterMaintenanceHandlerFromEndpoint(ctx, gwmux, addr, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = pb.RegisterAuthHandlerFromEndpoint(ctx, gwmux, addr, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gwmux, nil
|
||||
}
|
||||
|
||||
func (sctx *serveCtx) createMux(gwmux *gw.ServeMux, handler http.Handler) *http.ServeMux {
|
||||
httpmux := http.NewServeMux()
|
||||
for path, h := range sctx.userHandlers {
|
||||
httpmux.Handle(path, h)
|
||||
}
|
||||
|
||||
httpmux.Handle("/v3alpha/", gwmux)
|
||||
httpmux.Handle("/", handler)
|
||||
return httpmux
|
||||
}
|
||||
|
||||
func (sctx *serveCtx) registerPprof() {
|
||||
f := func(s string, h http.Handler) {
|
||||
if sctx.userHandlers[s] != nil {
|
||||
plog.Warningf("path %s already registered by user handler", s)
|
||||
return
|
||||
}
|
||||
sctx.userHandlers[s] = h
|
||||
}
|
||||
f(pprofPrefix+"/", http.HandlerFunc(pprof.Index))
|
||||
f(pprofPrefix+"/profile", http.HandlerFunc(pprof.Profile))
|
||||
f(pprofPrefix+"/symbol", http.HandlerFunc(pprof.Symbol))
|
||||
f(pprofPrefix+"/cmdline", http.HandlerFunc(pprof.Cmdline))
|
||||
f(pprofPrefix+"/trace", http.HandlerFunc(pprof.Trace))
|
||||
|
||||
f(pprofPrefix+"/heap", pprof.Handler("heap"))
|
||||
f(pprofPrefix+"/goroutine", pprof.Handler("goroutine"))
|
||||
f(pprofPrefix+"/threadcreate", pprof.Handler("threadcreate"))
|
||||
f(pprofPrefix+"/block", pprof.Handler("block"))
|
||||
}
|
||||
30
vendor/github.com/coreos/etcd/embed/util.go
generated
vendored
Normal file
30
vendor/github.com/coreos/etcd/embed/util.go
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package embed
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/coreos/etcd/wal"
|
||||
)
|
||||
|
||||
func isMemberInitialized(cfg *Config) bool {
|
||||
waldir := cfg.WalDir
|
||||
if waldir == "" {
|
||||
waldir = filepath.Join(cfg.Dir, "member", "wal")
|
||||
}
|
||||
|
||||
return wal.Exist(waldir)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue