aboutsummaryrefslogtreecommitdiffstats
path: root/src/k8splugin/internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/k8splugin/internal')
-rw-r--r--src/k8splugin/internal/app/instance.go13
-rw-r--r--src/k8splugin/internal/namegenerator/namegenerator.go148
2 files changed, 151 insertions, 10 deletions
diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go
index cf96d50c..47cea972 100644
--- a/src/k8splugin/internal/app/instance.go
+++ b/src/k8splugin/internal/app/instance.go
@@ -17,13 +17,12 @@
package app
import (
- "encoding/base64"
"encoding/json"
"log"
- "math/rand"
"github.com/onap/multicloud-k8s/src/k8splugin/internal/db"
"github.com/onap/multicloud-k8s/src/k8splugin/internal/helm"
+ "github.com/onap/multicloud-k8s/src/k8splugin/internal/namegenerator"
"github.com/onap/multicloud-k8s/src/k8splugin/internal/rb"
pkgerrors "github.com/pkg/errors"
@@ -88,13 +87,6 @@ type InstanceClient struct {
tagInst string
}
-// Using 6 bytes of randomness to generate an 8 character string
-func generateInstanceID() string {
- b := make([]byte, 6)
- rand.Read(b)
- return base64.URLEncoding.EncodeToString(b)
-}
-
// NewInstanceClient returns an instance of the InstanceClient
// which implements the InstanceManager
func NewInstanceClient() *InstanceClient {
@@ -127,7 +119,8 @@ func (v *InstanceClient) Create(i InstanceRequest) (InstanceResponse, error) {
return InstanceResponse{}, pkgerrors.Wrap(err, "Error resolving helm charts")
}
- id := generateInstanceID()
+ // TODO: Only generate if id is not provided
+ id := namegenerator.Generate()
k8sClient := KubernetesClient{}
err = k8sClient.init(i.CloudRegion, id)
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()
+}