summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKiran Kamineni <kiran.k.kamineni@intel.com>2018-10-03 22:11:28 -0700
committerKiran Kamineni <kiran.k.kamineni@intel.com>2018-10-04 13:25:58 -0700
commitb3254568d65e53c564a846a666fa6af912c9b474 (patch)
treead374fc666c8628e840141ecd8b9d0e85c9007de
parentc660d1b7dc666e23aed3e90ce6a01cd50172e9bc (diff)
Add preload commandline app to load secrets
Add a preload golang app that reads configuration files and loads the domains and corresponding secrets to SMS. The tool can configured via command line options. P2: Add support for domains as well as domain in JSON P3: Add sampleformat.json Issue-ID: AAF-532 Change-Id: If3f880b8ce61a282dc015cac7df723453b91f114 Signed-off-by: Kiran Kamineni <kiran.k.kamineni@intel.com>
-rw-r--r--sms-service/src/preload/Gopkg.lock28
-rw-r--r--sms-service/src/preload/Gopkg.toml34
-rw-r--r--sms-service/src/preload/Makefile30
-rw-r--r--sms-service/src/preload/preload.go256
-rw-r--r--sms-service/src/preload/sampleformat.json22
5 files changed, 370 insertions, 0 deletions
diff --git a/sms-service/src/preload/Gopkg.lock b/sms-service/src/preload/Gopkg.lock
new file mode 100644
index 0000000..94ca755
--- /dev/null
+++ b/sms-service/src/preload/Gopkg.lock
@@ -0,0 +1,28 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+ digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747"
+ name = "github.com/pkg/errors"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
+ version = "v0.8.0"
+
+[[projects]]
+ digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202"
+ name = "gopkg.in/yaml.v2"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
+ version = "v2.2.1"
+
+[solve-meta]
+ analyzer-name = "dep"
+ analyzer-version = 1
+ input-imports = [
+ "github.com/pkg/errors",
+ "gopkg.in/yaml.v2",
+ ]
+ solver-name = "gps-cdcl"
+ solver-version = 1
diff --git a/sms-service/src/preload/Gopkg.toml b/sms-service/src/preload/Gopkg.toml
new file mode 100644
index 0000000..b1ef744
--- /dev/null
+++ b/sms-service/src/preload/Gopkg.toml
@@ -0,0 +1,34 @@
+# Gopkg.toml example
+#
+# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
+# 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"
+#
+# [prune]
+# non-go = false
+# go-tests = true
+# unused-packages = true
+
+
+[[constraint]]
+ name = "github.com/pkg/errors"
+ version = "0.8.0"
+
+[prune]
+ go-tests = true
+ unused-packages = true
diff --git a/sms-service/src/preload/Makefile b/sms-service/src/preload/Makefile
new file mode 100644
index 0000000..c236049
--- /dev/null
+++ b/sms-service/src/preload/Makefile
@@ -0,0 +1,30 @@
+GOPATH := $(shell realpath "$(CURDIR)/../../")
+BINARY := preload
+PLATFORM := linux
+DEPENDENCIES := github.com/golang/dep/cmd/dep
+
+export GOPATH ...
+
+all: test build
+deploy: test build
+
+build: deps format
+ CGO_ENABLED=0 GOOS=$(PLATFORM) go build -a \
+ -ldflags '-extldflags "-static"' \
+ -o $(GOPATH)/target/$(BINARY) -v $(BINARY).go
+
+clean:
+ go clean
+ rm -f $(GOPATH)/target/$(BINARY)
+
+test:
+ @echo "Yet to Implement"
+
+format:
+ go fmt ./...
+
+deps:
+ go get -u $(DEPENDENCIES)
+ $(GOPATH)/bin/dep ensure
+
+.PHONY: test
diff --git a/sms-service/src/preload/preload.go b/sms-service/src/preload/preload.go
new file mode 100644
index 0000000..cbf345f
--- /dev/null
+++ b/sms-service/src/preload/preload.go
@@ -0,0 +1,256 @@
+/*
+ * 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 (
+ "bytes"
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "net/url"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "time"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+//DataJSON stores a list of domains from JSON file
+type DataJSON struct {
+ //Support single domain: {} structure in JSON
+ Domain SecretDomainJSON `json:"domain,omitempty"`
+ //Support plural domains: [{}] structure in JSON
+ Domains []SecretDomainJSON `json:"domains,omitempty"`
+}
+
+//SecretDomainJSON stores a name for the Domain and a list of Secrets
+type SecretDomainJSON struct {
+ Name string `json:"name"`
+ Secrets []SecretJSON `json:"secrets"`
+}
+
+//SecretJSON stores a name for the Secret and a list of Values
+type SecretJSON struct {
+ Name string `json:"name"`
+ Values map[string]interface{} `json:"values"`
+}
+
+//Processes the JSON file and returns a DataJSON struct
+func processJSONFile(name string) (DataJSON, error) {
+
+ data, err := ioutil.ReadFile(name)
+ if err != nil {
+ return DataJSON{}, pkgerrors.Cause(err)
+ }
+
+ d := DataJSON{}
+ err = json.Unmarshal(data, &d)
+ if err != nil {
+ return DataJSON{}, pkgerrors.Cause(err)
+ }
+
+ return d, nil
+}
+
+type smsClient struct {
+ BaseURL *url.URL
+ //In seconds
+ Timeout int
+ CaCertPath string
+
+ httpClient *http.Client
+}
+
+func (c *smsClient) init() error {
+
+ skipVerify := false
+ caCert, err := ioutil.ReadFile(c.CaCertPath)
+ if err != nil {
+ fmt.Println(pkgerrors.Cause(err))
+ fmt.Println("Using Insecure Server Verification")
+ skipVerify = true
+ }
+
+ tlsConfig := &tls.Config{
+ MinVersion: tls.VersionTLS12,
+ }
+
+ tlsConfig.InsecureSkipVerify = skipVerify
+
+ // Add cert information when skipVerify is false
+ if skipVerify == false {
+ caCertPool := x509.NewCertPool()
+ caCertPool.AppendCertsFromPEM(caCert)
+ tlsConfig.RootCAs = caCertPool
+ }
+
+ tr := &http.Transport{
+ TLSClientConfig: tlsConfig,
+ }
+
+ c.httpClient = &http.Client{
+ Transport: tr,
+ Timeout: time.Duration(c.Timeout) * time.Second,
+ }
+
+ return nil
+}
+
+func (c *smsClient) sendPostRequest(relURL string, message map[string]interface{}) error {
+
+ rel, err := url.Parse(relURL)
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+ u := c.BaseURL.ResolveReference(rel)
+
+ body, err := json.Marshal(message)
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+
+ resp, err := c.httpClient.Post(u.String(), "application/json", bytes.NewBuffer(body))
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+
+ if resp.StatusCode >= 400 && resp.StatusCode < 600 {
+ // Request Failed
+ errText, _ := ioutil.ReadAll(resp.Body)
+ return pkgerrors.Errorf("Request Failed with: %s and Error: %s",
+ resp.Status, string(errText))
+ }
+
+ return nil
+}
+
+func (c *smsClient) createDomain(domain string) error {
+
+ message := map[string]interface{}{
+ "name": domain,
+ }
+ url := "/v1/sms/domain"
+ err := c.sendPostRequest(url, message)
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+ return nil
+}
+
+func (c *smsClient) createSecret(domain string, secret string,
+
+ values map[string]interface{}) error {
+ message := map[string]interface{}{
+ "name": secret,
+ "values": values,
+ }
+
+ url := "/v1/sms/domain/" + strings.TrimSpace(domain) + "/secret"
+ err := c.sendPostRequest(url, message)
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+
+ return nil
+}
+
+//uploadToSMS reads through the domain or domains and uploads
+//their corresponding secrets to SMS service
+func (c *smsClient) uploadToSMS(data DataJSON) error {
+
+ var ldata []SecretDomainJSON
+
+ //Check if Domain is empty
+ if strings.TrimSpace(data.Domain.Name) != "" {
+ ldata = append(ldata, data.Domain)
+ } else if len(data.Domains) != 0 {
+ //Check if plural Domains are empty
+ ldata = append(ldata, data.Domains...)
+ } else {
+ return pkgerrors.New("Invalid JSON Data. No domain or domains found")
+ }
+
+ for _, d := range ldata {
+ err := c.createDomain(d.Name)
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+
+ for _, s := range d.Secrets {
+ err = c.createSecret(d.Name, s.Name, s.Values)
+ if err != nil {
+ return pkgerrors.Cause(err)
+ }
+ }
+ }
+
+ return nil
+}
+
+func main() {
+
+ cacert := flag.String("cacert", "/sms/certs/aaf_root_ca.cer",
+ "Path to the CA Certificate file")
+ serviceurl := flag.String("serviceurl", "https://aaf-sms.onap",
+ "Url for the SMS Service")
+ serviceport := flag.Int("serviceport", 10443,
+ "Service port if its different than the default")
+ jsondir := flag.String("jsondir", ".",
+ "Folder containing json files to upload")
+
+ flag.Parse()
+
+ files, err := ioutil.ReadDir(*jsondir)
+ if err != nil {
+ log.Fatal(pkgerrors.Cause(err))
+ }
+
+ serviceURL, err := url.Parse(*serviceurl + ":" + strconv.Itoa(*serviceport))
+ if err != nil {
+ log.Fatal(pkgerrors.Cause(err))
+ }
+
+ client := &smsClient{
+ Timeout: 30,
+ BaseURL: serviceURL,
+ CaCertPath: *cacert,
+ }
+ client.init()
+
+ for _, file := range files {
+ if filepath.Ext(file.Name()) == ".json" {
+ fmt.Println("Processing ", file.Name())
+ d, err := processJSONFile(file.Name())
+ if err != nil {
+ log.Printf("Error Reading %s : %s", file.Name(), pkgerrors.Cause(err))
+ continue
+ }
+
+ err = client.uploadToSMS(d)
+ if err != nil {
+ log.Printf("Error Uploading %s : %s", file.Name(), pkgerrors.Cause(err))
+ continue
+ }
+ }
+ }
+}
diff --git a/sms-service/src/preload/sampleformat.json b/sms-service/src/preload/sampleformat.json
new file mode 100644
index 0000000..1a8a9f5
--- /dev/null
+++ b/sms-service/src/preload/sampleformat.json
@@ -0,0 +1,22 @@
+{
+ "domains": [{
+ "name": "mysecretdomain ",
+ "secrets": [
+ {
+ "name": "database-credentials",
+ "values": {
+ "username": "admin",
+ "password": "admin",
+ "ttl": 3600
+ }
+ },
+ {
+ "name": "server-credentials",
+ "values": {
+ "username": "suser",
+ "password": "onap"
+ }
+ }
+ ]
+ }]
+}