ca114f7812
This patch adds etcd storage implementation. This should be useful in environments where - we dont want to depends on a separate, hard to maintain SQL cluster - we dont want to incur the overhead of talking to kubernetes apiservers - kubernetes is not available yet, or if kubernetes depends on dex to perform authentication and the operator would like to remove any circular dependency if possible.
93 lines
1.8 KiB
Go
93 lines
1.8 KiB
Go
package etcd
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/coreos/dex/storage"
|
|
"github.com/coreos/etcd/clientv3"
|
|
"github.com/coreos/etcd/clientv3/namespace"
|
|
"github.com/coreos/etcd/pkg/transport"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var (
|
|
defaultDialTimeout = 2 * time.Second
|
|
)
|
|
|
|
// SSL represents SSL options for etcd databases.
|
|
type SSL struct {
|
|
ServerName string
|
|
CAFile string
|
|
KeyFile string
|
|
CertFile string
|
|
}
|
|
|
|
// Etcd options for connecting to etcd databases.
|
|
// If you are using a shared etcd cluster for storage, it might be useful to
|
|
// configure an etcd namespace either via Namespace field or using `etcd grpc-proxy
|
|
// --namespace=<prefix>`
|
|
type Etcd struct {
|
|
Endpoints []string
|
|
Namespace string
|
|
Username string
|
|
Password string
|
|
SSL SSL
|
|
}
|
|
|
|
// Open creates a new storage implementation backed by Etcd
|
|
func (p *Etcd) Open(logger logrus.FieldLogger) (storage.Storage, error) {
|
|
return p.open(logger)
|
|
}
|
|
|
|
func (p *Etcd) open(logger logrus.FieldLogger) (*conn, error) {
|
|
cfg := clientv3.Config{
|
|
Endpoints: p.Endpoints,
|
|
DialTimeout: defaultDialTimeout * time.Second,
|
|
Username: p.Username,
|
|
Password: p.Password,
|
|
}
|
|
|
|
var cfgtls *transport.TLSInfo
|
|
tlsinfo := transport.TLSInfo{}
|
|
if p.SSL.CertFile != "" {
|
|
tlsinfo.CertFile = p.SSL.CertFile
|
|
cfgtls = &tlsinfo
|
|
}
|
|
|
|
if p.SSL.KeyFile != "" {
|
|
tlsinfo.KeyFile = p.SSL.KeyFile
|
|
cfgtls = &tlsinfo
|
|
}
|
|
|
|
if p.SSL.CAFile != "" {
|
|
tlsinfo.CAFile = p.SSL.CAFile
|
|
cfgtls = &tlsinfo
|
|
}
|
|
|
|
if p.SSL.ServerName != "" {
|
|
tlsinfo.ServerName = p.SSL.ServerName
|
|
cfgtls = &tlsinfo
|
|
}
|
|
|
|
if cfgtls != nil {
|
|
clientTLS, err := cfgtls.ClientConfig()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cfg.TLS = clientTLS
|
|
}
|
|
|
|
db, err := clientv3.New(cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(p.Namespace) > 0 {
|
|
db.KV = namespace.NewKV(db.KV, p.Namespace)
|
|
}
|
|
c := &conn{
|
|
db: db,
|
|
logger: logger,
|
|
}
|
|
return c, nil
|
|
}
|