diff --git a/auth/store.go b/auth/store.go new file mode 100644 index 000000000..591cc29f4 --- /dev/null +++ b/auth/store.go @@ -0,0 +1,66 @@ +// Copyright 2016 Nippon Telegraph and Telephone Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package auth + +import ( + "github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/pkg/capnslog" + "github.com/coreos/etcd/storage/backend" +) + +type backendGetter interface { + Backend() backend.Backend +} + +var ( + enableFlagKey = []byte("authEnabled") + authBucketName = []byte("auth") + + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "auth") +) + +type AuthStore interface { + // AuthEnable() turns on the authentication feature + AuthEnable() +} + +type authStore struct { + bgetter backendGetter +} + +func (as *authStore) AuthEnable() { + value := []byte{1} + + b := as.bgetter.Backend() + tx := b.BatchTx() + tx.Lock() + tx.UnsafePut(authBucketName, enableFlagKey, value) + tx.Unlock() + b.ForceCommit() + + plog.Noticef("Authentication enabled") +} + +func NewAuthStore(bgetter backendGetter) *authStore { + b := bgetter.Backend() + tx := b.BatchTx() + tx.Lock() + tx.UnsafeCreateBucket(authBucketName) + tx.Unlock() + b.ForceCommit() + + return &authStore{ + bgetter: bgetter, + } +} diff --git a/etcdserver/server.go b/etcdserver/server.go index e9ab9e2d6..fb8d75062 100644 --- a/etcdserver/server.go +++ b/etcdserver/server.go @@ -31,6 +31,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/go-semver/semver" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/pkg/capnslog" "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" + "github.com/coreos/etcd/auth" "github.com/coreos/etcd/compactor" "github.com/coreos/etcd/discovery" "github.com/coreos/etcd/etcdserver/etcdhttp/httptypes" @@ -172,10 +173,11 @@ type EtcdServer struct { store store.Store - kv dstorage.ConsistentWatchableKV - lessor lease.Lessor - bemu sync.Mutex - be backend.Backend + kv dstorage.ConsistentWatchableKV + lessor lease.Lessor + bemu sync.Mutex + be backend.Backend + authStore auth.AuthStore stats *stats.ServerStats lstats *stats.LeaderStats @@ -372,6 +374,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { srv.be = backend.NewDefaultBackend(path.Join(cfg.SnapDir(), databaseFilename)) srv.lessor = lease.NewLessor(srv.be) srv.kv = dstorage.New(srv.be, srv.lessor, &srv.consistIndex) + srv.authStore = auth.NewAuthStore(srv) if h := cfg.AutoCompactionRetention; h != 0 { srv.compactor = compactor.NewPeriodic(h, srv.kv, srv) srv.compactor.Run() @@ -1324,3 +1327,5 @@ func (s *EtcdServer) Backend() backend.Backend { defer s.bemu.Unlock() return s.be } + +func (s *EtcdServer) AuthStore() auth.AuthStore { return s.authStore } diff --git a/etcdserver/v3demo_server.go b/etcdserver/v3demo_server.go index cc255e18d..60eaf0c95 100644 --- a/etcdserver/v3demo_server.go +++ b/etcdserver/v3demo_server.go @@ -178,8 +178,11 @@ func (s *EtcdServer) LeaseRenew(id lease.LeaseID) (int64, error) { } func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) { - plog.Info("EtcdServer.AuthEnable isn't implemented yet") - return &pb.AuthEnableResponse{}, nil + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthEnable: r}) + if err != nil { + return nil, err + } + return result.resp.(*pb.AuthEnableResponse), result.err } type applyResult struct { @@ -248,8 +251,7 @@ func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) interface{} { case r.LeaseRevoke != nil: ar.resp, ar.err = applyLeaseRevoke(le, r.LeaseRevoke) case r.AuthEnable != nil: - plog.Info("AuthEnable is not implemented yet") - ar.resp, ar.err = nil, nil + ar.resp, ar.err = applyAuthEnable(s) default: panic("not implemented") } @@ -653,3 +655,8 @@ func compareInt64(a, b int64) int { func isGteRange(rangeEnd []byte) bool { return len(rangeEnd) == 1 && rangeEnd[0] == 0 } + +func applyAuthEnable(s *EtcdServer) (*pb.AuthEnableResponse, error) { + s.AuthStore().AuthEnable() + return &pb.AuthEnableResponse{}, nil +}