Create network service with cluster API 45/103645/6
authorEric Multanen <eric.w.multanen@intel.com>
Thu, 12 Mar 2020 22:59:24 +0000 (15:59 -0700)
committerEric Multanen <eric.w.multanen@intel.com>
Mon, 23 Mar 2020 21:06:22 +0000 (14:06 -0700)
Creates a new network customization and configuration
service.  Seed it by moving the cluster-provider and
cluster API from the orchestrator service to this new
service.  More APIs to follow.
Just put a Dockerfile in the ncm/scripts directory for now.

See: https://wiki.onap.org/pages/viewpage.action?pageId=79201398

Issue-ID: MULTICLOUD-1029
Signed-off-by: Eric Multanen <eric.w.multanen@intel.com>
Change-Id: Iea1b1151e5f87fecaca9cfe8c9746a59eb447a7a

19 files changed:
src/ncm/Makefile [new file with mode: 0644]
src/ncm/api/api.go [new file with mode: 0644]
src/ncm/api/clusterhandler.go [moved from src/orchestrator/api/clusterhandler.go with 99% similarity]
src/ncm/api/clusterhandler_test.go [moved from src/orchestrator/api/clusterhandler_test.go with 94% similarity]
src/ncm/api/testing.go [new file with mode: 0644]
src/ncm/cmd/main.go [new file with mode: 0644]
src/ncm/go.mod [new file with mode: 0644]
src/ncm/pkg/module/cluster.go [moved from src/orchestrator/pkg/module/cluster.go with 100% similarity]
src/ncm/pkg/module/module.go [new file with mode: 0644]
src/ncm/scripts/Dockerfile [new file with mode: 0644]
src/ncm/tests/certs/auth_test_certificate.pem [new file with mode: 0644]
src/ncm/tests/certs/auth_test_key.pem [new file with mode: 0644]
src/ncm/tests/configs/mock_config.json [new file with mode: 0644]
src/orchestrator/api/api.go
src/orchestrator/api/composite_profilehandler_test.go
src/orchestrator/api/controllerhandler_test.go
src/orchestrator/api/projecthandler_test.go
src/orchestrator/cmd/main.go
src/orchestrator/pkg/module/module.go

