aboutsummaryrefslogtreecommitdiffstats
path: root/src/orchestrator
diff options
context:
space:
mode:
Diffstat (limited to 'src/orchestrator')
-rw-r--r--src/orchestrator/api/api.go14
-rw-r--r--src/orchestrator/api/composite_profilehandler_test.go2
-rw-r--r--src/orchestrator/api/controllerhandler_test.go6
-rw-r--r--src/orchestrator/api/instantiation_handler.go47
-rw-r--r--src/orchestrator/api/projecthandler_test.go6
-rw-r--r--src/orchestrator/cmd/main.go2
-rw-r--r--src/orchestrator/go.mod4
-rw-r--r--src/orchestrator/go.sum113
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/Chart.yaml4
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/Chart.yaml4
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/templates/service.yaml15
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/values.yaml17
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/Chart.yaml4
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/templates/service.yaml15
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/values.yaml35
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/templates/NOTES.txt1
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/templates/service.yaml22
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart1/values.yaml55
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/Chart.yaml4
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/Chart.yaml4
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/templates/service.yaml15
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/values.yaml17
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/Chart.yaml4
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/templates/service.yaml15
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/values.yaml35
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/delete.yaml22
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/templates/NOTES.txt1
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/templates/service.yaml22
-rw-r--r--src/orchestrator/mock_files/mock_charts/testchart2/values.yaml55
-rw-r--r--src/orchestrator/mock_files/mock_profiles/profile1/faulty-dest-manifest.yaml7
-rw-r--r--src/orchestrator/mock_files/mock_profiles/profile1/faulty-manifest.yaml8
-rw-r--r--src/orchestrator/mock_files/mock_profiles/profile1/faulty-src-manifest.yaml7
-rw-r--r--src/orchestrator/mock_files/mock_profiles/profile1/manifest.yaml7
-rw-r--r--src/orchestrator/mock_files/mock_profiles/profile1/override_values.yaml9
-rw-r--r--src/orchestrator/mock_files/mock_profiles/profile1/subdir/p1.yaml22
-rw-r--r--src/orchestrator/pkg/infra/validation/validation.go24
-rw-r--r--src/orchestrator/pkg/infra/validation/validation_test.go37
-rw-r--r--src/orchestrator/pkg/module/app.go1
-rw-r--r--src/orchestrator/pkg/module/composite_profile.go6
-rw-r--r--src/orchestrator/pkg/module/instantiation.go142
-rw-r--r--src/orchestrator/pkg/module/module.go4
-rw-r--r--src/orchestrator/pkg/rtcontext/rtcontext_test.go4
-rw-r--r--src/orchestrator/utils/helm/helm.go331
-rw-r--r--src/orchestrator/utils/helm/helm_test.go203
-rw-r--r--src/orchestrator/utils/helm/profile_yaml.go109
-rw-r--r--src/orchestrator/utils/utils.go116
46 files changed, 1574 insertions, 23 deletions
diff --git a/src/orchestrator/api/api.go b/src/orchestrator/api/api.go
index d2673328..3e3f3eaa 100644
--- a/src/orchestrator/api/api.go
+++ b/src/orchestrator/api/api.go
@@ -33,7 +33,8 @@ func NewRouter(projectClient moduleLib.ProjectManager,
deploymentIntentGrpClient moduleLib.DeploymentIntentGroupManager,
intentClient moduleLib.IntentManager,
compositeProfileClient moduleLib.CompositeProfileManager,
- appProfileClient moduleLib.AppProfileManager) *mux.Router {
+ appProfileClient moduleLib.AppProfileManager,
+ instantiationClient moduleLib.InstantiationManager) *mux.Router {
router := mux.NewRouter().PathPrefix("/v2").Subrouter()
@@ -164,5 +165,16 @@ func NewRouter(projectClient moduleLib.ProjectManager,
router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/intents/{intent-name}", intentHandler.getIntentHandler).Methods("GET")
router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/intents/{intent-name}", intentHandler.deleteIntentHandler).Methods("DELETE")
+ // setting routes for Instantiation
+ if instantiationClient == nil {
+ instantiationClient = moduleClient.Instantiation
+ }
+
+ instantiationHandler := instantiationHandler{
+ client: instantiationClient,
+ }
+
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/instantiate", instantiationHandler.instantiateHandler).Methods("POST")
+
return router
}
diff --git a/src/orchestrator/api/composite_profilehandler_test.go b/src/orchestrator/api/composite_profilehandler_test.go
index 360653c7..42b9b3a1 100644
--- a/src/orchestrator/api/composite_profilehandler_test.go
+++ b/src/orchestrator/api/composite_profilehandler_test.go
@@ -128,7 +128,7 @@ func Test_compositeProfileHandler_createHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("POST", "/v2/projects/{project-name}/composite-apps/{composite-app-name}/{version}/composite-profiles", testCase.reader)
- resp := executeRequest(request, NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, testCase.cProfClient, nil))
+ resp := executeRequest(request, NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, testCase.cProfClient, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
diff --git a/src/orchestrator/api/controllerhandler_test.go b/src/orchestrator/api/controllerhandler_test.go
index 1844fb32..3c543cb8 100644
--- a/src/orchestrator/api/controllerhandler_test.go
+++ b/src/orchestrator/api/controllerhandler_test.go
@@ -110,7 +110,7 @@ func TestControllerCreateHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("POST", "/v2/controllers", testCase.reader)
- resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, nil, nil, nil, nil, nil, nil))
+ resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, nil, nil, nil, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -173,7 +173,7 @@ func TestControllerGetHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("GET", "/v2/controllers/"+testCase.name, nil)
- resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, nil, nil, nil, nil, nil, nil))
+ resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, nil, nil, nil, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -222,7 +222,7 @@ func TestControllerDeleteHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("DELETE", "/v2/controllers/"+testCase.name, nil)
- resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, nil, nil, nil, nil, nil, nil))
+ resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, nil, nil, nil, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
diff --git a/src/orchestrator/api/instantiation_handler.go b/src/orchestrator/api/instantiation_handler.go
new file mode 100644
index 00000000..c95785f2
--- /dev/null
+++ b/src/orchestrator/api/instantiation_handler.go
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 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 api
+
+import (
+ "github.com/gorilla/mux"
+ moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
+ "net/http"
+)
+
+/* Used to store backend implementation objects
+Also simplifies mocking for unit testing purposes
+*/
+type instantiationHandler struct {
+ client moduleLib.InstantiationManager
+}
+
+func (h instantiationHandler) instantiateHandler(w http.ResponseWriter, r *http.Request) {
+
+ vars := mux.Vars(r)
+ p := vars["project-name"]
+ ca := vars["composite-app-name"]
+ v := vars["composite-app-version"]
+ di := vars["deployment-intent-group-name"]
+
+ iErr := h.client.Instantiate(p, ca, v, di)
+ if iErr != nil {
+ http.Error(w, iErr.Error(), http.StatusInternalServerError)
+ return
+ }
+ w.WriteHeader(http.StatusAccepted)
+
+}
diff --git a/src/orchestrator/api/projecthandler_test.go b/src/orchestrator/api/projecthandler_test.go
index af40f961..5e820aa2 100644
--- a/src/orchestrator/api/projecthandler_test.go
+++ b/src/orchestrator/api/projecthandler_test.go
@@ -119,7 +119,7 @@ func TestProjectCreateHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("POST", "/v2/projects", testCase.reader)
- resp := executeRequest(request, NewRouter(testCase.projectClient, nil, nil, nil, nil, nil, nil, nil, nil, nil))
+ resp := executeRequest(request, NewRouter(testCase.projectClient, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -188,7 +188,7 @@ func TestProjectGetHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("GET", "/v2/projects/"+testCase.name, nil)
- resp := executeRequest(request, NewRouter(testCase.projectClient, nil, nil, nil, nil, nil, nil, nil, nil, nil))
+ resp := executeRequest(request, NewRouter(testCase.projectClient, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
@@ -237,7 +237,7 @@ func TestProjectDeleteHandler(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.label, func(t *testing.T) {
request := httptest.NewRequest("DELETE", "/v2/projects/"+testCase.name, nil)
- resp := executeRequest(request, NewRouter(testCase.projectClient, nil, nil, nil, nil, nil, nil, nil, nil, nil))
+ resp := executeRequest(request, NewRouter(testCase.projectClient, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil))
//Check returned code
if resp.StatusCode != testCase.expectedCode {
diff --git a/src/orchestrator/cmd/main.go b/src/orchestrator/cmd/main.go
index f95c057e..001903a7 100644
--- a/src/orchestrator/cmd/main.go
+++ b/src/orchestrator/cmd/main.go
@@ -47,7 +47,7 @@ func main() {
log.Fatalln("Exiting...")
}
- httpRouter := api.NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
+ httpRouter := api.NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
loggedRouter := handlers.LoggingHandler(os.Stdout, httpRouter)
log.Println("Starting Kubernetes Multicloud API")
diff --git a/src/orchestrator/go.mod b/src/orchestrator/go.mod
index 547fa8ed..39d28d5c 100644
--- a/src/orchestrator/go.mod
+++ b/src/orchestrator/go.mod
@@ -2,13 +2,11 @@ module github.com/onap/multicloud-k8s/src/orchestrator
require (
github.com/coreos/etcd v3.3.12+incompatible
- github.com/docker/engine v0.0.0-20190620014054-c513a4c6c298
github.com/ghodss/yaml v1.0.0
github.com/gogo/protobuf v1.3.1 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/gorilla/handlers v1.3.0
github.com/gorilla/mux v1.6.2
- github.com/hashicorp/consul v1.4.0
github.com/json-iterator/go v1.1.8 // indirect
github.com/onap/multicloud-k8s/src/k8splugin v0.0.0-20191115005109-f168ebb73d8d // indirect
github.com/pkg/errors v0.8.1
@@ -17,9 +15,7 @@ require (
go.mongodb.org/mongo-driver v1.0.0
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
- k8s.io/api v0.0.0-20190831074750-7364b6bdad65
k8s.io/apimachinery v0.0.0-20190831074630-461753078381
- k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
k8s.io/helm v2.14.3+incompatible
k8s.io/klog v1.0.0 // indirect
)
diff --git a/src/orchestrator/go.sum b/src/orchestrator/go.sum
index aeab3b50..8205385d 100644
--- a/src/orchestrator/go.sum
+++ b/src/orchestrator/go.sum
@@ -1,80 +1,119 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
+github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e h1:eb0Pzkt15Bm7f2FFYv7sjY7NPFi3cPkS3tv1CcrFBWA=
github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
+github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/sprig v2.17.1+incompatible h1:PChbxFGKTWsg9IWh+pSZRCSj3zQkVpL6Hd9uWsFwxtc=
github.com/Masterminds/sprig v2.17.1+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/aokoli/goutils v1.1.0 h1:jy4ghdcYvs5EIoGssZNslIASX5m+KNMfyyKvRQ0TEVE=
github.com/aokoli/goutils v1.1.0/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 h1:HD4PLRzjuCVW79mQ0/pdsalOLHJ+FaEoqJLxfltpb2U=
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.12+incompatible h1:pAWNwdf7QiT1zfaWyqCtNZQWCLByQyA3JrSQyuYAqnQ=
github.com/coreos/etcd v3.3.12+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/docker/distribution v2.7.0+incompatible h1:neUDAlf3wX6Ml4HdqTrbcOHXtfRN0TFIwt6YFL7N9RU=
github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v0.7.3-0.20190912223608-ad718029b705 h1:up4REDeXtcm77SlkowEGUuakgjpdNR2N9TkGTZSL4rM=
github.com/docker/docker v0.7.3-0.20190912223608-ad718029b705/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/engine v0.0.0-20190620014054-c513a4c6c298/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY=
+github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s=
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
+github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 h1:yY9rWGoXv1U5pl4gxqlULARMQD7x0QG85lqEXTWysik=
github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
+github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
+github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
+github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
+github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
+github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU=
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
+github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4=
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
+github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg=
github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk=
github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw=
+github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff h1:kOkM9whyQYodu09SJ6W3NCsHG7crFaJILQ22Gozp3lg=
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -85,26 +124,36 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v1.3.0 h1:tsg9qP3mjt1h4Roxp+M1paRjrVBfPSOpBuVclh6YluI=
github.com/gorilla/handlers v1.3.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f h1:ShTPMJQes6tubcjzGMODIVG5hlrCeImaBnZzKF2N8SM=
github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg=
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.11.1 h1:/dBYI+n4xIL+Y9SKXQrjlKTmJJDwCSlNLRwZ5nBhIek=
github.com/grpc-ecosystem/grpc-gateway v1.11.1/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul v1.4.0 h1:PQTW4xCuAExEiSbhrsFsikzbW5gVBoi74BjUvYFyKHw=
github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
@@ -120,17 +169,25 @@ github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:VBj0QYQ0
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.1 h1:mYs6SMzu72+90OcPa5wr3nfznA4Dw9UyR791ZFNOIf4=
github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
+github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
+github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -142,23 +199,32 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
@@ -177,41 +243,57 @@ github.com/onap/multicloud-k8s/src/k8splugin v0.0.0-20191115005109-f168ebb73d8d
github.com/onap/multicloud-k8s/src/k8splugin v0.0.0-20191115005109-f168ebb73d8d/go.mod h1:EnQd/vQGZR1/55IihaHxiux4ZUig/zfXZux7bfmU0S8=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rubenv/sql-migrate v0.0.0-20190902133344-8926f37f0bc1 h1:G7j/gxkXAL80NMLOWi6EEctDET1Iuxl3sBMJXDnu2z0=
github.com/rubenv/sql-migrate v0.0.0-20190902133344-8926f37f0bc1/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
+github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -223,29 +305,41 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245 h1:DNVk+NIkGS0RbLkjQOLCJb/759yfCysThkMbl7EXxyY=
github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A=
+github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51 h1:BP2bjP495BBPaBcS5rmqviTfrOkN5rO5ceKAMRZCRFc=
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
+github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1 h1:j2hhcujLRHAg872RWAV5yaUrEjHEObwDv3aImCaNLek=
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
+go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v3.3.12+incompatible h1:V6PRYRGpU4k5EajJaaj/GL3hqIdzyPnBU8aPUp+35yw=
go.etcd.io/etcd v3.3.12+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
go.mongodb.org/mongo-driver v1.0.0 h1:KxPRDyfB2xXnDE2My8acoOWBQkfv3tz0SaWTRZjJR0c=
go.mongodb.org/mongo-driver v1.0.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -274,6 +368,7 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -300,6 +395,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -313,6 +409,7 @@ golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgw
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -322,43 +419,59 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b h1:aBGgKJUM9Hk/3AE8WaZIApnTxG35kbuQba2w+SXqezo=
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
+k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8 h1:q1Qvjzs/iEdXF6A1a8H3AKVFDzJNcJn3nXMs6R6qFtA=
k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE=
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d h1:Jmdtdt1ZnoGfWWIIik61Z7nKYgO3J+swQJtPYsP9wHA=
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
+k8s.io/apiserver v0.0.0-20190409021813-1ec86e4da56c h1:k7ALUVzrOEgz4hOF+pr4pePn7TqZ9lB/8Z8ndMSsWSU=
k8s.io/apiserver v0.0.0-20190409021813-1ec86e4da56c/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w=
+k8s.io/cli-runtime v0.0.0-20190409023024-d644b00f3b79 h1:bZyxc0wzVA5KgUfAXZA6z872zDWmyslwfvrr175VF68=
k8s.io/cli-runtime v0.0.0-20190409023024-d644b00f3b79/go.mod h1:qWnH3/b8sp/l7EvlDh7ulDU3UWA4P4N1NFbEEP791tM=
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible h1:U5Bt+dab9K8qaUmXINrkXO135kA11/i5Kg1RUydgaMQ=
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
+k8s.io/cloud-provider v0.0.0-20190409023720-1bc0c81fa51d h1:ad7UpNUGRx6FbYoK4+xIYyeS2CUShjNKY45YN1ipjLI=
k8s.io/cloud-provider v0.0.0-20190409023720-1bc0c81fa51d/go.mod h1:LlIffnLBu+GG7d4ppPzC8UnA1Ex8S+ntmSRVsnr7Xy4=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
+k8s.io/helm v2.14.3+incompatible h1:uzotTcZXa/b2SWVoUzM1xiCXVjI38TuxMujS/1s+3Gw=
k8s.io/helm v2.14.3+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
+k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ=
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
+k8s.io/kubernetes v1.14.1 h1:I9F52h5sqVxBmoSsBlNQ0YygNcukDilkpGxUbJRoBoY=
k8s.io/kubernetes v1.14.1/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
+k8s.io/utils v0.0.0-20190907131718-3d4f5b7dea0b h1:eMM0sTvh3KBVGwJfuNcU86P38TJhlVMAICbFPDG3t0M=
k8s.io/utils v0.0.0-20190907131718-3d4f5b7dea0b/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
+sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 h1:O69FD9pJA4WUZlEwYatBEEkRWKQ5cKodWpdKTrCS/iQ=
vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/Chart.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/Chart.yaml
new file mode 100644
index 00000000..91a641bd
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/Chart.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+description: A Helm chart for Kubernetes
+name: testchart1
+version: 0.1.0
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/Chart.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/Chart.yaml
new file mode 100644
index 00000000..be3edcef
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/Chart.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+description: A Helm chart for Kubernetes
+name: subcharta
+version: 0.1.0
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/templates/service.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/templates/service.yaml
new file mode 100644
index 00000000..fdf75aa9
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Chart.Name }}
+ labels:
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.externalPort }}
+ targetPort: {{ .Values.service.internalPort }}
+ protocol: TCP
+ name: {{ .Values.service.name }}
+ selector:
+ app: {{ .Chart.Name }}
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/values.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/values.yaml
new file mode 100644
index 00000000..f0381ae6
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subcharta/values.yaml
@@ -0,0 +1,17 @@
+# Default values for subchart.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+# subchartA
+service:
+ name: apache
+ type: ClusterIP
+ externalPort: 80
+ internalPort: 80
+SCAdata:
+ SCAbool: false
+ SCAfloat: 3.1
+ SCAint: 55
+ SCAstring: "jabba"
+ SCAnested1:
+ SCAnested2: true
+
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/Chart.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/Chart.yaml
new file mode 100644
index 00000000..c3c6bbaf
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/Chart.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+description: A Helm chart for Kubernetes
+name: subchartb
+version: 0.1.0
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/templates/service.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/templates/service.yaml
new file mode 100644
index 00000000..fdf75aa9
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Chart.Name }}
+ labels:
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.externalPort }}
+ targetPort: {{ .Values.service.internalPort }}
+ protocol: TCP
+ name: {{ .Values.service.name }}
+ selector:
+ app: {{ .Chart.Name }}
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/values.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/values.yaml
new file mode 100644
index 00000000..774fdd75
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/charts/subchartb/values.yaml
@@ -0,0 +1,35 @@
+# Default values for subchart.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+service:
+ name: nginx
+ type: ClusterIP
+ externalPort: 80
+ internalPort: 80
+
+SCBdata:
+ SCBbool: true
+ SCBfloat: 7.77
+ SCBint: 33
+ SCBstring: "boba"
+
+exports:
+ SCBexported1:
+ SCBexported1A:
+ SCBexported1B: 1965
+
+ SCBexported2:
+ SCBexported2A: "blaster"
+
+global:
+ kolla:
+ nova:
+ api:
+ all:
+ port: 8774
+ metadata:
+ all:
+ port: 8775
+
+
+
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/templates/NOTES.txt b/src/orchestrator/mock_files/mock_charts/testchart1/templates/NOTES.txt
new file mode 100644
index 00000000..4bdf443f
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/templates/NOTES.txt
@@ -0,0 +1 @@
+Sample notes for {{ .Chart.Name }} \ No newline at end of file
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/templates/service.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/templates/service.yaml
new file mode 100644
index 00000000..e06d19b9
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/templates/service.yaml
@@ -0,0 +1,22 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Chart.Name }}
+ labels:
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+ namespace: "{{ .Release.Namespace }}"
+ release-name: "{{ .Release.Name }}"
+ release-is-upgrade: "{{ .Release.IsUpgrade }}"
+ release-is-install: "{{ .Release.IsInstall }}"
+ kube-version/major: "{{ .Capabilities.KubeVersion.Major }}"
+ kube-version/minor: "{{ .Capabilities.KubeVersion.Minor }}"
+ kube-version/gitversion: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0"
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.externalPort }}
+ targetPort: {{ .Values.service.internalPort }}
+ protocol: TCP
+ name: {{ .Values.service.name }}
+ selector:
+ app: {{ .Chart.Name }}
diff --git a/src/orchestrator/mock_files/mock_charts/testchart1/values.yaml b/src/orchestrator/mock_files/mock_charts/testchart1/values.yaml
new file mode 100644
index 00000000..72d3fa5c
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart1/values.yaml
@@ -0,0 +1,55 @@
+# Default values for subchart.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+# subchart1
+service:
+ name: nginx
+ type: ClusterIP
+ externalPort: 80
+ internalPort: 80
+
+
+SC1data:
+ SC1bool: true
+ SC1float: 3.14
+ SC1int: 100
+ SC1string: "dollywood"
+ SC1extra1: 11
+
+imported-chartA:
+ SC1extra2: 1.337
+
+overridden-chartA:
+ SCAbool: true
+ SCAfloat: 3.14
+ SCAint: 100
+ SCAstring: "jabathehut"
+ SC1extra3: true
+
+imported-chartA-B:
+ SC1extra5: "tiller"
+
+overridden-chartA-B:
+ SCAbool: true
+ SCAfloat: 3.33
+ SCAint: 555
+ SCAstring: "wormwood"
+ SCAextra1: 23
+
+ SCBbool: true
+ SCBfloat: 0.25
+ SCBint: 98
+ SCBstring: "murkwood"
+ SCBextra1: 13
+
+ SC1extra6: 77
+
+SCBexported1A:
+ SC1extra7: true
+
+exports:
+ SC1exported1:
+ global:
+ SC1exported2:
+ all:
+ SC1exported3: "SC1expstr" \ No newline at end of file
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/Chart.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/Chart.yaml
new file mode 100644
index 00000000..f2818e52
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/Chart.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+description: A Helm chart for Kubernetes
+name: testchart2
+version: 0.1.0
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/Chart.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/Chart.yaml
new file mode 100644
index 00000000..be3edcef
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/Chart.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+description: A Helm chart for Kubernetes
+name: subcharta
+version: 0.1.0
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/templates/service.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/templates/service.yaml
new file mode 100644
index 00000000..fdf75aa9
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Chart.Name }}
+ labels:
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.externalPort }}
+ targetPort: {{ .Values.service.internalPort }}
+ protocol: TCP
+ name: {{ .Values.service.name }}
+ selector:
+ app: {{ .Chart.Name }}
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/values.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/values.yaml
new file mode 100644
index 00000000..f0381ae6
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subcharta/values.yaml
@@ -0,0 +1,17 @@
+# Default values for subchart.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+# subchartA
+service:
+ name: apache
+ type: ClusterIP
+ externalPort: 80
+ internalPort: 80
+SCAdata:
+ SCAbool: false
+ SCAfloat: 3.1
+ SCAint: 55
+ SCAstring: "jabba"
+ SCAnested1:
+ SCAnested2: true
+
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/Chart.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/Chart.yaml
new file mode 100644
index 00000000..c3c6bbaf
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/Chart.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+description: A Helm chart for Kubernetes
+name: subchartb
+version: 0.1.0
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/templates/service.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/templates/service.yaml
new file mode 100644
index 00000000..fdf75aa9
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Chart.Name }}
+ labels:
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.externalPort }}
+ targetPort: {{ .Values.service.internalPort }}
+ protocol: TCP
+ name: {{ .Values.service.name }}
+ selector:
+ app: {{ .Chart.Name }}
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/values.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/values.yaml
new file mode 100644
index 00000000..774fdd75
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/charts/subchartb/values.yaml
@@ -0,0 +1,35 @@
+# Default values for subchart.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+service:
+ name: nginx
+ type: ClusterIP
+ externalPort: 80
+ internalPort: 80
+
+SCBdata:
+ SCBbool: true
+ SCBfloat: 7.77
+ SCBint: 33
+ SCBstring: "boba"
+
+exports:
+ SCBexported1:
+ SCBexported1A:
+ SCBexported1B: 1965
+
+ SCBexported2:
+ SCBexported2A: "blaster"
+
+global:
+ kolla:
+ nova:
+ api:
+ all:
+ port: 8774
+ metadata:
+ all:
+ port: 8775
+
+
+
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/delete.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/delete.yaml
new file mode 100644
index 00000000..70efc671
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/delete.yaml
@@ -0,0 +1,22 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: testchart2
+ labels:
+ chart: "testchart2-0.1.0"
+ namespace: "testnamespace"
+ release-name: "testreleasename"
+ release-is-upgrade: "false"
+ release-is-install: "true"
+ kube-version/major: "1"
+ kube-version/minor: "14"
+ kube-version/gitversion: "v1.14.0"
+spec:
+ type: ClusterIP
+ ports:
+ - port: 80
+ targetPort: 80
+ protocol: TCP
+ name: nginx
+ selector:
+ app: testchart2 \ No newline at end of file
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/templates/NOTES.txt b/src/orchestrator/mock_files/mock_charts/testchart2/templates/NOTES.txt
new file mode 100644
index 00000000..4bdf443f
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/templates/NOTES.txt
@@ -0,0 +1 @@
+Sample notes for {{ .Chart.Name }} \ No newline at end of file
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/templates/service.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/templates/service.yaml
new file mode 100644
index 00000000..e06d19b9
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/templates/service.yaml
@@ -0,0 +1,22 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Chart.Name }}
+ labels:
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+ namespace: "{{ .Release.Namespace }}"
+ release-name: "{{ .Release.Name }}"
+ release-is-upgrade: "{{ .Release.IsUpgrade }}"
+ release-is-install: "{{ .Release.IsInstall }}"
+ kube-version/major: "{{ .Capabilities.KubeVersion.Major }}"
+ kube-version/minor: "{{ .Capabilities.KubeVersion.Minor }}"
+ kube-version/gitversion: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0"
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.externalPort }}
+ targetPort: {{ .Values.service.internalPort }}
+ protocol: TCP
+ name: {{ .Values.service.name }}
+ selector:
+ app: {{ .Chart.Name }}
diff --git a/src/orchestrator/mock_files/mock_charts/testchart2/values.yaml b/src/orchestrator/mock_files/mock_charts/testchart2/values.yaml
new file mode 100644
index 00000000..72d3fa5c
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_charts/testchart2/values.yaml
@@ -0,0 +1,55 @@
+# Default values for subchart.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+# subchart1
+service:
+ name: nginx
+ type: ClusterIP
+ externalPort: 80
+ internalPort: 80
+
+
+SC1data:
+ SC1bool: true
+ SC1float: 3.14
+ SC1int: 100
+ SC1string: "dollywood"
+ SC1extra1: 11
+
+imported-chartA:
+ SC1extra2: 1.337
+
+overridden-chartA:
+ SCAbool: true
+ SCAfloat: 3.14
+ SCAint: 100
+ SCAstring: "jabathehut"
+ SC1extra3: true
+
+imported-chartA-B:
+ SC1extra5: "tiller"
+
+overridden-chartA-B:
+ SCAbool: true
+ SCAfloat: 3.33
+ SCAint: 555
+ SCAstring: "wormwood"
+ SCAextra1: 23
+
+ SCBbool: true
+ SCBfloat: 0.25
+ SCBint: 98
+ SCBstring: "murkwood"
+ SCBextra1: 13
+
+ SC1extra6: 77
+
+SCBexported1A:
+ SC1extra7: true
+
+exports:
+ SC1exported1:
+ global:
+ SC1exported2:
+ all:
+ SC1exported3: "SC1expstr" \ No newline at end of file
diff --git a/src/orchestrator/mock_files/mock_profiles/profile1/faulty-dest-manifest.yaml b/src/orchestrator/mock_files/mock_profiles/profile1/faulty-dest-manifest.yaml
new file mode 100644
index 00000000..8c61a4e4
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_profiles/profile1/faulty-dest-manifest.yaml
@@ -0,0 +1,7 @@
+---
+version: v1
+type:
+ values: "override_values.yaml"
+ configresource:
+ - filepath: subdir/p1.yaml
+ chartpath: testchart1/folderdoesNOTexist/p1.yaml
diff --git a/src/orchestrator/mock_files/mock_profiles/profile1/faulty-manifest.yaml b/src/orchestrator/mock_files/mock_profiles/profile1/faulty-manifest.yaml
new file mode 100644
index 00000000..a123111a
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_profiles/profile1/faulty-manifest.yaml
@@ -0,0 +1,8 @@
+---
+version: v1
+type:
+ values:
+ - override_values.yaml
+ configresource:
+ - filepath: subdir/p1.yaml
+ chartpath: testchart1/templates/p1.yaml
diff --git a/src/orchestrator/mock_files/mock_profiles/profile1/faulty-src-manifest.yaml b/src/orchestrator/mock_files/mock_profiles/profile1/faulty-src-manifest.yaml
new file mode 100644
index 00000000..eff534bb
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_profiles/profile1/faulty-src-manifest.yaml
@@ -0,0 +1,7 @@
+---
+version: v1
+type:
+ values: "override_values.yaml"
+ configresource:
+ - filepath: subdir/filedoesNOTexist.yaml
+ chartpath: testchart1/templates/p1.yaml
diff --git a/src/orchestrator/mock_files/mock_profiles/profile1/manifest.yaml b/src/orchestrator/mock_files/mock_profiles/profile1/manifest.yaml
new file mode 100644
index 00000000..e4beada0
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_profiles/profile1/manifest.yaml
@@ -0,0 +1,7 @@
+---
+version: v1
+type:
+ values: "override_values.yaml"
+ configresource:
+ - filepath: subdir/p1.yaml
+ chartpath: testchart1/templates/p1.yaml
diff --git a/src/orchestrator/mock_files/mock_profiles/profile1/override_values.yaml b/src/orchestrator/mock_files/mock_profiles/profile1/override_values.yaml
new file mode 100644
index 00000000..0186c662
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_profiles/profile1/override_values.yaml
@@ -0,0 +1,9 @@
+# Default values for subchart.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+# subchart1
+service:
+ name: nginx
+ type: ClusterIP
+ externalPort: 8080
+ internalPort: 8080 \ No newline at end of file
diff --git a/src/orchestrator/mock_files/mock_profiles/profile1/subdir/p1.yaml b/src/orchestrator/mock_files/mock_profiles/profile1/subdir/p1.yaml
new file mode 100644
index 00000000..2dad677a
--- /dev/null
+++ b/src/orchestrator/mock_files/mock_profiles/profile1/subdir/p1.yaml
@@ -0,0 +1,22 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Chart.Name }}-override
+ labels:
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+ namespace: "{{ .Release.Namespace }}"
+ release-name: "{{ .Release.Name }}"
+ release-is-upgrade: "{{ .Release.IsUpgrade }}"
+ release-is-install: "{{ .Release.IsInstall }}"
+ kube-version/major: "{{ .Capabilities.KubeVersion.Major }}"
+ kube-version/minor: "{{ .Capabilities.KubeVersion.Minor }}"
+ kube-version/gitversion: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0"
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.externalPort }}
+ targetPort: {{ .Values.service.internalPort }}
+ protocol: TCP
+ name: {{ .Values.service.name }}
+ selector:
+ app: {{ .Chart.Name }}
diff --git a/src/orchestrator/pkg/infra/validation/validation.go b/src/orchestrator/pkg/infra/validation/validation.go
index 0b44a8ba..448ea5de 100644
--- a/src/orchestrator/pkg/infra/validation/validation.go
+++ b/src/orchestrator/pkg/infra/validation/validation.go
@@ -71,21 +71,37 @@ func IsTarGz(r io.Reader) error {
}
func IsIpv4Cidr(cidr string) error {
- _, _, err := net.ParseCIDR(cidr)
- if err != nil {
- return pkgerrors.Wrapf(err, "could not parse subnet %v", cidr)
+ ip, _, err := net.ParseCIDR(cidr)
+ if err != nil || ip.To4() == nil {
+ return pkgerrors.Wrapf(err, "could not parse ipv4 cidr %v", cidr)
}
return nil
}
-func IsIpv4(ip string) error {
+func IsIp(ip string) error {
addr := net.ParseIP(ip)
if addr == nil {
+ return pkgerrors.Errorf("invalid ip address %v", ip)
+ }
+ return nil
+}
+
+func IsIpv4(ip string) error {
+ addr := net.ParseIP(ip)
+ if addr == nil || addr.To4() == nil {
return pkgerrors.Errorf("invalid ipv4 address %v", ip)
}
return nil
}
+func IsMac(mac string) error {
+ _, err := net.ParseMAC(mac)
+ if err != nil {
+ return pkgerrors.Errorf("invalid MAC address %v", mac)
+ }
+ return nil
+}
+
// default name check - matches valid label value with addtion that length > 0
func IsValidName(name string) []string {
var errs []string
diff --git a/src/orchestrator/pkg/infra/validation/validation_test.go b/src/orchestrator/pkg/infra/validation/validation_test.go
index 5109b6c7..6a7f504b 100644
--- a/src/orchestrator/pkg/infra/validation/validation_test.go
+++ b/src/orchestrator/pkg/infra/validation/validation_test.go
@@ -185,6 +185,43 @@ func TestIsIpv4(t *testing.T) {
})
}
+func TestIsMac(t *testing.T) {
+ t.Run("Valid MAC", func(t *testing.T) {
+ validmacs := []string{
+ "11:22:33:44:55:66",
+ "ab-cd-ef-12-34-56",
+ "AB-CD-EF-12-34-56",
+ }
+ for _, mac := range validmacs {
+ err := IsMac(mac)
+ if err != nil {
+ t.Errorf("Valid MAC string failed to pass: %v", mac)
+ }
+ }
+ })
+
+ t.Run("Invalid MAC", func(t *testing.T) {
+ invalidmacs := []string{
+ "",
+ "1.2.3.4.5",
+ "1.2.3.45/32",
+ "ab:cd:ef:gh:12:34",
+ "11:22-33-44:55:66",
+ "11,22,33,44,55,66",
+ "11|22|33|44|55|66",
+ "11:22:33:44:55:66:77",
+ "11-22-33-44-55",
+ "11-22-33-44-55-66-77",
+ }
+ for _, mac := range invalidmacs {
+ err := IsMac(mac)
+ if err == nil {
+ t.Errorf("Invalid MAC passed: %v", mac)
+ }
+ }
+ })
+}
+
func TestIsValidString(t *testing.T) {
t.Run("Valid Strings", func(t *testing.T) {
validStrings := []struct {
diff --git a/src/orchestrator/pkg/module/app.go b/src/orchestrator/pkg/module/app.go
index 1e1a5974..40659de8 100644
--- a/src/orchestrator/pkg/module/app.go
+++ b/src/orchestrator/pkg/module/app.go
@@ -38,6 +38,7 @@ type AppMetaData struct {
}
//AppContent contains fileContent
+// TODO : This should have been []byte
type AppContent struct {
FileContent string
}
diff --git a/src/orchestrator/pkg/module/composite_profile.go b/src/orchestrator/pkg/module/composite_profile.go
index dca2116a..25a9721c 100644
--- a/src/orchestrator/pkg/module/composite_profile.go
+++ b/src/orchestrator/pkg/module/composite_profile.go
@@ -121,7 +121,7 @@ func (c *CompositeProfileClient) CreateCompositeProfile(cpf CompositeProfile, p
return cpf, nil
}
-// GetCompositeProfile shall take arguments - name of the composite profile, name of //// the project, name of the composite app and version of the composite app. It shall return the CompositeProfile if its present.
+// GetCompositeProfile shall take arguments - name of the composite profile, name of the project, name of the composite app and version of the composite app. It shall return the CompositeProfile if its present.
func (c *CompositeProfileClient) GetCompositeProfile(cpf string, p string, ca string, v string) (CompositeProfile, error) {
key := CompositeProfileKey{
Name: cpf,
@@ -147,7 +147,7 @@ func (c *CompositeProfileClient) GetCompositeProfile(cpf string, p string, ca st
return CompositeProfile{}, pkgerrors.New("Error getting CompositeProfile")
}
-// GetCompositeProfile shall take arguments - name of the composite profile, name of //// the project, name of the composite app and version of the composite app. It shall return the CompositeProfile if its present.
+// GetCompositeProfiles shall take arguments - name of the project, name of the composite profile and version of the composite app. It shall return an array of CompositeProfile.
func (c *CompositeProfileClient) GetCompositeProfiles(p string, ca string, v string) ([]CompositeProfile, error) {
key := CompositeProfileKey{
Name: "",
@@ -175,7 +175,7 @@ func (c *CompositeProfileClient) GetCompositeProfiles(p string, ca string, v str
return resp, nil
}
-// DeleteCompositeProfile the intent from the database
+// DeleteCompositeProfile deletes the compsiteApp profile from the database
func (c *CompositeProfileClient) DeleteCompositeProfile(cpf string, p string, ca string, v string) error {
key := CompositeProfileKey{
Name: cpf,
diff --git a/src/orchestrator/pkg/module/instantiation.go b/src/orchestrator/pkg/module/instantiation.go
new file mode 100644
index 00000000..5fabe81e
--- /dev/null
+++ b/src/orchestrator/pkg/module/instantiation.go
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2020 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 module
+
+import (
+ "fmt"
+ "github.com/onap/multicloud-k8s/src/orchestrator/utils/helm"
+
+ pkgerrors "github.com/pkg/errors"
+
+ "encoding/base64"
+ "log"
+)
+
+// ManifestFileName is the name given to the manifest file in the profile package
+const ManifestFileName = "manifest.yaml"
+
+// InstantiationClient implements the InstantiationManager
+type InstantiationClient struct {
+ storeName string
+ tagMetaData string
+}
+
+// InstantiationManager is an interface which exposes the
+// InstantiationManager functionalities
+type InstantiationManager interface {
+ //ApproveInstantiation(p string, ca string, v string, di string) (error)
+ Instantiate(p string, ca string, v string, di string) error
+}
+
+// NewInstantiationClient returns an instance of InstantiationClient
+func NewInstantiationClient() *InstantiationClient {
+ return &InstantiationClient{
+ storeName: "orchestrator",
+ tagMetaData: "instantiation",
+ }
+}
+
+// TODO
+//ApproveInstantiation approves an instantiation
+// func (c InstantiationClient) ApproveInstantiation(p string, ca string, v string, di string) (error){
+// }
+
+func getOverrideValuesByAppName(ov []OverrideValues, a string) map[string]string {
+ for _, eachOverrideVal := range ov {
+ if eachOverrideVal.AppName == a {
+ return eachOverrideVal.ValuesObj
+ }
+ }
+ return map[string]string{}
+}
+
+// GetSortedTemplateForApp returns the sorted templates.
+//It takes in arguments - appName, project, compositeAppName, releaseName, compositeProfileName, array of override values
+func GetSortedTemplateForApp(appName, p, ca, v, rName, cp string, overrideValues []OverrideValues) ([]helm.KubernetesResourceTemplate, error) {
+
+ log.Println("Processing App.. ", appName)
+
+ var sortedTemplates []helm.KubernetesResourceTemplate
+
+ aC, err := NewAppClient().GetAppContent(appName, p, ca, v)
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, fmt.Sprint("Not finding the content of app:: ", appName))
+ }
+ appContent, err := base64.StdEncoding.DecodeString(aC.FileContent)
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, "Fail to convert to byte array")
+ }
+ log.Println("Got the app content..")
+
+ appPC, err := NewAppProfileClient().GetAppProfileContentByApp(p, ca, v, cp, appName)
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, fmt.Sprintf("Not finding the appProfileContent for:: %s", appName))
+ }
+ appProfileContent, err := base64.StdEncoding.DecodeString(appPC.Profile)
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, "Fail to convert to byte array")
+ }
+
+ log.Println("Got the app Profile content ...")
+
+ overrideValuesOfApp := getOverrideValuesByAppName(overrideValues, appName)
+ //Convert override values from map to array of strings of the following format
+ //foo=bar
+ overrideValuesOfAppStr := []string{}
+ if overrideValuesOfApp != nil {
+ for k, v := range overrideValuesOfApp {
+ overrideValuesOfAppStr = append(overrideValuesOfAppStr, k+"="+v)
+ }
+ }
+
+ sortedTemplates, err = helm.NewTemplateClient("", "default", rName,
+ ManifestFileName).Resolve(appContent,
+ appProfileContent, overrideValuesOfAppStr,
+ appName)
+
+ log.Printf("The len of the sortedTemplates :: %d", len(sortedTemplates))
+
+ return sortedTemplates, err
+}
+
+// Instantiate methods takes in project
+func (c InstantiationClient) Instantiate(p string, ca string, v string, di string) error {
+
+ dIGrp, err := NewDeploymentIntentGroupClient().GetDeploymentIntentGroup(di, p, ca, v)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Not finding the deploymentIntentGroup")
+ }
+ rName := dIGrp.Spec.Version //rName is releaseName
+ overrideValues := dIGrp.Spec.OverrideValuesObj
+ cp := dIGrp.Spec.Profile
+
+ log.Printf("dIGrp :: %s, releaseName :: %s and cp :: %s \n", dIGrp.MetaData.Name, rName, cp)
+ allApps, err := NewAppClient().GetApps(p, ca, v)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Not finding the apps")
+ }
+ for _, eachApp := range allApps {
+ sortedTemplates, err := GetSortedTemplateForApp(eachApp.Metadata.Name, p, ca, v, rName, cp, overrideValues)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Unable to get the sorted templates for app")
+ }
+ log.Printf("Resolved all the templates for app :: %s under the compositeApp...", eachApp.Metadata.Name)
+ log.Printf("sortedTemplates :: %v ", sortedTemplates)
+ }
+ log.Printf("Done with instantiation...")
+ return err
+}
diff --git a/src/orchestrator/pkg/module/module.go b/src/orchestrator/pkg/module/module.go
index c697bbff..e05b8753 100644
--- a/src/orchestrator/pkg/module/module.go
+++ b/src/orchestrator/pkg/module/module.go
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Intel Corporation, Inc
+ * Copyright 2020 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.
@@ -29,6 +29,7 @@ type Client struct {
CompositeProfile *CompositeProfileClient
AppProfile *AppProfileClient
// Add Clients for API's here
+ Instantiation *InstantiationClient
}
// NewClient creates a new client for using the services
@@ -45,5 +46,6 @@ func NewClient() *Client {
c.CompositeProfile = NewCompositeProfileClient()
c.AppProfile = NewAppProfileClient()
// Add Client API handlers here
+ c.Instantiation = NewInstantiationClient()
return c
}
diff --git a/src/orchestrator/pkg/rtcontext/rtcontext_test.go b/src/orchestrator/pkg/rtcontext/rtcontext_test.go
index e9610ef0..eedbeb82 100644
--- a/src/orchestrator/pkg/rtcontext/rtcontext_test.go
+++ b/src/orchestrator/pkg/rtcontext/rtcontext_test.go
@@ -59,7 +59,7 @@ func (c *MockContextDb) Delete(key string) error {
// Delete all function
func (c *MockContextDb) DeleteAll(key string) error {
- for kvKey, _ := range c.Items {
+ for kvKey := range c.Items {
delete(c.Items, kvKey)
}
return c.Err
@@ -69,7 +69,7 @@ func (c *MockContextDb) DeleteAll(key string) error {
func (c *MockContextDb) GetAllKeys(path string) ([]string, error) {
var keys []string
- for k, _ := range c.Items {
+ for k := range c.Items {
keys = append(keys, string(k))
}
return keys, c.Err
diff --git a/src/orchestrator/utils/helm/helm.go b/src/orchestrator/utils/helm/helm.go
new file mode 100644
index 00000000..80cdfe5a
--- /dev/null
+++ b/src/orchestrator/utils/helm/helm.go
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2020 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 helm
+
+import (
+ "bytes"
+ utils "github.com/onap/multicloud-k8s/src/orchestrator/utils"
+
+ pkgerrors "github.com/pkg/errors"
+ "log"
+
+ "fmt"
+ "io/ioutil"
+ "k8s.io/helm/pkg/strvals"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ "github.com/ghodss/yaml"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/runtime/serializer/json"
+ "k8s.io/apimachinery/pkg/util/validation"
+ k8syaml "k8s.io/apimachinery/pkg/util/yaml"
+ "k8s.io/helm/pkg/chartutil"
+ "k8s.io/helm/pkg/manifest"
+ "k8s.io/helm/pkg/proto/hapi/chart"
+ "k8s.io/helm/pkg/releaseutil"
+ "k8s.io/helm/pkg/renderutil"
+ "k8s.io/helm/pkg/tiller"
+ "k8s.io/helm/pkg/timeconv"
+)
+
+//KubernetesResourceTemplate - Represents the template that is used to create a particular
+//resource in Kubernetes
+type KubernetesResourceTemplate struct {
+ // Tracks the apiVersion and Kind of the resource
+ GVK schema.GroupVersionKind
+ // Path to the file that contains the resource info
+ FilePath string
+}
+
+// Template is the interface for all helm templating commands
+// Any backend implementation will implement this interface and will
+// access the functionality via this.
+type Template interface {
+ GenerateKubernetesArtifacts(
+ chartPath string,
+ valueFiles []string,
+ values []string) (map[string][]string, error)
+}
+
+// TemplateClient implements the Template interface
+// It will also be used to maintain any localized state
+type TemplateClient struct {
+ whitespaceRegex *regexp.Regexp
+ kubeVersion string
+ kubeNameSpace string
+ releaseName string
+ manifestName string
+}
+
+// NewTemplateClient returns a new instance of TemplateClient
+func NewTemplateClient(k8sversion, namespace, releasename, manifestFileName string) *TemplateClient {
+ return &TemplateClient{
+ whitespaceRegex: regexp.MustCompile(`^\s*$`),
+ // defaultKubeVersion is the default value of --kube-version flag
+ kubeVersion: k8sversion,
+ kubeNameSpace: namespace,
+ releaseName: releasename,
+ manifestName: manifestFileName,
+ }
+}
+
+// Combines valueFiles and values into a single values stream.
+// values takes precedence over valueFiles
+func (h *TemplateClient) processValues(valueFiles []string, values []string) ([]byte, error) {
+ base := map[string]interface{}{}
+
+ //Values files that are used for overriding the chart
+ for _, filePath := range valueFiles {
+ currentMap := map[string]interface{}{}
+
+ var bytes []byte
+ var err error
+ if strings.TrimSpace(filePath) == "-" {
+ bytes, err = ioutil.ReadAll(os.Stdin)
+ } else {
+ bytes, err = ioutil.ReadFile(filePath)
+ }
+
+ if err != nil {
+ return []byte{}, err
+ }
+
+ if err := yaml.Unmarshal(bytes, &currentMap); err != nil {
+ return []byte{}, fmt.Errorf("failed to parse %s: %s", filePath, err)
+ }
+ // Merge with the previous map
+ base = h.mergeValues(base, currentMap)
+ }
+
+ //User specified value. Similar to ones provided by -x
+ for _, value := range values {
+ if err := strvals.ParseInto(value, base); err != nil {
+ return []byte{}, fmt.Errorf("failed parsing --set data: %s", err)
+ }
+ }
+
+ return yaml.Marshal(base)
+}
+
+func (h *TemplateClient) mergeValues(dest map[string]interface{}, src map[string]interface{}) map[string]interface{} {
+ for k, v := range src {
+ // If the key doesn't exist already, then just set the key to that value
+ if _, exists := dest[k]; !exists {
+ dest[k] = v
+ continue
+ }
+ nextMap, ok := v.(map[string]interface{})
+ // If it isn't another map, overwrite the value
+ if !ok {
+ dest[k] = v
+ continue
+ }
+ // Edge case: If the key exists in the destination, but isn't a map
+ destMap, isMap := dest[k].(map[string]interface{})
+ // If the source map has a map for this key, prefer it
+ if !isMap {
+ dest[k] = v
+ continue
+ }
+ // If we got to this point, it is a map in both, so merge them
+ dest[k] = h.mergeValues(destMap, nextMap)
+ }
+ return dest
+}
+
+// GenerateKubernetesArtifacts a mapping of type to fully evaluated helm template
+func (h *TemplateClient) GenerateKubernetesArtifacts(inputPath string, valueFiles []string,
+ values []string) ([]KubernetesResourceTemplate, error) {
+
+ var outputDir, chartPath, namespace, releaseName string
+ var retData []KubernetesResourceTemplate
+
+ releaseName = h.releaseName
+ namespace = h.kubeNameSpace
+
+ // verify chart path exists
+ if _, err := os.Stat(inputPath); err == nil {
+ if chartPath, err = filepath.Abs(inputPath); err != nil {
+ return retData, err
+ }
+ } else {
+ return retData, err
+ }
+
+ //Create a temp directory in the system temp folder
+ outputDir, err := ioutil.TempDir("", "helm-tmpl-")
+ if err != nil {
+ return retData, pkgerrors.Wrap(err, "Got error creating temp dir")
+ }
+ log.Printf("The o/p dir:: %s ", outputDir)
+
+ if namespace == "" {
+ namespace = "default"
+ }
+
+ // get combined values and create config
+ rawVals, err := h.processValues(valueFiles, values)
+ if err != nil {
+ return retData, err
+ }
+ config := &chart.Config{Raw: string(rawVals), Values: map[string]*chart.Value{}}
+
+ if msgs := validation.IsDNS1123Label(releaseName); releaseName != "" && len(msgs) > 0 {
+ return retData, fmt.Errorf("release name %s is not a valid DNS label: %s", releaseName, strings.Join(msgs, ";"))
+ }
+
+ // Check chart requirements to make sure all dependencies are present in /charts
+ c, err := chartutil.Load(chartPath)
+ if err != nil {
+ return retData, pkgerrors.Errorf("Got error: %s", err.Error())
+ }
+
+ renderOpts := renderutil.Options{
+ ReleaseOptions: chartutil.ReleaseOptions{
+ Name: releaseName,
+ IsInstall: true,
+ IsUpgrade: false,
+ Time: timeconv.Now(),
+ Namespace: namespace,
+ },
+ KubeVersion: h.kubeVersion,
+ }
+
+ renderedTemplates, err := renderutil.Render(c, config, renderOpts)
+ if err != nil {
+ return retData, err
+ }
+
+ newRenderedTemplates := make(map[string]string)
+
+ //Some manifests can contain multiple yaml documents
+ //This step is splitting them up into multiple files
+ //Each file contains only a single k8s kind
+ for k, v := range renderedTemplates {
+ //Splits into manifest-0, manifest-1 etc
+ if filepath.Base(k) == "NOTES.txt" {
+ continue
+ }
+ rmap := releaseutil.SplitManifests(v)
+ count := 0
+ for _, v1 := range rmap {
+ key := fmt.Sprintf("%s-%d", k, count)
+ newRenderedTemplates[key] = v1
+ count = count + 1
+ }
+ }
+
+ listManifests := manifest.SplitManifests(newRenderedTemplates)
+ var manifestsToRender []manifest.Manifest
+ //render all manifests in the chart
+ manifestsToRender = listManifests
+ for _, m := range tiller.SortByKind(manifestsToRender) {
+ data := m.Content
+ b := filepath.Base(m.Name)
+ if b == "NOTES.txt" {
+ continue
+ }
+ if strings.HasPrefix(b, "_") {
+ continue
+ }
+
+ // blank template after execution
+ if h.whitespaceRegex.MatchString(data) {
+ continue
+ }
+
+ mfilePath := filepath.Join(outputDir, m.Name)
+ utils.EnsureDirectory(mfilePath)
+ err = ioutil.WriteFile(mfilePath, []byte(data), 0666)
+ if err != nil {
+ return retData, err
+ }
+
+ gvk, err := getGroupVersionKind(data)
+ if err != nil {
+ return retData, err
+ }
+
+ kres := KubernetesResourceTemplate{
+ GVK: gvk,
+ FilePath: mfilePath,
+ }
+ retData = append(retData, kres)
+ }
+ return retData, nil
+}
+
+func getGroupVersionKind(data string) (schema.GroupVersionKind, error) {
+ out, err := k8syaml.ToJSON([]byte(data))
+ if err != nil {
+ return schema.GroupVersionKind{}, pkgerrors.Wrap(err, "Converting yaml to json")
+ }
+
+ simpleMeta := json.SimpleMetaFactory{}
+ gvk, err := simpleMeta.Interpret(out)
+ if err != nil {
+ return schema.GroupVersionKind{}, pkgerrors.Wrap(err, "Parsing apiversion and kind")
+ }
+
+ return *gvk, nil
+}
+
+// Resolver is an interface exposes the helm related functionalities
+type Resolver interface {
+ Resolve(appContent, appProfileContent []byte, overrideValuesOfAppStr []string, appName string) ([]KubernetesResourceTemplate, error)
+}
+
+// Resolve function
+func (h *TemplateClient) Resolve(appContent []byte, appProfileContent []byte, overrideValuesOfAppStr []string, appName string) ([]KubernetesResourceTemplate, error) {
+
+ var sortedTemplates []KubernetesResourceTemplate
+
+ //chartBasePath is the tmp path where the appContent(rawHelmCharts) is extracted.
+ chartBasePath, err := utils.ExtractTarBall(bytes.NewBuffer(appContent))
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, "Extracting appContent")
+ }
+ log.Printf("The chartBasePath :: %s", chartBasePath)
+
+ //prPath is the tmp path where the appProfileContent is extracted.
+ prPath, err := utils.ExtractTarBall(bytes.NewBuffer(appProfileContent))
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, "Extracting Profile Content")
+ }
+ log.Printf("The profile path:: %s", prPath)
+
+ prYamlClient, err := ProcessProfileYaml(prPath, h.manifestName)
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, "Processing Profile Manifest")
+ }
+ log.Println("Got the profileYamlClient..")
+
+ err = prYamlClient.CopyConfigurationOverrides(chartBasePath)
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, "Copying configresources to chart")
+ }
+
+ chartPath := filepath.Join(chartBasePath, appName)
+ sortedTemplates, err = h.GenerateKubernetesArtifacts(chartPath, []string{prYamlClient.GetValues()}, overrideValuesOfAppStr)
+ if err != nil {
+ return sortedTemplates, pkgerrors.Wrap(err, "Generate final k8s yaml")
+ }
+ return sortedTemplates, nil
+}
diff --git a/src/orchestrator/utils/helm/helm_test.go b/src/orchestrator/utils/helm/helm_test.go
new file mode 100644
index 00000000..e9442e8a
--- /dev/null
+++ b/src/orchestrator/utils/helm/helm_test.go
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2020 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 helm
+
+import (
+ "crypto/sha256"
+ "fmt"
+
+ "io/ioutil"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+func TestProcessValues(t *testing.T) {
+
+ chartDir := "../../mock_files/mock_charts/testchart2"
+ profileDir := "../../mock_files/mock_profiles/profile1"
+
+ testCases := []struct {
+ label string
+ valueFiles []string
+ values []string
+ expectedHash string
+ expectedError string
+ }{
+ {
+ label: "Process Values with Value Files Override",
+ valueFiles: []string{
+ filepath.Join(chartDir, "values.yaml"),
+ filepath.Join(profileDir, "override_values.yaml"),
+ },
+ //Hash of a combined values.yaml file that is expected
+ expectedHash: "c18a70f426933de3c051c996dc34fd537d0131b2d13a2112a2ecff674db6c2f9",
+ expectedError: "",
+ },
+ {
+ label: "Process Values with Values Pair Override",
+ valueFiles: []string{
+ filepath.Join(chartDir, "values.yaml"),
+ },
+ //Use the same convention as specified in helm template --set
+ values: []string{
+ "service.externalPort=82",
+ },
+ //Hash of a combined values.yaml file that is expected
+ expectedHash: "028a3521fc9f8777ea7e67a6de0c51f2c875b88ca91734999657f0ca924ddb7a",
+ expectedError: "",
+ },
+ {
+ label: "Process Values with Both Overrides",
+ valueFiles: []string{
+ filepath.Join(chartDir, "values.yaml"),
+ filepath.Join(profileDir, "override_values.yaml"),
+ },
+ //Use the same convention as specified in helm template --set
+ //Key takes precedence over the value from override_values.yaml
+ values: []string{
+ "service.externalPort=82",
+ },
+ //Hash of a combined values.yaml file that is expected
+ expectedHash: "516fab4ab7b76ba2ff35a97c2a79b74302543f532857b945f2fe25e717e755be",
+ expectedError: "",
+ },
+ {
+ label: "Process complex Pair Override",
+ values: []string{
+ "name={a,b,c}",
+ "servers[0].port=80",
+ },
+ expectedError: "",
+ expectedHash: "50d9401b003f65c1ccfd1c5155106fff88c8201ab8b7d66bd6ffa4fe2883bead",
+ },
+ }
+
+ h := sha256.New()
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ tc := NewTemplateClient("1.12.3", "testnamespace", "testreleasename", "manifest.yaml")
+ out, err := tc.processValues(testCase.valueFiles, testCase.values)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Got an error %s", err)
+ }
+ if strings.Contains(err.Error(), testCase.expectedError) == false {
+ t.Fatalf("Got unexpected error message %s", err)
+ }
+ } else {
+ //Compute the hash of returned data and compare
+ h.Write(out)
+ gotHash := fmt.Sprintf("%x", h.Sum(nil))
+ h.Reset()
+ if gotHash != testCase.expectedHash {
+ t.Fatalf("Got unexpected hash '%s' of values.yaml:\n%s", gotHash, out)
+ }
+ }
+ })
+ }
+}
+
+func TestGenerateKubernetesArtifacts(t *testing.T) {
+
+ chartDir := "../../mock_files/mock_charts/testchart2"
+ profileDir := "../../mock_files/mock_profiles/profile1"
+
+ testCases := []struct {
+ label string
+ chartPath string
+ valueFiles []string
+ values []string
+ expectedHashMap map[string]string
+ expectedError string
+ }{
+ {
+ label: "Generate artifacts without any overrides",
+ chartPath: chartDir,
+ valueFiles: []string{},
+ values: []string{},
+ //sha256 hash of the evaluated templates in each chart
+ expectedHashMap: map[string]string{
+ "testchart2/templates/service.yaml": "fdd6a2b6795486f0dd1d8c44379afb5ffe4072c09f9cf6594738e8ded4dd872d",
+ "subcharta/templates/service.yaml": "570389588fffdb7193ab265888d781f3d751f3a40362533344f9aa7bb93a8bb0",
+ "subchartb/templates/service.yaml": "5654e03d922e8ec49649b4bbda9dfc9e643b3b7c9c18b602cc7e26fd36a39c2a",
+ },
+ expectedError: "",
+ },
+ {
+ label: "Generate artifacts with overrides",
+ chartPath: chartDir,
+ valueFiles: []string{
+ filepath.Join(profileDir, "override_values.yaml"),
+ },
+ values: []string{
+ "service.externalPort=82",
+ },
+ //sha256 hash of the evaluated templates in each chart
+ expectedHashMap: map[string]string{
+ "testchart2/templates/service.yaml": "2bb96e791ecb6a3404bc5de3f6c4182aed881630269e2aa6766df38b0f852724",
+ "subcharta/templates/service.yaml": "570389588fffdb7193ab265888d781f3d751f3a40362533344f9aa7bb93a8bb0",
+ "subchartb/templates/service.yaml": "5654e03d922e8ec49649b4bbda9dfc9e643b3b7c9c18b602cc7e26fd36a39c2a",
+ },
+ expectedError: "",
+ },
+ }
+
+ h := sha256.New()
+
+ for _, testCase := range testCases {
+ t.Run(testCase.label, func(t *testing.T) {
+ tc := NewTemplateClient("1.12.3", "testnamespace", "testreleasename", "manifest.yaml")
+ out, err := tc.GenerateKubernetesArtifacts(testCase.chartPath, testCase.valueFiles,
+ testCase.values)
+ if err != nil {
+ if testCase.expectedError == "" {
+ t.Fatalf("Got an error %s", err)
+ }
+ if strings.Contains(err.Error(), testCase.expectedError) == false {
+ t.Fatalf("Got unexpected error message %s", err)
+ }
+ } else {
+ //Compute the hash of returned data and compare
+ for _, v := range out {
+ f := v.FilePath
+ data, err := ioutil.ReadFile(f)
+ if err != nil {
+ t.Errorf("Unable to read file %s", v)
+ }
+ h.Write(data)
+ gotHash := fmt.Sprintf("%x", h.Sum(nil))
+ h.Reset()
+
+ //Find the right hash from expectedHashMap
+ expectedHash := ""
+ for k1, v1 := range testCase.expectedHashMap {
+ if strings.Contains(f, k1) == true {
+ expectedHash = v1
+ break
+ }
+ }
+ if gotHash != expectedHash {
+ t.Fatalf("Got unexpected hash for %s", f)
+ }
+ }
+ }
+ })
+ }
+
+}
diff --git a/src/orchestrator/utils/helm/profile_yaml.go b/src/orchestrator/utils/helm/profile_yaml.go
new file mode 100644
index 00000000..e72fdbdc
--- /dev/null
+++ b/src/orchestrator/utils/helm/profile_yaml.go
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2020 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 helm
+
+import (
+ "io/ioutil"
+ "log"
+ "path/filepath"
+
+ "github.com/ghodss/yaml"
+ pkgerrors "github.com/pkg/errors"
+)
+
+/*
+#Sample Yaml format for profile manifest.yaml
+---
+version: v1
+type:
+ values: "values_override.yaml"
+ configresource:
+ - filepath: config.yaml
+ chartpath: chart/config/resources/config.yaml
+ - filepath: config2.yaml
+ chartpath: chart/config/resources/config2.yaml
+*/
+
+type overrideFiles struct {
+ FilePath string `yaml:"filepath"`
+ ChartPath string `yaml:"chartpath"`
+}
+
+type supportedOverrides struct {
+ ConfigResource []overrideFiles `yaml:"configresource"`
+ Values string `yaml:"values"`
+}
+
+type profileOverride struct {
+ Version string `yaml:"version"`
+ Type supportedOverrides `yaml:"type"`
+}
+
+type ProfileYamlClient struct {
+ path string
+ override profileOverride
+}
+
+func (p ProfileYamlClient) Print() {
+ log.Println(p.override)
+}
+
+//GetValues returns a path to the override values.yam
+//that was part of the profile
+func (p ProfileYamlClient) GetValues() string {
+ return filepath.Join(p.path, p.override.Type.Values)
+}
+
+//CopyConfigurationOverrides copies the various files that are
+//provided as overrides to their corresponding locations within
+//the destination chart.
+func (p ProfileYamlClient) CopyConfigurationOverrides(chartPath string) error {
+
+ //Iterate over each configresource and copy that file into
+ //the respective path in the chart.
+ for _, v := range p.override.Type.ConfigResource {
+ data, err := ioutil.ReadFile(filepath.Join(p.path, v.FilePath))
+ if err != nil {
+ return pkgerrors.Wrap(err, "Reading configuration file")
+ }
+ err = ioutil.WriteFile(filepath.Join(chartPath, v.ChartPath), data, 0644)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Writing configuration file into chartpath")
+ }
+ }
+
+ return nil
+}
+
+//ProcessProfileYaml parses the manifest.yaml file that is part of the profile
+//package and creates the appropriate structures out of it.
+func ProcessProfileYaml(fpath string, manifestFileName string) (ProfileYamlClient, error) {
+
+ p := filepath.Join(fpath, manifestFileName)
+ data, err := ioutil.ReadFile(p)
+ if err != nil {
+ return ProfileYamlClient{}, pkgerrors.Wrap(err, "Reading manifest file")
+ }
+
+ out := profileOverride{}
+ err = yaml.Unmarshal(data, &out)
+ if err != nil {
+ return ProfileYamlClient{}, pkgerrors.Wrap(err, "Marshaling manifest yaml file")
+ }
+
+ return ProfileYamlClient{path: fpath, override: out}, nil
+}
diff --git a/src/orchestrator/utils/utils.go b/src/orchestrator/utils/utils.go
new file mode 100644
index 00000000..13c78ba4
--- /dev/null
+++ b/src/orchestrator/utils/utils.go
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2020 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 utils
+
+import (
+ "archive/tar"
+ "compress/gzip"
+ "io"
+ "io/ioutil"
+ "os"
+ "path"
+ "path/filepath"
+
+ pkgerrors "github.com/pkg/errors"
+)
+
+//ExtractTarBall provides functionality to extract a tar.gz file
+//into a temporary location for later use.
+//It returns the path to the new location
+func ExtractTarBall(r io.Reader) (string, error) {
+ //Check if it is a valid gz
+ gzf, err := gzip.NewReader(r)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Invalid gzip format")
+ }
+
+ //Check if it is a valid tar file
+ //Unfortunately this can only be done by inspecting all the tar contents
+ tarR := tar.NewReader(gzf)
+ first := true
+
+ outDir, _ := ioutil.TempDir("", "k8s-ext-")
+
+ for true {
+ header, err := tarR.Next()
+
+ if err == io.EOF {
+ //Check if we have just a gzip file without a tar archive inside
+ if first {
+ return "", pkgerrors.New("Empty or non-existant Tar file found")
+ }
+ //End of archive
+ break
+ }
+
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Error reading tar file")
+ }
+
+ target := filepath.Join(outDir, header.Name)
+
+ switch header.Typeflag {
+ case tar.TypeDir:
+ if _, err := os.Stat(target); err != nil {
+ // Using 755 read, write, execute for owner
+ // groups and others get read and execute permissions
+ // on the folder.
+ if err := os.MkdirAll(target, 0755); err != nil {
+ return "", pkgerrors.Wrap(err, "Creating directory")
+ }
+ }
+ case tar.TypeReg:
+ if target == outDir { // Handle '.' substituted to '' entry
+ continue
+ }
+
+ err = EnsureDirectory(target)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Creating Directory")
+ }
+
+ f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Creating file")
+ }
+
+ // copy over contents
+ if _, err := io.Copy(f, tarR); err != nil {
+ return "", pkgerrors.Wrap(err, "Copying file content")
+ }
+
+ // close for each file instead of a defer for all
+ // at the end of the function
+ f.Close()
+ }
+
+ first = false
+ }
+
+ return outDir, nil
+}
+
+//EnsureDirectory makes sure that the directories specified in the path exist
+//If not, it will create them, if possible.
+func EnsureDirectory(f string) error {
+ base := path.Dir(f)
+ _, err := os.Stat(base)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+ return os.MkdirAll(base, 0755)
+}