diff options
Diffstat (limited to 'src/k8splugin/internal/namegenerator/namegenerator.go')
-rw-r--r-- | src/k8splugin/internal/namegenerator/namegenerator.go | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/k8splugin/internal/namegenerator/namegenerator.go b/src/k8splugin/internal/namegenerator/namegenerator.go new file mode 100644 index 00000000..1980944f --- /dev/null +++ b/src/k8splugin/internal/namegenerator/namegenerator.go @@ -0,0 +1,148 @@ +/* + * Copyright 2019 Intel Corporation, Inc + * + * 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 namegenerator + +import ( + "encoding/json" + "log" + "strings" + "sync" + + "github.com/onap/multicloud-k8s/src/k8splugin/internal/db" + + "github.com/moby/moby/pkg/namesgenerator" + pkgerrors "github.com/pkg/errors" +) + +const ( + storeName = "instanceNames" + tag = "names" +) + +var ( + nameCache = &cache{} + cacheKeyGlobal = cacheKey{"k8sPluginCacheKey"} +) + +type cache struct { + cache map[string]bool + mux sync.Mutex +} + +type cacheKey struct { + Key string `json:"key"` +} + +func (c cacheKey) String() string { + + out, err := json.Marshal(c) + if err != nil { + return "" + } + + return string(out) +} + +func (c *cache) init() { + + // We have either restarted or this is the first time + // that a name is being requested since the service came + // up. + if c.cache == nil { + c.cache = make(map[string]bool) + err := c.readCacheFromDB() + if err != nil { + log.Println("Error Reading from DB: ", err.Error()) + return + } + } +} + +func (c *cache) isAlreadyUsed(name string) bool { + + if _, ok := c.cache[name]; ok { + return true + } + return false +} + +func (c *cache) readCacheFromDB() error { + + // Read the latest from cache + data, err := db.DBconn.Read(storeName, cacheKeyGlobal, tag) + if err != nil { + log.Println("Error reading name cache from Database: ", err) + return pkgerrors.Wrap(err, "Reading cache from DB") + } + + err = db.DBconn.Unmarshal(data, &c.cache) + if err != nil { + log.Println("Error unmarshaling data into cache: ", err) + return pkgerrors.Wrap(err, "Unmarshaling cache from DB") + } + + return nil +} + +// writeCacheToDB will update the DB with the updated cache +func (c *cache) writeCacheToDB() { + + //Update the database as well + err := db.DBconn.Update(storeName, cacheKeyGlobal, tag, c.cache) + if err != nil { + // TODO: Replace with DBconn variable + if strings.Contains(err.Error(), "Error finding master table") { + err = db.DBconn.Create(storeName, cacheKeyGlobal, tag, c.cache) + if err != nil { + log.Println("Error creating the entry in DB. Will try later...") + return + } + } else { + log.Println("Error updating DB: ", err.Error()) + return + } + } +} + +func (c *cache) generateName() string { + c.mux.Lock() + defer c.mux.Unlock() + + c.init() + + for { + //Call moby package here to generate name + name := namesgenerator.GetRandomName(0) + if c.isAlreadyUsed(name) { + // Generate another name + log.Printf("Name %s already used", name) + continue + } + + c.cache[name] = true + + // Update the cache and db + c.writeCacheToDB() + return name + } +} + +// Generate returns an autogenerated name +func Generate() string { + + return nameCache.generateName() +} |