1
// Copyright 2018 The CubeFS Authors.
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
7
// http://www.apache.org/licenses/LICENSE-2.0
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
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
22
"github.com/cubefs/cubefs/proto"
23
"github.com/cubefs/cubefs/raftstore"
24
"github.com/cubefs/cubefs/util"
25
"github.com/cubefs/cubefs/util/caps"
26
"github.com/cubefs/cubefs/util/cryptoutil"
27
"github.com/cubefs/cubefs/util/errors"
28
"github.com/cubefs/cubefs/util/keystore"
29
"github.com/cubefs/cubefs/util/log"
32
// PKIKey defines the pki keys
35
AuthRootPrivateKey []byte
36
AuthRootPublicKey []byte
39
// Cluster stores all the cluster-level information.
42
leaderInfo *LeaderInfo
45
DisableAutoAllocate bool
47
partition raftstore.Partition
53
func newCluster(name string, leaderInfo *LeaderInfo, fsm *KeystoreFsm, partition raftstore.Partition, cfg *clusterConfig) (c *Cluster) {
56
c.leaderInfo = leaderInfo
59
c.partition = partition
60
c.fsm.keystore = make(map[string]*keystore.KeyInfo, 0)
61
c.fsm.accessKeystore = make(map[string]*keystore.AccessKeyInfo, 0)
65
func (c *Cluster) scheduleTask() {
66
c.scheduleToCheckHeartbeat()
69
func (c *Cluster) authAddr() (addr string) {
70
return c.leaderInfo.addr
73
func (c *Cluster) scheduleToCheckHeartbeat() {
76
if c.partition != nil && c.partition.IsRaftLeader() {
79
time.Sleep(time.Second * defaultIntervalToCheckHeartbeat)
84
func (c *Cluster) checkLeaderAddr() {
85
leaderID, _ := c.partition.LeaderTerm()
86
c.leaderInfo.addr = AddrDatabase[leaderID]
89
// CreateNewKey create a new key to the keystore
90
func (c *Cluster) CreateNewKey(id string, keyInfo *keystore.KeyInfo) (res *keystore.KeyInfo, err error) {
91
c.fsm.opKeyMutex.Lock()
92
defer c.fsm.opKeyMutex.Unlock()
93
accessKeyInfo := &keystore.AccessKeyInfo{
96
if _, err = c.fsm.GetKey(id); err == nil {
97
err = proto.ErrDuplicateKey
100
keyInfo.Ts = time.Now().Unix()
101
keyInfo.AuthKey = cryptoutil.GenSecretKey([]byte(c.AuthRootKey), keyInfo.Ts, id)
102
// TODO check duplicate
103
keyInfo.AccessKey = util.RandomString(16, util.Numeric|util.LowerLetter|util.UpperLetter)
104
keyInfo.SecretKey = util.RandomString(32, util.Numeric|util.LowerLetter|util.UpperLetter)
105
if err = c.syncAddKey(keyInfo); err != nil {
108
accessKeyInfo.AccessKey = keyInfo.AccessKey
109
if err = c.syncAddAccessKey(accessKeyInfo); err != nil {
113
c.fsm.PutKey(keyInfo)
114
c.fsm.PutAKInfo(accessKeyInfo)
117
err = fmt.Errorf("action[CreateNewKey], clusterID[%v] ID:%v, err:%v ", c.Name, keyInfo, err.Error())
118
log.LogError(errors.Stack(err))
122
// DeleteKey delete a key from the keystore
123
func (c *Cluster) DeleteKey(id string) (res *keystore.KeyInfo, err error) {
124
c.fsm.opKeyMutex.Lock()
125
defer c.fsm.opKeyMutex.Unlock()
126
akInfo := new(keystore.AccessKeyInfo)
127
if res, err = c.fsm.GetKey(id); err != nil {
128
err = proto.ErrKeyNotExists
131
if err = c.syncDeleteKey(res); err != nil {
134
akInfo.AccessKey = res.AccessKey
136
if err = c.syncDeleteAccessKey(akInfo); err != nil {
140
c.fsm.DeleteAKInfo(akInfo.AccessKey)
143
err = fmt.Errorf("action[DeleteKey], clusterID[%v] ID:%v, err:%v ", c.Name, id, err.Error())
144
log.LogError(errors.Stack(err))
148
// GetKey get a key from the keystore
149
func (c *Cluster) GetKey(id string) (res *keystore.KeyInfo, err error) {
150
if res, err = c.fsm.GetKey(id); err != nil {
151
err = proto.ErrKeyNotExists
156
err = fmt.Errorf("action[GetKey], clusterID[%v] ID:%v, err:%v ", c.Name, id, err.Error())
157
log.LogError(errors.Stack(err))
161
// GetKey get a key from the AKstore
162
func (c *Cluster) GetAKInfo(accessKey string) (akInfo *keystore.AccessKeyInfo, err error) {
163
if akInfo, err = c.fsm.GetAKInfo(accessKey); err != nil {
164
err = proto.ErrAccessKeyNotExists
169
err = fmt.Errorf("action[GetAKInfo], clusterID[%v] ID:%v, err:%v ", c.Name, accessKey, err.Error())
170
log.LogError(errors.Stack(err))
174
// AddCaps add caps to the key
175
func (c *Cluster) AddCaps(id string, keyInfo *keystore.KeyInfo) (res *keystore.KeyInfo, err error) {
181
c.fsm.opKeyMutex.Lock()
182
defer c.fsm.opKeyMutex.Unlock()
183
if res, err = c.fsm.GetKey(id); err != nil {
184
err = proto.ErrKeyNotExists
188
addCaps = &caps.Caps{}
189
if err = addCaps.Init(keyInfo.Caps); err != nil {
192
curCaps = &caps.Caps{}
193
if err = curCaps.Init(res.Caps); err != nil {
196
curCaps.Union(addCaps)
197
if newCaps, err = json.Marshal(curCaps); err != nil {
201
if err = c.syncAddCaps(res); err != nil {
207
err = fmt.Errorf("action[AddCaps], clusterID[%v] ID:%v, err:%v ", c.Name, keyInfo, err.Error())
208
log.LogError(errors.Stack(err))
212
// DeleteCaps delete caps from the key
213
func (c *Cluster) DeleteCaps(id string, keyInfo *keystore.KeyInfo) (res *keystore.KeyInfo, err error) {
219
c.fsm.opKeyMutex.Lock()
220
defer c.fsm.opKeyMutex.Unlock()
221
if res, err = c.fsm.GetKey(id); err != nil {
222
err = proto.ErrKeyNotExists
226
delCaps = &caps.Caps{}
227
if err = delCaps.Init(keyInfo.Caps); err != nil {
230
curCaps = &caps.Caps{}
231
if err = curCaps.Init(res.Caps); err != nil {
235
curCaps.Delete(delCaps)
237
if newCaps, err = json.Marshal(curCaps); err != nil {
241
if err = c.syncDeleteCaps(res); err != nil {
247
err = fmt.Errorf("action[DeleteCaps], clusterID[%v] ID:%v, err:%v ", c.Name, keyInfo, err.Error())
248
log.LogError(errors.Stack(err))