1// Copyright 2015 The etcd Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package api 16 17import ( 18 "sync" 19 20 "go.etcd.io/etcd/version" 21 "go.uber.org/zap" 22 23 "github.com/coreos/go-semver/semver" 24 "github.com/coreos/pkg/capnslog" 25) 26 27type Capability string 28 29const ( 30 AuthCapability Capability = "auth" 31 V3rpcCapability Capability = "v3rpc" 32) 33 34var ( 35 plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/api") 36 37 // capabilityMaps is a static map of version to capability map. 38 capabilityMaps = map[string]map[Capability]bool{ 39 "3.0.0": {AuthCapability: true, V3rpcCapability: true}, 40 "3.1.0": {AuthCapability: true, V3rpcCapability: true}, 41 "3.2.0": {AuthCapability: true, V3rpcCapability: true}, 42 "3.3.0": {AuthCapability: true, V3rpcCapability: true}, 43 "3.4.0": {AuthCapability: true, V3rpcCapability: true}, 44 } 45 46 enableMapMu sync.RWMutex 47 // enabledMap points to a map in capabilityMaps 48 enabledMap map[Capability]bool 49 50 curVersion *semver.Version 51) 52 53func init() { 54 enabledMap = map[Capability]bool{ 55 AuthCapability: true, 56 V3rpcCapability: true, 57 } 58} 59 60// UpdateCapability updates the enabledMap when the cluster version increases. 61func UpdateCapability(lg *zap.Logger, v *semver.Version) { 62 if v == nil { 63 // if recovered but version was never set by cluster 64 return 65 } 66 enableMapMu.Lock() 67 if curVersion != nil && !curVersion.LessThan(*v) { 68 enableMapMu.Unlock() 69 return 70 } 71 curVersion = v 72 enabledMap = capabilityMaps[curVersion.String()] 73 enableMapMu.Unlock() 74 75 if lg != nil { 76 lg.Info( 77 "enabled capabilities for version", 78 zap.String("cluster-version", version.Cluster(v.String())), 79 ) 80 } else { 81 plog.Infof("enabled capabilities for version %s", version.Cluster(v.String())) 82 } 83} 84 85func IsCapabilityEnabled(c Capability) bool { 86 enableMapMu.RLock() 87 defer enableMapMu.RUnlock() 88 if enabledMap == nil { 89 return false 90 } 91 return enabledMap[c] 92} 93 94func EnableCapability(c Capability) { 95 enableMapMu.Lock() 96 defer enableMapMu.Unlock() 97 enabledMap[c] = true 98} 99