Moved from backend to services

This commit is contained in:
Alex Lyulkov
2015-08-25 20:54:16 +03:00
parent 909276fe3b
commit 888c340f97
37 changed files with 455 additions and 1979 deletions
+58 -5
View File
@@ -4,29 +4,82 @@ import (
"time"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/services"
)
// AccessPoint is a interface needed by nodes to control the access
// to the node, and provide heartbeats
type AccessPoint interface {
// GetServers returns a list of registered servers
GetServers() ([]backend.Server, error)
GetServers() ([]services.Server, error)
// UpsertServer registers server presence, permanently if ttl is 0 or
// for the specified duration with second resolution if it's >= 1 second
UpsertServer(s backend.Server, ttl time.Duration) error
UpsertServer(s services.Server, ttl time.Duration) error
// GetUserCAPub returns the user certificate authority public key
GetUserCAPub() ([]byte, error)
// GetUserKeys returns a list of authorized keys for a given user
// in a OpenSSH key authorized_keys format
GetUserKeys(user string) ([]backend.AuthorizedKey, error)
GetUserKeys(user string) ([]services.AuthorizedKey, error)
// GetWebSessionsKeys returns a list of generated public keys
// associated with user web session
GetWebSessionsKeys(user string) ([]backend.AuthorizedKey, error)
GetWebSessionsKeys(user string) ([]services.AuthorizedKey, error)
// GetRemoteCerts returns a list of trusted remote certificates
GetRemoteCerts(ctype, fqdn string) ([]backend.RemoteCert, error)
GetRemoteCerts(ctype, fqdn string) ([]services.RemoteCert, error)
}
type BackendAccessPoint struct {
caS *services.CAService
presenceS *services.PresenceService
provisioningS *services.ProvisioningService
userS *services.UserService
webS *services.WebService
}
func NewBackendAccessPoint(bk backend.Backend) *BackendAccessPoint {
ap := BackendAccessPoint{}
ap.caS = services.NewCAService(bk)
ap.presenceS = services.NewPresenceService(bk)
ap.provisioningS = services.NewProvisioningService(bk)
ap.userS = services.NewUserService(bk)
ap.webS = services.NewWebService(bk)
return &ap
}
// GetServers returns a list of registered servers
func (ap *BackendAccessPoint) GetServers() ([]services.Server, error) {
return ap.presenceS.GetServers()
}
// UpsertServer registers server presence, permanently if ttl is 0 or
// for the specified duration with second resolution if it's >= 1 second
func (ap *BackendAccessPoint) UpsertServer(s services.Server, ttl time.Duration) error {
return ap.presenceS.UpsertServer(s, ttl)
}
// GetUserCAPub returns the user certificate authority public key
func (ap *BackendAccessPoint) GetUserCAPub() ([]byte, error) {
return ap.caS.GetUserCAPub()
}
// GetUserKeys returns a list of authorized keys for a given user
// in a OpenSSH key authorized_keys format
func (ap *BackendAccessPoint) GetUserKeys(user string) ([]services.AuthorizedKey, error) {
return ap.userS.GetUserKeys(user)
}
// GetWebSessionsKeys returns a list of generated public keys
// associated with user web session
func (ap *BackendAccessPoint) GetWebSessionsKeys(user string) ([]services.AuthorizedKey, error) {
return ap.webS.GetWebSessionsKeys(user)
}
// GetRemoteCerts returns a list of trusted remote certificates
func (ap *BackendAccessPoint) GetRemoteCerts(ctype, fqdn string) ([]services.RemoteCert, error) {
return ap.caS.GetRemoteCerts(ctype, fqdn)
}
+72 -63
View File
@@ -11,10 +11,12 @@ import (
"fmt"
"time"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/session"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/mailgun/lemma/secret"
"github.com/gravitational/teleport/Godeps/_workspace/src/golang.org/x/crypto/bcrypt"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/services"
)
// Authority implements minimal key-management facility for generating OpenSSH
@@ -34,31 +36,47 @@ type Authority interface {
type Session struct {
SID session.SecureID
PID session.PlainID
WS backend.WebSession
WS services.WebSession
}
func NewAuthServer(b backend.Backend, a Authority, scrt *secret.Service) *AuthServer {
return &AuthServer{
b: b,
a: a,
scrt: scrt,
}
func NewAuthServer(bk backend.Backend, a Authority, scrt *secret.Service) *AuthServer {
as := AuthServer{}
as.bk = bk
as.a = a
as.scrt = scrt
as.caS = services.NewCAService(as.bk)
as.lockS = services.NewLockService(as.bk)
as.presenceS = services.NewPresenceService(as.bk)
as.provisioningS = services.NewProvisioningService(as.bk)
as.userS = services.NewUserService(as.bk)
as.webS = services.NewWebService(as.bk)
return &as
}
// AuthServer implements key signing, generation and ACL functionality
// used by teleport
type AuthServer struct {
b backend.Backend
bk backend.Backend
a Authority
scrt *secret.Service
caS *services.CAService
lockS *services.LockService
presenceS *services.PresenceService
provisioningS *services.ProvisioningService
userS *services.UserService
webS *services.WebService
}
func (s *AuthServer) UpsertServer(srv backend.Server, ttl time.Duration) error {
return s.b.UpsertServer(srv, ttl)
func (s *AuthServer) UpsertServer(srv services.Server, ttl time.Duration) error {
return s.presenceS.UpsertServer(srv, ttl)
}
func (s *AuthServer) GetServers() ([]backend.Server, error) {
return s.b.GetServers()
func (s *AuthServer) GetServers() ([]services.Server, error) {
return s.presenceS.GetServers()
}
// UpsertUserKey takes user's public key, generates certificate for it
@@ -66,34 +84,34 @@ func (s *AuthServer) GetServers() ([]backend.Server, error) {
// by user CA in case of success, error otherwise. The certificate will be
// valid for the duration of the ttl passed in.
func (s *AuthServer) UpsertUserKey(
user string, key backend.AuthorizedKey, ttl time.Duration) ([]byte, error) {
user string, key services.AuthorizedKey, ttl time.Duration) ([]byte, error) {
cert, err := s.GenerateUserCert(key.Value, key.ID, user, ttl)
if err != nil {
return nil, err
}
key.Value = cert
if err := s.b.UpsertUserKey(user, key, ttl); err != nil {
if err := s.userS.UpsertUserKey(user, key, ttl); err != nil {
return nil, err
}
return cert, nil
}
func (s *AuthServer) GetUsers() ([]string, error) {
return s.b.GetUsers()
return s.userS.GetUsers()
}
func (s *AuthServer) DeleteUser(user string) error {
return s.b.DeleteUser(user)
return s.userS.DeleteUser(user)
}
func (s *AuthServer) GetUserKeys(user string) ([]backend.AuthorizedKey, error) {
return s.b.GetUserKeys(user)
func (s *AuthServer) GetUserKeys(user string) ([]services.AuthorizedKey, error) {
return s.userS.GetUserKeys(user)
}
// DeleteUserKey deletes user key by given ID
func (s *AuthServer) DeleteUserKey(user, key string) error {
return s.b.DeleteUserKey(user, key)
return s.userS.DeleteUserKey(user, key)
}
// GenerateKeyPair generates private and public key pair of OpenSSH certs
@@ -101,16 +119,16 @@ func (s *AuthServer) GenerateKeyPair(pass string) ([]byte, []byte, error) {
return s.a.GenerateKeyPair(pass)
}
func (s *AuthServer) UpsertRemoteCert(cert backend.RemoteCert, ttl time.Duration) error {
return s.b.UpsertRemoteCert(cert, ttl)
func (s *AuthServer) UpsertRemoteCert(cert services.RemoteCert, ttl time.Duration) error {
return s.caS.UpsertRemoteCert(cert, ttl)
}
func (s *AuthServer) GetRemoteCerts(ctype string, fqdn string) ([]backend.RemoteCert, error) {
return s.b.GetRemoteCerts(ctype, fqdn)
func (s *AuthServer) GetRemoteCerts(ctype string, fqdn string) ([]services.RemoteCert, error) {
return s.caS.GetRemoteCerts(ctype, fqdn)
}
func (s *AuthServer) DeleteRemoteCert(ctype string, fqdn, id string) error {
return s.b.DeleteRemoteCert(ctype, fqdn, id)
return s.caS.DeleteRemoteCert(ctype, fqdn, id)
}
// ResetHostCA generates host certificate authority and updates the backend
@@ -119,7 +137,7 @@ func (s *AuthServer) ResetHostCA(pass string) error {
if err != nil {
return err
}
return s.b.UpsertHostCA(backend.CA{Pub: pub, Priv: priv})
return s.caS.UpsertHostCA(services.CA{Pub: pub, Priv: priv})
}
// ResetHostCA generates user certificate authority and updates the backend
@@ -128,17 +146,17 @@ func (s *AuthServer) ResetUserCA(pass string) error {
if err != nil {
return err
}
return s.b.UpsertUserCA(backend.CA{Pub: pub, Priv: priv})
return s.caS.UpsertUserCA(services.CA{Pub: pub, Priv: priv})
}
// GetHostCAPub returns a public key for host key signing authority
func (s *AuthServer) GetHostCAPub() ([]byte, error) {
return s.b.GetHostCAPub()
return s.caS.GetHostCAPub()
}
// GetHostCAPub returns a public key for user key signing authority
func (s *AuthServer) GetUserCAPub() ([]byte, error) {
return s.b.GetUserCAPub()
return s.caS.GetUserCAPub()
}
// GenerateHostCert generates host certificate, it takes pkey as a signing
@@ -146,7 +164,7 @@ func (s *AuthServer) GetUserCAPub() ([]byte, error) {
func (s *AuthServer) GenerateHostCert(
key []byte, id, hostname string, ttl time.Duration) ([]byte, error) {
hk, err := s.b.GetHostCA()
hk, err := s.caS.GetHostCA()
if err != nil {
return nil, err
}
@@ -158,7 +176,7 @@ func (s *AuthServer) GenerateHostCert(
func (s *AuthServer) GenerateUserCert(
key []byte, id, username string, ttl time.Duration) ([]byte, error) {
hk, err := s.b.GetUserCA()
hk, err := s.caS.GetUserCA()
if err != nil {
return nil, err
}
@@ -173,19 +191,19 @@ func (s *AuthServer) UpsertPassword(user string, password []byte) error {
if err != nil {
return err
}
return s.b.UpsertPasswordHash(user, hash)
return s.webS.UpsertPasswordHash(user, hash)
}
func (s *AuthServer) CheckPassword(user string, password []byte) error {
if err := verifyPassword(password); err != nil {
return err
}
hash, err := s.b.GetPasswordHash(user)
hash, err := s.webS.GetPasswordHash(user)
if err != nil {
return err
}
if err := bcrypt.CompareHashAndPassword(hash, password); err != nil {
return &BadParameterError{Msg: "passwords do not match"}
return &teleport.BadParameterError{Err: "passwords do not match"}
}
return nil
}
@@ -209,7 +227,7 @@ func (s *AuthServer) GenerateToken(fqdn string, ttl time.Duration) (string, erro
if err != nil {
return "", err
}
if err := s.b.UpsertToken(string(p.PID), fqdn, ttl); err != nil {
if err := s.provisioningS.UpsertToken(string(p.PID), fqdn, ttl); err != nil {
return "", err
}
return string(p.SID), nil
@@ -220,7 +238,7 @@ func (s *AuthServer) ValidateToken(token, fqdn string) error {
if err != nil {
return err
}
out, err := s.b.GetToken(string(pid))
out, err := s.provisioningS.GetToken(string(pid))
if err != nil {
return err
}
@@ -235,7 +253,7 @@ func (s *AuthServer) DeleteToken(token string) error {
if err != nil {
return err
}
return s.b.DeleteToken(string(pid))
return s.provisioningS.DeleteToken(string(pid))
}
func (s *AuthServer) NewWebSession(user string) (*Session, error) {
@@ -247,7 +265,7 @@ func (s *AuthServer) NewWebSession(user string) (*Session, error) {
if err != nil {
return nil, err
}
hk, err := s.b.GetUserCA()
hk, err := s.caS.GetUserCA()
if err != nil {
return nil, err
}
@@ -258,13 +276,13 @@ func (s *AuthServer) NewWebSession(user string) (*Session, error) {
sess := &Session{
SID: p.SID,
PID: p.PID,
WS: backend.WebSession{Priv: priv, Pub: cert},
WS: services.WebSession{Priv: priv, Pub: cert},
}
return sess, nil
}
func (s *AuthServer) UpsertWebSession(user string, sess *Session, ttl time.Duration) error {
return s.b.UpsertWebSession(user, string(sess.PID), sess.WS, ttl)
return s.webS.UpsertWebSession(user, string(sess.PID), sess.WS, ttl)
}
func (s *AuthServer) GetWebSession(user string, sid session.SecureID) (*Session, error) {
@@ -272,7 +290,7 @@ func (s *AuthServer) GetWebSession(user string, sid session.SecureID) (*Session,
if err != nil {
return nil, err
}
ws, err := s.b.GetWebSession(user, string(pid))
ws, err := s.webS.GetWebSession(user, string(pid))
if err != nil {
return nil, err
}
@@ -283,8 +301,8 @@ func (s *AuthServer) GetWebSession(user string, sid session.SecureID) (*Session,
}, nil
}
func (s *AuthServer) GetWebSessionsKeys(user string) ([]backend.AuthorizedKey, error) {
return s.b.GetWebSessionsKeys(user)
func (s *AuthServer) GetWebSessionsKeys(user string) ([]services.AuthorizedKey, error) {
return s.webS.GetWebSessionsKeys(user)
}
func (s *AuthServer) DeleteWebSession(user string, sid session.SecureID) error {
@@ -292,39 +310,39 @@ func (s *AuthServer) DeleteWebSession(user string, sid session.SecureID) error {
if err != nil {
return err
}
return s.b.DeleteWebSession(user, string(pid))
return s.webS.DeleteWebSession(user, string(pid))
}
func (s *AuthServer) UpsertWebTun(t backend.WebTun, ttl time.Duration) error {
return s.b.UpsertWebTun(t, ttl)
func (s *AuthServer) UpsertWebTun(t services.WebTun, ttl time.Duration) error {
return s.webS.UpsertWebTun(t, ttl)
}
func (s *AuthServer) GetWebTun(prefix string) (*backend.WebTun, error) {
return s.b.GetWebTun(prefix)
func (s *AuthServer) GetWebTun(prefix string) (*services.WebTun, error) {
return s.webS.GetWebTun(prefix)
}
func (s *AuthServer) GetWebTuns() ([]backend.WebTun, error) {
return s.b.GetWebTuns()
func (s *AuthServer) GetWebTuns() ([]services.WebTun, error) {
return s.webS.GetWebTuns()
}
func (s *AuthServer) DeleteWebTun(prefix string) error {
return s.b.DeleteWebTun(prefix)
return s.webS.DeleteWebTun(prefix)
}
// make sure password satisfies our requirements (relaxed),
// mostly to avoid putting garbage in
func verifyPassword(password []byte) error {
if len(password) < MinPasswordLength {
return &BadParameterError{
return &teleport.BadParameterError{
Param: "password",
Msg: fmt.Sprintf(
Err: fmt.Sprintf(
"password is too short, min length is %v", MinPasswordLength),
}
}
if len(password) > MaxPasswordLength {
return &BadParameterError{
return &teleport.BadParameterError{
Param: "password",
Msg: fmt.Sprintf(
Err: fmt.Sprintf(
"password is too long, max length is %v", MaxPasswordLength),
}
}
@@ -336,12 +354,3 @@ const (
MinPasswordLength = 6
MaxPasswordLength = 128
)
type BadParameterError struct {
Param string
Msg string
}
func (p *BadParameterError) Error() string {
return fmt.Sprintf("bad parameter: %v, err: %v", p.Param, p.Msg)
}
+23 -10
View File
@@ -1,18 +1,25 @@
package auth
import (
"path/filepath"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/mailgun/lemma/secret"
authority "github.com/gravitational/teleport/auth/native"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/backend/membk"
"github.com/gravitational/teleport/backend/boltbk"
"github.com/gravitational/log"
. "github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/check.v1"
)
type AuthSuite struct {
bk *membk.MemBackend
bk backend.Backend
scrt *secret.Service
a *AuthServer
dir string
}
var _ = Suite(&AuthSuite{})
@@ -23,10 +30,16 @@ func (s *AuthSuite) SetUpSuite(c *C) {
srv, err := secret.New(&secret.Config{KeyBytes: key})
c.Assert(err, IsNil)
s.scrt = srv
log.Init([]*log.LogConfig{&log.LogConfig{Name: "console"}})
}
func (s *AuthSuite) SetUpTest(c *C) {
s.bk = membk.New()
s.dir = c.MkDir()
var err error
s.bk, err = boltbk.New(filepath.Join(s.dir, "db"))
c.Assert(err, IsNil)
s.a = NewAuthServer(s.bk, authority.New(), s.scrt)
}
@@ -34,11 +47,11 @@ func (s *AuthSuite) TestPasswordCRUD(c *C) {
pass := []byte("abc123")
err := s.a.CheckPassword("user1", pass)
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
c.Assert(s.a.UpsertPassword("user1", pass), IsNil)
c.Assert(s.a.CheckPassword("user1", pass), IsNil)
c.Assert(s.a.CheckPassword("user1", []byte("abc123123")), FitsTypeOf, &BadParameterError{})
c.Assert(s.a.CheckPassword("user1", []byte("abc123123")), FitsTypeOf, &teleport.BadParameterError{})
}
func (s *AuthSuite) TestPasswordGarbage(c *C) {
@@ -49,7 +62,7 @@ func (s *AuthSuite) TestPasswordGarbage(c *C) {
}
for _, g := range garbage {
err := s.a.CheckPassword("user1", g)
c.Assert(err, FitsTypeOf, &BadParameterError{})
c.Assert(err, FitsTypeOf, &teleport.BadParameterError{})
}
}
@@ -61,7 +74,7 @@ func (s *AuthSuite) TestSessions(c *C) {
pass := []byte("abc123")
ws, err := s.a.SignIn(user, pass)
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
c.Assert(ws, IsNil)
c.Assert(s.a.UpsertPassword(user, pass), IsNil)
@@ -78,7 +91,7 @@ func (s *AuthSuite) TestSessions(c *C) {
c.Assert(err, IsNil)
_, err = s.a.GetWebSession(user, ws.SID)
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
}
func (s *AuthSuite) TestTokensCRUD(c *C) {
@@ -88,9 +101,9 @@ func (s *AuthSuite) TestTokensCRUD(c *C) {
c.Assert(s.a.ValidateToken(tok, "a.example.com"), IsNil)
c.Assert(s.a.DeleteToken(tok), IsNil)
c.Assert(s.a.DeleteToken(tok), FitsTypeOf, &backend.NotFoundError{})
c.Assert(s.a.DeleteToken(tok), FitsTypeOf, &teleport.NotFoundError{})
c.Assert(s.a.ValidateToken(tok, "a.example.com"),
FitsTypeOf, &backend.NotFoundError{})
FitsTypeOf, &teleport.NotFoundError{})
}
func (s *AuthSuite) TestBadTokens(c *C) {
+24 -23
View File
@@ -10,9 +10,10 @@ import (
"strconv"
"time"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/events"
"github.com/gravitational/teleport/recorder"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/session"
"github.com/gravitational/teleport/utils"
@@ -63,7 +64,7 @@ func (c *Client) convertResponse(
return nil, err
}
if re.Code() == http.StatusNotFound {
return nil, &backend.NotFoundError{Message: string(re.Bytes())}
return nil, &teleport.NotFoundError{Message: string(re.Bytes())}
}
if re.Code() < 200 || re.Code() > 299 {
return nil, fmt.Errorf("error: %v", string(re.Bytes()))
@@ -157,7 +158,7 @@ func (c *Client) UpsertParty(id string, p session.Party, ttl time.Duration) erro
return nil
}
func (c *Client) UpsertRemoteCert(cert backend.RemoteCert, ttl time.Duration) error {
func (c *Client) UpsertRemoteCert(cert services.RemoteCert, ttl time.Duration) error {
out, err := c.PostForm(c.Endpoint("ca", "remote", cert.Type, "hosts", cert.FQDN), url.Values{
"key": []string{string(cert.Value)},
"ttl": []string{ttl.String()},
@@ -173,7 +174,7 @@ func (c *Client) UpsertRemoteCert(cert backend.RemoteCert, ttl time.Duration) er
return nil
}
func (c *Client) GetRemoteCerts(ctype string, fqdn string) ([]backend.RemoteCert, error) {
func (c *Client) GetRemoteCerts(ctype string, fqdn string) ([]services.RemoteCert, error) {
out, err := c.Get(c.Endpoint("ca", "remote", ctype), url.Values{
"fqdn": []string{fqdn},
})
@@ -261,7 +262,7 @@ func (c *Client) GetChunkReader(id string) (recorder.ChunkReadCloser, error) {
// UpsertServer is used by SSH servers to reprt their presense
// to the auth servers in form of hearbeat expiring after ttl period.
func (c *Client) UpsertServer(s backend.Server, ttl time.Duration) error {
func (c *Client) UpsertServer(s services.Server, ttl time.Duration) error {
_, err := c.PostForm(c.Endpoint("servers"), url.Values{
"id": []string{string(s.ID)},
"addr": []string{string(s.Addr)},
@@ -271,7 +272,7 @@ func (c *Client) UpsertServer(s backend.Server, ttl time.Duration) error {
}
// GetServers returns the list of servers registered in the cluster.
func (c *Client) GetServers() ([]backend.Server, error) {
func (c *Client) GetServers() ([]services.Server, error) {
out, err := c.Get(c.Endpoint("servers"), url.Values{})
if err != nil {
return nil, err
@@ -285,8 +286,8 @@ func (c *Client) GetServers() ([]backend.Server, error) {
// UpsertWebTun creates a persistent SSH tunnel to the specified web target
// server that is valid for ttl period.
// See backend.WebTun documentation for details
func (c *Client) UpsertWebTun(wt backend.WebTun, ttl time.Duration) error {
// See services.WebTun documentation for details
func (c *Client) UpsertWebTun(wt services.WebTun, ttl time.Duration) error {
_, err := c.PostForm(c.Endpoint("tunnels", "web"), url.Values{
"target": []string{string(wt.TargetAddr)},
"proxy": []string{string(wt.ProxyAddr)},
@@ -297,7 +298,7 @@ func (c *Client) UpsertWebTun(wt backend.WebTun, ttl time.Duration) error {
}
// GetWebTuns returns a list of web tunnels supported by the system
func (c *Client) GetWebTuns() ([]backend.WebTun, error) {
func (c *Client) GetWebTuns() ([]services.WebTun, error) {
out, err := c.Get(c.Endpoint("tunnels", "web"), url.Values{})
if err != nil {
return nil, err
@@ -310,7 +311,7 @@ func (c *Client) GetWebTuns() ([]backend.WebTun, error) {
}
// GetWebTun retruns the web tunel details by it unique prefix
func (c *Client) GetWebTun(prefix string) (*backend.WebTun, error) {
func (c *Client) GetWebTun(prefix string) (*services.WebTun, error) {
out, err := c.Get(c.Endpoint("tunnels", "web", prefix), url.Values{})
if err != nil {
return nil, err
@@ -382,7 +383,7 @@ func (c *Client) GetWebSession(user string, sid string) (string, error) {
// certificate generated, that is stored for the duration of this web
// session. These keys are used to access SSH servers via web portal.
func (c *Client) GetWebSessionsKeys(
user string) ([]backend.AuthorizedKey, error) {
user string) ([]services.AuthorizedKey, error) {
out, err := c.Get(c.Endpoint("users", user, "web", "sessions"), url.Values{})
if err != nil {
@@ -425,7 +426,7 @@ func (c *Client) DeleteUser(user string) error {
// by user CA in case of success, error otherwise. The certificate will be
// valid for the duration of the ttl passed in.
func (c *Client) UpsertUserKey(username string,
key backend.AuthorizedKey, ttl time.Duration) ([]byte, error) {
key services.AuthorizedKey, ttl time.Duration) ([]byte, error) {
out, err := c.PostForm(c.Endpoint("users", username, "keys"), url.Values{
"key": []string{string(key.Value)},
@@ -445,7 +446,7 @@ func (c *Client) UpsertUserKey(username string,
// GetUserKeys returns a list of keys registered for this user.
// This list does not include the temporary keys associated with user
// web sessions.
func (c *Client) GetUserKeys(user string) ([]backend.AuthorizedKey, error) {
func (c *Client) GetUserKeys(user string) ([]services.AuthorizedKey, error) {
out, err := c.Get(c.Endpoint("users", user, "keys"), url.Values{})
if err != nil {
return nil, err
@@ -625,8 +626,8 @@ type ClientI interface {
DeleteSession(id string) error
UpsertSession(id string, ttl time.Duration) error
UpsertParty(id string, p session.Party, ttl time.Duration) error
UpsertRemoteCert(cert backend.RemoteCert, ttl time.Duration) error
GetRemoteCerts(ctype string, fqdn string) ([]backend.RemoteCert, error)
UpsertRemoteCert(cert services.RemoteCert, ttl time.Duration) error
GetRemoteCerts(ctype string, fqdn string) ([]services.RemoteCert, error)
DeleteRemoteCert(ctype string, fqdn, id string) error
GenerateToken(fqdn string, ttl time.Duration) (string, error)
Log(id lunk.EventID, e lunk.Event)
@@ -634,22 +635,22 @@ type ClientI interface {
GetEvents(filter events.Filter) ([]lunk.Entry, error)
GetChunkWriter(id string) (recorder.ChunkWriteCloser, error)
GetChunkReader(id string) (recorder.ChunkReadCloser, error)
UpsertServer(s backend.Server, ttl time.Duration) error
GetServers() ([]backend.Server, error)
UpsertWebTun(wt backend.WebTun, ttl time.Duration) error
GetWebTuns() ([]backend.WebTun, error)
GetWebTun(prefix string) (*backend.WebTun, error)
UpsertServer(s services.Server, ttl time.Duration) error
GetServers() ([]services.Server, error)
UpsertWebTun(wt services.WebTun, ttl time.Duration) error
GetWebTuns() ([]services.WebTun, error)
GetWebTun(prefix string) (*services.WebTun, error)
DeleteWebTun(prefix string) error
UpsertPassword(user string, password []byte) error
CheckPassword(user string, password []byte) error
SignIn(user string, password []byte) (string, error)
GetWebSession(user string, sid string) (string, error)
GetWebSessionsKeys(user string) ([]backend.AuthorizedKey, error)
GetWebSessionsKeys(user string) ([]services.AuthorizedKey, error)
DeleteWebSession(user string, sid string) error
GetUsers() ([]string, error)
DeleteUser(user string) error
UpsertUserKey(username string, key backend.AuthorizedKey, ttl time.Duration) ([]byte, error)
GetUserKeys(user string) ([]backend.AuthorizedKey, error)
UpsertUserKey(username string, key services.AuthorizedKey, ttl time.Duration) ([]byte, error)
GetUserKeys(user string) ([]services.AuthorizedKey, error)
DeleteUserKey(username string, id string) error
GetHostCAPub() ([]byte, error)
GetUserCAPub() ([]byte, error)
+8 -4
View File
@@ -7,7 +7,9 @@ import (
"path/filepath"
"time"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/sshutils"
"github.com/gravitational/teleport/utils"
@@ -26,10 +28,12 @@ func Init(b backend.Backend, a Authority,
return nil, nil, fmt.Errorf("path can not be empty")
}
if err := b.AcquireLock(authDomain, 60*time.Second); err != nil {
lockService := services.NewLockService(b)
err := lockService.AcquireLock(authDomain, 60*time.Second)
if err != nil {
return nil, nil, err
}
defer b.ReleaseLock(authDomain)
defer lockService.ReleaseLock(authDomain)
scrt, err := InitSecret(dataDir)
if err != nil {
@@ -41,7 +45,7 @@ func Init(b backend.Backend, a Authority,
if _, e := asrv.GetHostCAPub(); e != nil {
log.Infof("Host CA error: %v", e)
if _, ok := e.(*backend.NotFoundError); ok {
if _, ok := e.(*teleport.NotFoundError); ok {
log.Infof("Reseting host CA")
if err := asrv.ResetHostCA(""); err != nil {
return nil, nil, err
@@ -51,7 +55,7 @@ func Init(b backend.Backend, a Authority,
if _, e := asrv.GetUserCAPub(); e != nil {
log.Infof("User CA error: %v", e)
if _, ok := e.(*backend.NotFoundError); ok {
if _, ok := e.(*teleport.NotFoundError); ok {
log.Infof("Reseting host CA")
if err := asrv.ResetUserCA(""); err != nil {
return nil, nil, err
+15 -13
View File
@@ -8,9 +8,11 @@ import (
"strconv"
"time"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/events"
"github.com/gravitational/teleport/recorder"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/session"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/codahale/lunk"
@@ -125,7 +127,7 @@ func (s *APIServer) upsertServer(w http.ResponseWriter, r *http.Request, p httpr
replyErr(w, err)
return
}
if err := s.s.UpsertServer(backend.Server{ID: id, Addr: addr}, ttl); err != nil {
if err := s.s.UpsertServer(services.Server{ID: id, Addr: addr}, ttl); err != nil {
replyErr(w, err)
return
}
@@ -155,7 +157,7 @@ func (s *APIServer) upsertWebTun(w http.ResponseWriter, r *http.Request, p httpr
replyErr(w, err)
return
}
t, err := backend.NewWebTun(prefix, proxyAddr, targetAddr)
t, err := services.NewWebTun(prefix, proxyAddr, targetAddr)
if err != nil {
replyErr(w, err)
return
@@ -292,7 +294,7 @@ func (s *APIServer) upsertUserKey(w http.ResponseWriter, r *http.Request, p http
replyErr(w, err)
return
}
cert, err := s.s.UpsertUserKey(p[0].Value, backend.AuthorizedKey{ID: id, Value: []byte(key)}, ttl)
cert, err := s.s.UpsertUserKey(p[0].Value, services.AuthorizedKey{ID: id, Value: []byte(key)}, ttl)
if err != nil {
replyErr(w, err)
return
@@ -637,10 +639,10 @@ func (s *APIServer) getChunks(w http.ResponseWriter, r *http.Request, p httprout
func replyErr(w http.ResponseWriter, e error) {
switch err := e.(type) {
case *backend.NotFoundError:
case *teleport.NotFoundError:
reply(w, http.StatusNotFound, message(err.Error()))
return
case *backend.MissingParameterError, *BadParameterError, *form.MissingParameterError, *form.BadParameterError:
case *teleport.MissingParameterError, *teleport.BadParameterError, *form.MissingParameterError, *form.BadParameterError:
reply(w, http.StatusBadRequest, message(err.Error()))
return
}
@@ -674,7 +676,7 @@ func (s *APIServer) upsertRemoteCert(w http.ResponseWriter, r *http.Request, p h
replyErr(w, err)
return
}
cert := backend.RemoteCert{ID: id, Value: []byte(key), FQDN: fqdn, Type: ctype}
cert := services.RemoteCert{ID: id, Value: []byte(key), FQDN: fqdn, Type: ctype}
if err := s.s.UpsertRemoteCert(cert, ttl); err != nil {
replyErr(w, err)
return
@@ -781,7 +783,7 @@ type pubKeyResponse struct {
}
type pubKeysResponse struct {
PubKeys []backend.AuthorizedKey `json:"pubkeys"`
PubKeys []services.AuthorizedKey `json:"pubkeys"`
}
type certResponse struct {
@@ -789,11 +791,11 @@ type certResponse struct {
}
type remoteCertResponse struct {
RemoteCert backend.RemoteCert `hson:"remote_cert"`
RemoteCert services.RemoteCert `hson:"remote_cert"`
}
type remoteCertsResponse struct {
RemoteCerts []backend.RemoteCert `hson:"remote_certs"`
RemoteCerts []services.RemoteCert `hson:"remote_certs"`
}
type usersResponse struct {
@@ -810,19 +812,19 @@ type webSessionResponse struct {
}
type webSessionsResponse struct {
Keys []backend.AuthorizedKey `json:"keys"`
Keys []services.AuthorizedKey `json:"keys"`
}
type webTunResponse struct {
Tunnel backend.WebTun `json:"tunnel"`
Tunnel services.WebTun `json:"tunnel"`
}
type webTunsResponse struct {
Tunnels []backend.WebTun `json:"tunnels"`
Tunnels []services.WebTun `json:"tunnels"`
}
type serversResponse struct {
Servers []backend.Server `json:"servers"`
Servers []services.Server `json:"servers"`
}
type tokenResponse struct {
+30 -15
View File
@@ -6,12 +6,13 @@ import (
"testing"
"time"
"github.com/gravitational/teleport"
authority "github.com/gravitational/teleport/auth/native"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/backend/boltbk"
"github.com/gravitational/teleport/events/boltlog"
etest "github.com/gravitational/teleport/events/test"
rtest "github.com/gravitational/teleport/recorder/test"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/recorder"
"github.com/gravitational/teleport/recorder/boltrec"
@@ -34,6 +35,13 @@ type APISuite struct {
rec recorder.Recorder
a *AuthServer
dir string
CAS *services.CAService
LockS *services.LockService
PresenceS *services.PresenceService
ProvisioningS *services.ProvisioningService
UserS *services.UserService
WebS *services.WebService
}
var _ = Suite(&APISuite{})
@@ -65,6 +73,13 @@ func (s *APISuite) SetUpTest(c *C) {
clt, err := NewClient(s.srv.URL)
c.Assert(err, IsNil)
s.clt = clt
s.CAS = services.NewCAService(s.bk)
s.LockS = services.NewLockService(s.bk)
s.PresenceS = services.NewPresenceService(s.bk)
s.ProvisioningS = services.NewProvisioningService(s.bk)
s.UserS = services.NewUserService(s.bk)
s.WebS = services.NewWebService(s.bk)
}
func (s *APISuite) TearDownTest(c *C) {
@@ -76,12 +91,12 @@ func (s *APISuite) TearDownTest(c *C) {
func (s *APISuite) TestHostCACRUD(c *C) {
c.Assert(s.clt.ResetHostCA(), IsNil)
hca, err := s.bk.GetHostCA()
hca, err := s.CAS.GetHostCA()
c.Assert(err, IsNil)
c.Assert(s.clt.ResetHostCA(), IsNil)
hca2, err := s.bk.GetHostCA()
hca2, err := s.CAS.GetHostCA()
c.Assert(err, IsNil)
c.Assert(hca, Not(DeepEquals), hca2)
@@ -94,11 +109,11 @@ func (s *APISuite) TestHostCACRUD(c *C) {
func (s *APISuite) TestUserCACRUD(c *C) {
c.Assert(s.clt.ResetUserCA(), IsNil)
uca, err := s.bk.GetUserCA()
uca, err := s.CAS.GetUserCA()
c.Assert(err, IsNil)
c.Assert(s.clt.ResetUserCA(), IsNil)
uca2, err := s.bk.GetUserCA()
uca2, err := s.CAS.GetUserCA()
c.Assert(err, IsNil)
c.Assert(uca, Not(DeepEquals), uca2)
@@ -168,11 +183,11 @@ func (s *APISuite) TestUserKeyCRUD(c *C) {
_, pub, err := s.clt.GenerateKeyPair("")
c.Assert(err, IsNil)
key := backend.AuthorizedKey{ID: "id", Value: pub}
key := services.AuthorizedKey{ID: "id", Value: pub}
cert, err := s.clt.UpsertUserKey("user1", key, 0)
c.Assert(err, IsNil)
keys, err := s.bk.GetUserKeys("user1")
keys, err := s.UserS.GetUserKeys("user1")
c.Assert(err, IsNil)
c.Assert(string(keys[0].Value), DeepEquals, string(cert))
@@ -180,7 +195,7 @@ func (s *APISuite) TestUserKeyCRUD(c *C) {
c.Assert(err, IsNil)
c.Assert(s.clt.DeleteUserKey("user1", "id"), IsNil)
keys, err = s.bk.GetUserKeys("user1")
keys, err = s.UserS.GetUserKeys("user1")
c.Assert(err, IsNil)
c.Assert(len(keys), Equals, 0)
}
@@ -227,7 +242,7 @@ func (s *APISuite) TestWebTuns(c *C) {
_, err := s.clt.GetWebTun("p1")
c.Assert(err, NotNil)
t := backend.WebTun{
t := services.WebTun{
Prefix: "p1",
TargetAddr: "http://localhost:5000",
ProxyAddr: "node1.gravitational.io",
@@ -240,7 +255,7 @@ func (s *APISuite) TestWebTuns(c *C) {
tuns, err := s.clt.GetWebTuns()
c.Assert(err, IsNil)
c.Assert(tuns, DeepEquals, []backend.WebTun{t})
c.Assert(tuns, DeepEquals, []services.WebTun{t})
c.Assert(s.clt.DeleteWebTun("p1"), IsNil)
@@ -253,10 +268,10 @@ func (s *APISuite) TestServers(c *C) {
c.Assert(err, IsNil)
c.Assert(len(out), Equals, 0)
srv := backend.Server{ID: "id1", Addr: "host:1233"}
srv := services.Server{ID: "id1", Addr: "host:1233"}
c.Assert(s.clt.UpsertServer(srv, 0), IsNil)
srv1 := backend.Server{ID: "id2", Addr: "host:1234"}
srv1 := services.Server{ID: "id2", Addr: "host:1234"}
c.Assert(s.clt.UpsertServer(srv1, 0), IsNil)
out, err = s.clt.GetServers()
@@ -287,11 +302,11 @@ func (s *APISuite) TestTokens(c *C) {
}
func (s *APISuite) TestRemoteCACRUD(c *C) {
key := backend.RemoteCert{
key := services.RemoteCert{
FQDN: "example.com",
ID: "id",
Value: []byte("hello1"),
Type: backend.UserCert,
Type: services.UserCert,
}
err := s.clt.UpsertRemoteCert(key, 0)
c.Assert(err, IsNil)
@@ -304,7 +319,7 @@ func (s *APISuite) TestRemoteCACRUD(c *C) {
c.Assert(err, IsNil)
err = s.clt.DeleteRemoteCert(key.Type, key.FQDN, key.ID)
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
}
func (s *APISuite) TestSharedSessions(c *C) {
+15 -11
View File
@@ -9,11 +9,11 @@ import (
"path/filepath"
authority "github.com/gravitational/teleport/auth/native"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/backend/membk"
"github.com/gravitational/teleport/backend/boltbk"
"github.com/gravitational/teleport/events/boltlog"
"github.com/gravitational/teleport/recorder"
"github.com/gravitational/teleport/recorder/boltrec"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/session"
"github.com/gravitational/teleport/sshutils"
"github.com/gravitational/teleport/utils"
@@ -25,7 +25,7 @@ import (
)
type TunSuite struct {
bk *membk.MemBackend
bk *boltbk.BoltBackend
scrt *secret.Service
srv *httptest.Server
@@ -40,7 +40,6 @@ type TunSuite struct {
var _ = Suite(&TunSuite{})
func (s *TunSuite) SetUpSuite(c *C) {
s.dir = c.MkDir()
key, err := secret.NewKey()
c.Assert(err, IsNil)
@@ -49,11 +48,6 @@ func (s *TunSuite) SetUpSuite(c *C) {
s.scrt = srv
log.Init([]*log.LogConfig{&log.LogConfig{Name: "console"}})
s.bl, err = boltlog.New(filepath.Join(s.dir, "eventsdb"))
c.Assert(err, IsNil)
s.rec, err = boltrec.New(s.dir)
c.Assert(err, IsNil)
}
func (s *TunSuite) TearDownTest(c *C) {
@@ -61,7 +55,17 @@ func (s *TunSuite) TearDownTest(c *C) {
}
func (s *TunSuite) SetUpTest(c *C) {
s.bk = membk.New()
s.dir = c.MkDir()
var err error
s.bk, err = boltbk.New(filepath.Join(s.dir, "db"))
c.Assert(err, IsNil)
s.bl, err = boltlog.New(filepath.Join(s.dir, "eventsdb"))
c.Assert(err, IsNil)
s.rec, err = boltrec.New(s.dir)
c.Assert(err, IsNil)
s.a = NewAuthServer(s.bk, authority.New(), s.scrt)
s.srv = httptest.NewServer(
NewAPIServer(s.a, s.bl, session.New(s.bk), s.rec))
@@ -133,7 +137,7 @@ func (s *TunSuite) TestUnixServerClient(c *C) {
c.Assert(err, IsNil)
err = clt.UpsertServer(
backend.Server{ID: "a.example.com", Addr: "hello"}, 0)
services.Server{ID: "a.example.com", Addr: "hello"}, 0)
c.Assert(err, IsNil)
}
-199
View File
@@ -2,8 +2,6 @@
package backend
import (
"fmt"
"net/url"
"time"
)
@@ -15,201 +13,4 @@ type Backend interface {
GetVal(path []string, key string) ([]byte, error)
DeleteKey(path []string, key string) error
DeleteBucket(path []string, bkt string) error
// Grab a lock that will be released automatically in ttl time
AcquireLock(token string, ttl time.Duration) error
// Grab a lock that will be released automatically in ttl time
ReleaseLock(token string) error
// UpsertUserCA upserts the user certificate authority keys in OpenSSH authorized_keys format
UpsertUserCA(CA) error
// GetUserCAPub returns the user certificate authority public key
GetUserCAPub() ([]byte, error)
// Remote Certificate management
UpsertRemoteCert(RemoteCert, time.Duration) error
GetRemoteCerts(ctype string, fqdn string) ([]RemoteCert, error)
DeleteRemoteCert(ctype string, fqdn, id string) error
// GetCA returns private, public key and certificate for user CA
GetUserCA() (*CA, error)
// UpsertHostCA upserts host certificate authority keys in OpenSSH authorized_keys format
UpsertHostCA(CA) error
// GetHostCA returns private, public key and certificate for host CA
GetHostCA() (*CA, error)
// GetHostCACert returns the host certificate authority certificate
GetHostCAPub() ([]byte, error)
// GetUserKeys returns a list of authorized keys for a given user
// in a OpenSSH key authorized_keys format
GetUserKeys(user string) ([]AuthorizedKey, error)
// GetUsers returns a list of users registered in the backend
GetUsers() ([]string, error)
// DeleteUser deletes a user with all the keys from the backend
DeleteUser(user string) error
// Upsert Public key in OpenSSH authorized Key format
// user is a user name, keyID is a unique IDentifier for the key
// in case if ttl is 0, the key will be upserted permanently, otherwise
// it will expire in ttl seconds
UpsertUserKey(user string, key AuthorizedKey, ttl time.Duration) error
// DeleteUserKey deletes user key by given ID
DeleteUserKey(user, key string) error
// GetServers returns a list of registered servers
GetServers() ([]Server, error)
// UpsertServer registers server presence, permanently if ttl is 0 or
// for the specified duration with second resolution if it's >= 1 second
UpsertServer(s Server, ttl time.Duration) error
// UpsertPasswordHash upserts user password hash
UpsertPasswordHash(user string, hash []byte) error
// GetPasswordHash returns the password hash for a given user
GetPasswordHash(user string) ([]byte, error)
// UpsertSession
UpsertWebSession(user, sid string, s WebSession, ttl time.Duration) error
// GetWebSession
GetWebSession(user, sid string) (*WebSession, error)
// GetWebSessionsKeys
GetWebSessionsKeys(user string) ([]AuthorizedKey, error)
// DeleteWebSession
DeleteWebSession(user, sid string) error
UpsertWebTun(WebTun, time.Duration) error
DeleteWebTun(prefix string) error
GetWebTun(prefix string) (*WebTun, error)
GetWebTuns() ([]WebTun, error)
// Tokens are provisioning tokens for the auth server
UpsertToken(token, fqdn string, ttl time.Duration) error
GetToken(token string) (string, error)
DeleteToken(token string) error
}
// WebTun is a web tunnel, the SSH tunnel
// created by the SSH server to a remote web server
type WebTun struct {
// Prefix is a domain prefix that will be used
// to serve this tunnel
Prefix string `json:"prefix"`
// ProxyAddr is the address of the SSH server
// that will be acting as a SSH proxy
ProxyAddr string `json:"proxy"`
// TargetAddr is the target http address of the server
TargetAddr string `json:"target"`
}
func NewWebTun(prefix, proxyAddr, targetAddr string) (*WebTun, error) {
if prefix == "" {
return nil, &MissingParameterError{Param: "prefix"}
}
if targetAddr == "" {
return nil, &MissingParameterError{Param: "target"}
}
if proxyAddr == "" {
return nil, &MissingParameterError{Param: "proxy"}
}
if _, err := url.ParseRequestURI(targetAddr); err != nil {
return nil, &BadParameterError{Param: "target", Err: err.Error()}
}
return &WebTun{Prefix: prefix, ProxyAddr: proxyAddr, TargetAddr: targetAddr}, nil
}
// WebSession
type WebSession struct {
Pub []byte `json:"pub"`
Priv []byte `json:"priv"`
}
// CA is a set of private and public keys
type CA struct {
Pub []byte `json:"pub"`
Priv []byte `json:"priv"`
}
// Server represents a running Teleport server instance
type Server struct {
ID string `json:"id"`
Addr string `json:"addr"`
}
// AuthorizedKey is a key in form of OpenSSH authorized keys
type AuthorizedKey struct {
ID string `json:"id"`
Value []byte `json:"value"`
}
type NotFoundError struct {
Message string
}
func (n *NotFoundError) Error() string {
if n.Message != "" {
return n.Message
} else {
return "Object not found"
}
}
type AlreadyExistsError struct {
Message string
}
func (n *AlreadyExistsError) Error() string {
if n.Message != "" {
return n.Message
} else {
return "Object already exists"
}
}
type MissingParameterError struct {
Param string
}
func (m *MissingParameterError) Error() string {
return fmt.Sprintf("missing required parameter '%v'", m.Param)
}
type BadParameterError struct {
Param string
Err string
}
func (m *BadParameterError) Error() string {
return fmt.Sprintf("bad parameter '%v', %v", m.Param, m.Err)
}
type RemoteCert struct {
Type string
ID string
FQDN string
Value []byte
}
const (
HostCert = "host"
UserCert = "user"
)
func IsNotFound(e error) bool {
_, ok := e.(*NotFoundError)
return ok
}
+14 -345
View File
@@ -8,7 +8,7 @@ import (
"sync"
"time"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/boltdb/bolt"
)
@@ -31,10 +31,14 @@ func New(path string) (*BoltBackend, error) {
}, nil
}
func (b *BoltBackend) Close() error {
return nil
}
func (b *BoltBackend) GetKeys(path []string) ([]string, error) {
keys, err := b.getKeys(path)
if err != nil {
if isNotFound(err) {
if teleport.IsNotFound(err) {
return []string{}, nil
}
return nil, err
@@ -45,7 +49,7 @@ func (b *BoltBackend) GetKeys(path []string) ([]string, error) {
}
keys, err = b.getKeys(path)
if err != nil {
if isNotFound(err) {
if teleport.IsNotFound(err) {
return []string{}, nil
}
return nil, err
@@ -80,7 +84,7 @@ func (b *BoltBackend) GetVal(path []string, key string) ([]byte, error) {
if err := b.deleteKey(path, key); err != nil {
return nil, err
}
return nil, &backend.NotFoundError{
return nil, &teleport.NotFoundError{
Message: fmt.Sprintf("%v: %v not found", path, key)}
}
return k.Value, nil
@@ -94,336 +98,6 @@ func (b *BoltBackend) DeleteBucket(path []string, bucket string) error {
return b.deleteBucket(path, bucket)
}
func (b *BoltBackend) AcquireLock(token string, ttl time.Duration) error {
b.Lock()
defer b.Unlock()
expires, ok := b.locks[token]
if ok && expires.After(time.Now()) {
return &backend.AlreadyExistsError{
Message: fmt.Sprintf("lock %v already locked", token)}
}
b.locks[token] = time.Now().Add(ttl)
return nil
}
func (b *BoltBackend) ReleaseLock(token string) error {
b.Lock()
defer b.Unlock()
expires, ok := b.locks[token]
if !ok || expires.Before(time.Now()) {
return &backend.NotFoundError{
Message: fmt.Sprintf(
"lock %v is deleted or expired", token),
}
}
delete(b.locks, token)
return nil
}
func (b *BoltBackend) Close() error {
return nil
}
func (b *BoltBackend) UpsertRemoteCert(cert backend.RemoteCert, ttl time.Duration) error {
return b.upsertKey([]string{"certs", cert.Type, "hosts", cert.FQDN}, cert.ID, cert.Value)
}
func (b *BoltBackend) GetRemoteCerts(ctype string, fqdn string) ([]backend.RemoteCert, error) {
out := []backend.RemoteCert{}
err := b.db.View(func(tx *bolt.Tx) error {
hosts := []string{}
if fqdn == "" {
bkt, err := GetBucket(tx, []string{"certs", ctype, "hosts"})
if err != nil {
if isNotFound(err) {
return nil
}
return err
}
c := bkt.Cursor()
for k, _ := c.First(); k != nil; k, _ = c.Next() {
hosts = append(hosts, string(k))
}
} else {
hosts = []string{fqdn}
}
for _, h := range hosts {
bkt, err := GetBucket(tx, []string{"certs", ctype, "hosts", h})
if err != nil {
return err
}
c := bkt.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
out = append(out, backend.RemoteCert{
Type: ctype,
FQDN: h,
ID: string(k),
Value: v,
})
}
}
return nil
})
if err != nil {
return nil, err
}
return out, nil
}
func (b *BoltBackend) DeleteRemoteCert(ctype string, fqdn, id string) error {
return b.deleteKey([]string{"certs", ctype, "hosts", fqdn}, id)
}
// GetUsers returns a list of users registered in the backend
func (b *BoltBackend) GetUsers() ([]string, error) {
out := []string{}
err := b.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("users"))
if b == nil {
return nil
}
c := b.Cursor()
for k, _ := c.First(); k != nil; k, _ = c.Next() {
out = append(out, string(k))
}
return nil
})
if err != nil {
return nil, err
}
return out, nil
}
// DeleteUser deletes a user with all the keys from the backend
func (b *BoltBackend) DeleteUser(user string) error {
return b.deleteBucket([]string{"users"}, user)
}
func (b *BoltBackend) UpsertUserCA(a backend.CA) error {
return b.upsertJSONKey([]string{"userca"}, "val", a)
}
func (b *BoltBackend) GetUserCA() (*backend.CA, error) {
var ca *backend.CA
return ca, b.getJSONKey([]string{"userca"}, "val", &ca)
}
func (b *BoltBackend) GetUserCAPub() ([]byte, error) {
ca, err := b.GetUserCA()
if err != nil {
return nil, err
}
return ca.Pub, nil
}
func (b *BoltBackend) UpsertHostCA(a backend.CA) error {
return b.upsertJSONKey([]string{"hostca"}, "val", a)
}
func (b *BoltBackend) GetHostCA() (*backend.CA, error) {
var ca *backend.CA
return ca, b.getJSONKey([]string{"hostca"}, "val", &ca)
}
func (b *BoltBackend) GetHostCAPub() ([]byte, error) {
ca, err := b.GetHostCA()
if err != nil {
return nil, err
}
return ca.Pub, nil
}
func (b *BoltBackend) GetUserKeys(user string) ([]backend.AuthorizedKey, error) {
if user == "" {
return nil, &backend.MissingParameterError{Param: "user"}
}
values := []backend.AuthorizedKey{}
err := b.db.View(func(tx *bolt.Tx) error {
bkt, err := GetBucket(tx, []string{"users", user, "keys"})
if err != nil {
if _, ok := err.(*backend.NotFoundError); ok {
return nil
}
return err
}
c := bkt.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
var key *backend.AuthorizedKey
if err := json.Unmarshal(v, &key); err != nil {
return err
}
values = append(values, *key)
}
return nil
})
if err != nil {
return nil, err
}
return values, nil
}
func (b *BoltBackend) UpsertToken(token, fqdn string, ttl time.Duration) error {
return b.upsertKey([]string{"tokens"}, token, []byte(fqdn))
}
func (b *BoltBackend) GetToken(token string) (string, error) {
var fqdn []byte
if err := b.getKey([]string{"tokens"}, token, &fqdn); err != nil {
return "", err
}
return string(fqdn), nil
}
func (b *BoltBackend) DeleteToken(token string) error {
return b.deleteKey([]string{"tokens"}, token)
}
func (b *BoltBackend) UpsertUserKey(user string, key backend.AuthorizedKey, ttl time.Duration) error {
if user == "" {
return &backend.MissingParameterError{Param: "user"}
}
if key.ID == "" {
return &backend.MissingParameterError{Param: "key.id"}
}
if len(key.Value) == 0 {
return &backend.MissingParameterError{Param: "key.val"}
}
return b.upsertJSONKey([]string{"users", user, "keys"}, key.ID, key)
}
func (b *BoltBackend) DeleteUserKey(user, keyID string) error {
if user == "" {
return &backend.MissingParameterError{Param: "user"}
}
if keyID == "" {
return &backend.MissingParameterError{Param: "key.id"}
}
return b.deleteKey([]string{"users", user, "keys"}, keyID)
}
func (b *BoltBackend) UpsertServer(s backend.Server, ttl time.Duration) error {
return b.upsertJSONKey([]string{"servers"}, s.ID, s)
}
func (b *BoltBackend) GetServers() ([]backend.Server, error) {
values := []backend.Server{}
err := b.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("servers"))
if b == nil {
return nil
}
c := b.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
var key *backend.Server
if err := json.Unmarshal(v, &key); err != nil {
return err
}
values = append(values, *key)
}
return nil
})
if err != nil {
return nil, err
}
return values, nil
}
func (b *BoltBackend) UpsertPasswordHash(user string, hash []byte) error {
return b.upsertKey([]string{"users", user}, "password-hash", hash)
}
func (b *BoltBackend) GetPasswordHash(user string) ([]byte, error) {
var hash []byte
err := b.getKey([]string{"users", user}, "password-hash", &hash)
if err != nil {
return nil, err
}
return hash, nil
}
func (b *BoltBackend) UpsertWebSession(user, sid string, s backend.WebSession, ttl time.Duration) error {
return b.upsertJSONKey([]string{"users", user, "web-sessions"}, sid, s)
}
func (b *BoltBackend) GetWebSession(user, sid string) (*backend.WebSession, error) {
var ws *backend.WebSession
return ws, b.getJSONKey([]string{"users", user, "web-sessions"}, sid, &ws)
}
func (b *BoltBackend) GetWebSessionsKeys(user string) ([]backend.AuthorizedKey, error) {
values := []backend.AuthorizedKey{}
err := b.db.View(func(tx *bolt.Tx) error {
bkt, err := GetBucket(tx, []string{"users", user, "web-sessions"})
if err != nil {
if _, ok := err.(*backend.NotFoundError); ok {
return nil
}
return err
}
c := bkt.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
var ws *backend.WebSession
if err := json.Unmarshal(v, &ws); err != nil {
return err
}
values = append(values, backend.AuthorizedKey{
ID: string(k),
Value: ws.Pub,
})
}
return nil
})
if err != nil {
return nil, err
}
return values, nil
}
func (b *BoltBackend) DeleteWebSession(user, sid string) error {
return b.deleteKey([]string{"users", user, "web-sessions"}, sid)
}
func (b *BoltBackend) UpsertWebTun(t backend.WebTun, ttl time.Duration) error {
if t.Prefix == "" {
return &backend.MissingParameterError{Param: "Prefix"}
}
return b.upsertJSONKey([]string{"web-tuns"}, t.Prefix, t)
}
func (b *BoltBackend) GetWebTun(prefix string) (*backend.WebTun, error) {
var wt *backend.WebTun
return wt, b.getJSONKey([]string{"web-tuns"}, prefix, &wt)
}
func (b *BoltBackend) DeleteWebTun(prefix string) error {
return b.deleteKey([]string{"web-tuns"}, prefix)
}
func (b *BoltBackend) GetWebTuns() ([]backend.WebTun, error) {
out := []backend.WebTun{}
err := b.db.View(func(tx *bolt.Tx) error {
bkt, err := GetBucket(tx, []string{"web-tuns"})
if err != nil {
return err
}
c := bkt.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
var wt *backend.WebTun
if err := json.Unmarshal(v, &wt); err != nil {
return err
}
out = append(out, *wt)
}
return nil
})
if err != nil {
return nil, err
}
return out, nil
}
func (b *BoltBackend) deleteBucket(buckets []string, bucket string) error {
return b.db.Update(func(tx *bolt.Tx) error {
bkt, err := GetBucket(tx, buckets)
@@ -431,7 +105,7 @@ func (b *BoltBackend) deleteBucket(buckets []string, bucket string) error {
return err
}
if bkt.Bucket([]byte(bucket)) == nil {
return &backend.NotFoundError{
return &teleport.NotFoundError{
fmt.Sprintf("%v not found", bucket)}
}
return bkt.DeleteBucket([]byte(bucket))
@@ -445,7 +119,7 @@ func (b *BoltBackend) deleteKey(buckets []string, key string) error {
return err
}
if bkt.Get([]byte(key)) == nil {
return &backend.NotFoundError{}
return &teleport.NotFoundError{}
}
return bkt.Delete([]byte(key))
})
@@ -483,7 +157,7 @@ func (b *BoltBackend) getJSONKey(buckets []string, key string, val interface{})
}
bytes := bkt.Get([]byte(key))
if bytes == nil {
return &backend.NotFoundError{
return &teleport.NotFoundError{
Message: fmt.Sprintf("%v %v not found", buckets, key),
}
}
@@ -499,7 +173,7 @@ func (b *BoltBackend) getKey(buckets []string, key string, val *[]byte) error {
}
bytes := bkt.Get([]byte(key))
if bytes == nil {
return &backend.NotFoundError{
return &teleport.NotFoundError{
Message: fmt.Sprintf("%v %v not found", buckets, key),
}
}
@@ -545,24 +219,19 @@ func UpsertBucket(b *bolt.Tx, buckets []string) (*bolt.Bucket, error) {
func GetBucket(b *bolt.Tx, buckets []string) (*bolt.Bucket, error) {
bkt := b.Bucket([]byte(buckets[0]))
if bkt == nil {
return nil, &backend.NotFoundError{
return nil, &teleport.NotFoundError{
Message: fmt.Sprintf("bucket %v not found", buckets[0])}
}
for _, key := range buckets[1:] {
bkt = bkt.Bucket([]byte(key))
if bkt == nil {
return nil, &backend.NotFoundError{
return nil, &teleport.NotFoundError{
Message: fmt.Sprintf("bucket %v not found", key)}
}
}
return bkt, nil
}
func isNotFound(err error) bool {
_, ok := err.(*backend.NotFoundError)
return ok
}
type kv struct {
Created time.Time `json:"created"`
TTL time.Duration `json:"ttl"`
-44
View File
@@ -34,50 +34,6 @@ func (s *BoltSuite) TearDownTest(c *C) {
c.Assert(s.bk.Close(), IsNil)
}
func (s *BoltSuite) TestUserKeyCRUD(c *C) {
s.suite.UserKeyCRUD(c)
}
func (s *BoltSuite) TestUserCACRUD(c *C) {
s.suite.UserCACRUD(c)
}
func (s *BoltSuite) TestHostCACRUD(c *C) {
s.suite.HostCACRUD(c)
}
func (s *BoltSuite) TestServerCRUD(c *C) {
s.suite.ServerCRUD(c)
}
func (s *BoltSuite) TestUsersCRUD(c *C) {
s.suite.UsersCRUD(c)
}
func (s *BoltSuite) TestPasswordHashCRUD(c *C) {
s.suite.PasswordHashCRUD(c)
}
func (s *BoltSuite) TestWebSessionCRUD(c *C) {
s.suite.WebSessionCRUD(c)
}
func (s *BoltSuite) TestWebTunCRUD(c *C) {
s.suite.WebTunCRUD(c)
}
func (s *BoltSuite) TestLocking(c *C) {
s.suite.Locking(c)
}
func (s *BoltSuite) TestToken(c *C) {
s.suite.TokenCRUD(c)
}
func (s *BoltSuite) TestRemoteCert(c *C) {
s.suite.RemoteCertCRUD(c)
}
func (s *BoltSuite) TestBasicCRUD(c *C) {
s.suite.BasicCRUD(c)
}
+3 -352
View File
@@ -2,12 +2,12 @@
package etcdbk
import (
"encoding/json"
"fmt"
"sort"
"strings"
"time"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd"
"github.com/gravitational/teleport/backend"
)
@@ -104,54 +104,6 @@ func (b *bk) DeleteBucket(path []string, key string) error {
return convertErr(err)
}
func (b *bk) AcquireLock(token string, ttl time.Duration) error {
_, err := b.client.Create(
b.key("locks", token), "lock", uint64(ttl/time.Second))
return convertErr(err)
}
func (b *bk) ReleaseLock(token string) error {
_, err := b.client.Delete(b.key("locks", token), false)
return convertErr(err)
}
func (b *bk) UpsertUserCA(a backend.CA) error {
return b.upsertCA(UserCA, a)
}
func (b *bk) GetUserCA() (*backend.CA, error) {
return b.getCA(UserCA)
}
func (b *bk) GetUserCAPub() ([]byte, error) {
ca, err := b.GetUserCA()
if err != nil {
return nil, err
}
return ca.Pub, nil
}
func (b *bk) UpsertHostCA(a backend.CA) error {
return b.upsertCA(HostCA, a)
}
func (b *bk) GetHostCA() (*backend.CA, error) {
return b.getCA(HostCA)
}
func (b *bk) GetHostCAPub() ([]byte, error) {
ca, err := b.GetHostCA()
if err != nil {
return nil, err
}
return ca.Pub, nil
}
func (b *bk) UpsertRemoteCert(cert backend.RemoteCert, ttl time.Duration) error {
_, err := b.client.Set(b.key("certs", cert.Type, "hosts", cert.FQDN, cert.ID), string(cert.Value), uint64(ttl/time.Second))
return convertErr(err)
}
func (b *bk) getKeys(key string) ([]string, error) {
vals := []string{}
re, err := b.client.Get(key, true, false)
@@ -170,302 +122,6 @@ func (b *bk) getKeys(key string) ([]string, error) {
return vals, nil
}
func (b *bk) GetRemoteCerts(ctype, fqdn string) ([]backend.RemoteCert, error) {
certs := []backend.RemoteCert{}
if ctype == "" {
return nil, fmt.Errorf("provide certificate type")
}
var hosts []string
var err error
if fqdn != "" {
hosts = []string{fqdn}
} else {
if hosts, err = b.getKeys(b.key("certs", ctype, "hosts")); err != nil {
return nil, err
}
}
// for each host, get a list of ids
hs := make(map[string][]string)
for _, h := range hosts {
vals, err := b.getKeys(b.key("certs", ctype, "hosts", h))
if err != nil {
return nil, err
}
hs[h] = vals
}
// now, for each id retrieve it's value
for h, ids := range hs {
for _, id := range ids {
re, err := b.client.Get(b.key("certs", ctype, "hosts", h), true, true)
if err != nil {
return nil, convertErr(err)
}
cert := backend.RemoteCert{
Value: []byte(re.Node.Nodes[0].Value),
Type: ctype,
FQDN: h,
ID: id,
}
certs = append(certs, cert)
}
}
return certs, nil
}
func (b *bk) DeleteRemoteCert(ctype, fqdn, id string) error {
_, err := b.client.Delete(b.key("certs", ctype, "hosts", fqdn, id), true)
return convertErr(err)
}
// GetUsers returns a list of users registered in the backend
func (b *bk) GetUsers() ([]string, error) {
values := []string{}
re, err := b.client.Get(b.key("users"), true, false)
if err != nil {
if notFound(err) {
return values, nil
}
return nil, convertErr(err)
}
if !isDir(re.Node) {
return values, nil
}
for _, sn := range re.Node.Nodes {
values = append(values, suffix(sn.Key))
}
return values, nil
}
// DeleteUser deletes a user with all the keys from the backend
func (b *bk) DeleteUser(user string) error {
_, err := b.client.Delete(b.key("users", user), true)
return convertErr(err)
}
func (b *bk) GetUserKeys(user string) ([]backend.AuthorizedKey, error) {
values := []backend.AuthorizedKey{}
re, err := b.client.Get(b.key("users", user, "keys"), true, true)
if err != nil {
if notFound(err) {
return values, nil
}
return nil, convertErr(err)
}
if !isDir(re.Node) {
return values, nil
}
for _, sn := range re.Node.Nodes {
if !isDir(sn) {
values = append(values, backend.AuthorizedKey{ID: suffix(sn.Key), Value: []byte(sn.Value)})
}
}
return values, nil
}
func (b *bk) UpsertUserKey(user string, key backend.AuthorizedKey, ttl time.Duration) error {
_, err := b.client.Set(b.key("users", user, "keys", key.ID), string(key.Value), uint64(ttl/time.Second))
return convertErr(err)
}
func (b *bk) DeleteUserKey(user, keyID string) error {
_, err := b.client.Delete(b.key("users", user, "keys", keyID), true)
return convertErr(err)
}
func (b *bk) GetServers() ([]backend.Server, error) {
values := []backend.Server{}
re, err := b.client.Get(b.key("servers"), true, true)
if err != nil {
if notFound(err) {
return values, nil
}
return nil, convertErr(err)
}
if !isDir(re.Node) {
return values, nil
}
for _, sn := range re.Node.Nodes {
if !isDir(sn) {
values = append(values, backend.Server{ID: suffix(sn.Key), Addr: sn.Value})
}
}
return values, nil
}
func (b *bk) UpsertServer(s backend.Server, ttl time.Duration) error {
_, err := b.client.Set(b.key("servers", s.ID), string(s.Addr), uint64(ttl/time.Second))
return convertErr(err)
}
func (b *bk) UpsertPasswordHash(user string, hash []byte) error {
bytes, err := json.Marshal(hash)
if err != nil {
return err
}
_, err = b.client.Set(b.key("users", user, "web", "pwd"), string(bytes), 0)
return convertErr(err)
}
func (b *bk) GetPasswordHash(user string) ([]byte, error) {
re, err := b.client.Get(b.key("users", user, "web", "pwd"), false, false)
if err != nil {
return nil, convertErr(err)
}
var hash []byte
if err := json.Unmarshal([]byte(re.Node.Value), &hash); err != nil {
return nil, err
}
return hash, nil
}
func (b *bk) UpsertWebSession(user, sid string, s backend.WebSession, ttl time.Duration) error {
bytes, err := json.Marshal(s)
if err != nil {
return err
}
_, err = b.client.Set(b.key("users", user, "web", "sessions", sid), string(bytes), uint64(ttl/time.Second))
return convertErr(err)
}
func (b *bk) GetWebSession(user, sid string) (*backend.WebSession, error) {
re, err := b.client.Get(b.key("users", user, "web", "sessions", sid), false, false)
if err != nil {
return nil, convertErr(err)
}
var sess *backend.WebSession
if err := json.Unmarshal([]byte(re.Node.Value), &sess); err != nil {
return nil, err
}
return sess, nil
}
func (b *bk) GetWebSessionsKeys(user string) ([]backend.AuthorizedKey, error) {
values := []backend.AuthorizedKey{}
re, err := b.client.Get(b.key("users", user, "web", "sessions"), true, true)
if err != nil {
if notFound(err) {
return values, nil
}
return nil, convertErr(err)
}
if !isDir(re.Node) {
return values, nil
}
for _, sn := range re.Node.Nodes {
if isDir(sn) {
continue
}
var sess *backend.WebSession
if err := json.Unmarshal([]byte(sn.Value), &sess); err != nil {
return nil, err
}
values = append(values, backend.AuthorizedKey{Value: sess.Pub})
}
return values, nil
}
func (b *bk) DeleteWebSession(user, sid string) error {
_, err := b.client.Delete(b.key("users", user, "web", "sessions", sid), true)
return convertErr(err)
}
func (b *bk) UpsertWebTun(t backend.WebTun, ttl time.Duration) error {
if t.Prefix == "" {
return &backend.MissingParameterError{Param: "Prefix"}
}
bytes, err := json.Marshal(t)
if err != nil {
return err
}
_, err = b.client.Set(b.key("tunnels", "web", t.Prefix), string(bytes), uint64(ttl/time.Second))
return err
}
func (b *bk) DeleteWebTun(prefix string) error {
_, err := b.client.Delete(b.key("tunnels", "web", prefix), true)
return convertErr(err)
}
func (b *bk) GetWebTun(prefix string) (*backend.WebTun, error) {
re, err := b.client.Get(b.key("tunnels", "web", prefix), false, false)
if err != nil {
return nil, convertErr(err)
}
var tun *backend.WebTun
if err := json.Unmarshal([]byte(re.Node.Value), &tun); err != nil {
return nil, err
}
return tun, nil
}
func (b *bk) GetWebTuns() ([]backend.WebTun, error) {
values := []backend.WebTun{}
re, err := b.client.Get(b.key("tunnels", "web"), true, true)
if err != nil {
if notFound(err) {
return values, nil
}
return nil, convertErr(err)
}
if !isDir(re.Node) {
return values, nil
}
for _, sn := range re.Node.Nodes {
if isDir(sn) {
continue
}
var tun *backend.WebTun
if err := json.Unmarshal([]byte(sn.Value), &tun); err != nil {
return nil, err
}
tun.Prefix = suffix(sn.Key)
values = append(values, *tun)
}
return values, nil
}
func (b *bk) UpsertToken(token, fqdn string, ttl time.Duration) error {
_, err := b.client.Set(
b.key("tokens", token), fqdn, uint64(ttl/time.Second))
return convertErr(err)
}
func (b *bk) GetToken(token string) (string, error) {
re, err := b.client.Get(b.key("tokens", token), false, false)
if err != nil {
return "", convertErr(err)
}
return re.Node.Value, nil
}
func (b *bk) DeleteToken(token string) error {
_, err := b.client.Delete(b.key("tokens", token), false)
return convertErr(err)
}
func (b *bk) upsertCA(id string, a backend.CA) error {
out, err := json.Marshal(a)
if err != nil {
return err
}
_, err = b.client.Set(b.key("auth", id, "key"), string(out), 0)
return convertErr(err)
}
func (b *bk) getCA(id string) (*backend.CA, error) {
re, err := b.client.Get(b.key("auth", id, "key"), false, false)
if err != nil {
return nil, convertErr(err)
}
var ca *backend.CA
if err := json.Unmarshal([]byte(re.Node.Value), &ca); err != nil {
return nil, err
}
return ca, nil
}
func notFound(e error) bool {
err, ok := e.(*etcd.EtcdError)
return ok && err.ErrorCode == 100
@@ -479,9 +135,9 @@ func convertErr(e error) error {
case *etcd.EtcdError:
switch err.ErrorCode {
case 100:
return &backend.NotFoundError{Message: err.Error()}
return &teleport.NotFoundError{Message: err.Error()}
case 105:
return &backend.AlreadyExistsError{Message: err.Error()}
return &teleport.AlreadyExistsError{Message: err.Error()}
}
}
return e
@@ -495,8 +151,3 @@ func suffix(key string) string {
vals := strings.Split(key, "/")
return vals[len(vals)-1]
}
const (
HostCA = "host"
UserCA = "user"
)
-44
View File
@@ -78,50 +78,6 @@ func (s *EtcdSuite) TestFromString(c *C) {
c.Assert(b, NotNil)
}
func (s *EtcdSuite) TestUserKeyCRUD(c *C) {
s.suite.UserKeyCRUD(c)
}
func (s *EtcdSuite) TestUserCACRUD(c *C) {
s.suite.UserCACRUD(c)
}
func (s *EtcdSuite) TestHostCACRUD(c *C) {
s.suite.HostCACRUD(c)
}
func (s *EtcdSuite) TestServerCRUD(c *C) {
s.suite.ServerCRUD(c)
}
func (s *EtcdSuite) TestUsersCRUD(c *C) {
s.suite.UsersCRUD(c)
}
func (s *EtcdSuite) TestPasswordHashCRUD(c *C) {
s.suite.PasswordHashCRUD(c)
}
func (s *EtcdSuite) TestWebSessionCRUD(c *C) {
s.suite.WebSessionCRUD(c)
}
func (s *EtcdSuite) TestWebTunCRUD(c *C) {
s.suite.WebTunCRUD(c)
}
func (s *EtcdSuite) TestLocking(c *C) {
s.suite.Locking(c)
}
func (s *EtcdSuite) TestToken(c *C) {
s.suite.TokenCRUD(c)
}
func (s *EtcdSuite) TestRemoteCert(c *C) {
s.suite.RemoteCertCRUD(c)
}
func (s *EtcdSuite) TestBasicCRUD(c *C) {
s.suite.BasicCRUD(c)
}
-372
View File
@@ -1,372 +0,0 @@
// package membk implements in-memory backend used for tests purposes
package membk
import (
"fmt"
"sync"
"time"
"github.com/gravitational/teleport/backend"
)
type MemBackend struct {
sync.Mutex
HostCA *backend.CA
UserCA *backend.CA
Users map[string]*User
Servers map[string]backend.Server
WebTuns map[string]backend.WebTun
Tokens map[string]string
Locks map[string]time.Time
RemoteCerts []backend.RemoteCert
}
type User struct {
Keys map[string]backend.AuthorizedKey
Sessions map[string]backend.WebSession
Hash []byte
}
func New() *MemBackend {
return &MemBackend{
Users: make(map[string]*User),
Servers: make(map[string]backend.Server),
WebTuns: make(map[string]backend.WebTun),
Locks: make(map[string]time.Time),
Tokens: make(map[string]string),
}
}
func (b *MemBackend) GetKeys(path []string) ([]string, error) {
return nil, nil
}
func (b *MemBackend) UpsertVal(path []string, key string, val []byte, ttl time.Duration) error {
return nil
}
func (b *MemBackend) GetVal(path []string, key string) ([]byte, error) {
return nil, nil
}
func (b *MemBackend) DeleteKey(path []string, key string) error {
return nil
}
func (b *MemBackend) DeleteBucket(path []string, key string) error {
return nil
}
func (b *MemBackend) AcquireLock(token string, ttl time.Duration) error {
b.Lock()
defer b.Unlock()
expires, ok := b.Locks[token]
if ok && expires.After(time.Now()) {
return &backend.AlreadyExistsError{
Message: fmt.Sprintf("lock %v already locked", token)}
}
b.Locks[token] = time.Now().Add(ttl)
return nil
}
func (b *MemBackend) ReleaseLock(token string) error {
b.Lock()
defer b.Unlock()
expires, ok := b.Locks[token]
if !ok || expires.Before(time.Now()) {
return &backend.NotFoundError{
Message: fmt.Sprintf(
"lock %v is deleted or expired", token),
}
}
delete(b.Locks, token)
return nil
}
func (b *MemBackend) Close() error {
return nil
}
// Remote Certificate management
func (b *MemBackend) UpsertRemoteCert(crt backend.RemoteCert, ttl time.Duration) error {
for i, c := range b.RemoteCerts {
if c.ID == crt.ID && c.FQDN == crt.FQDN && c.Type == crt.Type {
b.RemoteCerts[i] = crt
return nil
}
}
b.RemoteCerts = append(b.RemoteCerts, crt)
return nil
}
func (b *MemBackend) GetRemoteCerts(ctype string, fqdn string) ([]backend.RemoteCert, error) {
out := []backend.RemoteCert{}
for _, c := range b.RemoteCerts {
if c.Type != ctype {
continue
}
if fqdn != "" && fqdn != c.FQDN {
continue
}
out = append(out, c)
}
return out, nil
}
func (b *MemBackend) DeleteRemoteCert(ctype string, fqdn, id string) error {
for i, c := range b.RemoteCerts {
if c.ID == id && c.FQDN == fqdn && c.Type == ctype {
b.RemoteCerts = append(b.RemoteCerts[:i], b.RemoteCerts[i+1:]...)
return nil
}
}
return &backend.NotFoundError{}
}
// GetUsers returns a list of users registered in the backend
func (b *MemBackend) GetUsers() ([]string, error) {
out := []string{}
for k := range b.Users {
out = append(out, k)
}
return out, nil
}
// DeleteUser deletes a user with all the keys from the backend
func (b *MemBackend) DeleteUser(user string) error {
_, ok := b.Users[user]
if !ok {
return &backend.NotFoundError{}
}
delete(b.Users, user)
return nil
}
func (b *MemBackend) UpsertUserCA(a backend.CA) error {
b.UserCA = &a
return nil
}
func (b *MemBackend) GetUserCA() (*backend.CA, error) {
if b.UserCA == nil {
return nil, &backend.NotFoundError{}
}
return b.UserCA, nil
}
func (b *MemBackend) GetUserCAPub() ([]byte, error) {
ca, err := b.GetUserCA()
if err != nil {
return nil, err
}
return ca.Pub, nil
}
func (b *MemBackend) UpsertHostCA(a backend.CA) error {
b.HostCA = &a
return nil
}
func (b *MemBackend) GetHostCA() (*backend.CA, error) {
if b.HostCA == nil {
return nil, &backend.NotFoundError{}
}
return b.HostCA, nil
}
func (b *MemBackend) GetHostCAPub() ([]byte, error) {
ca, err := b.GetHostCA()
if err != nil {
return nil, err
}
return ca.Pub, nil
}
func (b *MemBackend) GetUserKeys(user string) ([]backend.AuthorizedKey, error) {
if user == "" {
return nil, &backend.MissingParameterError{Param: "user"}
}
values := []backend.AuthorizedKey{}
u, ok := b.Users[user]
if !ok || len(u.Keys) == 0 {
return values, nil
}
for _, k := range u.Keys {
values = append(values, k)
}
return values, nil
}
func (b *MemBackend) UpsertToken(token, fqdn string, ttl time.Duration) error {
b.Tokens[token] = fqdn
return nil
}
func (b *MemBackend) GetToken(token string) (string, error) {
fqdn, ok := b.Tokens[token]
if !ok {
return "", &backend.NotFoundError{}
}
return fqdn, nil
}
func (b *MemBackend) DeleteToken(token string) error {
if _, ok := b.Tokens[token]; !ok {
return &backend.NotFoundError{}
}
delete(b.Tokens, token)
return nil
}
func (b *MemBackend) getUser(user string) *User {
u, ok := b.Users[user]
if ok {
return u
}
u = &User{
Keys: make(map[string]backend.AuthorizedKey),
Sessions: make(map[string]backend.WebSession),
}
b.Users[user] = u
return u
}
func (b *MemBackend) UpsertUserKey(user string, key backend.AuthorizedKey, ttl time.Duration) error {
if user == "" {
return &backend.MissingParameterError{Param: "user"}
}
if key.ID == "" {
return &backend.MissingParameterError{Param: "key.id"}
}
if len(key.Value) == 0 {
return &backend.MissingParameterError{Param: "key.val"}
}
b.getUser(user).Keys[key.ID] = key
return nil
}
func (b *MemBackend) DeleteUserKey(user, keyID string) error {
if user == "" {
return &backend.MissingParameterError{Param: "user"}
}
if keyID == "" {
return &backend.MissingParameterError{Param: "key.id"}
}
u, ok := b.Users[user]
if !ok {
return &backend.NotFoundError{}
}
if _, ok := u.Keys[keyID]; !ok {
return &backend.NotFoundError{}
}
delete(u.Keys, keyID)
return nil
}
func (b *MemBackend) UpsertServer(s backend.Server, ttl time.Duration) error {
b.Servers[s.ID] = s
return nil
}
func (b *MemBackend) GetServers() ([]backend.Server, error) {
values := []backend.Server{}
for _, s := range b.Servers {
values = append(values, s)
}
return values, nil
}
func (b *MemBackend) UpsertPasswordHash(user string, hash []byte) error {
b.getUser(user).Hash = hash
return nil
}
func (b *MemBackend) GetPasswordHash(user string) ([]byte, error) {
u, ok := b.Users[user]
if !ok {
return nil, &backend.NotFoundError{Message: fmt.Sprintf("user '%v' not found", user)}
}
return u.Hash, nil
}
func (b *MemBackend) UpsertWebSession(user, sid string, s backend.WebSession, ttl time.Duration) error {
b.getUser(user).Sessions[sid] = s
return nil
}
func (b *MemBackend) GetWebSession(user, sid string) (*backend.WebSession, error) {
u, ok := b.Users[user]
if !ok {
return nil, &backend.NotFoundError{Message: fmt.Sprintf("user '%v' not found", user)}
}
ws, ok := u.Sessions[sid]
if !ok {
return nil, &backend.NotFoundError{Message: fmt.Sprintf("session '%v' not found for user '%v'", sid, user)}
}
return &ws, nil
}
func (b *MemBackend) GetWebSessionsKeys(user string) ([]backend.AuthorizedKey, error) {
u, ok := b.Users[user]
if !ok {
return nil, &backend.NotFoundError{Message: fmt.Sprintf("user '%v' not found", user)}
}
out := []backend.AuthorizedKey{}
if len(u.Sessions) == 0 {
return out, nil
}
for _, ws := range u.Sessions {
out = append(out, backend.AuthorizedKey{Value: ws.Pub})
}
return out, nil
}
func (b *MemBackend) DeleteWebSession(user, sid string) error {
u, ok := b.Users[user]
if !ok {
return &backend.NotFoundError{Message: fmt.Sprintf("user '%v' not found", user)}
}
if _, ok := u.Sessions[sid]; !ok {
return &backend.NotFoundError{Message: fmt.Sprintf("session '%v' not found for user '%v'", user, sid)}
}
delete(u.Sessions, sid)
return nil
}
func (b *MemBackend) UpsertWebTun(t backend.WebTun, ttl time.Duration) error {
if t.Prefix == "" {
return &backend.MissingParameterError{Param: "Prefix"}
}
b.WebTuns[t.Prefix] = t
return nil
}
func (b *MemBackend) GetWebTun(prefix string) (*backend.WebTun, error) {
t, ok := b.WebTuns[prefix]
if !ok {
return nil, &backend.NotFoundError{Message: fmt.Sprintf("web tunnel '%v' not found", prefix)}
}
return &t, nil
}
func (b *MemBackend) DeleteWebTun(prefix string) error {
_, ok := b.WebTuns[prefix]
if !ok {
return &backend.NotFoundError{Message: fmt.Sprintf("web tunnel '%v' not found", prefix)}
}
delete(b.WebTuns, prefix)
return nil
}
func (b *MemBackend) GetWebTuns() ([]backend.WebTun, error) {
out := []backend.WebTun{}
for _, t := range b.WebTuns {
out = append(out, t)
}
return out, nil
}
-74
View File
@@ -1,74 +0,0 @@
package membk
import (
"testing"
"github.com/gravitational/teleport/backend/test"
. "github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/check.v1"
)
func TestMem(t *testing.T) { TestingT(t) }
type MemSuite struct {
bk *MemBackend
suite test.BackendSuite
}
var _ = Suite(&MemSuite{})
func (s *MemSuite) SetUpTest(c *C) {
// Initiate a backend with a registry
s.bk = New()
s.suite.ChangesC = make(chan interface{})
s.suite.B = s.bk
}
func (s *MemSuite) TearDownTest(c *C) {
c.Assert(s.bk.Close(), IsNil)
}
func (s *MemSuite) TestUserKeyCRUD(c *C) {
s.suite.UserKeyCRUD(c)
}
func (s *MemSuite) TestUserCACRUD(c *C) {
s.suite.UserCACRUD(c)
}
func (s *MemSuite) TestHostCACRUD(c *C) {
s.suite.HostCACRUD(c)
}
func (s *MemSuite) TestServerCRUD(c *C) {
s.suite.ServerCRUD(c)
}
func (s *MemSuite) TestUsersCRUD(c *C) {
s.suite.UsersCRUD(c)
}
func (s *MemSuite) TestPasswordHashCRUD(c *C) {
s.suite.PasswordHashCRUD(c)
}
func (s *MemSuite) TestWebSessionCRUD(c *C) {
s.suite.WebSessionCRUD(c)
}
func (s *MemSuite) TestWebTunCRUD(c *C) {
s.suite.WebTunCRUD(c)
}
func (s *MemSuite) TestLocking(c *C) {
s.suite.Locking(c)
}
func (s *MemSuite) TestToken(c *C) {
s.suite.TokenCRUD(c)
}
func (s *MemSuite) TestRemoteCert(c *C) {
s.suite.RemoteCertCRUD(c)
}
+2 -253
View File
@@ -6,6 +6,7 @@ import (
"testing"
"time"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/mailgun/lemma/random"
"github.com/gravitational/teleport/backend"
@@ -39,258 +40,6 @@ func (s *BackendSuite) expectChanges(c *C, expected ...interface{}) {
}
}
func (s *BackendSuite) UserKeyCRUD(c *C) {
k := backend.AuthorizedKey{ID: "id1", Value: []byte("val1")}
c.Assert(s.B.UpsertUserKey("user1", k, 0), IsNil)
keys, err := s.B.GetUserKeys("user1")
c.Assert(err, IsNil)
c.Assert(keys, DeepEquals, []backend.AuthorizedKey{k})
c.Assert(s.B.DeleteUserKey("user1", k.ID), IsNil)
keys, err = s.B.GetUserKeys("user1")
c.Assert(err, IsNil)
c.Assert(keys, DeepEquals, []backend.AuthorizedKey{})
}
func (s *BackendSuite) UsersCRUD(c *C) {
u, err := s.B.GetUsers()
c.Assert(err, IsNil)
c.Assert(len(u), Equals, 0)
k := backend.AuthorizedKey{ID: "id1", Value: []byte("val1")}
c.Assert(s.B.UpsertUserKey("user1", k, 0), IsNil)
c.Assert(s.B.UpsertUserKey("user2", k, 0), IsNil)
u, err = s.B.GetUsers()
c.Assert(err, IsNil)
c.Assert(toSet(u), DeepEquals, map[string]struct{}{"user1": struct{}{}, "user2": struct{}{}})
c.Assert(s.B.DeleteUser("user1"), IsNil)
u, err = s.B.GetUsers()
c.Assert(err, IsNil)
c.Assert(toSet(u), DeepEquals, map[string]struct{}{"user2": struct{}{}})
c.Assert(s.B.DeleteUser("user1"), FitsTypeOf, &backend.NotFoundError{})
}
func (s *BackendSuite) UserCACRUD(c *C) {
ca := backend.CA{
Pub: []byte("capub"),
Priv: []byte("capriv"),
}
c.Assert(s.B.UpsertUserCA(ca), IsNil)
out, err := s.B.GetUserCA()
c.Assert(err, IsNil)
c.Assert(out, DeepEquals, &ca)
outp, err := s.B.GetUserCAPub()
c.Assert(err, IsNil)
c.Assert(outp, DeepEquals, ca.Pub)
}
func (s *BackendSuite) HostCACRUD(c *C) {
ca := backend.CA{
Pub: []byte("capub"),
Priv: []byte("capriv"),
}
c.Assert(s.B.UpsertHostCA(ca), IsNil)
out, err := s.B.GetHostCA()
c.Assert(err, IsNil)
c.Assert(out, DeepEquals, &ca)
outp, err := s.B.GetHostCAPub()
c.Assert(err, IsNil)
c.Assert(outp, DeepEquals, ca.Pub)
}
func (s *BackendSuite) ServerCRUD(c *C) {
out, err := s.B.GetServers()
c.Assert(err, IsNil)
c.Assert(len(out), Equals, 0)
srv := backend.Server{ID: "srv1", Addr: "localhost:2022"}
c.Assert(s.B.UpsertServer(srv, 0), IsNil)
out, err = s.B.GetServers()
c.Assert(err, IsNil)
c.Assert(out, DeepEquals, []backend.Server{srv})
}
func (s *BackendSuite) PasswordHashCRUD(c *C) {
_, err := s.B.GetPasswordHash("user1")
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
err = s.B.UpsertPasswordHash("user1", []byte("hello123"))
c.Assert(err, IsNil)
hash, err := s.B.GetPasswordHash("user1")
c.Assert(err, IsNil)
c.Assert(hash, DeepEquals, []byte("hello123"))
err = s.B.UpsertPasswordHash("user1", []byte("hello321"))
c.Assert(err, IsNil)
hash, err = s.B.GetPasswordHash("user1")
c.Assert(err, IsNil)
c.Assert(hash, DeepEquals, []byte("hello321"))
}
func (s *BackendSuite) WebSessionCRUD(c *C) {
_, err := s.B.GetWebSession("user1", "sid1")
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
ws := backend.WebSession{Pub: []byte("pub123"), Priv: []byte("priv123")}
err = s.B.UpsertWebSession("user1", "sid1", ws, 0)
c.Assert(err, IsNil)
out, err := s.B.GetWebSession("user1", "sid1")
c.Assert(err, IsNil)
c.Assert(out, DeepEquals, &ws)
ws1 := backend.WebSession{Pub: []byte("pub321"), Priv: []byte("priv321")}
err = s.B.UpsertWebSession("user1", "sid1", ws1, 0)
c.Assert(err, IsNil)
out2, err := s.B.GetWebSession("user1", "sid1")
c.Assert(err, IsNil)
c.Assert(out2, DeepEquals, &ws1)
keys, err := s.B.GetWebSessionsKeys("user1")
c.Assert(err, IsNil)
c.Assert(keys[0].Value, DeepEquals, out2.Pub)
c.Assert(s.B.DeleteWebSession("user1", "sid1"), IsNil)
_, err = s.B.GetWebSession("user1", "sid1")
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
}
func (s *BackendSuite) WebTunCRUD(c *C) {
_, err := s.B.GetWebTun("p1")
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
t := backend.WebTun{
Prefix: "p1",
TargetAddr: "http://localhost:5000",
ProxyAddr: "node1.gravitational.io",
}
c.Assert(s.B.UpsertWebTun(t, 0), IsNil)
out, err := s.B.GetWebTun("p1")
c.Assert(out, DeepEquals, &t)
tuns, err := s.B.GetWebTuns()
c.Assert(err, IsNil)
c.Assert(tuns, DeepEquals, []backend.WebTun{t})
t1 := backend.WebTun{
Prefix: "p1",
TargetAddr: "http://localhost:5001",
ProxyAddr: "node1.gravitational2.io",
}
c.Assert(s.B.UpsertWebTun(t1, 0), IsNil)
out, err = s.B.GetWebTun("p1")
c.Assert(out, DeepEquals, &t1)
c.Assert(s.B.DeleteWebTun("p1"), IsNil)
_, err = s.B.GetWebTun("p1")
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
}
func (s *BackendSuite) Locking(c *C) {
tok := randomToken()
ttl := 30 * time.Second
c.Assert(s.B.AcquireLock(tok, ttl), IsNil)
c.Assert(s.B.AcquireLock(tok, ttl),
FitsTypeOf, &backend.AlreadyExistsError{})
c.Assert(s.B.ReleaseLock(tok), IsNil)
c.Assert(s.B.ReleaseLock(tok), FitsTypeOf, &backend.NotFoundError{})
c.Assert(s.B.AcquireLock(tok, 30*time.Second), IsNil)
}
func (s *BackendSuite) TokenCRUD(c *C) {
_, err := s.B.GetToken("token")
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
c.Assert(s.B.UpsertToken("token", "a.example.com", 0), IsNil)
out, err := s.B.GetToken("token")
c.Assert(out, Equals, "a.example.com")
c.Assert(err, IsNil)
c.Assert(s.B.DeleteToken("token"), IsNil)
_, err = s.B.GetToken("token")
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
}
func (s *BackendSuite) RemoteCertCRUD(c *C) {
out, err := s.B.GetRemoteCerts(backend.HostCert, "")
c.Assert(err, IsNil)
c.Assert(out, DeepEquals, []backend.RemoteCert{})
ca := backend.RemoteCert{
Type: backend.HostCert,
ID: "c1",
FQDN: "example.com",
Value: []byte("hello"),
}
c.Assert(s.B.UpsertRemoteCert(ca, 0), IsNil)
out, err = s.B.GetRemoteCerts(backend.HostCert, ca.FQDN)
c.Assert(err, IsNil)
c.Assert(out[0], DeepEquals, ca)
ca2 := backend.RemoteCert{
Type: backend.HostCert,
ID: "c2",
FQDN: "example.org",
Value: []byte("hello2"),
}
c.Assert(s.B.UpsertRemoteCert(ca2, 0), IsNil)
out, err = s.B.GetRemoteCerts(backend.HostCert, ca2.FQDN)
c.Assert(err, IsNil)
c.Assert(out[0], DeepEquals, ca2)
out, err = s.B.GetRemoteCerts(backend.HostCert, "")
c.Assert(err, IsNil)
c.Assert(len(out), Equals, 2)
certs := make(map[string]backend.RemoteCert)
for _, c := range out {
certs[c.FQDN+c.ID] = c
}
c.Assert(certs[ca.FQDN+ca.ID], DeepEquals, ca)
c.Assert(certs[ca2.FQDN+ca2.ID], DeepEquals, ca2)
// Update ca
ca.Value = []byte("hello updated")
c.Assert(s.B.UpsertRemoteCert(ca, 0), IsNil)
out, err = s.B.GetRemoteCerts(backend.HostCert, ca.FQDN)
c.Assert(err, IsNil)
c.Assert(out[0], DeepEquals, ca)
err = s.B.DeleteRemoteCert(backend.HostCert, ca.FQDN, ca.ID)
c.Assert(err, IsNil)
err = s.B.DeleteRemoteCert(backend.HostCert, ca.FQDN, ca.ID)
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
}
func (s *BackendSuite) BasicCRUD(c *C) {
keys, err := s.B.GetKeys([]string{"keys"})
c.Assert(err, IsNil)
@@ -313,7 +62,7 @@ func (s *BackendSuite) BasicCRUD(c *C) {
c.Assert(string(out), Equals, "val-updated")
c.Assert(s.B.DeleteKey([]string{"a", "b"}, "bkey"), IsNil)
c.Assert(s.B.DeleteKey([]string{"a", "b"}, "bkey"), FitsTypeOf, &backend.NotFoundError{})
c.Assert(s.B.DeleteKey([]string{"a", "b"}, "bkey"), FitsTypeOf, &teleport.NotFoundError{})
}
func (s *BackendSuite) Expiration(c *C) {
+6 -5
View File
@@ -12,9 +12,10 @@ import (
"strconv"
"time"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/Godeps/_workspace/src/code.google.com/p/go-uuid/uuid"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/events"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/sshutils/scp"
"github.com/gravitational/teleport/utils"
@@ -402,7 +403,7 @@ func (s *CPHandler) sendMessage(w http.ResponseWriter, r *http.Request, p httpro
func (s *CPHandler) getSession(w http.ResponseWriter, r *http.Request, p httprouter.Params, c Context) {
ses, err := c.GetClient().GetSession(p[0].Value)
if err != nil {
if !backend.IsNotFound(err) {
if !teleport.IsNotFound(err) {
log.Errorf("failed to retrieve session: %v", err)
replyErr(w, http.StatusInternalServerError, err)
return
@@ -504,7 +505,7 @@ func (s *CPHandler) upsertWebTun(w http.ResponseWriter, r *http.Request, _ httpr
roundtrip.ReplyJSON(w, http.StatusBadRequest, message(err.Error()))
return
}
wt, err := backend.NewWebTun(prefix, proxy, target)
wt, err := services.NewWebTun(prefix, proxy, target)
if err != nil {
log.Errorf("failed to parse form: %v", err)
roundtrip.ReplyJSON(w, http.StatusBadRequest, message(err.Error()))
@@ -603,13 +604,13 @@ func (s *CPHandler) postKey(w http.ResponseWriter, r *http.Request, _ httprouter
roundtrip.ReplyJSON(w, http.StatusBadRequest, message(err.Error()))
return
}
cert, err := c.GetClient().UpsertUserKey(c.GetUser(), backend.AuthorizedKey{ID: id, Value: []byte(key)}, 0)
cert, err := c.GetClient().UpsertUserKey(c.GetUser(), services.AuthorizedKey{ID: id, Value: []byte(key)}, 0)
if err != nil {
log.Errorf("failed to upsert keys: %v", err)
roundtrip.ReplyJSON(w, http.StatusBadRequest, message("invalid key format"))
return
}
roundtrip.ReplyJSON(w, http.StatusOK, backend.AuthorizedKey{ID: key, Value: cert})
roundtrip.ReplyJSON(w, http.StatusOK, services.AuthorizedKey{ID: key, Value: cert})
}
func (s *CPHandler) deleteKey(w http.ResponseWriter, r *http.Request, p httprouter.Params, c Context) {
+63
View File
@@ -0,0 +1,63 @@
package teleport
import "fmt"
type AlreadyAcquiredError struct {
Message string
}
func (e *AlreadyAcquiredError) Error() string {
if e.Message != "" {
return e.Message
} else {
return "Lock is already aquired"
}
}
type NotFoundError struct {
Message string
}
func (e *NotFoundError) Error() string {
if e.Message != "" {
return e.Message
} else {
return "Object not found"
}
}
func IsNotFound(e error) bool {
_, ok := e.(*NotFoundError)
return ok
}
type AlreadyExistsError struct {
Message string
}
func (n *AlreadyExistsError) Error() string {
if n.Message != "" {
return n.Message
} else {
return "Object already exists"
}
}
type MissingParameterError struct {
Param string
}
func (m *MissingParameterError) Error() string {
return fmt.Sprintf("missing required parameter '%v'", m.Param)
}
type BadParameterError struct {
Param string
Err string
}
func (m *BadParameterError) Error() string {
return fmt.Sprintf("bad parameter '%v', %v", m.Param, m.Err)
}
+2 -2
View File
@@ -6,7 +6,7 @@ import (
"fmt"
"time"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/backend/boltbk"
"github.com/gravitational/teleport/events"
@@ -88,7 +88,7 @@ func (b *BoltLog) GetEvents(f events.Filter) ([]lunk.Entry, error) {
bkt, err = boltbk.GetBucket(tx, []string{"events"})
}
if err != nil {
if backend.IsNotFound(err) {
if teleport.IsNotFound(err) {
return nil
}
return err
+6 -6
View File
@@ -7,7 +7,7 @@ import (
"path/filepath"
"sync"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/backend/boltbk"
"github.com/gravitational/teleport/recorder"
@@ -99,7 +99,7 @@ func (b *boltRW) initWriteIter() error {
}
bytes := bkt.Get([]byte("val"))
if bytes == nil {
return &backend.NotFoundError{
return &teleport.NotFoundError{
Message: fmt.Sprintf("not found"),
}
}
@@ -110,7 +110,7 @@ func (b *boltRW) initWriteIter() error {
if err == nil {
return nil
}
if !backend.IsNotFound(err) {
if !teleport.IsNotFound(err) {
return err
}
return b.db.Update(func(tx *bolt.Tx) error {
@@ -132,7 +132,7 @@ func (b *boltRW) WriteChunks(ch []recorder.Chunk) error {
}
iterb := ibkt.Get([]byte("val"))
if iterb == nil {
return &backend.NotFoundError{fmt.Sprintf("iter not found")}
return &teleport.NotFoundError{fmt.Sprintf("iter not found")}
}
lastChunk := binary.BigEndian.Uint64(iterb)
cbkt, err := boltbk.UpsertBucket(tx, []string{"chunks"})
@@ -166,7 +166,7 @@ func (b *boltRW) ReadChunk(chunk uint64) ([]byte, error) {
}
bytes := cbkt.Get(bin)
if bytes == nil {
return &backend.NotFoundError{fmt.Sprintf("chunk not found")}
return &teleport.NotFoundError{fmt.Sprintf("chunk not found")}
}
bt = make([]byte, len(bytes))
copy(bt, bytes)
@@ -196,7 +196,7 @@ func (r *boltRef) ReadChunks(start int, end int) ([]recorder.Chunk, error) {
for i := start; i < end; i++ {
out, err := r.rw.ReadChunk(uint64(i))
if err != nil {
if backend.IsNotFound(err) {
if teleport.IsNotFound(err) {
return chunks, nil
}
return nil, err
+9 -17
View File
@@ -41,8 +41,7 @@ func (s *CAService) UpsertUserCA(ca CA) error {
func (s *CAService) GetUserCA() (*CA, error) {
val, err := s.backend.GetVal([]string{"ca"}, "userca")
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
var ca CA
@@ -59,8 +58,7 @@ func (s *CAService) GetUserCA() (*CA, error) {
func (s *CAService) GetUserCAPub() ([]byte, error) {
val, err := s.backend.GetVal([]string{"ca"}, "userca")
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
var ca CA
@@ -106,7 +104,7 @@ func (s *CAService) GetRemoteCerts(ctype string,
"hosts", fqdn})
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
certs := make([]RemoteCert, len(IDs))
for i, id := range IDs {
@@ -127,7 +125,7 @@ func (s *CAService) GetRemoteCerts(ctype string,
"hosts"})
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
allCerts := make([]RemoteCert, 0)
for _, f := range FQDNs {
@@ -148,16 +146,12 @@ func (s *CAService) DeleteRemoteCert(ctype, fqdn, id string) error {
return trace.Errorf("Unknown certificate type '" + ctype + "'")
}
err := convertErr(s.backend.DeleteKey(
err := s.backend.DeleteKey(
[]string{"certs", ctype, "hosts", fqdn},
id,
))
)
if err != nil {
log.Errorf(err.Error())
return err
}
return nil
return err
}
// UpsertHostCA upserts host certificate authority keys in OpenSSH authorized_keys format
@@ -179,8 +173,7 @@ func (s *CAService) UpsertHostCA(ca CA) error {
func (s *CAService) GetHostCA() (*CA, error) {
val, err := s.backend.GetVal([]string{"ca"}, "hostca")
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
var ca CA
@@ -197,8 +190,7 @@ func (s *CAService) GetHostCA() (*CA, error) {
func (s *CAService) GetHostCAPub() ([]byte, error) {
val, err := s.backend.GetVal([]string{"ca"}, "hostca")
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
var ca CA
-40
View File
@@ -1,40 +0,0 @@
package services
import "github.com/gravitational/teleport/backend"
type AlreadyAcquiredError struct {
Message string
}
func (e *AlreadyAcquiredError) Error() string {
if e.Message != "" {
return e.Message
} else {
return "Lock is already aquired"
}
}
type NotFoundError struct {
Message string
}
func (e *NotFoundError) Error() string {
if e.Message != "" {
return e.Message
} else {
return "Object not found"
}
}
func convertErr(e error) error {
if e == nil {
return nil
}
switch e.(type) {
case *backend.NotFoundError:
return &NotFoundError{}
}
return e
}
+4 -3
View File
@@ -4,6 +4,7 @@ import (
"time"
"github.com/gravitational/log"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/trace"
)
@@ -20,10 +21,10 @@ func NewLockService(backend backend.Backend) *LockService {
func (s *LockService) AcquireLock(token string, ttl time.Duration) error {
_, err := s.backend.GetVal([]string{"locks"}, token)
if err == nil {
return &AlreadyAcquiredError{""}
return &teleport.AlreadyAcquiredError{""}
} else {
switch err.(type) {
case *backend.NotFoundError:
case *teleport.NotFoundError:
default:
log.Errorf(err.Error())
return err
@@ -43,7 +44,7 @@ func (s *LockService) ReleaseLock(token string) error {
err := s.backend.DeleteKey([]string{"locks"}, token)
if err != nil {
log.Errorf(err.Error())
return convertErr(err)
return err
}
return nil
}
+2 -6
View File
@@ -29,15 +29,11 @@ func (s *ProvisioningService) UpsertToken(token, fqdn string, ttl time.Duration)
func (s *ProvisioningService) GetToken(token string) (string, error) {
fqdn, err := s.backend.GetVal([]string{"tokens"}, token)
if err != nil {
log.Errorf(err.Error())
return "", convertErr(err)
return "", err
}
return string(fqdn), nil
}
func (s *ProvisioningService) DeleteToken(token string) error {
err := s.backend.DeleteKey([]string{"tokens"}, token)
if err != nil {
log.Errorf(err.Error())
}
return convertErr(err)
return err
}
+6 -2
View File
@@ -4,9 +4,9 @@ import (
"path/filepath"
"testing"
"github.com/gravitational/teleport/backend/boltbk"
"github.com/gravitational/log"
. "github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/check.v1"
"github.com/gravitational/teleport/backend/boltbk"
)
func TestBolt(t *testing.T) { TestingT(t) }
@@ -19,6 +19,10 @@ type BoltSuite struct {
var _ = Suite(&BoltSuite{})
func (s *BoltSuite) SetUpSuite(c *C) {
log.Init([]*log.LogConfig{&log.LogConfig{Name: "console"}})
}
func (s *BoltSuite) SetUpTest(c *C) {
s.dir = c.MkDir()
+12 -11
View File
@@ -4,6 +4,7 @@ import (
"testing"
"time"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/mailgun/lemma/random"
"github.com/gravitational/teleport/backend"
@@ -90,7 +91,7 @@ func (s *ServicesTestSuite) UsersCRUD(c *C) {
c.Assert(err, IsNil)
c.Assert(toSet(u), DeepEquals, map[string]struct{}{"user2": struct{}{}})
c.Assert(s.UserS.DeleteUser("user1"), FitsTypeOf, &NotFoundError{})
c.Assert(s.UserS.DeleteUser("user1"), FitsTypeOf, &teleport.NotFoundError{})
}
func (s *ServicesTestSuite) UserCACRUD(c *C) {
@@ -140,7 +141,7 @@ func (s *ServicesTestSuite) ServerCRUD(c *C) {
func (s *ServicesTestSuite) PasswordHashCRUD(c *C) {
_, err := s.WebS.GetPasswordHash("user1")
c.Assert(err, FitsTypeOf, &NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
err = s.WebS.UpsertPasswordHash("user1", []byte("hello123"))
c.Assert(err, IsNil)
@@ -159,7 +160,7 @@ func (s *ServicesTestSuite) PasswordHashCRUD(c *C) {
func (s *ServicesTestSuite) WebSessionCRUD(c *C) {
_, err := s.WebS.GetWebSession("user1", "sid1")
c.Assert(err, FitsTypeOf, &NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
ws := WebSession{Pub: []byte("pub123"), Priv: []byte("priv123")}
err = s.WebS.UpsertWebSession("user1", "sid1", ws, 0)
@@ -184,12 +185,12 @@ func (s *ServicesTestSuite) WebSessionCRUD(c *C) {
c.Assert(s.WebS.DeleteWebSession("user1", "sid1"), IsNil)
_, err = s.WebS.GetWebSession("user1", "sid1")
c.Assert(err, FitsTypeOf, &NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
}
func (s *ServicesTestSuite) WebTunCRUD(c *C) {
_, err := s.WebS.GetWebTun("p1")
c.Assert(err, FitsTypeOf, &NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
t := WebTun{
Prefix: "p1",
@@ -218,7 +219,7 @@ func (s *ServicesTestSuite) WebTunCRUD(c *C) {
c.Assert(s.WebS.DeleteWebTun("p1"), IsNil)
_, err = s.WebS.GetWebTun("p1")
c.Assert(err, FitsTypeOf, &NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
}
func (s *ServicesTestSuite) Locking(c *C) {
@@ -227,17 +228,17 @@ func (s *ServicesTestSuite) Locking(c *C) {
c.Assert(s.LockS.AcquireLock(tok, ttl), IsNil)
c.Assert(s.LockS.AcquireLock(tok, ttl),
FitsTypeOf, &AlreadyAcquiredError{})
FitsTypeOf, &teleport.AlreadyAcquiredError{})
c.Assert(s.LockS.ReleaseLock(tok), IsNil)
c.Assert(s.LockS.ReleaseLock(tok), FitsTypeOf, &NotFoundError{})
c.Assert(s.LockS.ReleaseLock(tok), FitsTypeOf, &teleport.NotFoundError{})
c.Assert(s.LockS.AcquireLock(tok, 30*time.Second), IsNil)
}
func (s *ServicesTestSuite) TokenCRUD(c *C) {
_, err := s.ProvisioningS.GetToken("token")
c.Assert(err, FitsTypeOf, &NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
c.Assert(s.ProvisioningS.UpsertToken("token", "a.example.com", 0), IsNil)
@@ -248,7 +249,7 @@ func (s *ServicesTestSuite) TokenCRUD(c *C) {
c.Assert(s.ProvisioningS.DeleteToken("token"), IsNil)
_, err = s.ProvisioningS.GetToken("token")
c.Assert(err, FitsTypeOf, &NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
}
func (s *ServicesTestSuite) RemoteCertCRUD(c *C) {
@@ -303,7 +304,7 @@ func (s *ServicesTestSuite) RemoteCertCRUD(c *C) {
c.Assert(err, IsNil)
err = s.CAS.DeleteRemoteCert(HostCert, ca.FQDN, ca.ID)
c.Assert(err, FitsTypeOf, &NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
}
func toSet(vals []string) map[string]struct{} {
+3 -11
View File
@@ -32,8 +32,7 @@ func (s *UserService) UpsertUserKey(user string, key AuthorizedKey,
func (s *UserService) GetUserKeys(user string) ([]AuthorizedKey, error) {
IDs, err := s.backend.GetKeys([]string{"users", user, "keys"})
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
keys := make([]AuthorizedKey, len(IDs))
@@ -54,7 +53,6 @@ func (s *UserService) GetUserKeys(user string) ([]AuthorizedKey, error) {
func (s *UserService) GetUsers() ([]string, error) {
users, err := s.backend.GetKeys([]string{"users"})
if err != nil {
log.Errorf(err.Error())
return nil, trace.Wrap(err)
}
return users, nil
@@ -63,19 +61,13 @@ func (s *UserService) GetUsers() ([]string, error) {
// DeleteUser deletes a user with all the keys from the backend
func (s *UserService) DeleteUser(user string) error {
err := s.backend.DeleteBucket([]string{"users"}, user)
if err != nil {
log.Errorf(err.Error())
}
return convertErr(err)
return err
}
// DeleteUserKey deletes user key by given ID
func (s *UserService) DeleteUserKey(user, key string) error {
err := s.backend.DeleteKey([]string{"users", user, "keys"}, key)
if err != nil {
log.Errorf(err.Error())
}
return convertErr(err)
return err
}
type AuthorizedKey struct {
+24 -17
View File
@@ -3,9 +3,11 @@ package services
import (
"encoding/json"
"fmt"
"net/url"
"time"
"github.com/gravitational/log"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/trace"
)
@@ -33,8 +35,7 @@ func (s *WebService) UpsertPasswordHash(user string, hash []byte) error {
func (s *WebService) GetPasswordHash(user string) ([]byte, error) {
hash, err := s.backend.GetVal([]string{"web", "users", user}, "pwd")
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
return hash, err
}
@@ -66,8 +67,7 @@ func (s *WebService) GetWebSession(user, sid string) (*WebSession, error) {
sid,
)
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
var session WebSession
@@ -84,8 +84,7 @@ func (s *WebService) GetWebSession(user, sid string) (*WebSession, error) {
func (s *WebService) GetWebSessionsKeys(user string) ([]AuthorizedKey, error) {
keys, err := s.backend.GetKeys([]string{"web", "users", user, "sessions"})
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
values := make([]AuthorizedKey, len(keys))
@@ -106,10 +105,7 @@ func (s *WebService) DeleteWebSession(user, sid string) error {
[]string{"web", "users", user, "sessions"},
sid,
)
if err != nil {
log.Errorf(err.Error())
}
return convertErr(err)
return err
}
func (s *WebService) UpsertWebTun(tun WebTun, ttl time.Duration) error {
@@ -138,10 +134,7 @@ func (s *WebService) DeleteWebTun(prefix string) error {
[]string{"web", "tunnels"},
prefix,
)
if err != nil {
log.Errorf(err.Error())
}
return convertErr(err)
return err
}
func (s *WebService) GetWebTun(prefix string) (*WebTun, error) {
val, err := s.backend.GetVal(
@@ -149,8 +142,7 @@ func (s *WebService) GetWebTun(prefix string) (*WebTun, error) {
prefix,
)
if err != nil {
log.Errorf(err.Error())
return nil, convertErr(err)
return nil, err
}
var tun WebTun
@@ -165,7 +157,6 @@ func (s *WebService) GetWebTun(prefix string) (*WebTun, error) {
func (s *WebService) GetWebTuns() ([]WebTun, error) {
keys, err := s.backend.GetKeys([]string{"web", "tunnels"})
if err != nil {
log.Errorf(err.Error())
return nil, err
}
@@ -198,3 +189,19 @@ type WebTun struct {
// TargetAddr is the target http address of the server
TargetAddr string `json:"target"`
}
func NewWebTun(prefix, proxyAddr, targetAddr string) (*WebTun, error) {
if prefix == "" {
return nil, &teleport.MissingParameterError{Param: "prefix"}
}
if targetAddr == "" {
return nil, &teleport.MissingParameterError{Param: "target"}
}
if proxyAddr == "" {
return nil, &teleport.MissingParameterError{Param: "proxy"}
}
if _, err := url.ParseRequestURI(targetAddr); err != nil {
return nil, &teleport.BadParameterError{Param: "target", Err: err.Error()}
}
return &WebTun{Prefix: prefix, ProxyAddr: proxyAddr, TargetAddr: targetAddr}, nil
}
+3 -2
View File
@@ -3,6 +3,7 @@ package session
import (
"time"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/backend"
)
@@ -32,7 +33,7 @@ func (s *server) GetSessions() ([]Session, error) {
out := []Session{}
for _, sid := range keys {
se, err := s.GetSession(sid)
if backend.IsNotFound(err) {
if teleport.IsNotFound(err) {
continue
}
out = append(out, *se)
@@ -55,7 +56,7 @@ func (s *server) GetSession(id string) (*Session, error) {
var p *Party
err := s.bk.GetJSONVal([]string{"sessions", id, "parties"}, pk, &p)
if err != nil {
if backend.IsNotFound(err) { // key was expired
if teleport.IsNotFound(err) { // key was expired
continue
}
return nil, err
+3 -3
View File
@@ -5,7 +5,7 @@ import (
"testing"
"time"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/backend/boltbk"
. "github.com/gravitational/teleport/Godeps/_workspace/src/gopkg.in/check.v1"
@@ -104,8 +104,8 @@ func (s *BoltSuite) TestPartiesCRUD(c *C) {
// Delete session
c.Assert(s.srv.DeleteSession("s1"), IsNil)
c.Assert(s.srv.DeleteSession("s1"), FitsTypeOf, &backend.NotFoundError{})
c.Assert(s.srv.DeleteSession("s1"), FitsTypeOf, &teleport.NotFoundError{})
_, err = s.srv.GetSession("s1")
c.Assert(err, FitsTypeOf, &backend.NotFoundError{})
c.Assert(err, FitsTypeOf, &teleport.NotFoundError{})
}
+3 -3
View File
@@ -10,9 +10,9 @@ import (
"time"
"github.com/gravitational/teleport/auth"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/events"
"github.com/gravitational/teleport/recorder"
"github.com/gravitational/teleport/services"
rsession "github.com/gravitational/teleport/session"
"github.com/gravitational/teleport/sshutils"
"github.com/gravitational/teleport/sshutils/scp"
@@ -112,7 +112,7 @@ func (s *Server) ID() string {
func (s *Server) heartbeatPresence() {
for {
srv := backend.Server{
srv := services.Server{
ID: s.ID(),
Addr: s.addr.Addr,
}
@@ -132,7 +132,7 @@ func (s *Server) getTrustedCAKeys() ([]ssh.PublicKey, error) {
}
authKeys = append(authKeys, key)
certs, err := s.ap.GetRemoteCerts(backend.UserCert, "")
certs, err := s.ap.GetRemoteCerts(services.UserCert, "")
if err != nil {
return nil, err
}
+12 -6
View File
@@ -4,13 +4,14 @@ import (
"bytes"
"fmt"
"io"
"path/filepath"
"strings"
"testing"
"github.com/gravitational/teleport/auth"
authority "github.com/gravitational/teleport/auth/native"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/backend/membk"
"github.com/gravitational/teleport/backend/boltbk"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/sshutils"
"github.com/gravitational/teleport/utils"
@@ -25,10 +26,11 @@ func TestSrv(t *testing.T) { TestingT(t) }
type SrvSuite struct {
srv *Server
clt *ssh.Client
bk *membk.MemBackend
bk *boltbk.BoltBackend
a *auth.AuthServer
up *upack
scrt *secret.Service
dir string
}
var _ = Suite(&SrvSuite{})
@@ -42,7 +44,11 @@ func (s *SrvSuite) SetUpSuite(c *C) {
}
func (s *SrvSuite) SetUpTest(c *C) {
s.bk = membk.New()
s.dir = c.MkDir()
var err error
s.bk, err = boltbk.New(filepath.Join(s.dir, "db"))
c.Assert(err, IsNil)
s.a = auth.NewAuthServer(s.bk, authority.New(), s.scrt)
// set up host private key and certificate
@@ -61,7 +67,7 @@ func (s *SrvSuite) SetUpTest(c *C) {
srv, err := New(
utils.NetAddr{Network: "tcp", Addr: "localhost:0"},
[]ssh.Signer{signer},
s.bk,
auth.NewBackendAccessPoint(s.bk),
SetShell("/bin/sh"),
)
c.Assert(err, IsNil)
@@ -248,7 +254,7 @@ func newUpack(user string, a *auth.AuthServer) (*upack, error) {
return nil, err
}
ucert, err := a.UpsertUserKey(user, backend.AuthorizedKey{ID: user, Value: upub}, 0)
ucert, err := a.UpsertUserKey(user, services.AuthorizedKey{ID: user, Value: upub}, 0)
if err != nil {
return nil, err
}
+3 -3
View File
@@ -5,7 +5,7 @@ import (
"time"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/buger/goterm"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/services"
)
func (cmd *Command) resetHostCA(confirm bool) {
@@ -58,7 +58,7 @@ func (cmd *Command) upsertRemoteCert(id, fqdn, certType, path string, ttl time.D
cmd.printError(err)
return
}
cert := backend.RemoteCert{
cert := services.RemoteCert{
FQDN: fqdn,
Type: certType,
ID: id,
@@ -89,7 +89,7 @@ func (cmd *Command) deleteRemoteCert(id, fqdn, certType string) {
cmd.printOK("certificate deleted")
}
func remoteCertsView(certs []backend.RemoteCert) string {
func remoteCertsView(certs []services.RemoteCert) string {
t := goterm.NewTable(0, 10, 5, ' ', 0)
fmt.Fprint(t, "Type\tFQDN\tID\tValue\n")
if len(certs) == 0 {
+23 -8
View File
@@ -17,6 +17,7 @@ import (
"github.com/gravitational/teleport/events/boltlog"
"github.com/gravitational/teleport/recorder"
"github.com/gravitational/teleport/recorder/boltrec"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/session"
"github.com/gravitational/teleport/utils"
@@ -36,12 +37,19 @@ type CmdSuite struct {
clt *auth.Client
cmd *Command
out *bytes.Buffer
bk *boltbk.BoltBackend
bk backend.Backend
bl *boltlog.BoltLog
scrt *secret.Service
rec recorder.Recorder
addr utils.NetAddr
dir string
CAS *services.CAService
LockS *services.LockService
PresenceS *services.PresenceService
ProvisioningS *services.ProvisioningService
UserS *services.UserService
WebS *services.WebService
}
var _ = Suite(&CmdSuite{})
@@ -83,6 +91,13 @@ func (s *CmdSuite) SetUpTest(c *C) {
s.out = &bytes.Buffer{}
s.cmd = &Command{out: s.out}
s.CAS = services.NewCAService(s.bk)
s.LockS = services.NewLockService(s.bk)
s.PresenceS = services.NewPresenceService(s.bk)
s.ProvisioningS = services.NewProvisioningService(s.bk)
s.UserS = services.NewUserService(s.bk)
s.WebS = services.NewWebService(s.bk)
}
func (s *CmdSuite) TearDownTest(c *C) {
@@ -108,7 +123,7 @@ func (s *CmdSuite) TestHostCACRUD(c *C) {
s.run("host-ca", "reset", "--confirm"),
Matches, fmt.Sprintf(".*%v.*", "regenerated"))
hostCA, err := s.bk.GetHostCA()
hostCA, err := s.CAS.GetHostCA()
c.Assert(err, IsNil)
c.Assert(hostCA, NotNil)
@@ -122,7 +137,7 @@ func (s *CmdSuite) TestUserCACRUD(c *C) {
s.run("user-ca", "reset", "--confirm"),
Matches, fmt.Sprintf(".*%v.*", "regenerated"))
userCA, err := s.bk.GetUserCA()
userCA, err := s.CAS.GetUserCA()
c.Assert(err, IsNil)
c.Assert(userCA, NotNil)
c.Assert(userCA, NotNil)
@@ -146,8 +161,8 @@ func (s *CmdSuite) TestUserCRUD(c *C) {
out := s.run("user", "upsert-key", "--user", "alex", "--key-id", "key1", "--key", fkey.Name())
c.Assert(out, Matches, fmt.Sprintf(".*%v.*", pub))
var keys []backend.AuthorizedKey
keys, err = s.bk.GetUserKeys("alex")
var keys []services.AuthorizedKey
keys, err = s.UserS.GetUserKeys("alex")
c.Assert(err, IsNil)
c.Assert(trim(keys[0].ID), Equals, "key1")
c.Assert(trim(string(keys[0].Value)), Equals, trim(out))
@@ -183,8 +198,8 @@ func (s *CmdSuite) TestRemoteCertCRUD(c *C) {
out := s.run("remote-ca", "upsert", "--id", "id1", "--type", "user", "--fqdn", "example.com", "--path", fkey.Name())
c.Assert(out, Matches, fmt.Sprintf(".*%v.*", "upserted"))
var remoteCerts []backend.RemoteCert
remoteCerts, err = s.bk.GetRemoteCerts("user", "example.com")
var remoteCerts []services.RemoteCert
remoteCerts, err = s.CAS.GetRemoteCerts("user", "example.com")
c.Assert(err, IsNil)
c.Assert(trim(string(remoteCerts[0].Value)), Equals, trim(string(pub)))
@@ -194,7 +209,7 @@ func (s *CmdSuite) TestRemoteCertCRUD(c *C) {
out = s.run("remote-ca", "rm", "--type", "user", "--fqdn", "example.com", "--id", "id1")
c.Assert(out, Matches, fmt.Sprintf(".*%v.*", "deleted"))
remoteCerts, err = s.bk.GetRemoteCerts("user", "")
remoteCerts, err = s.CAS.GetRemoteCerts("user", "")
c.Assert(len(remoteCerts), Equals, 0)
}
+3 -3
View File
@@ -5,7 +5,7 @@ import (
"time"
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/buger/goterm"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/services"
)
func (cmd *Command) setPass(user, pass string) {
@@ -24,7 +24,7 @@ func (cmd *Command) upsertKey(user, keyID, key string, ttl time.Duration) {
return
}
signed, err := cmd.client.UpsertUserKey(
user, backend.AuthorizedKey{ID: keyID, Value: bytes}, ttl)
user, services.AuthorizedKey{ID: keyID, Value: bytes}, ttl)
if err != nil {
cmd.printError(err)
return
@@ -72,7 +72,7 @@ func usersView(users []string) string {
return t.String()
}
func keysView(keys []backend.AuthorizedKey) string {
func keysView(keys []services.AuthorizedKey) string {
t := goterm.NewTable(0, 10, 5, ' ', 0)
fmt.Fprint(t, "KeyID\tKey\n")
if len(keys) == 0 {
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"time"
"github.com/gravitational/teleport/auth"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/sshutils"
"github.com/gravitational/teleport/utils"
@@ -113,7 +113,7 @@ func (a *Agent) checkHostSignature(hostport string, remote net.Addr, key ssh.Pub
log.Errorf("error spliting hostport(%v), err: %v", hostport, err)
return err
}
certs, err := a.clt.GetRemoteCerts(backend.HostCert, hostname)
certs, err := a.clt.GetRemoteCerts(services.HostCert, hostname)
if err != nil {
log.Errorf("failed to fetch remote certs: %v", err)
return err
+2 -2
View File
@@ -8,8 +8,8 @@ import (
"time"
"github.com/gravitational/teleport/auth"
"github.com/gravitational/teleport/backend"
"github.com/gravitational/teleport/events"
"github.com/gravitational/teleport/services"
"github.com/gravitational/teleport/sshutils"
"github.com/gravitational/teleport/utils"
@@ -273,7 +273,7 @@ func (s *remoteSite) ConnectToServer(server, user string, auth []ssh.AuthMethod)
return ssh.NewClient(conn, chans, reqs), nil
}
func (s *remoteSite) GetServers() ([]backend.Server, error) {
func (s *remoteSite) GetServers() ([]services.Server, error) {
return s.clt.GetServers()
}