summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKiran <kiran.k.kamineni@intel.com>2018-02-05 14:04:32 -0800
committerKiran <kiran.k.kamineni@intel.com>2018-02-05 14:19:57 -0800
commit53b6f4630af634272ed60d582f9bb29205c6ff17 (patch)
tree45f879bbdd86b9d47aa5a3527fcb32b4f68a961b
parent611e20c99b004e5fd64e456986c172d80f34f125 (diff)
Initial Project Structure
Includes a directory stucture for all the current components The implemented code establishes a mTLS connection to client and serves a GET status request Other requests and handlers will come in future patches Issue-ID: AAF-102 Change-Id: Ib3bca066586d23330b10550f83772ab11aacabc7 Signed-off-by: Kiran <kiran.k.kamineni@intel.com>
-rw-r--r--.gitreview4
-rw-r--r--sms-cli/.keep0
-rw-r--r--sms-client/.keep0
-rw-r--r--sms-gui/.keep0
-rw-r--r--sms-service/.gitignore4
-rw-r--r--sms-service/doc/swagger.yaml588
-rw-r--r--sms-service/src/sms/Gopkg.lock134
-rw-r--r--sms-service/src/sms/Gopkg.toml29
-rw-r--r--sms-service/src/sms/auth/auth.go51
-rw-r--r--sms-service/src/sms/backend/backend.go47
-rw-r--r--sms-service/src/sms/backend/vault/vault.go56
-rw-r--r--sms-service/src/sms/config/config.go52
-rw-r--r--sms-service/src/sms/handler/handler.go105
-rw-r--r--sms-service/src/sms/sms.go47
-rw-r--r--sms-service/src/sms/smsconfig.json7
15 files changed, 1124 insertions, 0 deletions
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..651dace
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.onap.org
+port=29418
+project=aaf/sms.git
diff --git a/sms-cli/.keep b/sms-cli/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sms-cli/.keep
diff --git a/sms-client/.keep b/sms-client/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sms-client/.keep
diff --git a/sms-gui/.keep b/sms-gui/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sms-gui/.keep
diff --git a/sms-service/.gitignore b/sms-service/.gitignore
new file mode 100644
index 0000000..e98d43b
--- /dev/null
+++ b/sms-service/.gitignore
@@ -0,0 +1,4 @@
+pkg/
+src/sms/.vscode/
+src/sms/vendor/
+src/sms/test/
diff --git a/sms-service/doc/swagger.yaml b/sms-service/doc/swagger.yaml
new file mode 100644
index 0000000..c1fb634
--- /dev/null
+++ b/sms-service/doc/swagger.yaml
@@ -0,0 +1,588 @@
+swagger: "2.0"
+info:
+ description: "This is a service that provides secret management facilities"
+ version: "1.0.0"
+ title: "Secret Management Service"
+ contact:
+ email: "kiran.k.kamineni@intel.com"
+ license:
+ name: "Apache 2.0"
+ url: "http://www.apache.org/licenses/LICENSE-2.0.html"
+host: "aaf.onap.org:8000"
+basePath: "/v1/sms/"
+tags:
+- name: "domain"
+ description: "Operations related to Secret Domains"
+ externalDocs:
+ description: "Find out more"
+ url: "http://swagger.io"
+- name: "secret"
+ description: "Operations related to Secrets"
+schemes:
+- "https"
+paths:
+ /domain:
+ post:
+ tags:
+ - "domain"
+ summary: "Add a new domain"
+ description: ""
+ operationId: "addDomain"
+ consumes:
+ - "application/json"
+ produces:
+ - "application/json"
+ parameters:
+ - in: "body"
+ name: "body"
+ required: true
+ schema:
+ $ref: "#/definitions/Domain"
+ responses:
+ 405:
+ description: "Invalid input"
+ 200:
+ description: "Successful Creation"
+ schema:
+ $ref: "#/definitions/Domain"
+ /domain/{domain_name}:
+ get:
+ tags:
+ - "domain"
+ summary: "Gets domain by name"
+ description: "Multiple status values can be provided with comma separated strings"
+ operationId: "findPetsByStatus"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - name: "status"
+ in: "query"
+ description: "Status values that need to be considered for filter"
+ required: true
+ type: "array"
+ items:
+ type: "string"
+ enum:
+ - "available"
+ - "pending"
+ - "sold"
+ default: "available"
+ collectionFormat: "multi"
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ type: "array"
+ items:
+ $ref: "#/definitions/Pet"
+ 400:
+ description: "Invalid status value"
+ security:
+ - petstore_auth:
+ - "write:pets"
+ - "read:pets"
+ /pet/findByTags:
+ get:
+ tags:
+ - "pet"
+ summary: "Finds Pets by tags"
+ description: "Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing."
+ operationId: "findPetsByTags"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - name: "tags"
+ in: "query"
+ description: "Tags to filter by"
+ required: true
+ type: "array"
+ items:
+ type: "string"
+ collectionFormat: "multi"
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ type: "array"
+ items:
+ $ref: "#/definitions/Pet"
+ 400:
+ description: "Invalid tag value"
+ security:
+ - petstore_auth:
+ - "write:pets"
+ - "read:pets"
+ deprecated: true
+ /{domainName}/{secretName}:
+ get:
+ tags:
+ - "secret"
+ summary: "Find Secret by Name"
+ description: "Returns a single secret"
+ operationId: "getSecretByName"
+ produces:
+ - "application/json"
+ parameters:
+ - name: "domainName"
+ in: "path"
+ description: "Name of the domain in which to look at"
+ required: true
+ type: "string"
+ - name: "secretName"
+ in: "path"
+ description: "Name of the secret which is needed"
+ required: true
+ type: "string"
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ $ref: "#/definitions/Secret"
+ 404:
+ description: "Invalid Path or Path not found"
+ security:
+ - api_key: []
+ delete:
+ tags:
+ - "secret"
+ summary: "Deletes a Secret"
+ description: ""
+ operationId: "deleteSecret"
+ produces:
+ - "application/json"
+ parameters:
+ - name: "token"
+ in: "header"
+ required: true
+ type: "string"
+ - name: "secretName"
+ in: "path"
+ description: "Name of Secret to Delete"
+ required: true
+ type: "string"
+ - name: "domainName"
+ in: "path"
+ description: "Path to the SecretDomain which contains the Secret"
+ type: "string"
+ responses:
+ 204:
+ description: "Successful Deletion"
+ 404:
+ description: "Invalid Path or Path not found"
+ /pet/{petId}/uploadImage:
+ post:
+ tags:
+ - "pet"
+ summary: "uploads an image"
+ description: ""
+ operationId: "uploadFile"
+ consumes:
+ - "multipart/form-data"
+ produces:
+ - "application/json"
+ parameters:
+ - name: "petId"
+ in: "path"
+ description: "ID of pet to update"
+ required: true
+ type: "integer"
+ format: "int64"
+ - name: "additionalMetadata"
+ in: "formData"
+ description: "Additional data to pass to server"
+ required: false
+ type: "string"
+ - name: "file"
+ in: "formData"
+ description: "file to upload"
+ required: false
+ type: "file"
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ $ref: "#/definitions/ApiResponse"
+ security:
+ - petstore_auth:
+ - "write:pets"
+ - "read:pets"
+ /store/inventory:
+ get:
+ tags:
+ - "store"
+ summary: "Returns pet inventories by status"
+ description: "Returns a map of status codes to quantities"
+ operationId: "getInventory"
+ produces:
+ - "application/json"
+ parameters: []
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ type: "object"
+ additionalProperties:
+ type: "integer"
+ format: "int32"
+ security:
+ - api_key: []
+ /store/order:
+ post:
+ tags:
+ - "store"
+ summary: "Place an order for a pet"
+ description: ""
+ operationId: "placeOrder"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - in: "body"
+ name: "body"
+ description: "order placed for purchasing the pet"
+ required: true
+ schema:
+ $ref: "#/definitions/Order"
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ $ref: "#/definitions/Order"
+ 400:
+ description: "Invalid Order"
+ /store/order/{orderId}:
+ get:
+ tags:
+ - "store"
+ summary: "Find purchase order by ID"
+ description: "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions"
+ operationId: "getOrderById"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - name: "orderId"
+ in: "path"
+ description: "ID of pet that needs to be fetched"
+ required: true
+ type: "integer"
+ maximum: 10.0
+ minimum: 1.0
+ format: "int64"
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ $ref: "#/definitions/Order"
+ 400:
+ description: "Invalid ID supplied"
+ 404:
+ description: "Order not found"
+ delete:
+ tags:
+ - "store"
+ summary: "Delete purchase order by ID"
+ description: "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors"
+ operationId: "deleteOrder"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - name: "orderId"
+ in: "path"
+ description: "ID of the order that needs to be deleted"
+ required: true
+ type: "integer"
+ minimum: 1.0
+ format: "int64"
+ responses:
+ 400:
+ description: "Invalid ID supplied"
+ 404:
+ description: "Order not found"
+ /user:
+ post:
+ tags:
+ - "user"
+ summary: "Create user"
+ description: "This can only be done by the logged in user."
+ operationId: "createUser"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - in: "body"
+ name: "body"
+ description: "Created user object"
+ required: true
+ schema:
+ $ref: "#/definitions/User"
+ responses:
+ default:
+ description: "successful operation"
+ /user/createWithArray:
+ post:
+ tags:
+ - "user"
+ summary: "Creates list of users with given input array"
+ description: ""
+ operationId: "createUsersWithArrayInput"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - in: "body"
+ name: "body"
+ description: "List of user object"
+ required: true
+ schema:
+ type: "array"
+ items:
+ $ref: "#/definitions/User"
+ responses:
+ default:
+ description: "successful operation"
+ /user/createWithList:
+ post:
+ tags:
+ - "user"
+ summary: "Creates list of users with given input array"
+ description: ""
+ operationId: "createUsersWithListInput"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - in: "body"
+ name: "body"
+ description: "List of user object"
+ required: true
+ schema:
+ type: "array"
+ items:
+ $ref: "#/definitions/User"
+ responses:
+ default:
+ description: "successful operation"
+ /user/login:
+ get:
+ tags:
+ - "user"
+ summary: "Logs user into the system"
+ description: ""
+ operationId: "loginUser"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - name: "username"
+ in: "query"
+ description: "The user name for login"
+ required: true
+ type: "string"
+ - name: "password"
+ in: "query"
+ description: "The password for login in clear text"
+ required: true
+ type: "string"
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ type: "string"
+ headers:
+ X-Rate-Limit:
+ type: "integer"
+ format: "int32"
+ description: "calls per hour allowed by the user"
+ X-Expires-After:
+ type: "string"
+ format: "date-time"
+ description: "date in UTC when token expires"
+ 400:
+ description: "Invalid username/password supplied"
+ /user/logout:
+ get:
+ tags:
+ - "user"
+ summary: "Logs out current logged in user session"
+ description: ""
+ operationId: "logoutUser"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters: []
+ responses:
+ default:
+ description: "successful operation"
+ /user/{username}:
+ get:
+ tags:
+ - "user"
+ summary: "Get user by user name"
+ description: ""
+ operationId: "getUserByName"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - name: "username"
+ in: "path"
+ description: "The name that needs to be fetched. Use user1 for testing. "
+ required: true
+ type: "string"
+ responses:
+ 200:
+ description: "successful operation"
+ schema:
+ $ref: "#/definitions/User"
+ 400:
+ description: "Invalid username supplied"
+ 404:
+ description: "User not found"
+ put:
+ tags:
+ - "user"
+ summary: "Updated user"
+ description: "This can only be done by the logged in user."
+ operationId: "updateUser"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - name: "username"
+ in: "path"
+ description: "name that need to be updated"
+ required: true
+ type: "string"
+ - in: "body"
+ name: "body"
+ description: "Updated user object"
+ required: true
+ schema:
+ $ref: "#/definitions/User"
+ responses:
+ 400:
+ description: "Invalid user supplied"
+ 404:
+ description: "User not found"
+ delete:
+ tags:
+ - "user"
+ summary: "Delete user"
+ description: "This can only be done by the logged in user."
+ operationId: "deleteUser"
+ produces:
+ - "application/xml"
+ - "application/json"
+ parameters:
+ - name: "username"
+ in: "path"
+ description: "The name that needs to be deleted"
+ required: true
+ type: "string"
+ responses:
+ 400:
+ description: "Invalid username supplied"
+ 404:
+ description: "User not found"
+securityDefinitions:
+ petstore_auth:
+ type: "oauth2"
+ authorizationUrl: "http://petstore.swagger.io/oauth/dialog"
+ flow: "implicit"
+ scopes:
+ write:pets: "modify pets in your account"
+ read:pets: "read your pets"
+ api_key:
+ type: "apiKey"
+ name: "api_key"
+ in: "header"
+definitions:
+ Domain:
+ type: "object"
+ properties:
+ uuid:
+ type: "string"
+ description: "Optional value provided by user. If user does not provide, server will auto generate"
+ name:
+ type: "string"
+ description: "Name of the secret domain under which all secrets will be stored"
+ Secret:
+ type: "object"
+ properties:
+ name:
+ type: "string"
+ description: "Name of the secret"
+ value:
+ type: "array"
+ description: "Array of key value pairs that constitute the secret"
+ items:
+ type: "object"
+ properties:
+ key:
+ type: "string"
+ value:
+ type: "string"
+ Tag:
+ type: "object"
+ properties:
+ id:
+ type: "integer"
+ format: "int64"
+ name:
+ type: "string"
+ xml:
+ name: "Tag"
+ Pet:
+ type: "object"
+ required:
+ - "name"
+ - "photoUrls"
+ properties:
+ id:
+ type: "integer"
+ format: "int64"
+ category:
+ $ref: "#/definitions/Category"
+ name:
+ type: "string"
+ example: "doggie"
+ photoUrls:
+ type: "array"
+ xml:
+ name: "photoUrl"
+ wrapped: true
+ items:
+ type: "string"
+ tags:
+ type: "array"
+ xml:
+ name: "tag"
+ wrapped: true
+ items:
+ $ref: "#/definitions/Tag"
+ status:
+ type: "string"
+ description: "pet status in the store"
+ enum:
+ - "available"
+ - "pending"
+ - "sold"
+ xml:
+ name: "Pet"
+ ApiResponse:
+ type: "object"
+ properties:
+ code:
+ type: "integer"
+ format: "int32"
+ type:
+ type: "string"
+ message:
+ type: "string"
+externalDocs:
+ description: "Find out more about Swagger"
+ url: "http://swagger.io" \ No newline at end of file
diff --git a/sms-service/src/sms/Gopkg.lock b/sms-service/src/sms/Gopkg.lock
new file mode 100644
index 0000000..da2fafd
--- /dev/null
+++ b/sms-service/src/sms/Gopkg.lock
@@ -0,0 +1,134 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+ name = "github.com/fatih/structs"
+ packages = ["."]
+ revision = "a720dfa8df582c51dee1b36feabb906bde1588bd"
+ version = "v1.0"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/golang/snappy"
+ packages = ["."]
+ revision = "553a641470496b2327abcac10b36396bd98e45c9"
+
+[[projects]]
+ name = "github.com/gorilla/context"
+ packages = ["."]
+ revision = "1ea25387ff6f684839d82767c1733ff4d4d15d0a"
+ version = "v1.1"
+
+[[projects]]
+ name = "github.com/gorilla/mux"
+ packages = ["."]
+ revision = "53c1911da2b537f792e7cafcb446b05ffe33b996"
+ version = "v1.6.1"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/hashicorp/errwrap"
+ packages = ["."]
+ revision = "7554cd9344cec97297fa6649b055a8c98c2a1e55"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/hashicorp/go-cleanhttp"
+ packages = ["."]
+ revision = "d5fe4b57a186c716b0e00b8c301cbd9b4182694d"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/hashicorp/go-multierror"
+ packages = ["."]
+ revision = "b7773ae218740a7be65057fc60b366a49b538a44"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/hashicorp/go-rootcerts"
+ packages = ["."]
+ revision = "6bb64b370b90e7ef1fa532be9e591a81c3493e00"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/hashicorp/hcl"
+ packages = [
+ ".",
+ "hcl/ast",
+ "hcl/parser",
+ "hcl/scanner",
+ "hcl/strconv",
+ "hcl/token",
+ "json/parser",
+ "json/scanner",
+ "json/token"
+ ]
+ revision = "23c074d0eceb2b8a5bfdbb271ab780cde70f05a8"
+
+[[projects]]
+ name = "github.com/hashicorp/vault"
+ packages = [
+ "api",
+ "helper/compressutil",
+ "helper/jsonutil",
+ "helper/parseutil"
+ ]
+ revision = "5acd6a21d5a69ab49d0f7c0bf540123a9b2c696d"
+ version = "v0.9.3"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/mitchellh/go-homedir"
+ packages = ["."]
+ revision = "b8bc1bf767474819792c23f32d8286a45736f1c6"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/mitchellh/mapstructure"
+ packages = ["."]
+ revision = "b4575eea38cca1123ec2dc90c26529b5c5acfcff"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/sethgrid/pester"
+ packages = ["."]
+ revision = "760f8913c0483b776294e1bee43f1d687527127b"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/net"
+ packages = [
+ "http2",
+ "http2/hpack",
+ "idna",
+ "lex/httplex"
+ ]
+ revision = "0ed95abb35c445290478a5348a7b38bb154135fd"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/text"
+ packages = [
+ "collate",
+ "collate/build",
+ "internal/colltab",
+ "internal/gen",
+ "internal/tag",
+ "internal/triegen",
+ "internal/ucd",
+ "language",
+ "secure/bidirule",
+ "transform",
+ "unicode/bidi",
+ "unicode/cldr",
+ "unicode/norm",
+ "unicode/rangetable"
+ ]
+ revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3"
+
+[solve-meta]
+ analyzer-name = "dep"
+ analyzer-version = 1
+ inputs-digest = "04ef42d3e34fec943a6bbcbde4a3caea30a3ca59d53faf7c99aa63094bea4e8f"
+ solver-name = "gps-cdcl"
+ solver-version = 1
diff --git a/sms-service/src/sms/Gopkg.toml b/sms-service/src/sms/Gopkg.toml
new file mode 100644
index 0000000..af2ce87
--- /dev/null
+++ b/sms-service/src/sms/Gopkg.toml
@@ -0,0 +1,29 @@
+# Gopkg.toml example
+#
+# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
+# for detailed Gopkg.toml documentation.
+#
+# required = ["github.com/user/thing/cmd/thing"]
+# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
+#
+# [[constraint]]
+# name = "github.com/user/project"
+# version = "1.0.0"
+#
+# [[constraint]]
+# name = "github.com/user/project2"
+# branch = "dev"
+# source = "github.com/myfork/project2"
+#
+# [[override]]
+# name = "github.com/x/y"
+# version = "2.4.0"
+
+
+[[constraint]]
+ name = "github.com/gorilla/mux"
+ version = "1.6.1"
+
+[[constraint]]
+ name = "github.com/hashicorp/vault"
+ version = "0.9.3"
diff --git a/sms-service/src/sms/auth/auth.go b/sms-service/src/sms/auth/auth.go
new file mode 100644
index 0000000..690fe62
--- /dev/null
+++ b/sms-service/src/sms/auth/auth.go
@@ -0,0 +1,51 @@
+/*
+ * 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 auth
+
+import (
+ "crypto/tls"
+ "crypto/x509"
+ "io/ioutil"
+ "log"
+)
+
+var tlsConfig *tls.Config
+
+// GetTLSConfig initializes a tlsConfig using the CA's certificate
+// This config is then used to enable the server for mutual TLS
+func GetTLSConfig(caCertFile string) *tls.Config {
+ // Initialize tlsConfig once
+ if tlsConfig == nil {
+ caCert, err := ioutil.ReadFile(caCertFile)
+
+ if err != nil {
+ log.Fatal("Error reading CA Certificate")
+ log.Fatal(err)
+ }
+
+ caCertPool := x509.NewCertPool()
+ caCertPool.AppendCertsFromPEM(caCert)
+
+ tlsConfig = &tls.Config{
+ ClientAuth: tls.RequireAndVerifyClientCert,
+ ClientCAs: caCertPool,
+ MinVersion: tls.VersionTLS12,
+ }
+ tlsConfig.BuildNameToCertificate()
+ }
+ return tlsConfig
+}
diff --git a/sms-service/src/sms/backend/backend.go b/sms-service/src/sms/backend/backend.go
new file mode 100644
index 0000000..ceb28a4
--- /dev/null
+++ b/sms-service/src/sms/backend/backend.go
@@ -0,0 +1,47 @@
+/*
+ * 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 (
+ vaultwrap "sms/backend/vault"
+)
+
+// SecretDomain struct that will be passed around between http handler
+// and code that interfaces with vault
+type SecretDomain struct {
+ ID int
+ Name string
+ MountPoint string
+}
+
+// SecretBackend interface that will be implemented for various secret backends
+type SecretBackend interface {
+ Init()
+
+ GetStatus() bool
+}
+
+// InitSecretBackend returns an interface implementation
+func InitSecretBackend() SecretBackend {
+ backendImpl := &vaultwrap.Vault{}
+ backendImpl.Init()
+ return backendImpl
+}
+
+// LoginBackend Interface that will be implemented for various login backends
+type LoginBackend interface {
+}
diff --git a/sms-service/src/sms/backend/vault/vault.go b/sms-service/src/sms/backend/vault/vault.go
new file mode 100644
index 0000000..37cb19a
--- /dev/null
+++ b/sms-service/src/sms/backend/vault/vault.go
@@ -0,0 +1,56 @@
+/*
+ * 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
+}
diff --git a/sms-service/src/sms/config/config.go b/sms-service/src/sms/config/config.go
new file mode 100644
index 0000000..d958e15
--- /dev/null
+++ b/sms-service/src/sms/config/config.go
@@ -0,0 +1,52 @@
+/*
+ * 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 config
+
+import (
+ "encoding/json"
+ "log"
+ "os"
+)
+
+type SMSConfiguration struct {
+ CAFile string `json:"cafile"`
+ ServerCert string `json:"servercert"`
+ ServerKey string `json:"serverkey"`
+
+ VaultAddress string `json:"vaultaddress"`
+}
+
+// SMSConfig is the structure that stores the configuration
+var SMSConfig *SMSConfiguration
+
+// ReadConfigFile reads the specified smsConfig file to setup some env variables
+func ReadConfigFile(file string) *SMSConfiguration {
+ if SMSConfig == nil {
+ f, err := os.Open(file)
+ if err != nil {
+ log.Fatalf("Unable to find file %s", file)
+ }
+
+ decoder := json.NewDecoder(f)
+ err = decoder.Decode(&SMSConfig)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ return SMSConfig
+}
diff --git a/sms-service/src/sms/handler/handler.go b/sms-service/src/sms/handler/handler.go
new file mode 100644
index 0000000..79b8618
--- /dev/null
+++ b/sms-service/src/sms/handler/handler.go
@@ -0,0 +1,105 @@
+/*
+ * 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 handler
+
+import (
+ "encoding/json"
+ "net/http"
+
+ "sms/backend"
+
+ "github.com/gorilla/mux"
+)
+
+type secretDomainJSON struct {
+ name string
+}
+
+type secretKeyValue struct {
+ name string
+ value string
+}
+
+type secretJSON struct {
+ name string
+ values []secretKeyValue
+}
+
+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) {
+
+}
+
+// CreateSecretDomainHandler creates a secret domain with a name provided
+func (h handler) CreateSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
+ var d secretDomainJSON
+
+ err := json.NewDecoder(r.Body).Decode(&d)
+ if err != nil {
+ http.Error(w, err.Error(), 400)
+ return
+ }
+}
+
+// DeleteSecretDomainHandler deletes a secret domain with the ID provided
+func (h handler) DeleteSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
+
+}
+
+// struct that tracks various status items for SMS and backend
+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()
+ status := status{Seal: s}
+ err := json.NewEncoder(w).Encode(status)
+ if err != nil {
+ http.Error(w, err.Error(), 400)
+ return
+ }
+}
+
+// LoginHandler handles login via password and username
+func (h handler) LoginHandler(w http.ResponseWriter, r *http.Request) {
+
+}
+
+// CreateRouter returns an http.Handler for the registered URLs
+func CreateRouter(b backend.SecretBackend) http.Handler {
+ h := handler{secretBackend: b}
+
+ // Create a new mux to handle URL endpoints
+ router := mux.NewRouter()
+
+ router.HandleFunc("/v1/sms/login", h.LoginHandler).Methods("POST")
+
+ router.HandleFunc("/v1/sms/status", h.StatusHandler).Methods("GET")
+
+ 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")
+
+ return router
+}
diff --git a/sms-service/src/sms/sms.go b/sms-service/src/sms/sms.go
new file mode 100644
index 0000000..8fdf399
--- /dev/null
+++ b/sms-service/src/sms/sms.go
@@ -0,0 +1,47 @@
+/*
+ * 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 main
+
+import (
+ "log"
+ "net/http"
+
+ smsauth "sms/auth"
+ smsbackend "sms/backend"
+ smsconfig "sms/config"
+ smshandler "sms/handler"
+)
+
+func main() {
+ // Read Configuration File
+ smsConf := smsconfig.ReadConfigFile("smsconfig.json")
+
+ backendImpl := smsbackend.InitSecretBackend()
+ httpRouter := smshandler.CreateRouter(backendImpl)
+
+ // TODO: Use CA certificate from AAF
+ tlsConfig := smsauth.GetTLSConfig(smsConf.CAFile)
+
+ httpServer := &http.Server{
+ Handler: httpRouter,
+ Addr: ":10443",
+ TLSConfig: tlsConfig,
+ }
+
+ err := httpServer.ListenAndServeTLS(smsConf.ServerCert, smsConf.ServerKey)
+ log.Fatal(err)
+}
diff --git a/sms-service/src/sms/smsconfig.json b/sms-service/src/sms/smsconfig.json
new file mode 100644
index 0000000..ddb89d3
--- /dev/null
+++ b/sms-service/src/sms/smsconfig.json
@@ -0,0 +1,7 @@
+{
+ "cafile": "auth/selfsignedca.pem",
+ "servercert": "auth/server_cat.cert",
+ "serverkey": "auth/server.key",
+
+ "vaultaddress": "http://localhost:8200"
+}