diff --git a/src/ncm/Makefile b/src/ncm/Makefile
new file mode 100644 (file)
index 0000000..fbdd53f
--- /dev/null
@@ -0,0 +1,36 @@
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2020 Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+export GO111MODULE=on
+
+all: clean
+       CGO_ENABLED=1 GOOS=linux GOARCH=amd64
+       @go build -tags netgo -o ./ncm ./cmd/main.go
+
+# The following is done this way as each patch on CI runs build and each merge runs deploy. So for build we don't need to build binary and hence
+# no need to create a static binary with additional flags. However, for generating binary, additional build flags are necessary. This if used with
+# mock plugin errors out for unit tests. So the seperation avoids the error.
+
+build: clean test cover
+deploy: build
+
+.PHONY: test
+test: clean
+       @go test -race ./...
+
+format:
+       @go fmt ./...
+
+clean:
+       @rm -f ncm coverage.html coverage.out
+
+.PHONY: cover
+cover:
+       @go test -race ./... -coverprofile=coverage.out
+       @go tool cover -html=coverage.out -o coverage.html
diff --git a/src/ncm/api/api.go b/src/ncm/api/api.go
new file mode 100644 (file)
index 0000000..c26f54e
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 (
+       "fmt"
+       "reflect"
+
+       "github.com/gorilla/mux"
+       moduleLib "github.com/onap/multicloud-k8s/src/ncm/pkg/module"
+)
+
+var moduleClient *moduleLib.Client
+
+// for the given client and testClient, if the testClient is not null and
+// implements the client manager interface corresponding to client, then
+// return the testClient, otherwise return the client.
+func setClient(client, testClient interface{}) interface{} {
+       switch cl := client.(type) {
+       case *moduleLib.ClusterClient:
+               if testClient != nil && reflect.TypeOf(testClient).Implements(reflect.TypeOf((*moduleLib.ClusterManager)(nil)).Elem()) {
+                       c, ok := testClient.(moduleLib.ClusterManager)
+                       if ok {
+                               return c
+                       }
+               }
+       default:
+               fmt.Printf("unknown type %T\n", cl)
+       }
+       return client
+}
+
+// NewRouter creates a router that registers the various urls that are supported
+// testClient parameter allows unit testing for a given client
+func NewRouter(testClient interface{}) *mux.Router {
+
+       moduleClient = moduleLib.NewClient()
+
+       clusterHandler := clusterHandler{
+               client: setClient(moduleClient.Cluster, testClient).(moduleLib.ClusterManager),
+       }
+
+       router := mux.NewRouter().PathPrefix("/v2").Subrouter()
+
+       router.HandleFunc("/cluster-providers", clusterHandler.createClusterProviderHandler).Methods("POST")
+       router.HandleFunc("/cluster-providers", clusterHandler.getClusterProviderHandler).Methods("GET")
+       router.HandleFunc("/cluster-providers/{name}", clusterHandler.getClusterProviderHandler).Methods("GET")
+       router.HandleFunc("/cluster-providers/{name}", clusterHandler.deleteClusterProviderHandler).Methods("DELETE")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters", clusterHandler.createClusterHandler).Methods("POST")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters", clusterHandler.getClusterHandler).Methods("GET")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{name}", clusterHandler.getClusterHandler).Methods("GET")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{name}", clusterHandler.deleteClusterHandler).Methods("DELETE")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/labels", clusterHandler.createClusterLabelHandler).Methods("POST")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/labels", clusterHandler.getClusterLabelHandler).Methods("GET")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/labels/{label}", clusterHandler.getClusterLabelHandler).Methods("GET")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/labels/{label}", clusterHandler.deleteClusterLabelHandler).Methods("DELETE")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs", clusterHandler.createClusterKvPairsHandler).Methods("POST")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs", clusterHandler.getClusterKvPairsHandler).Methods("GET")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs/{kvpair}", clusterHandler.getClusterKvPairsHandler).Methods("GET")
+       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs/{kvpair}", clusterHandler.deleteClusterKvPairsHandler).Methods("DELETE")
+
+       return router
+}
similarity index 99%
rename from src/orchestrator/api/clusterhandler.go
rename to src/ncm/api/clusterhandler.go
index ac4191e..cb147a8 100644 (file)
@@ -27,7 +27,7 @@ import (
        "net/http"
        "net/textproto"
 
-       moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
+       moduleLib "github.com/onap/multicloud-k8s/src/ncm/pkg/module"
 
        "github.com/gorilla/mux"
 )
similarity index 94%
rename from src/orchestrator/api/clusterhandler_test.go
rename to src/ncm/api/clusterhandler_test.go
index e5161a4..af5bd16 100644 (file)
@@ -27,7 +27,7 @@ import (
        "reflect"
        "testing"
 
-       moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
+       moduleLib "github.com/onap/multicloud-k8s/src/ncm/pkg/module"
 
        pkgerrors "github.com/pkg/errors"
 )
