Refactor code and cleanup with stub completion 31/30931/2
authorKiran <kiran.k.kamineni@intel.com>
Thu, 8 Feb 2018 22:11:44 +0000 (14:11 -0800)
committerKiran Kamineni <kiran.k.kamineni@intel.com>
Fri, 9 Feb 2018 02:08:48 +0000 (02:08 +0000)
Refactored code and moved some structs from handler to backend
Completed the interface that is part of the backend
Currently, the interface implementation is empty and will need to be fleshed out

Issue-ID: AAF-99

Change-Id: I0083bc9d7ce7f6e5294339bf1e270b90c1b3de29
Signed-off-by: Kiran <kiran.k.kamineni@intel.com>
LICENSE.txt [new file with mode: 0644]
sms-service/doc/api_swagger.yaml [moved from sms-service/doc/swagger.yaml with 100% similarity]
sms-service/src/sms/backend/backend.go
sms-service/src/sms/backend/vault.go [new file with mode: 0644]
sms-service/src/sms/backend/vault/vault.go [deleted file]
sms-service/src/sms/config/config.go
sms-service/src/sms/handler/handler.go
sms-service/src/sms/sms.go

diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..5f63bb7
--- /dev/null
@@ -0,0 +1,18 @@
+
+ ============LICENSE_START==========================================
+ ===================================================================
+ Copyright © 2018 Intel Corp, Inc
+ All rights reserved.
+ ===================================================================
+ 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.
+ ============LICENSE_END============================================
index ceb28a4..5611f37 100644 (file)
 
 package backend
 
-import (
-       vaultwrap "sms/backend/vault"
-)
-
-// SecretDomain struct that will be passed around between http handler
-// and code that interfaces with vault
+// SecretDomain is where Secrets are stored.
+// A single domain can have any number of secrets
 type SecretDomain struct {
-       ID         int
-       Name       string
-       MountPoint string
+       UUID string `json:"uuid"`
+       Name string `json:"name"`
+}
+
+// SecretKeyValue is building block for a Secret
+type SecretKeyValue struct {
+       Key   string `json:"name"`
+       Value string `json:"value"`
+}
+
+// Secret is the struct that defines the structure of a secret
+// A single Secret can have any number of SecretKeyValue pairs
+type Secret struct {
+       Name   string           `json:"name"`
+       Values []SecretKeyValue `json:"values"`
 }
 
 // SecretBackend interface that will be implemented for various secret backends
 type SecretBackend interface {
-       Init()
+       Init() error
+
+       GetStatus() (bool, error)
+       GetSecretDomain(name string) (SecretDomain, error)
+       GetSecret(dom string, sec string) (Secret, error)
 
-       GetStatus() bool
+       CreateSecretDomain(name string) (SecretDomain, error)
+       CreateSecret(dom string, sec Secret) (Secret, error)
+
+       DeleteSecretDomain(name string) error
+       DeleteSecret(dom string, name string) error
 }
 
 // InitSecretBackend returns an interface implementation
