cubefs

Форк
0
/
cluster.go 
250 строк · 6.6 Кб
1
// Copyright 2018 The CubeFS 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
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
14

15
package authnode
16

17
import (
18
	"encoding/json"
19
	"fmt"
20
	"time"
21

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"
30
)
31

32
// PKIKey defines the pki keys
33
type PKIKey struct {
34
	EnableHTTPS        bool
35
	AuthRootPrivateKey []byte
36
	AuthRootPublicKey  []byte
37
}
38

39
// Cluster stores all the cluster-level information.
40
type Cluster struct {
41
	Name                string
42
	leaderInfo          *LeaderInfo
43
	cfg                 *clusterConfig
44
	retainLogs          uint64
45
	DisableAutoAllocate bool
46
	fsm                 *KeystoreFsm
47
	partition           raftstore.Partition
48
	AuthSecretKey       []byte
49
	AuthRootKey         []byte
50
	PKIKey              PKIKey
51
}
52

53
func newCluster(name string, leaderInfo *LeaderInfo, fsm *KeystoreFsm, partition raftstore.Partition, cfg *clusterConfig) (c *Cluster) {
54
	c = new(Cluster)
55
	c.Name = name
56
	c.leaderInfo = leaderInfo
57
	c.cfg = cfg
58
	c.fsm = fsm
59
	c.partition = partition
60
	c.fsm.keystore = make(map[string]*keystore.KeyInfo, 0)
61
	c.fsm.accessKeystore = make(map[string]*keystore.AccessKeyInfo, 0)
62
	return
63
}
64

65
func (c *Cluster) scheduleTask() {
66
	c.scheduleToCheckHeartbeat()
67
}
68

69
func (c *Cluster) authAddr() (addr string) {
70
	return c.leaderInfo.addr
71
}
72

73
func (c *Cluster) scheduleToCheckHeartbeat() {
74
	go func() {
75
		for {
76
			if c.partition != nil && c.partition.IsRaftLeader() {
77
				c.checkLeaderAddr()
78
			}
79
			time.Sleep(time.Second * defaultIntervalToCheckHeartbeat)
80
		}
81
	}()
82
}
83

84
func (c *Cluster) checkLeaderAddr() {
85
	leaderID, _ := c.partition.LeaderTerm()
86
	c.leaderInfo.addr = AddrDatabase[leaderID]
87
}
88

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{
94
		ID: keyInfo.ID,
95
	}
96
	if _, err = c.fsm.GetKey(id); err == nil {
97
		err = proto.ErrDuplicateKey
98
		goto errHandler
99
	}
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 {
106
		goto errHandler
107
	}
108
	accessKeyInfo.AccessKey = keyInfo.AccessKey
109
	if err = c.syncAddAccessKey(accessKeyInfo); err != nil {
110
		goto errHandler
111
	}
112
	res = keyInfo
113
	c.fsm.PutKey(keyInfo)
114
	c.fsm.PutAKInfo(accessKeyInfo)
115
	return
116
errHandler:
117
	err = fmt.Errorf("action[CreateNewKey], clusterID[%v] ID:%v, err:%v ", c.Name, keyInfo, err.Error())
118
	log.LogError(errors.Stack(err))
119
	return
120
}
121

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
129
		goto errHandler
130
	}
131
	if err = c.syncDeleteKey(res); err != nil {
132
		goto errHandler
133
	}
134
	akInfo.AccessKey = res.AccessKey
135
	akInfo.ID = res.ID
136
	if err = c.syncDeleteAccessKey(akInfo); err != nil {
137
		goto errHandler
138
	}
139
	c.fsm.DeleteKey(id)
140
	c.fsm.DeleteAKInfo(akInfo.AccessKey)
141
	return
142
errHandler:
143
	err = fmt.Errorf("action[DeleteKey], clusterID[%v] ID:%v, err:%v ", c.Name, id, err.Error())
144
	log.LogError(errors.Stack(err))
145
	return
146
}
147

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
152
		goto errHandler
153
	}
154
	return
155
errHandler:
156
	err = fmt.Errorf("action[GetKey], clusterID[%v] ID:%v, err:%v ", c.Name, id, err.Error())
157
	log.LogError(errors.Stack(err))
158
	return
159
}
160

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
165
		goto errHandler
166
	}
167
	return
168
errHandler:
169
	err = fmt.Errorf("action[GetAKInfo], clusterID[%v] ID:%v, err:%v ", c.Name, accessKey, err.Error())
170
	log.LogError(errors.Stack(err))
171
	return
172
}
173

174
// AddCaps add caps to the key
175
func (c *Cluster) AddCaps(id string, keyInfo *keystore.KeyInfo) (res *keystore.KeyInfo, err error) {
176
	var (
177
		addCaps *caps.Caps
178
		curCaps *caps.Caps
179
		newCaps []byte
180
	)
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
185
		goto errHandler
186
	}
187

188
	addCaps = &caps.Caps{}
189
	if err = addCaps.Init(keyInfo.Caps); err != nil {
190
		goto errHandler
191
	}
192
	curCaps = &caps.Caps{}
193
	if err = curCaps.Init(res.Caps); err != nil {
194
		goto errHandler
195
	}
196
	curCaps.Union(addCaps)
197
	if newCaps, err = json.Marshal(curCaps); err != nil {
198
		goto errHandler
199
	}
200
	res.Caps = newCaps
201
	if err = c.syncAddCaps(res); err != nil {
202
		goto errHandler
203
	}
204
	c.fsm.PutKey(res)
205
	return
206
errHandler:
207
	err = fmt.Errorf("action[AddCaps], clusterID[%v] ID:%v, err:%v ", c.Name, keyInfo, err.Error())
208
	log.LogError(errors.Stack(err))
209
	return
210
}
211

212
// DeleteCaps delete caps from the key
213
func (c *Cluster) DeleteCaps(id string, keyInfo *keystore.KeyInfo) (res *keystore.KeyInfo, err error) {
214
	var (
215
		delCaps *caps.Caps
216
		curCaps *caps.Caps
217
		newCaps []byte
218
	)
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
223
		goto errHandler
224
	}
225

226
	delCaps = &caps.Caps{}
227
	if err = delCaps.Init(keyInfo.Caps); err != nil {
228
		return
229
	}
230
	curCaps = &caps.Caps{}
231
	if err = curCaps.Init(res.Caps); err != nil {
232
		return
233
	}
234

235
	curCaps.Delete(delCaps)
236

237
	if newCaps, err = json.Marshal(curCaps); err != nil {
238
		goto errHandler
239
	}
240
	res.Caps = newCaps
241
	if err = c.syncDeleteCaps(res); err != nil {
242
		goto errHandler
243
	}
244
	c.fsm.PutKey(res)
245
	return
246
errHandler:
247
	err = fmt.Errorf("action[DeleteCaps], clusterID[%v] ID:%v, err:%v ", c.Name, keyInfo, err.Error())
248
	log.LogError(errors.Stack(err))
249
	return
250
}
251

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.