github.com/polarismesh/polaris@v1.17.8/store/boltdb/namespace.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package boltdb 19 20 import ( 21 "errors" 22 "fmt" 23 "sort" 24 "time" 25 26 "github.com/polarismesh/polaris/common/model" 27 "github.com/polarismesh/polaris/common/utils" 28 ) 29 30 const ( 31 tblNameNamespace string = "namespace" 32 OwnerAttribute string = "owner" 33 NameAttribute string = "name" 34 ) 35 36 type namespaceStore struct { 37 handler BoltHandler 38 } 39 40 const ( 41 defaultNamespace = "default" 42 polarisNamespace = "Polaris" 43 ) 44 45 var ( 46 namespaceToToken = map[string]string{ 47 defaultNamespace: "e2e473081d3d4306b52264e49f7ce227", 48 polarisNamespace: "2d1bfe5d12e04d54b8ee69e62494c7fd", 49 } 50 namespaceToComment = map[string]string{ 51 defaultNamespace: "Default Environment", 52 polarisNamespace: "Polaris-server", 53 } 54 ) 55 56 // InitData initialize the namespace data 57 func (n *namespaceStore) InitData() error { 58 namespaces := []string{defaultNamespace, polarisNamespace} 59 for _, namespace := range namespaces { 60 ns, err := n.GetNamespace(namespace) 61 if err != nil { 62 return err 63 } 64 if ns == nil { 65 err = n.AddNamespace(&model.Namespace{ 66 Name: namespace, 67 Comment: namespaceToComment[namespace], 68 Token: namespaceToToken[namespace], 69 Owner: "polaris", 70 Valid: true, 71 CreateTime: time.Now(), 72 ModifyTime: time.Now(), 73 }) 74 if err != nil { 75 return err 76 } 77 } 78 } 79 return nil 80 } 81 82 // AddNamespace add a namespace 83 func (n *namespaceStore) AddNamespace(namespace *model.Namespace) error { 84 if namespace.Name == "" { 85 return errors.New("store add namespace name is empty") 86 } 87 88 // 先删除无效数据,再添加新数据 89 if err := n.cleanNamespace(namespace.Name); err != nil { 90 return err 91 } 92 93 tn := time.Now() 94 95 namespace.CreateTime = tn 96 namespace.ModifyTime = tn 97 namespace.Valid = true 98 return n.handler.SaveValue(tblNameNamespace, namespace.Name, namespace) 99 } 100 101 func (n *namespaceStore) cleanNamespace(name string) error { 102 if err := n.handler.DeleteValues(tblNameNamespace, []string{name}); err != nil { 103 log.Errorf("[Store][boltdb] delete invalid namespace error, %+v", err) 104 return err 105 } 106 107 return nil 108 } 109 110 // UpdateNamespace update a namespace 111 func (n *namespaceStore) UpdateNamespace(namespace *model.Namespace) error { 112 if namespace.Name == "" { 113 return errors.New("store update namespace name is empty") 114 } 115 properties := make(map[string]interface{}) 116 properties["Owner"] = namespace.Owner 117 properties["Comment"] = namespace.Comment 118 properties["ModifyTime"] = time.Now() 119 return n.handler.UpdateValue(tblNameNamespace, namespace.Name, properties) 120 } 121 122 // UpdateNamespaceToken update the token of a namespace 123 func (n *namespaceStore) UpdateNamespaceToken(name string, token string) error { 124 if name == "" || token == "" { 125 return fmt.Errorf( 126 "store update namespace token some param are empty, name is %s, token is %s", name, token) 127 } 128 properties := make(map[string]interface{}) 129 properties["Token"] = token 130 properties["ModifyTime"] = time.Now() 131 return n.handler.UpdateValue(tblNameNamespace, name, properties) 132 } 133 134 // GetNamespace query namespace by name 135 func (n *namespaceStore) GetNamespace(name string) (*model.Namespace, error) { 136 values, err := n.handler.LoadValues(tblNameNamespace, []string{name}, &model.Namespace{}) 137 if err != nil { 138 return nil, err 139 } 140 nsValue, ok := values[name] 141 if !ok { 142 return nil, nil 143 } 144 ns := nsValue.(*model.Namespace) 145 return ns, nil 146 } 147 148 type NamespaceSlice []*model.Namespace 149 150 // Len length of namespace slice 151 func (ns NamespaceSlice) Len() int { 152 return len(ns) 153 } 154 155 // Less compare namespace 156 func (ns NamespaceSlice) Less(i, j int) bool { 157 return ns[i].ModifyTime.Before(ns[j].ModifyTime) 158 } 159 160 // Swap swap elements 161 func (ns NamespaceSlice) Swap(i, j int) { 162 ns[i], ns[j] = ns[j], ns[i] 163 } 164 165 func matchFieldValue(value string, pattern string) bool { 166 if utils.IsWildName(pattern) { 167 return utils.IsWildMatch(value, pattern) 168 } 169 return pattern == value 170 } 171 172 func matchFieldValueByPatterns(value string, patterns []string) bool { 173 for _, p := range patterns { 174 if matchFieldValue(value, p) { 175 return true 176 } 177 } 178 return false 179 } 180 181 // GetNamespaces get namespaces by offset and limit 182 func (n *namespaceStore) GetNamespaces( 183 filter map[string][]string, offset, limit int) ([]*model.Namespace, uint32, error) { 184 values, err := n.handler.LoadValuesAll(tblNameNamespace, &model.Namespace{}) 185 if err != nil { 186 return nil, 0, err 187 } 188 namespaces := NamespaceSlice(toNamespaces(values)) 189 190 ret := make([]*model.Namespace, 0) 191 for i := range namespaces { 192 ns := namespaces[i] 193 if !ns.Valid { 194 continue 195 } 196 matched := true 197 for index, patterns := range filter { 198 if index == OwnerAttribute { 199 if matched = matchFieldValueByPatterns(ns.Owner, patterns); !matched { 200 break 201 } 202 } 203 if index == NameAttribute { 204 if matched = matchFieldValueByPatterns(ns.Name, patterns); !matched { 205 break 206 } 207 } 208 } 209 if matched { 210 ret = append(ret, ns) 211 } 212 } 213 namespaces = ret 214 215 sort.Sort(sort.Reverse(namespaces)) 216 startIdx := offset 217 if startIdx >= len(namespaces) { 218 return nil, uint32(len(namespaces)), nil 219 } 220 endIdx := startIdx + limit 221 if endIdx > len(namespaces) { 222 endIdx = len(namespaces) 223 } 224 ret = namespaces[startIdx:endIdx] 225 return ret, uint32(len(namespaces)), nil 226 } 227 228 func toNamespaces(values map[string]interface{}) []*model.Namespace { 229 namespaces := make([]*model.Namespace, 0, len(values)) 230 for _, nsValue := range values { 231 namespaces = append(namespaces, nsValue.(*model.Namespace)) 232 } 233 return namespaces 234 } 235 236 // GetMoreNamespaces get the latest updated namespaces 237 func (n *namespaceStore) GetMoreNamespaces(mtime time.Time) ([]*model.Namespace, error) { 238 values, err := n.handler.LoadValuesByFilter( 239 tblNameNamespace, []string{"ModifyTime"}, &model.Namespace{}, func(value map[string]interface{}) bool { 240 mTimeValue, ok := value["ModifyTime"] 241 if !ok { 242 return false 243 } 244 return mTimeValue.(time.Time).After(mtime) 245 }) 246 if err != nil { 247 return nil, err 248 } 249 return toNamespaces(values), nil 250 }