aboutsummaryrefslogtreecommitdiffstats
path: root/src/k8splugin/internal/namegenerator/namegenerator.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/k8splugin/internal/namegenerator/namegenerator.go')
-rw-r--r--src/k8splugin/internal/namegenerator/namegenerator.go148
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()
+}