-func InitSecretBackend() SecretBackend {
-       backendImpl := &vaultwrap.Vault{}
-       backendImpl.Init()
-       return backendImpl
+func InitSecretBackend() (SecretBackend, error) {
+       backendImpl := &Vault{}
+       err := backendImpl.Init()
+       if err != nil {
+               return nil, err
+       }
+
+       return backendImpl, nil
 }
 
 // LoginBackend Interface that will be implemented for various login backends
diff --git a/sms-service/src/sms/backend/vault.go b/sms-service/src/sms/backend/vault.go
new file mode 100644 (file)
index 0000000..f3e2ac1
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2018 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 backend
+
+import (
+       vaultapi "github.com/hashicorp/vault/api"
+
+       smsconfig "sms/config"
+)
+
+// Vault is the main Struct used in Backend to initialize the struct
+type Vault struct {
+       vaultClient *vaultapi.Client
+}
+
+// Init will initialize the vault connection
+// TODO: Check to see if we need to wait for vault to be running
+func (v *Vault) Init() error {
+       vaultCFG := vaultapi.DefaultConfig()
+       vaultCFG.Address = smsconfig.SMSConfig.VaultAddress
+
+       client, err := vaultapi.NewClient(vaultCFG)
+       if err != nil {
+               return err
+       }
+
+       v.vaultClient = client
+       return nil
+}
+
+// GetStatus returns the current seal status of vault
+func (v *Vault) GetStatus() (bool, error) {
+       sys := v.vaultClient.Sys()
+       sealStatus, err := sys.SealStatus()
+       if err != nil {
+               return false, err
+       }
+
+       return sealStatus.Sealed, nil
+}
+
+// GetSecretDomain returns any information related to the secretDomain
+// More information can be added in the future with updates to the struct
+func (v *Vault) GetSecretDomain(name string) (SecretDomain, error) {
+
+       return SecretDomain{}, nil
+}
+
+// GetSecret returns a secret mounted on a particular domain name
+// The secret itself is referenced via its name which translates to
+// a mount path in vault
+func (v *Vault) GetSecret(dom string, sec string) (Secret, error) {
+
+       return Secret{}, nil
+}
+
+// CreateSecretDomain mounts the kv backend on a path with the given name
+func (v *Vault) CreateSecretDomain(name string) (SecretDomain, error) {
+
+       return SecretDomain{}, nil
+}
+
+// CreateSecret creates a secret mounted on a particular domain name
+// The secret itself is mounted on a path specified by name
+func (v *Vault) CreateSecret(dom string, sec Secret) (Secret, error) {
+
+       return Secret{}, nil
+}
+
+// DeleteSecretDomain deletes a secret domain which translates to
+// an unmount operation on the given path in Vault
+func (v *Vault) DeleteSecretDomain(name string) error {
+
+       return nil
+}
+
+// DeleteSecret deletes a secret mounted on the path provided
+func (v *Vault) DeleteSecret(dom string, name string) error {
+
+       return nil
+}
diff --git a/sms-service/src/sms/backend/vault/vault.go b/sms-service/src/sms/backend/vault/vault.go
deleted file mode 100644 (file)
index 37cb19a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2018 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 vault
-
-import (
-       "fmt"
-       "log"
-
-       vaultapi "github.com/hashicorp/vault/api"
-       smsConfig "sms/config"
-)
-
-// Vault is the main Struct used in Backend to initialize the struct
-type Vault struct {
-       vaultClient *vaultapi.Client
-}
-
-// Init will initialize the vault connection
-// TODO: Check to see if we need to wait for vault to be running
-func (v *Vault) Init() {
-       vaultCFG := vaultapi.DefaultConfig()
-       vaultCFG.Address = smsConfig.SMSConfig.VaultAddress
-
-       client, err := vaultapi.NewClient(vaultCFG)
-       if err != nil {
-               log.Fatal(err)
-       }
-
-       v.vaultClient = client
-}
-
-// GetStatus returns the current seal status of vault
-func (v *Vault) GetStatus() bool {
-       sys := v.vaultClient.Sys()
-       fmt.Println(v.vaultClient.Address())
-       sealStatus, err := sys.SealStatus()
-       if err != nil {
-               log.Fatal(err)
-       }
-
-       return sealStatus.Sealed
-}
index d958e15..e1c1b86 100644 (file)
@@ -18,7 +18,6 @@ package config
 
 import (
        "encoding/json"
-       "log"
        "os"
 )
 
@@ -34,19 +33,19 @@ type SMSConfiguration struct {
 var SMSConfig *SMSConfiguration
 
 // ReadConfigFile reads the specified smsConfig file to setup some env variables
-func ReadConfigFile(file string) *SMSConfiguration {
+func ReadConfigFile(file string) (*SMSConfiguration, error) {
        if SMSConfig == nil {
                f, err := os.Open(file)
                if err != nil {
-                       log.Fatalf("Unable to find file %s", file)
+                       return nil, err
                }
 
                decoder := json.NewDecoder(f)
                err = decoder.Decode(&SMSConfig)
                if err != nil {
-                       log.Fatal(err)
+                       return nil, err
                }
        }
 
-       return SMSConfig
+       return SMSConfig, nil
 }
index 79b8618..1b9b869 100644 (file)
@@ -18,51 +18,79 @@ package handler
 
 import (
        "encoding/json"
+       "github.com/gorilla/mux"
        "net/http"
 
        "sms/backend"
-
-       "github.com/gorilla/mux"
 )
 
-type secretDomainJSON struct {
-       name string
+type handler struct {
+       secretBackend backend.SecretBackend
+       loginBackend  backend.LoginBackend
 }
 
-type secretKeyValue struct {
-       name  string
-       value string
-}
+// createSecretDomainHandler creates a secret domain with a name provided
+func (h handler) createSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
+       var d backend.SecretDomain
 
-type secretJSON struct {
-       name   string
-       values []secretKeyValue
+       err := json.NewDecoder(r.Body).Decode(&d)
+       if err != nil {
+               http.Error(w, err.Error(), 400)
+               return
+       }
+
+       h.secretBackend.CreateSecretDomain(d.Name)
 }
 
-type handler struct {
-       secretBackend backend.SecretBackend
-       loginBackend  backend.LoginBackend
+// getSecretDomainHandler returns list of secret domains
+func (h handler) getSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       domName := vars["domName"]
+
+       h.secretBackend.GetSecretDomain(domName)
+       //encode data into json and return
 }
 
-// GetSecretDomainHandler returns list of secret domains
-func (h handler) GetSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
+// deleteSecretDomainHandler deletes a secret domain with the name provided
+func (h handler) deleteSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       domName := vars["domName"]
 
+       h.secretBackend.DeleteSecretDomain(domName)
 }
 
-// CreateSecretDomainHandler creates a secret domain with a name provided
-func (h handler) CreateSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
-       var d secretDomainJSON
+// createSecretHandler handles creation of secrets on a given domain name
+func (h handler) createSecretHandler(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       domName := vars["domName"]
 
-       err := json.NewDecoder(r.Body).Decode(&d)
+       var b backend.Secret
+       err := json.NewDecoder(r.Body).Decode(&b)
        if err != nil {
                http.Error(w, err.Error(), 400)
                return
        }
+
+       h.secretBackend.CreateSecret(domName, b)
+}
+
+// getSecretHandler handles reading a secret by given domain name and secret name
+func (h handler) getSecretHandler(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       domName := vars["domName"]
+       secName := vars["secretName"]
+
+       h.secretBackend.GetSecret(domName, secName)
+       //encode and return response
 }
 
-// DeleteSecretDomainHandler deletes a secret domain with the ID provided
-func (h handler) DeleteSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
+// deleteSecretHandler handles deleting a secret by given domain name and secret name
+func (h handler) deleteSecretHandler(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       domName := vars["domName"]
+       secName := vars["secretName"]
 
+       h.secretBackend.DeleteSecret(domName, secName)
 }
 
 // struct that tracks various status items for SMS and backend
@@ -70,19 +98,24 @@ type status struct {
        Seal bool `json:"sealstatus"`
 }
 
-// StatusHandler returns information related to SMS and SMS backend services
-func (h handler) StatusHandler(w http.ResponseWriter, r *http.Request) {
-       s := h.secretBackend.GetStatus()
+// statusHandler returns information related to SMS and SMS backend services
+func (h handler) statusHandler(w http.ResponseWriter, r *http.Request) {
+       s, err := h.secretBackend.GetStatus()
+       if err != nil {
+               http.Error(w, err.Error(), 500)
+               return
+       }
+
        status := status{Seal: s}
-       err := json.NewEncoder(w).Encode(status)
+       err = json.NewEncoder(w).Encode(status)
        if err != nil {
-               http.Error(w, err.Error(), 400)
+               http.Error(w, err.Error(), 500)
                return
        }
 }
 
-// LoginHandler handles login via password and username
-func (h handler) LoginHandler(w http.ResponseWriter, r *http.Request) {
+// loginHandler handles login via password and username
+func (h handler) loginHandler(w http.ResponseWriter, r *http.Request) {
 
 }
 
@@ -93,13 +126,17 @@ func CreateRouter(b backend.SecretBackend) http.Handler {
        // Create a new mux to handle URL endpoints
        router := mux.NewRouter()
 
-       router.HandleFunc("/v1/sms/login", h.LoginHandler).Methods("POST")
+       router.HandleFunc("/v1/sms/login", h.loginHandler).Methods("POST")
+
+       router.HandleFunc("/v1/sms/status", h.statusHandler).Methods("GET")
 
-       router.HandleFunc("/v1/sms/status", h.StatusHandler).Methods("GET")
+       router.HandleFunc("/v1/sms/domain", h.createSecretDomainHandler).Methods("POST")
+       router.HandleFunc("/v1/sms/domain/{domName}", h.getSecretDomainHandler).Methods("GET")
+       router.HandleFunc("/v1/sms/domain/{domName}", h.deleteSecretDomainHandler).Methods("DELETE")
 
-       router.HandleFunc("/v1/sms/domain", h.GetSecretDomainHandler).Methods("GET")
-       router.HandleFunc("/v1/sms/domain", h.CreateSecretDomainHandler).Methods("POST")
-       router.HandleFunc("/v1/sms/domain/{domName}", h.DeleteSecretDomainHandler).Methods("DELETE")
+       router.HandleFunc("v1/sms/domain/{domainName}/secret", h.createSecretHandler).Methods("POST")
+       router.HandleFunc("v1/sms/domain/{domainName}/secret/{secretName}", h.getSecretHandler).Methods("GET")
+       router.HandleFunc("v1/sms/domain/{domainName}/secret/{secretName}", h.deleteSecretHandler).Methods("DELETE")
 
        return router
 }
index 8fdf399..98b2824 100644 (file)
@@ -28,9 +28,16 @@ import (
 
 func main() {
        // Read Configuration File
-       smsConf := smsconfig.ReadConfigFile("smsconfig.json")
+       smsConf, err := smsconfig.ReadConfigFile("smsconfig.json")
+       if err != nil {
+               log.Fatal(err)
+       }
+
+       backendImpl, err := smsbackend.InitSecretBackend()
+       if err != nil {
+               log.Fatal(err)
+       }
 
-       backendImpl := smsbackend.InitSecretBackend()
        httpRouter := smshandler.CreateRouter(backendImpl)
 
        // TODO: Use CA certificate from AAF
@@ -42,6 +49,6 @@ func main() {
                TLSConfig: tlsConfig,
        }
 
-       err := httpServer.ListenAndServeTLS(smsConf.ServerCert, smsConf.ServerKey)
+       err = httpServer.ListenAndServeTLS(smsConf.ServerCert, smsConf.ServerKey)
        log.Fatal(err)
 }