Initial Project Structure 43/30343/2
authorKiran <kiran.k.kamineni@intel.com>
Mon, 5 Feb 2018 22:04:32 +0000 (14:04 -0800)
committerKiran <kiran.k.kamineni@intel.com>
Mon, 5 Feb 2018 22:19:57 +0000 (14:19 -0800)
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>
15 files changed:
.gitreview [new file with mode: 0644]
sms-cli/.keep [new file with mode: 0644]
sms-client/.keep [new file with mode: 0644]
sms-gui/.keep [new file with mode: 0644]
sms-service/.gitignore [new file with mode: 0644]
sms-service/doc/swagger.yaml [new file with mode: 0644]
sms-service/src/sms/Gopkg.lock [new file with mode: 0644]
sms-service/src/sms/Gopkg.toml [new file with mode: 0644]
sms-service/src/sms/auth/auth.go [new file with mode: 0644]
sms-service/src/sms/backend/backend.go [new file with mode: 0644]
sms-service/src/sms/backend/vault/vault.go [new file with mode: 0644]
sms-service/src/sms/config/config.go [new file with mode: 0644]
sms-service/src/sms/handler/handler.go [new file with mode: 0644]
sms-service/src/sms/sms.go [new file with mode: 0644]
sms-service/src/sms/smsconfig.json [new file with mode: 0644]

diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..651dace
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/sms-client/.keep b/sms-client/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sms-gui/.keep b/sms-gui/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sms-service/.gitignore b/sms-service/.gitignore
new file mode 100644 (file)
index 0000000..e98d43b
--- /dev/null
@@ -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 (file)
index 0000000..c1fb634
--- /dev/null
@@ -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 (file)
index 0000000..da2fafd
--- /dev/null
@@ -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 (file)
index 0000000..af2ce87
--- /dev/null
@@ -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 (file)
index 0000000..690fe62
--- /dev/null
@@ -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 (file)
index 0000000..ceb28a4
--- /dev/null
@@ -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 (file)
index 0000000..37cb19a
--- /dev/null
@@ -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 (file)
index 0000000..d958e15
--- /dev/null
@@ -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 (file)
index 0000000..79b8618
--- /dev/null
@@ -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 (file)
index 0000000..8fdf399
--- /dev/null
@@ -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 (file)
index 0000000..ddb89d3
--- /dev/null
@@ -0,0 +1,7 @@
+{
+    "cafile": "auth/selfsignedca.pem",
+    "servercert": "auth/server_cat.cert",
+    "serverkey": "auth/server.key",
+
+    "vaultaddress": "http://localhost:8200"
+}