@@ -229,7 +229,7 @@ func TestClusterProviderCreateHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("POST", "/v2/cluster-providers", testCase.reader)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -307,7 +307,7 @@ func TestClusterProviderGetAllHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("GET", "/v2/cluster-providers", nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -377,7 +377,7 @@ func TestClusterProviderGetHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("GET", "/v2/cluster-providers/"+testCase.name, nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -426,7 +426,7 @@ func TestClusterProviderDeleteHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("DELETE", "/v2/cluster-providers/"+testCase.name, nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -538,7 +538,7 @@ of clusterTest
 
                        request := httptest.NewRequest("POST", "/v2/cluster-providers/clusterProvider1/clusters", bytes.NewBuffer(body.Bytes()))
                        request.Header.Set("Content-Type", multiwr.FormDataContentType())
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -625,7 +625,7 @@ func TestClusterGetAllHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("GET", "/v2/cluster-providers/clusterProvder1/clusters", nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -706,7 +706,7 @@ func TestClusterGetHandler(t *testing.T) {
                        if len(testCase.accept) > 0 {
                                request.Header.Set("Accept", testCase.accept)
                        }
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -784,7 +784,7 @@ of clusterTest
                        if len(testCase.accept) > 0 {
                                request.Header.Set("Accept", testCase.accept)
                        }
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -834,7 +834,7 @@ func TestClusterDeleteHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("DELETE", "/v2/cluster-providers/clusterProvider1/clusters/"+testCase.name, nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -880,7 +880,7 @@ func TestClusterLabelCreateHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("POST", "/v2/cluster-providers/cp1/clusters/cl1/labels", testCase.reader)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -944,7 +944,7 @@ func TestClusterLabelsGetHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("GET", "/v2/cluster-providers/cp1/clusters/cl1/labels", nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -1004,7 +1004,7 @@ func TestClusterLabelGetHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("GET", "/v2/cluster-providers/clusterProvider1/clusters/cl1/labels/"+testCase.name, nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -1053,7 +1053,7 @@ func TestClusterLabelDeleteHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("DELETE", "/v2/cluster-providers/cp1/clusters/cl1/labels/"+testCase.name, nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -1144,7 +1144,7 @@ func TestClusterKvPairsCreateHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("POST", "/v2/cluster-providers/cp1/clusters/cl1/kv-pairs", testCase.reader)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -1262,7 +1262,7 @@ func TestClusterKvPairsGetAllHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("GET", "/v2/cluster-providers/cp1/clusters/cl1/kv-pairs", nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -1352,7 +1352,7 @@ func TestClusterKvPairsGetHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("GET", "/v2/cluster-providers/clusterProvider1/clusters/cl1/kv-pairs/"+testCase.name, nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
@@ -1401,7 +1401,7 @@ func TestClusterKvPairsDeleteHandler(t *testing.T) {
        for _, testCase := range testCases {
                t.Run(testCase.label, func(t *testing.T) {
                        request := httptest.NewRequest("DELETE", "/v2/cluster-providers/cp1/clusters/cl1/kv-pairs/"+testCase.name, nil)
-                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, testCase.clusterClient, nil, nil, nil, nil, nil, nil))
+                       resp := executeRequest(request, NewRouter(testCase.clusterClient))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
diff --git a/src/ncm/api/testing.go b/src/ncm/api/testing.go
new file mode 100644 (file)
index 0000000..fed5c08
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 (
+       "net/http"
+       "net/http/httptest"
+
+       "github.com/gorilla/mux"
+)
+
+func executeRequest(request *http.Request, router *mux.Router) *http.Response {
+       recorder := httptest.NewRecorder()
+       router.ServeHTTP(recorder, request)
+       resp := recorder.Result()
+       return resp
+}
diff --git a/src/ncm/cmd/main.go b/src/ncm/cmd/main.go
new file mode 100644 (file)
index 0000000..c4ae423
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+Copyright 2020 Intel Corporation.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+       "context"
+       "log"
+       "math/rand"
+       "net/http"
+       "os"
+       "os/signal"
+       "time"
+
+       "github.com/gorilla/handlers"
+       "github.com/onap/multicloud-k8s/src/ncm/api"
+       "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/auth"
+       "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/config"
+       contextDb "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/contextdb"
+       "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
+)
+
+func main() {
+
+       rand.Seed(time.Now().UnixNano())
+
+       err := db.InitializeDatabaseConnection("mco")
+       if err != nil {
+               log.Println("Unable to initialize database connection...")
+               log.Println(err)
+               log.Fatalln("Exiting...")
+       }
+       err = contextDb.InitializeContextDatabase()
+       if err != nil {
+               log.Println("Unable to initialize database connection...")
+               log.Println(err)
+               log.Fatalln("Exiting...")
+       }
+
+       httpRouter := api.NewRouter(nil)
+       loggedRouter := handlers.LoggingHandler(os.Stdout, httpRouter)
+       log.Println("Starting Network Customization Manager")
+
+       httpServer := &http.Server{
+               Handler: loggedRouter,
+               Addr:    ":" + config.GetConfiguration().ServicePort,
+       }
+
+       connectionsClose := make(chan struct{})
+       go func() {
+               c := make(chan os.Signal, 1)
+               signal.Notify(c, os.Interrupt)
+               <-c
+               httpServer.Shutdown(context.Background())
+               close(connectionsClose)
+       }()
+
+       tlsConfig, err := auth.GetTLSConfig("ca.cert", "server.cert", "server.key")
+       if err != nil {
+               log.Println("Error Getting TLS Configuration. Starting without TLS...")
+               log.Fatal(httpServer.ListenAndServe())
+       } else {
+               httpServer.TLSConfig = tlsConfig
+               // empty strings because tlsconfig already has this information
+               err = httpServer.ListenAndServeTLS("", "")
+       }
+}
diff --git a/src/ncm/go.mod b/src/ncm/go.mod
new file mode 100644 (file)
index 0000000..32ff481
--- /dev/null
@@ -0,0 +1,31 @@
+module github.com/onap/multicloud-k8s/src/ncm
+
+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/gorilla/handlers v1.3.0
+       github.com/gorilla/mux v1.6.2
+       github.com/hashicorp/consul v1.4.0
+       github.com/pkg/errors v0.8.1
+       github.com/sirupsen/logrus v1.4.2
+       go.etcd.io/etcd v3.3.12+incompatible
+       go.mongodb.org/mongo-driver v1.0.0
+       golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
+       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
+)
+
+replace (
+       k8s.io/api => k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b
+       k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8
+       k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d
+       k8s.io/apiserver => k8s.io/apiserver v0.0.0-20190409021813-1ec86e4da56c
+       k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20190409023024-d644b00f3b79
+       k8s.io/client-go => k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
+       k8s.io/cloud-provider => k8s.io/cloud-provider v0.0.0-20190409023720-1bc0c81fa51d
+)
+
+go 1.13
diff --git a/src/ncm/pkg/module/module.go b/src/ncm/pkg/module/module.go
new file mode 100644 (file)
index 0000000..c1c2451
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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
+
+// Client for using the services in the orchestrator
+type Client struct {
+       Cluster *ClusterClient
+       // Add Clients for API's here
+}
+
+// NewClient creates a new client for using the services
+func NewClient() *Client {
+       c := &Client{}
+       c.Cluster = NewClusterClient()
+       // Add Client API handlers here
+       return c
+}
diff --git a/src/ncm/scripts/Dockerfile b/src/ncm/scripts/Dockerfile
new file mode 100644 (file)
index 0000000..d1b5867
--- /dev/null
@@ -0,0 +1,30 @@
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2020
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+FROM ubuntu:18.04
+
+ARG HTTP_PROXY=${HTTP_PROXY}
+ARG HTTPS_PROXY=${HTTPS_PROXY}
+
+ENV http_proxy $HTTP_PROXY
+ENV https_proxy $HTTPS_PROXY
+ENV no_proxy $NO_PROXY
+
+EXPOSE 9016
+
+RUN groupadd -r onap && useradd -r -g onap onap
+
+WORKDIR /opt/multicloud/k8s/ncm
+RUN chown onap:onap /opt/multicloud/k8s/ncm -R
+
+ADD --chown=onap ./ncm ./
+
+USER onap
+
+CMD ["./ncm"]
diff --git a/src/ncm/tests/certs/auth_test_certificate.pem b/src/ncm/tests/certs/auth_test_certificate.pem
new file mode 100644 (file)
index 0000000..42e7749
--- /dev/null
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIJAKAHJi8eUs73MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTgwNTE1MDQ0MDQwWhcNMTkwNTE1MDQ0MDQwWjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA5PHDk+RRFh5o3Xe2nZuLn0Vo+5BjnHp/ul2NNYSG00Slc8F86gW4xcNA
+wm6xC8tYCSangV2lFG3E8H2L7SCEVaM5VDV2GCOpOoMihc+2Qenk/YbHwuYenwjo
+OgTK4aCItqjcAJ2DB1KC7AxARxHBDu9Kif+M/pc49so+G9ObQuS8k2vmTTaRYkMK
+ZvbTJcWsc0vbNnPhxcG5PVj4unlaREM+yQDm18/glUkkBNnYKMHABRvPnBrDktTT
+BQWsqkbQTw7ZuLOrl9rCzVTstZX9wEXarrstIdQJj3KZjbFOp2opND8bjNIjcdVt
+iRFnP1nHQYr7EgRqcx/YMJZ+gmCy3wIDAQABo1AwTjAdBgNVHQ4EFgQU9qPNwwIu
+kZh41sJqFtnMC2blSYMwHwYDVR0jBBgwFoAU9qPNwwIukZh41sJqFtnMC2blSYMw
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA4+daLY1wE10IMPaOKurG
+QBvfYeO/rgNXGeg0TisTIKAfx/We9Hmwo/37Bd2Nk5gxfy/DIJ4lMbrzXjgWITlm
+XOrS5QfluwvaEcREtHFtPFa3NZqn2VzKNDFTR+rJj7I5o600NKdcPrGeQ1i/vny2
+K0g68ogw2jfufcuePvZTYGst8RclomPr7ZXxI24kIjcE1MbiViy68sQueTXBEr5s
+Th6RsvPfVnLxjR/m/V6VJl31nn4T6hbmKzXCHo/X7aC3I8Isui4bQGKgfAxyBkhE
+0T7tP+GgymiEKQ6qJ/1c4HFFSuFRUQjLnK7uJu9jM/HMKoLCPayx6birHZRIMF94
+pg==
+-----END CERTIFICATE-----
diff --git a/src/ncm/tests/certs/auth_test_key.pem b/src/ncm/tests/certs/auth_test_key.pem
new file mode 100644 (file)
index 0000000..5f01f57
--- /dev/null
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDk8cOT5FEWHmjd
+d7adm4ufRWj7kGOcen+6XY01hIbTRKVzwXzqBbjFw0DCbrELy1gJJqeBXaUUbcTw
+fYvtIIRVozlUNXYYI6k6gyKFz7ZB6eT9hsfC5h6fCOg6BMrhoIi2qNwAnYMHUoLs
+DEBHEcEO70qJ/4z+lzj2yj4b05tC5LyTa+ZNNpFiQwpm9tMlxaxzS9s2c+HFwbk9
+WPi6eVpEQz7JAObXz+CVSSQE2dgowcAFG8+cGsOS1NMFBayqRtBPDtm4s6uX2sLN
+VOy1lf3ARdquuy0h1AmPcpmNsU6naik0PxuM0iNx1W2JEWc/WcdBivsSBGpzH9gw
+ln6CYLLfAgMBAAECggEAYB3H2D0QddLKf8AUoNJ+qZ1AV+zkhPtAyIMiF4fN+sBl
+HdXrlWxViGFSvM4v8h2qlhzuUfd4qLz042ox5pmyNSnTlbDkJXpDP9dyFO+BOubx
+Ribhksd9r5LTvBfq/RKikt0NkAyQx/AyGtuB2NRxUs3PY2QwU2o1dhauQIx0MH5/
+6D8PgQf6+5njKQaKa4e8Kp4kB+KjnALvt6JgYuNJUHWap+nnDbuuVy5dl1bKkAZ+
+qa7CITKWO4kE2EqaCb2asFc2w3538+w72UJZtwQCmOaxtKpRSl9fQXu54N8jIGoZ
+1FvEj5x3X6QkglE+iVJYaX3RmiJ3uzZ2LICDr89vEQKBgQD7fquIw4p1idSxz3Cm
+5o3Y5kD0CKm61ZaRJWKd+tNlSsxubmV9HROYW6vj2xEPSDvyp1na00pDXxMJQLLc
+O5Awd1SaU+d45jnoi70fsEY8X0WH1rDTYfnU+zQBmpbGqX5qTIfpy4yoADiUD1CQ
+EBdaSBWiKPx2jFSct58TwDP9YwKBgQDpC64TScZYz7uQq4gAbDso/7TjNwgt/Bw8
+JgLSdx1UdUclh81smTujsouyCFwJSvRjKik8e/Qt0f5patukFbFRINxUGUDhOKbA
+7zqeNQbeYaP7Rvw+3z01CU2BTBmB/EWa2xWDam8B9xQvjiHSOrubqkt3sIQJb045
+hzuigdV7VQKBgQD7Gnd0nyCwyMSIIMGuswYv6X4y6i9lr3qdQ4GakOTe/vbsz+cf
+K5f0CJuwbnszEgFg/zzVIx/D8rqUA3hSMlp+ObdMO7gi22Q4TsWvTRZjkxBeV7rH
+48xJneNIMqyWgIcK5YzSn3y6BTZ4hm3+2UInz09iUJ/6UZTtwNzhIIgIVwKBgQCT
+LxRHDE4gIzrT+PHRSonmr/DfnA8nc9WlS2B26lH02IkRs/5Su0iGb6p4y3zNRbCp
+vKQElki2c60ZiSqlLCosEfP1jWmDlRMEQVMlPlpTMxmtBr0jPDzc9T4lDhoCFYEk
+d3/T2vG3LQRrsHm92+hHPTuioTIS/2BJRxar4RIibQKBgQC8zoayoQ7zfEYxy3Ax
+OSao8g85hj0EAJk/VKQP2POgz6KoPay3JE9D7P7OvkebTyv/pijAuTPby4XipCNI
+K0JbFC2Kn7RW/ZV23UdnoO9crh2omOh+/52prStWXKoc+/pJe70Af+4rU7FUiI7F
+y1mIE9krIoVis6iYsyFEmkP7iw==
+-----END PRIVATE KEY-----
diff --git a/src/ncm/tests/configs/mock_config.json b/src/ncm/tests/configs/mock_config.json
new file mode 100644 (file)
index 0000000..47a6b62
--- /dev/null
@@ -0,0 +1,5 @@
+{
+    "database-type": "mock_db_test",
+    "database-ip": "127.0.0.1",
+    "plugin-dir": "."
+}
\ No newline at end of file
index a261319..1d38f10 100644 (file)
@@ -28,7 +28,6 @@ func NewRouter(projectClient moduleLib.ProjectManager,
        compositeAppClient moduleLib.CompositeAppManager,
        appClient moduleLib.AppManager,
        ControllerClient moduleLib.ControllerManager,
-       clusterClient moduleLib.ClusterManager,
        genericPlacementIntentClient moduleLib.GenericPlacementIntentManager,
        appIntentClient moduleLib.AppIntentManager,
        deploymentIntentGrpClient moduleLib.DeploymentIntentGroupManager,
@@ -54,12 +53,6 @@ func NewRouter(projectClient moduleLib.ProjectManager,
        controlHandler := controllerHandler{
                client: ControllerClient,
        }
-       if clusterClient == nil {
-               clusterClient = moduleClient.Cluster
-       }
-       clusterHandler := clusterHandler{
-               client: clusterClient,
-       }
        router.HandleFunc("/projects", projHandler.createHandler).Methods("POST")
        router.HandleFunc("/projects/{project-name}", projHandler.getHandler).Methods("GET")
        router.HandleFunc("/projects/{project-name}", projHandler.deleteHandler).Methods("DELETE")
@@ -120,22 +113,6 @@ func NewRouter(projectClient moduleLib.ProjectManager,
        router.HandleFunc("/controllers", controlHandler.createHandler).Methods("PUT")
        router.HandleFunc("/controllers/{controller-name}", controlHandler.getHandler).Methods("GET")
        router.HandleFunc("/controllers/{controller-name}", controlHandler.deleteHandler).Methods("DELETE")
-       router.HandleFunc("/cluster-providers", clusterHandler.createClusterProviderHandler).Methods("POST")
-       router.HandleFunc("/cluster-providers", clusterHandler.getClusterProviderHandler).Methods("GET")
-       router.HandleFunc("/cluster-providers/{name}", clusterHandler.getClusterProviderHandler).Methods("GET")
-       router.HandleFunc("/cluster-providers/{name}", clusterHandler.deleteClusterProviderHandler).Methods("DELETE")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters", clusterHandler.createClusterHandler).Methods("POST")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters", clusterHandler.getClusterHandler).Methods("GET")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{name}", clusterHandler.getClusterHandler).Methods("GET")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{name}", clusterHandler.deleteClusterHandler).Methods("DELETE")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/labels", clusterHandler.createClusterLabelHandler).Methods("POST")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/labels", clusterHandler.getClusterLabelHandler).Methods("GET")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/labels/{label}", clusterHandler.getClusterLabelHandler).Methods("GET")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/labels/{label}", clusterHandler.deleteClusterLabelHandler).Methods("DELETE")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs", clusterHandler.createClusterKvPairsHandler).Methods("POST")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs", clusterHandler.getClusterKvPairsHandler).Methods("GET")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs/{kvpair}", clusterHandler.getClusterKvPairsHandler).Methods("GET")
-       router.HandleFunc("/cluster-providers/{provider-name}/clusters/{cluster-name}/kv-pairs/{kvpair}", clusterHandler.deleteClusterKvPairsHandler).Methods("DELETE")
        //setting routes for genericPlacementIntent
        if genericPlacementIntentClient == nil {
                genericPlacementIntentClient = moduleClient.GenericPlacementIntent
index 7c84f12..360653c 100644 (file)
@@ -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, nil, testCase.cProfClient, nil))
+                       resp := executeRequest(request, NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, testCase.cProfClient, nil))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
index 3c543cb..1844fb3 100644 (file)
@@ -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, nil))
+                       resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, 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, nil))
+                       resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, 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, nil))
+                       resp := executeRequest(request, NewRouter(nil, nil, nil, testCase.controllerClient, nil, nil, nil, nil, nil, nil))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
index 5e820aa..af40f96 100644 (file)
@@ -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, nil))
+                       resp := executeRequest(request, NewRouter(testCase.projectClient, 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, nil))
+                       resp := executeRequest(request, NewRouter(testCase.projectClient, 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, nil))
+                       resp := executeRequest(request, NewRouter(testCase.projectClient, nil, nil, nil, nil, nil, nil, nil, nil, nil))
 
                        //Check returned code
                        if resp.StatusCode != testCase.expectedCode {
index 001903a..f95c057 100644 (file)
@@ -47,7 +47,7 @@ func main() {
                log.Fatalln("Exiting...")
        }
 
-       httpRouter := api.NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
+       httpRouter := api.NewRouter(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
        loggedRouter := handlers.LoggingHandler(os.Stdout, httpRouter)
        log.Println("Starting Kubernetes Multicloud API")
 
index 77a2f5b..c697bbf 100644 (file)
@@ -22,7 +22,6 @@ type Client struct {
        CompositeApp           *CompositeAppClient
        App                    *AppClient
        Controller             *ControllerClient
-       Cluster                *ClusterClient
        GenericPlacementIntent *GenericPlacementIntentClient
        AppIntent              *AppIntentClient
        DeploymentIntentGroup  *DeploymentIntentGroupClient
@@ -39,7 +38,6 @@ func NewClient() *Client {
        c.CompositeApp = NewCompositeAppClient()
        c.App = NewAppClient()
        c.Controller = NewControllerClient()
-       c.Cluster = NewClusterClient()
        c.GenericPlacementIntent = NewGenericPlacementIntentClient()
        c.AppIntent = NewAppIntentClient()
        c.DeploymentIntentGroup = NewDeploymentIntentGroupClient()