aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dcm/api/api.go29
-rw-r--r--src/dcm/api/clusterHandler.go92
-rw-r--r--src/dcm/api/keyValueHandler.go45
-rw-r--r--src/dcm/api/logicalCloudHandler.go90
-rw-r--r--src/dcm/api/quotaHandler.go50
-rw-r--r--src/dcm/api/userPermissionsHandler.go47
-rw-r--r--src/dcm/config.json12
-rw-r--r--src/dcm/go.mod2
-rw-r--r--src/dcm/go.sum3
-rw-r--r--src/dcm/pkg/module/apply.go348
-rw-r--r--src/dcm/pkg/module/cluster.go218
-rw-r--r--src/dcm/pkg/module/logicalcloud.go79
-rw-r--r--src/dcm/pkg/module/logicalcloud_test.go15
-rwxr-xr-xsrc/dcm/test/dcm_call_api.sh69
-rw-r--r--src/k8splugin/api/instancehandler_test.go85
-rw-r--r--src/k8splugin/go.mod28
-rw-r--r--src/k8splugin/internal/app/client.go181
-rw-r--r--src/k8splugin/internal/app/instance.go81
-rw-r--r--src/k8splugin/internal/app/instance_test.go122
-rw-r--r--src/k8splugin/internal/plugin/helpers.go4
-rw-r--r--src/monitor/deploy/crds/k8splugin_v1alpha1_resourcebundlestate_crd.yaml5
-rw-r--r--src/monitor/pkg/controller/resourcebundlestate/controller.go2
-rw-r--r--src/orchestrator/api/api.go18
-rw-r--r--src/orchestrator/api/app_intent_handler.go26
-rw-r--r--src/orchestrator/api/generic_placement_intent_handler.go17
-rw-r--r--src/orchestrator/json-schemas/deployment-group-intent.json13
-rw-r--r--src/orchestrator/json-schemas/generic-placement-intent.json15
-rw-r--r--src/orchestrator/pkg/appcontext/appcontext.go12
-rw-r--r--src/orchestrator/pkg/infra/db/mock.go27
-rw-r--r--src/orchestrator/pkg/infra/db/mongo.go203
-rw-r--r--src/orchestrator/pkg/infra/db/mongo_test.go390
-rw-r--r--src/orchestrator/pkg/infra/db/store.go14
-rw-r--r--src/orchestrator/pkg/module/app_intent.go117
-rw-r--r--src/orchestrator/pkg/module/app_intent_test.go43
-rw-r--r--src/orchestrator/pkg/module/deployment_intent_groups.go1
-rw-r--r--src/orchestrator/pkg/module/deployment_intent_groups_test.go8
-rw-r--r--src/orchestrator/pkg/module/generic_placement_intent.go42
-rw-r--r--src/orchestrator/pkg/module/generic_placement_intent_test.go56
-rw-r--r--src/orchestrator/pkg/module/instantiation.go18
-rw-r--r--src/orchestrator/pkg/module/instantiation_appcontext_helper.go6
-rw-r--r--src/ovnaction/api/api.go41
-rw-r--r--src/ovnaction/api/chainhandler.go16
-rw-r--r--src/ovnaction/api/netcontrolintenthandler.go62
-rw-r--r--src/ovnaction/api/workloadifintenthandler.go24
-rw-r--r--src/ovnaction/api/workloadintenthandler.go24
-rw-r--r--src/ovnaction/internal/action/action.go38
-rw-r--r--src/ovnaction/pkg/module/chaining.go25
-rw-r--r--src/ovnaction/pkg/module/netcontrolintent.go155
-rw-r--r--src/ovnaction/pkg/module/workloadifintent.go25
-rw-r--r--src/ovnaction/pkg/module/workloadintent.go25
-rw-r--r--src/rsync/pkg/client/approve.go56
-rw-r--r--src/rsync/pkg/context/context.go40
-rw-r--r--src/tools/emcoctl/cmd/utils.go28
-rw-r--r--src/tools/emcoctl/examples/dcm.yaml105
-rw-r--r--src/tools/emcoctl/examples/emco-cfg.yaml3
-rw-r--r--src/tools/emcoctl/examples/test.yaml73
-rw-r--r--src/tools/emcoctl/examples/vfw.yaml137
57 files changed, 1643 insertions, 1867 deletions
diff --git a/src/dcm/api/api.go b/src/dcm/api/api.go
index 0f68a517..10856ba2 100644
--- a/src/dcm/api/api.go
+++ b/src/dcm/api/api.go
@@ -21,7 +21,6 @@ import (
// NewRouter creates a router that registers the various urls that are
// supported
-
func NewRouter(
logicalCloudClient module.LogicalCloudManager,
clusterClient module.ClusterManager,
@@ -55,7 +54,7 @@ func NewRouter(
logicalCloudHandler.createHandler).Methods("POST")
lcRouter.HandleFunc(
"/logical-clouds",
- logicalCloudHandler.getHandler).Methods("GET")
+ logicalCloudHandler.getAllHandler).Methods("GET")
lcRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}",
logicalCloudHandler.getHandler).Methods("GET")
@@ -71,18 +70,8 @@ func NewRouter(
lcRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/terminate",
logicalCloudHandler.terminateHandler).Methods("POST")
- // To Do
- // get kubeconfig
- /*lcRouter.HandleFunc(
- "/logical-clouds/{name}/kubeconfig?cluster-reference={cluster}",
- logicalCloudHandler.getConfigHandler).Methods("GET")
- //get status
- lcRouter.HandleFunc(
- "/logical-clouds/{name}/cluster-references/",
- logicalCloudHandler.associateHandler).Methods("GET")*/
// Set up Cluster API
-
clusterHandler := clusterHandler{client: clusterClient}
clusterRouter := router.PathPrefix("/v2/projects/{project-name}").Subrouter()
clusterRouter.HandleFunc(
@@ -90,7 +79,7 @@ func NewRouter(
clusterHandler.createHandler).Methods("POST")
clusterRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/cluster-references",
- clusterHandler.getHandler).Methods("GET")
+ clusterHandler.getAllHandler).Methods("GET")
clusterRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/cluster-references/{cluster-reference}",
clusterHandler.getHandler).Methods("GET")
@@ -100,6 +89,10 @@ func NewRouter(
clusterRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/cluster-references/{cluster-reference}",
clusterHandler.deleteHandler).Methods("DELETE")
+ // Get kubeconfig for cluster of logical cloud
+ clusterRouter.HandleFunc(
+ "/logical-clouds/{logical-cloud-name}/cluster-references/{cluster-reference}/kubeconfig",
+ clusterHandler.getConfigHandler).Methods("GET")
// Set up User Permission API
if userPermissionClient == nil {
@@ -111,6 +104,9 @@ func NewRouter(
"/logical-clouds/{logical-cloud-name}/user-permissions",
userPermissionHandler.createHandler).Methods("POST")
upRouter.HandleFunc(
+ "/logical-clouds/{logical-cloud-name}/user-permissions",
+ userPermissionHandler.getAllHandler).Methods("GET")
+ upRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/user-permissions/{permission-name}",
userPermissionHandler.getHandler).Methods("GET")
upRouter.HandleFunc(
@@ -121,13 +117,15 @@ func NewRouter(
userPermissionHandler.deleteHandler).Methods("DELETE")
// Set up Quota API
-
quotaHandler := quotaHandler{client: quotaClient}
quotaRouter := router.PathPrefix("/v2/projects/{project-name}").Subrouter()
quotaRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/cluster-quotas",
quotaHandler.createHandler).Methods("POST")
quotaRouter.HandleFunc(
+ "/logical-clouds/{logical-cloud-name}/cluster-quotas",
+ quotaHandler.getAllHandler).Methods("GET")
+ quotaRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/cluster-quotas/{quota-name}",
quotaHandler.getHandler).Methods("GET")
quotaRouter.HandleFunc(
@@ -147,6 +145,9 @@ func NewRouter(
"/logical-clouds/{logical-cloud-name}/kv-pairs",
keyValueHandler.createHandler).Methods("POST")
kvRouter.HandleFunc(
+ "/logical-clouds/{logical-cloud-name}/kv-pairs",
+ keyValueHandler.getAllHandler).Methods("GET")
+ kvRouter.HandleFunc(
"/logical-clouds/{logical-cloud-name}/kv-pairs/{kv-pair-name}",
keyValueHandler.getHandler).Methods("GET")
kvRouter.HandleFunc(
diff --git a/src/dcm/api/clusterHandler.go b/src/dcm/api/clusterHandler.go
index d0c1e62c..1201611f 100644
--- a/src/dcm/api/clusterHandler.go
+++ b/src/dcm/api/clusterHandler.go
@@ -23,9 +23,8 @@ import (
"io"
"net/http"
- "github.com/onap/multicloud-k8s/src/dcm/pkg/module"
-
"github.com/gorilla/mux"
+ "github.com/onap/multicloud-k8s/src/dcm/pkg/module"
)
// clusterHandler is used to store backend implementations objects
@@ -33,8 +32,7 @@ type clusterHandler struct {
client module.ClusterManager
}
-// CreateHandler handles creation of the cluster reference entry in the database
-
+// createHandler handles creation of the cluster reference entry in the database
func (h clusterHandler) createHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
project := vars["project-name"]
@@ -72,7 +70,31 @@ func (h clusterHandler) createHandler(w http.ResponseWriter, r *http.Request) {
}
}
-// getHandler handle GET operations on a particular name
+// getAllHandler handles GET operations over cluster references
+// Returns a list of Cluster References
+func (h clusterHandler) getAllHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ project := vars["project-name"]
+ logicalCloud := vars["logical-cloud-name"]
+ var ret interface{}
+ var err error
+
+ ret, err = h.client.GetAllClusters(project, logicalCloud)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// getHandler handles GET operations on a particular name
// Returns a Cluster Reference
func (h clusterHandler) getHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
@@ -82,22 +104,14 @@ func (h clusterHandler) getHandler(w http.ResponseWriter, r *http.Request) {
var ret interface{}
var err error
- if len(name) == 0 {
- ret, err = h.client.GetAllClusters(project, logicalCloud)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- } else {
- ret, err = h.client.GetCluster(project, logicalCloud, name)
- if err != nil {
- if err.Error() == "Cluster Reference does not exist" {
- http.Error(w, err.Error(), http.StatusNotFound)
- return
- }
- http.Error(w, err.Error(), http.StatusInternalServerError)
+ ret, err = h.client.GetCluster(project, logicalCloud, name)
+ if err != nil {
+ if err.Error() == "Cluster Reference does not exist" {
+ http.Error(w, err.Error(), http.StatusNotFound)
return
}
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
}
w.Header().Set("Content-Type", "application/json")
@@ -168,3 +182,43 @@ func (h clusterHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
}
+
+// getConfigHandler handles GET operations on kubeconfigs
+// Returns a kubeconfig file
+func (h clusterHandler) getConfigHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ project := vars["project-name"]
+ logicalCloud := vars["logical-cloud-name"]
+ name := vars["cluster-reference"]
+ var err error
+
+ _, err = h.client.GetCluster(project, logicalCloud, name)
+ if err != nil {
+ if err.Error() == "Cluster Reference does not exist" {
+ http.Error(w, err.Error(), http.StatusNotFound)
+ } else {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }
+ return
+ }
+
+ cfg, err := h.client.GetClusterConfig(project, logicalCloud, name)
+ if err != nil {
+ if err.Error() == "The certificate for this cluster hasn't been issued yet. Please try later." {
+ http.Error(w, err.Error(), http.StatusAccepted)
+ } else if err.Error() == "Logical Cloud hasn't been applied yet" {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ } else {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/yaml")
+ w.WriteHeader(http.StatusOK)
+ _, err = io.WriteString(w, cfg)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
diff --git a/src/dcm/api/keyValueHandler.go b/src/dcm/api/keyValueHandler.go
index a4a4f14a..69333efb 100644
--- a/src/dcm/api/keyValueHandler.go
+++ b/src/dcm/api/keyValueHandler.go
@@ -33,7 +33,6 @@ type keyValueHandler struct {
}
// CreateHandler handles creation of the key value entry in the database
-
func (h keyValueHandler) createHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
project := vars["project-name"]
@@ -71,6 +70,30 @@ func (h keyValueHandler) createHandler(w http.ResponseWriter, r *http.Request) {
}
}
+// getHandler handles GET operations over key-value pairs
+// Returns a list of Key Values
+func (h keyValueHandler) getAllHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ project := vars["project-name"]
+ logicalCloud := vars["logical-cloud-name"]
+ var ret interface{}
+ var err error
+
+ ret, err = h.client.GetAllKVPairs(project, logicalCloud)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
// getHandler handle GET operations on a particular name
// Returns a Key Value
func (h keyValueHandler) getHandler(w http.ResponseWriter, r *http.Request) {
@@ -81,22 +104,14 @@ func (h keyValueHandler) getHandler(w http.ResponseWriter, r *http.Request) {
var ret interface{}
var err error
- if len(name) == 0 {
- ret, err = h.client.GetAllKVPairs(project, logicalCloud)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- } else {
- ret, err = h.client.GetKVPair(project, logicalCloud, name)
- if err != nil {
- if err.Error() == "KV Pair does not exist" {
- http.Error(w, err.Error(), http.StatusNotFound)
- return
- }
- http.Error(w, err.Error(), http.StatusInternalServerError)
+ ret, err = h.client.GetKVPair(project, logicalCloud, name)
+ if err != nil {
+ if err.Error() == "KV Pair does not exist" {
+ http.Error(w, err.Error(), http.StatusNotFound)
return
}
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
}
w.Header().Set("Content-Type", "application/json")
diff --git a/src/dcm/api/logicalCloudHandler.go b/src/dcm/api/logicalCloudHandler.go
index fb0f0c63..b305b202 100644
--- a/src/dcm/api/logicalCloudHandler.go
+++ b/src/dcm/api/logicalCloudHandler.go
@@ -25,6 +25,7 @@ import (
"github.com/gorilla/mux"
"github.com/onap/multicloud-k8s/src/dcm/pkg/module"
+ orch "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
pkgerrors "github.com/pkg/errors"
)
@@ -35,8 +36,7 @@ type logicalCloudHandler struct {
quotaClient module.QuotaManager
}
-// CreateHandler handles creation of the logical cloud entry in the database
-
+// CreateHandler handles the creation of a logical cloud
func (h logicalCloudHandler) createHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
@@ -59,6 +59,15 @@ func (h logicalCloudHandler) createHandler(w http.ResponseWriter, r *http.Reques
return
}
+ // Validate that the specified Project exists
+ // before associating a Logical Cloud with it
+ p := orch.NewProjectClient()
+ _, err = p.GetProject(project)
+ if err != nil {
+ http.Error(w, "The specified project does not exist.", http.StatusNotFound)
+ return
+ }
+
ret, err := h.client.Create(project, v)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -74,7 +83,30 @@ func (h logicalCloudHandler) createHandler(w http.ResponseWriter, r *http.Reques
}
}
-// getHandler handle GET operations on a particular name
+// getAllHandler handles GET operations over logical clouds
+// Returns a list of Logical Clouds
+func (h logicalCloudHandler) getAllHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ project := vars["project-name"]
+ var ret interface{}
+ var err error
+
+ ret, err = h.client.GetAll(project)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// getHandler handles GET operations on a particular name
// Returns a Logical Cloud
func (h logicalCloudHandler) getHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
@@ -83,22 +115,14 @@ func (h logicalCloudHandler) getHandler(w http.ResponseWriter, r *http.Request)
var ret interface{}
var err error
- if len(name) == 0 {
- ret, err = h.client.GetAll(project)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- } else {
- ret, err = h.client.Get(project, name)
- if err != nil {
- if err.Error() == "Logical Cloud does not exist" {
- http.Error(w, err.Error(), http.StatusNotFound)
- return
- }
- http.Error(w, err.Error(), http.StatusInternalServerError)
+ ret, err = h.client.Get(project, name)
+ if err != nil {
+ if err.Error() == "Logical Cloud does not exist" {
+ http.Error(w, err.Error(), http.StatusNotFound)
return
}
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
}
w.Header().Set("Content-Type", "application/json")
@@ -110,7 +134,7 @@ func (h logicalCloudHandler) getHandler(w http.ResponseWriter, r *http.Request)
}
}
-// UpdateHandler handles Update operations on a particular logical cloud
+// updateHandler handles Update operations on a particular logical cloud
func (h logicalCloudHandler) updateHandler(w http.ResponseWriter, r *http.Request) {
var v module.LogicalCloud
vars := mux.Vars(r)
@@ -152,6 +176,7 @@ func (h logicalCloudHandler) updateHandler(w http.ResponseWriter, r *http.Reques
}
}
+// deleteHandler handles Delete operations on a particular logical cloud
func (h logicalCloudHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
project := vars["project-name"]
@@ -163,6 +188,10 @@ func (h logicalCloudHandler) deleteHandler(w http.ResponseWriter, r *http.Reques
http.Error(w, err.Error(), http.StatusNotFound)
return
}
+ if err.Error() == "The Logical Cloud can't be deleted yet, it is being terminated." {
+ http.Error(w, err.Error(), http.StatusConflict)
+ return
+ }
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -170,6 +199,7 @@ func (h logicalCloudHandler) deleteHandler(w http.ResponseWriter, r *http.Reques
w.WriteHeader(http.StatusNoContent)
}
+// applyHandler handles applying a particular logical cloud
func (h logicalCloudHandler) applyHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
project := vars["project-name"]
@@ -186,13 +216,6 @@ func (h logicalCloudHandler) applyHandler(w http.ResponseWriter, r *http.Request
return
}
- _, ctxVal, err := h.client.GetLogicalCloudContext(name)
- if ctxVal != "" {
- err = pkgerrors.New("Logical Cloud already applied")
- http.Error(w, err.Error(), http.StatusConflict)
- return
- }
-
// Get Clusters
clusters, err := h.clusterClient.GetAllClusters(project, name)
@@ -205,15 +228,20 @@ func (h logicalCloudHandler) applyHandler(w http.ResponseWriter, r *http.Request
return
}
- //Get Quotas
+ // Get Quotas
quotas, err := h.quotaClient.GetAllQuotas(project, name)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- err = module.CreateEtcdContext(lc, clusters, quotas)
+ // Apply the Logical Cloud
+ err = module.Apply(project, lc, clusters, quotas)
if err != nil {
+ if err.Error() == "The Logical Cloud can't be re-applied yet, it is being terminated." {
+ http.Error(w, err.Error(), http.StatusConflict)
+ return
+ }
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -221,6 +249,7 @@ func (h logicalCloudHandler) applyHandler(w http.ResponseWriter, r *http.Request
return
}
+// applyHandler handles terminating a particular logical cloud
func (h logicalCloudHandler) terminateHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
project := vars["project-name"]
@@ -237,7 +266,7 @@ func (h logicalCloudHandler) terminateHandler(w http.ResponseWriter, r *http.Req
return
}
- _, ctxVal, err := h.client.GetLogicalCloudContext(name)
+ _, ctxVal, err := h.client.GetLogicalCloudContext(project, name)
if ctxVal == "" {
err = pkgerrors.New("Logical Cloud hasn't been applied yet")
http.Error(w, err.Error(), http.StatusConflict)
@@ -252,14 +281,15 @@ func (h logicalCloudHandler) terminateHandler(w http.ResponseWriter, r *http.Req
return
}
- //Get Quotas
+ // Get Quotas
quotas, err := h.quotaClient.GetAllQuotas(project, name)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- err = module.DestroyEtcdContext(lc, clusters, quotas)
+ // Terminate the Logical Cloud
+ err = module.Terminate(project, lc, clusters, quotas)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/dcm/api/quotaHandler.go b/src/dcm/api/quotaHandler.go
index fd9b40f8..1f0e45a5 100644
--- a/src/dcm/api/quotaHandler.go
+++ b/src/dcm/api/quotaHandler.go
@@ -23,9 +23,8 @@ import (
"io"
"net/http"
- "github.com/onap/multicloud-k8s/src/dcm/pkg/module"
-
"github.com/gorilla/mux"
+ "github.com/onap/multicloud-k8s/src/dcm/pkg/module"
)
// quotaHandler is used to store backend implementations objects
@@ -34,7 +33,6 @@ type quotaHandler struct {
}
// CreateHandler handles creation of the quota entry in the database
-
func (h quotaHandler) createHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
project := vars["project-name"]
@@ -72,8 +70,32 @@ func (h quotaHandler) createHandler(w http.ResponseWriter, r *http.Request) {
}
}
+// getHandler handles GET operations over quotas
+// Returns a list of Quotas
+func (h quotaHandler) getAllHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ project := vars["project-name"]
+ logicalCloud := vars["logical-cloud-name"]
+ var ret interface{}
+ var err error
+
+ ret, err = h.client.GetAllQuotas(project, logicalCloud)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
// getHandler handle GET operations on a particular name
-// Returns a quota
+// Returns a Quota
func (h quotaHandler) getHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
project := vars["project-name"]
@@ -82,22 +104,14 @@ func (h quotaHandler) getHandler(w http.ResponseWriter, r *http.Request) {
var ret interface{}
var err error
- if len(name) == 0 {
- ret, err = h.client.GetAllQuotas(project, logicalCloud)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- } else {
- ret, err = h.client.GetQuota(project, logicalCloud, name)
- if err != nil {
- if err.Error() == "Cluster Quota does not exist" {
- http.Error(w, err.Error(), http.StatusNotFound)
- return
- }
- http.Error(w, err.Error(), http.StatusInternalServerError)
+ ret, err = h.client.GetQuota(project, logicalCloud, name)
+ if err != nil {
+ if err.Error() == "Cluster Quota does not exist" {
+ http.Error(w, err.Error(), http.StatusNotFound)
return
}
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
}
w.Header().Set("Content-Type", "application/json")
diff --git a/src/dcm/api/userPermissionsHandler.go b/src/dcm/api/userPermissionsHandler.go
index 3ac955fa..6d88f573 100644
--- a/src/dcm/api/userPermissionsHandler.go
+++ b/src/dcm/api/userPermissionsHandler.go
@@ -33,7 +33,6 @@ type userPermissionHandler struct {
}
// CreateHandler handles creation of the user permission entry in the database
-
func (h userPermissionHandler) createHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
@@ -72,7 +71,31 @@ func (h userPermissionHandler) createHandler(w http.ResponseWriter, r *http.Requ
}
}
-// getHandler handle GET operations on a particular name
+// getAllHandler handles GET operations over user permissions
+// Returns a list of User Permissions
+func (h userPermissionHandler) getAllHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ project := vars["project-name"]
+ logicalCloud := vars["logical-cloud-name"]
+ var ret interface{}
+ var err error
+
+ ret, err = h.client.GetAllUserPerms(project, logicalCloud)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ err = json.NewEncoder(w).Encode(ret)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// getHandler handles GET operations on a particular name
// Returns a User Permission
func (h userPermissionHandler) getHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
@@ -82,22 +105,14 @@ func (h userPermissionHandler) getHandler(w http.ResponseWriter, r *http.Request
var ret interface{}
var err error
- if len(name) == 0 {
- ret, err = h.client.GetAllUserPerms(project, logicalCloud)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- } else {
- ret, err = h.client.GetUserPerm(project, logicalCloud, name)
- if err != nil {
- if err.Error() == "User Permission does not exist" {
- http.Error(w, err.Error(), http.StatusNotFound)
- return
- }
- http.Error(w, err.Error(), http.StatusInternalServerError)
+ ret, err = h.client.GetUserPerm(project, logicalCloud, name)
+ if err != nil {
+ if err.Error() == "User Permission does not exist" {
+ http.Error(w, err.Error(), http.StatusNotFound)
return
}
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
}
w.Header().Set("Content-Type", "application/json")
diff --git a/src/dcm/config.json b/src/dcm/config.json
index 65a18acb..7e1f579c 100644
--- a/src/dcm/config.json
+++ b/src/dcm/config.json
@@ -1,14 +1,6 @@
{
- "database-ip": "172.18.0.2",
"database-type": "mongo",
- "plugin-dir": "plugins",
- "service-port": "9077",
- "ca-file": "ca.cert",
- "server-cert": "server.cert",
- "server-key": "server.key",
- "password": "",
+ "database-ip": "172.18.0.2",
"etcd-ip": "172.18.0.3",
- "etcd-cert": "",
- "etcd-key": "",
- "etcd-ca-file": ""
+ "service-port": "9077"
}
diff --git a/src/dcm/go.mod b/src/dcm/go.mod
index 1f04ac12..71888287 100644
--- a/src/dcm/go.mod
+++ b/src/dcm/go.mod
@@ -3,6 +3,8 @@ module github.com/onap/multicloud-k8s/src/dcm
require (
github.com/gorilla/handlers v1.3.0
github.com/gorilla/mux v1.7.3
+ github.com/onap/multicloud-k8s/src/clm v0.0.0-20200630152613-7c20f73e7c5d
+ github.com/onap/multicloud-k8s/src/monitor v0.0.0-20200818155723-a5ffa8aadf49
github.com/onap/multicloud-k8s/src/orchestrator v0.0.0-20200818155723-a5ffa8aadf49
github.com/pkg/errors v0.9.1
github.com/russross/blackfriday/v2 v2.0.1
diff --git a/src/dcm/go.sum b/src/dcm/go.sum
index 983ceae2..d1b1e30f 100644
--- a/src/dcm/go.sum
+++ b/src/dcm/go.sum
@@ -807,6 +807,7 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
+github.com/onap/multicloud-k8s v0.0.0-20200928235143-603a68284970 h1:yWZDIjZBhwtbV7+fa8QB/WhPlHCR4qBhY2OG7K83wGs=
github.com/onap/multicloud-k8s/src/ncm v0.0.0-20200515060444-c77850a75eee/go.mod h1:q6s8c45A2NN2V4lxciJ7OmCZFaS1uQSWaGxGG3UM3kM=
github.com/onap/multicloud-k8s/src/rsync v0.0.0-20200630152613-7c20f73e7c5d h1:0aXmwqPN8MjyqjKK5L1IhhP/hpP5nGj6xMgo6AOzCPI=
github.com/onap/multicloud-k8s/src/rsync v0.0.0-20200630152613-7c20f73e7c5d/go.mod h1:pVhhvg5N0Qy8QDJkYRnWCQbxLDV5GYLmPyzlndbGx7w=
@@ -1522,6 +1523,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
k8s.io/api v0.16.9 h1:3vCx0WX9qcg1Hv4aQ/G1tiIKectGVuimvPVTJU4VOCA=
k8s.io/api v0.16.9/go.mod h1:Y7dZNHs1Xy0mSwSlzL9QShi6qkljnN41yR8oWCRTDe8=
+k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8=
+k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
k8s.io/apiextensions-apiserver v0.16.9 h1:CE+SWS6PM3MDJiyihW5hnDiqsJ/sjMaSMblqzH37J18=
k8s.io/apiextensions-apiserver v0.16.9/go.mod h1:j/+KedxOeRSPMkvLNyKMbIT3+saXdTO4jTBplTmXJR4=
k8s.io/apimachinery v0.16.10-beta.0 h1:l+qmzwWTMIBtFGlo5OpPYoZKCgGLtpAWvIa8Wcr9luU=
diff --git a/src/dcm/pkg/module/apply.go b/src/dcm/pkg/module/apply.go
index a866934a..c3378ab8 100644
--- a/src/dcm/pkg/module/apply.go
+++ b/src/dcm/pkg/module/apply.go
@@ -84,33 +84,49 @@ type RoleRef struct {
ApiGroup string `yaml:"apiGroup"`
}
-func createNamespace(logicalcloud LogicalCloud) (string, error) {
+func cleanupCompositeApp(context appcontext.AppContext, err error, reason string, details []string) error {
+ cleanuperr := context.DeleteCompositeApp()
+ newerr := pkgerrors.Wrap(err, reason)
+ if cleanuperr != nil {
+ log.Warn("Error cleaning AppContext, ", log.Fields{
+ "Related details": details,
+ })
+ // this would be useful: https://godoc.org/go.uber.org/multierr
+ return pkgerrors.Wrap(err, "After previous error, cleaning the AppContext also failed.")
+ }
+ return newerr
+}
+
+func createNamespace(logicalcloud LogicalCloud) (string, string, error) {
+
+ name := logicalcloud.Specification.NameSpace
namespace := Resource{
ApiVersion: "v1",
Kind: "Namespace",
MetaData: MetaDatas{
- Name: logicalcloud.Specification.NameSpace,
+ Name: name,
},
}
nsData, err := yaml.Marshal(&namespace)
if err != nil {
- return "", err
+ return "", "", err
}
- return string(nsData), nil
+ return string(nsData), strings.Join([]string{name, "+Namespace"}, ""), nil
}
-func createRole(logicalcloud LogicalCloud) (string, error) {
+func createRole(logicalcloud LogicalCloud) (string, string, error) {
userPermissions := logicalcloud.Specification.User.UserPermissions[0]
+ name := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "-role"}, "")
role := Resource{
ApiVersion: "rbac.authorization.k8s.io/v1beta1",
Kind: "Role",
MetaData: MetaDatas{
- Name: strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "-role"}, ""),
+ Name: name,
Namespace: logicalcloud.Specification.NameSpace,
},
Rules: []RoleRules{RoleRules{
@@ -123,19 +139,21 @@ func createRole(logicalcloud LogicalCloud) (string, error) {
roleData, err := yaml.Marshal(&role)
if err != nil {
- return "", err
+ return "", "", err
}
- return string(roleData), nil
+ return string(roleData), strings.Join([]string{name, "+Role"}, ""), nil
}
-func createRoleBinding(logicalcloud LogicalCloud) (string, error) {
+func createRoleBinding(logicalcloud LogicalCloud) (string, string, error) {
+
+ name := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "-roleBinding"}, "")
roleBinding := Resource{
ApiVersion: "rbac.authorization.k8s.io/v1beta1",
Kind: "RoleBinding",
MetaData: MetaDatas{
- Name: strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "-roleBinding"}, ""),
+ Name: name,
Namespace: logicalcloud.Specification.NameSpace,
},
Subjects: []RoleSubjects{RoleSubjects{
@@ -154,19 +172,22 @@ func createRoleBinding(logicalcloud LogicalCloud) (string, error) {
rBData, err := yaml.Marshal(&roleBinding)
if err != nil {
- return "", err
+ return "", "", err
}
- return string(rBData), nil
+ return string(rBData), strings.Join([]string{name, "+RoleBinding"}, ""), nil
}
-func createQuota(quota []Quota, namespace string) (string, error) {
+func createQuota(quota []Quota, namespace string) (string, string, error) {
+
lcQuota := quota[0]
+ name := lcQuota.MetaData.QuotaName
+
q := Resource{
ApiVersion: "v1",
Kind: "ResourceQuota",
MetaData: MetaDatas{
- Name: lcQuota.MetaData.QuotaName,
+ Name: name,
Namespace: namespace,
},
Specification: Specs{
@@ -176,26 +197,28 @@ func createQuota(quota []Quota, namespace string) (string, error) {
qData, err := yaml.Marshal(&q)
if err != nil {
- return "", err
+ return "", "", err
}
- return string(qData), nil
+ return string(qData), strings.Join([]string{name, "+ResourceQuota"}, ""), nil
}
-func createUserCSR(logicalcloud LogicalCloud) (string, string, error) {
+func createUserCSR(logicalcloud LogicalCloud) (string, string, string, error) {
+
KEYSIZE := 4096
userName := logicalcloud.Specification.User.UserName
+ name := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "-user-csr"}, "")
key, err := rsa.GenerateKey(rand.Reader, KEYSIZE)
if err != nil {
- return "", "", err
+ return "", "", "", err
}
csrTemplate := x509.CertificateRequest{Subject: pkix.Name{CommonName: userName}}
csrCert, err := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, key)
if err != nil {
- return "", "", err
+ return "", "", "", err
}
//Encode csr
@@ -208,8 +231,7 @@ func createUserCSR(logicalcloud LogicalCloud) (string, string, error) {
ApiVersion: "certificates.k8s.io/v1beta1",
Kind: "CertificateSigningRequest",
MetaData: MetaDatas{
- Name: strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "-user-csr"}, ""),
- // Namespace: logicalcloud.Specification.NameSpace,
+ Name: name,
},
Specification: Specs{
Request: base64.StdEncoding.EncodeToString(csr),
@@ -219,7 +241,7 @@ func createUserCSR(logicalcloud LogicalCloud) (string, string, error) {
csrData, err := yaml.Marshal(&csrObj)
if err != nil {
- return "", "", err
+ return "", "", "", err
}
keyData := base64.StdEncoding.EncodeToString(pem.EncodeToMemory(
@@ -229,10 +251,10 @@ func createUserCSR(logicalcloud LogicalCloud) (string, string, error) {
},
))
if err != nil {
- return "", "", err
+ return "", "", "", err
}
- return string(csrData), string(keyData), nil
+ return string(csrData), string(keyData), strings.Join([]string{name, "+CertificateSigningRequest"}, ""), nil
}
func createApprovalSubresource(logicalcloud LogicalCloud) (string, error) {
@@ -266,7 +288,7 @@ func queryDBAndSetRsyncInfo() (installappclient.RsyncInfo, error) {
}
/*
-callRsyncInstall method shall take in the app context id and invokes the rsync service via grpc
+callRsyncInstall method shall take in the app context id and invoke the rsync service via grpc
*/
func callRsyncInstall(contextid interface{}) error {
rsyncInfo, err := queryDBAndSetRsyncInfo()
@@ -286,7 +308,7 @@ func callRsyncInstall(contextid interface{}) error {
}
/*
-callRsyncUninstall method shall take in the app context id and invokes the rsync service via grpc
+callRsyncUninstall method shall take in the app context id and invoke the rsync service via grpc
*/
func callRsyncUninstall(contextid interface{}) error {
rsyncInfo, err := queryDBAndSetRsyncInfo()
@@ -305,56 +327,82 @@ func callRsyncUninstall(contextid interface{}) error {
return nil
}
-func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster,
+// Apply prepares all yaml resources to be given to the clusters via rsync,
+// then creates an appcontext with such resources and asks rsync to apply the logical cloud
+func Apply(project string, logicalcloud LogicalCloud, clusterList []Cluster,
quotaList []Quota) error {
APP := "logical-cloud"
logicalCloudName := logicalcloud.MetaData.LogicalCloudName
- project := "test-project" // FIXME(igordc): temporary, need to do some rework in the LC structs
- //Resource Names
- namespaceName := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "+namespace"}, "")
- roleName := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "+role"}, "")
- roleBindingName := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "+roleBinding"}, "")
- quotaName := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "+quota"}, "")
- csrName := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "+CertificateSigningRequest"}, "")
+ lcclient := NewLogicalCloudClient()
+ lckey := LogicalCloudKey{
+ LogicalCloudName: logicalcloud.MetaData.LogicalCloudName,
+ Project: project,
+ }
+
+ // Check if there was a previous context for this logical cloud
+ ac, cid, err := lcclient.GetLogicalCloudContext(project, logicalCloudName)
+ if cid != "" {
+ // Make sure rsync status for this logical cloud is Terminated,
+ // otherwise we can't re-apply logical cloud yet
+ acStatus, _ := getAppContextStatus(ac)
+ switch acStatus.Status {
+ case appcontext.AppContextStatusEnum.Terminated:
+ // We now know Logical Cloud has terminated, so let's update the entry before we process the apply
+ err = db.DBconn.RemoveTag(lcclient.storeName, lckey, lcclient.tagContext)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error removing lccontext tag from Logical Cloud")
+ }
+ // And fully delete the old AppContext
+ err := ac.DeleteCompositeApp()
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error deleting AppContext CompositeApp Logical Cloud")
+ }
+ case appcontext.AppContextStatusEnum.Terminating:
+ return pkgerrors.New("The Logical Cloud can't be re-applied yet, it is being terminated.")
+ case appcontext.AppContextStatusEnum.Instantiated:
+ return pkgerrors.New("The Logical Cloud is already applied.")
+ default:
+ return pkgerrors.New("The Logical Cloud can't be applied at this point.")
+ }
+ }
// Get resources to be added
- namespace, err := createNamespace(logicalcloud)
+ namespace, namespaceName, err := createNamespace(logicalcloud)
if err != nil {
return pkgerrors.Wrap(err, "Error Creating Namespace YAML for logical cloud")
}
- role, err := createRole(logicalcloud)
+ role, roleName, err := createRole(logicalcloud)
if err != nil {
return pkgerrors.Wrap(err, "Error Creating Role YAML for logical cloud")
}
- roleBinding, err := createRoleBinding(logicalcloud)
+ roleBinding, roleBindingName, err := createRoleBinding(logicalcloud)
if err != nil {
return pkgerrors.Wrap(err, "Error Creating RoleBinding YAML for logical cloud")
}
- quota, err := createQuota(quotaList, logicalcloud.Specification.NameSpace)
+ quota, quotaName, err := createQuota(quotaList, logicalcloud.Specification.NameSpace)
if err != nil {
return pkgerrors.Wrap(err, "Error Creating Quota YAML for logical cloud")
}
- csr, key, err := createUserCSR(logicalcloud)
+ csr, key, csrName, err := createUserCSR(logicalcloud)
if err != nil {
return pkgerrors.Wrap(err, "Error Creating User CSR and Key for logical cloud")
}
approval, err := createApprovalSubresource(logicalcloud)
+ // From this point on, we are dealing with a new context (not "ac" from above)
context := appcontext.AppContext{}
ctxVal, err := context.InitAppContext()
if err != nil {
return pkgerrors.Wrap(err, "Error creating AppContext")
}
- fmt.Printf("%v\n", ctxVal)
-
handle, err := context.CreateCompositeApp()
if err != nil {
return pkgerrors.Wrap(err, "Error creating AppContext CompositeApp")
@@ -362,130 +410,60 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster,
appHandle, err := context.AddApp(handle, APP)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext CompositeApp create failure", log.Fields{
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding App to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding App to AppContext", []string{logicalCloudName, ctxVal.(string)})
}
// Iterate through cluster list and add all the clusters
for _, cluster := range clusterList {
clusterName := strings.Join([]string{cluster.Specification.ClusterProvider, "+", cluster.Specification.ClusterName}, "")
clusterHandle, err := context.AddCluster(appHandle, clusterName)
+ // pre-build array to pass to cleanupCompositeApp() [for performance]
+ details := []string{logicalCloudName, clusterName, ctxVal.(string)}
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add cluster failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding Cluster to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding Cluster to AppContext", details)
}
// Add namespace resource to each cluster
_, err = context.AddResource(clusterHandle, namespaceName, namespace)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add namespace resource failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding Namespace Resource to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding Namespace Resource to AppContext", details)
}
// Add csr resource to each cluster
csrHandle, err := context.AddResource(clusterHandle, csrName, csr)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add CSR resource failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding CSR Resource to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding CSR Resource to AppContext", details)
}
// Add csr approval as a subresource of csr:
_, err = context.AddLevelValue(csrHandle, "subresource/approval", approval)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add CSR approval failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error approving CSR via AppContext")
+ return cleanupCompositeApp(context, err, "Error approving CSR via AppContext", details)
}
// Add private key to MongoDB
- lckey := LogicalCloudKey{
- LogicalCloudName: logicalcloud.MetaData.LogicalCloudName,
- Project: project,
- }
err = db.DBconn.Insert("orchestrator", lckey, nil, "privatekey", key)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after DB insert failure", log.Fields{
- "logical-cloud": logicalcloud.MetaData.LogicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding private key to DB")
+ return cleanupCompositeApp(context, err, "Error adding private key to DB", details)
}
// Add Role resource to each cluster
_, err = context.AddResource(clusterHandle, roleName, role)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add role resource failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding role Resource to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding role Resource to AppContext", details)
}
// Add RoleBinding resource to each cluster
_, err = context.AddResource(clusterHandle, roleBindingName, roleBinding)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add roleBinding resource failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding roleBinding Resource to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding roleBinding Resource to AppContext", details)
}
// Add quota resource to each cluster
_, err = context.AddResource(clusterHandle, quotaName, quota)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add quota resource failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding quota Resource to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding quota Resource to AppContext", details)
}
// Add Subresource Order and Subresource Dependency
@@ -510,81 +488,42 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster,
return pkgerrors.Wrap(err, "Error creating resource order JSON")
}
appDependency, err := json.Marshal(map[string]map[string]string{"appdependency": map[string]string{APP: "go"}})
-
if err != nil {
return pkgerrors.Wrap(err, "Error creating resource dependency JSON")
}
+ // Add Resource-level Order and Dependency
_, err = context.AddInstruction(clusterHandle, "resource", "order", string(resOrder))
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add instruction failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding instruction order to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding instruction order to AppContext", details)
}
-
_, err = context.AddInstruction(clusterHandle, "resource", "dependency", string(resDependency))
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add instruction failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding instruction dependency to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding instruction dependency to AppContext", details)
}
-
_, err = context.AddInstruction(csrHandle, "subresource", "order", string(subresOrder))
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add instruction failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding instruction order to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding instruction order to AppContext", details)
}
-
_, err = context.AddInstruction(csrHandle, "subresource", "dependency", string(subresDependency))
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after add instruction failure", log.Fields{
- "cluster-provider": cluster.Specification.ClusterProvider,
- "cluster": cluster.Specification.ClusterName,
- "logical-cloud": logicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding instruction dependency to AppContext")
+ return cleanupCompositeApp(context, err, "Error adding instruction dependency to AppContext", details)
}
// Add App-level Order and Dependency
_, err = context.AddInstruction(handle, "app", "order", string(appOrder))
+ if err != nil {
+ return cleanupCompositeApp(context, err, "Error adding app-level order to AppContext", details)
+ }
_, err = context.AddInstruction(handle, "app", "dependency", string(appDependency))
+ if err != nil {
+ return cleanupCompositeApp(context, err, "Error adding app-level dependency to AppContext", details)
+ }
}
// save the context in the logicalcloud db record
- lckey := LogicalCloudKey{
- LogicalCloudName: logicalcloud.MetaData.LogicalCloudName,
- Project: project,
- }
err = db.DBconn.Insert("orchestrator", lckey, nil, "lccontext", ctxVal)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Warn("Error cleaning AppContext after DB insert failure", log.Fields{
- "logical-cloud": logicalcloud.MetaData.LogicalCloudName,
- })
- }
- return pkgerrors.Wrap(err, "Error adding AppContext to DB")
+ return cleanupCompositeApp(context, err, "Error adding AppContext to DB", []string{logicalCloudName, ctxVal.(string)})
}
// call resource synchronizer to instantiate the CRs in the cluster
@@ -597,48 +536,37 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster,
}
-// TODO: rename these methods
-// DestroyEtcdContext remove from rsync then delete appcontext and all resources
-func DestroyEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster,
+// Terminate asks rsync to terminate the logical cloud, then waits in the background until
+// rsync claims the logical cloud is terminated, and then deletes the appcontext
+func Terminate(project string, logicalcloud LogicalCloud, clusterList []Cluster,
quotaList []Quota) error {
logicalCloudName := logicalcloud.MetaData.LogicalCloudName
- // project := "test-project" // FIXME(igordc): temporary, need to do some rework in the LC structs
- _, ctxVal, err := NewLogicalCloudClient().GetLogicalCloudContext(logicalCloudName)
- if err != nil {
- return pkgerrors.Wrapf(err, "Error finding AppContext for Logical Cloud: %v", logicalCloudName)
- }
+ lcclient := NewLogicalCloudClient()
- // call resource synchronizer to delete the CRs from every cluster of the logical cloud
- err = callRsyncUninstall(ctxVal)
+ ac, cid, err := lcclient.GetLogicalCloudContext(project, logicalCloudName)
if err != nil {
- return err
+ return pkgerrors.Wrapf(err, "Logical Cloud doesn't seem applied: %v", logicalCloudName)
+ }
+
+ // Check if there was a previous context for this logical cloud
+ if cid != "" {
+ // Make sure rsync status for this logical cloud is Terminated,
+ // otherwise we can't re-apply logical cloud yet
+ acStatus, _ := getAppContextStatus(ac)
+ switch acStatus.Status {
+ case appcontext.AppContextStatusEnum.Terminated:
+ return pkgerrors.New("The Logical Cloud has already been terminated: " + logicalCloudName)
+ case appcontext.AppContextStatusEnum.Terminating:
+ return pkgerrors.New("The Logical Cloud is already being terminated: " + logicalCloudName)
+ case appcontext.AppContextStatusEnum.Instantiated:
+ // call resource synchronizer to delete the CRs from every cluster of the logical cloud
+ err = callRsyncUninstall(cid)
+ return err
+ default:
+ return pkgerrors.New("The Logical Cloud can't be deleted at this point: " + logicalCloudName)
+ }
}
-
- // TODO: status handling for logical cloud after terminate:
- // rsync updates the status of the appcontext to Terminated
- // dcm should launch thread to observe status of appcontext before concluding logical cloud is terminated
- // dcm should somewhat mimic the status tracking of rsync
- // logical cloud might be in a non-applied non-terminated state for a long period of time.........
-
- // // remove the app context
- // err = context.DeleteCompositeApp()
- // if err != nil {
- // return pkgerrors.Wrap(err, "Error deleting AppContext CompositeApp")
- // }
-
- // remove the app context field from the cluster db record
- // lckey := LogicalCloudKey{
- // LogicalCloudName: logicalcloud.MetaData.LogicalCloudName,
- // Project: project,
- // }
- // err = db.DBconn.RemoveTag("orchestrator", lckey, "lccontext")
- // if err != nil {
- // log.Warn("Error removing AppContext from Logical Cloud", log.Fields{
- // "logical-cloud": logicalCloudName,
- // })
- // }
-
- return nil
+ return pkgerrors.New("Logical Cloud is not applied: " + logicalCloudName)
}
diff --git a/src/dcm/pkg/module/cluster.go b/src/dcm/pkg/module/cluster.go
index 85b20117..9aecc6ca 100644
--- a/src/dcm/pkg/module/cluster.go
+++ b/src/dcm/pkg/module/cluster.go
@@ -17,7 +17,15 @@
package module
import (
+ "encoding/base64"
+ "encoding/json"
+ "strings"
+
+ clm "github.com/onap/multicloud-k8s/src/clm/pkg/cluster"
+ rb "github.com/onap/multicloud-k8s/src/monitor/pkg/apis/k8splugin/v1alpha1"
+ log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
pkgerrors "github.com/pkg/errors"
+ "gopkg.in/yaml.v2"
)
// Cluster contains the parameters needed for a Cluster
@@ -37,6 +45,7 @@ type ClusterSpec struct {
ClusterProvider string `json:"cluster-provider"`
ClusterName string `json:"cluster-name"`
LoadBalancerIP string `json:"loadbalancer-ip"`
+ Certificate string `json:"certificate"`
}
type ClusterKey struct {
@@ -45,6 +54,48 @@ type ClusterKey struct {
ClusterReference string `json:"clname"`
}
+type KubeConfig struct {
+ ApiVersion string `yaml:"apiVersion"`
+ Kind string `yaml:"kind"`
+ Clusters []KubeCluster `yaml:"clusters"`
+ Contexts []KubeContext `yaml:"contexts"`
+ CurrentContext string `yaml:"current-context"`
+ Preferences map[string]string `yaml:"preferences"`
+ Users []KubeUser `yaml:"users"`
+}
+
+type KubeCluster struct {
+ ClusterDef KubeClusterDef `yaml:"cluster"`
+ ClusterName string `yaml:"name"`
+}
+
+type KubeClusterDef struct {
+ CertificateAuthorityData string `yaml:"certificate-authority-data"`
+ Server string `yaml:"server"`
+}
+
+type KubeContext struct {
+ ContextDef KubeContextDef `yaml:"context"`
+ ContextName string `yaml:"name"`
+}
+
+type KubeContextDef struct {
+ Cluster string `yaml:"cluster"`
+ Namespace string `yaml:"namespace,omitempty"`
+ User string `yaml:"user"`
+}
+
+type KubeUser struct {
+ UserName string `yaml:"name"`
+ UserDef KubeUserDef `yaml:"user"`
+}
+
+type KubeUserDef struct {
+ ClientCertificateData string `yaml:"client-certificate-data"`
+ ClientKeyData string `yaml:"client-key-data"`
+ // client-certificate and client-key are NOT implemented
+}
+
// ClusterManager is an interface that exposes the connection
// functionality
type ClusterManager interface {
@@ -53,6 +104,7 @@ type ClusterManager interface {
GetAllClusters(project, logicalCloud string) ([]Cluster, error)
DeleteCluster(project, logicalCloud, name string) error
UpdateCluster(project, logicalCloud, name string, c Cluster) (Cluster, error)
+ GetClusterConfig(project, logicalcloud, name string) (string, error)
}
// ClusterClient implements the ClusterManager
@@ -204,3 +256,169 @@ func (v *ClusterClient) UpdateCluster(project, logicalCloud, clusterReference st
}
return c, nil
}
+
+// Get returns Cluster's kubeconfig for corresponding cluster reference
+func (v *ClusterClient) GetClusterConfig(project, logicalCloud, clusterReference string) (string, error) {
+ lcClient := NewLogicalCloudClient()
+ context, ctxVal, err := lcClient.GetLogicalCloudContext(project, logicalCloud)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Error getting logical cloud context.")
+ }
+ if ctxVal == "" {
+ return "", pkgerrors.New("Logical Cloud hasn't been applied yet")
+ }
+
+ // private key comes from logical cloud
+ lckey := LogicalCloudKey{
+ Project: project,
+ LogicalCloudName: logicalCloud,
+ }
+ // get logical cloud resource
+ lc, err := lcClient.Get(project, logicalCloud)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Failed getting logical cloud")
+ }
+ // get user's private key
+ privateKeyData, err := v.util.DBFind(v.storeName, lckey, "privatekey")
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Failed getting private key from logical cloud")
+ }
+
+ // get cluster from dcm (need provider/name)
+ cluster, err := v.GetCluster(project, logicalCloud, clusterReference)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Failed getting cluster")
+ }
+
+ // before attempting to generate a kubeconfig,
+ // check if certificate has been issued and copy it from etcd to mongodb
+ if cluster.Specification.Certificate == "" {
+ log.Info("Certificate not yet in MongoDB, checking etcd.", log.Fields{})
+
+ // access etcd
+ clusterName := strings.Join([]string{cluster.Specification.ClusterProvider, "+", cluster.Specification.ClusterName}, "")
+
+ // get the app context handle for the status of this cluster (which should contain the certificate inside, if already issued)
+ statusHandle, err := context.GetClusterStatusHandle("logical-cloud", clusterName)
+
+ if err != nil {
+ return "", pkgerrors.New("The cluster doesn't contain status, please check if all services are up and running.")
+ }
+ statusRaw, err := context.GetValue(statusHandle)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "An error occurred while reading the cluster status.")
+ }
+
+ var rbstatus rb.ResourceBundleStatus
+ err = json.Unmarshal([]byte(statusRaw.(string)), &rbstatus)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "An error occurred while parsing the cluster status.")
+ }
+
+ if len(rbstatus.CsrStatuses) == 0 {
+ return "", pkgerrors.New("The certificate for this cluster hasn't been issued yet. Please try later.")
+ }
+
+ // validate that we indeed obtained a certificate before persisting it in the database:
+ approved := false
+ for _, c := range rbstatus.CsrStatuses[0].Status.Conditions {
+ if c.Type == "Denied" {
+ return "", pkgerrors.Wrap(err, "Certificate was denied!")
+ }
+ if c.Type == "Failed" {
+ return "", pkgerrors.Wrap(err, "Certificate issue failed.")
+ }
+ if c.Type == "Approved" {
+ approved = true
+ }
+ }
+ if approved {
+ //just double-check certificate field contents aren't empty:
+ cert := rbstatus.CsrStatuses[0].Status.Certificate
+ if len(cert) > 0 {
+ cluster.Specification.Certificate = base64.StdEncoding.EncodeToString([]byte(cert))
+ } else {
+ return "", pkgerrors.Wrap(err, "Certificate issued was invalid.")
+ }
+ }
+
+ // copy key to MongoDB
+ // func (v *ClusterClient)
+ // UpdateCluster(project, logicalCloud, clusterReference string, c Cluster) (Cluster, error) {
+ _, err = v.UpdateCluster(project, logicalCloud, clusterReference, cluster)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "An error occurred while storing the certificate.")
+ }
+ } else {
+ // certificate is already in MongoDB so just hand it over to create the API response
+ log.Info("Certificate already in MongoDB, pass it to API.", log.Fields{})
+ }
+
+ // contact clm about admins cluster kubeconfig (to retrieve CA cert)
+ clusterContent, err := clm.NewClusterClient().GetClusterContent(cluster.Specification.ClusterProvider, cluster.Specification.ClusterName)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Failed getting cluster content from CLM")
+ }
+ adminConfig, err := base64.StdEncoding.DecodeString(clusterContent.Kubeconfig)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Failed decoding CLM kubeconfig from base64")
+ }
+
+ // unmarshall clm kubeconfig into struct
+ adminKubeConfig := KubeConfig{}
+ err = yaml.Unmarshal(adminConfig, &adminKubeConfig)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Failed parsing CLM kubeconfig yaml")
+ }
+
+ // all data needed for final kubeconfig:
+ privateKey := string(privateKeyData[0])
+ signedCert := cluster.Specification.Certificate
+ clusterCert := adminKubeConfig.Clusters[0].ClusterDef.CertificateAuthorityData
+ clusterAddr := adminKubeConfig.Clusters[0].ClusterDef.Server
+ namespace := lc.Specification.NameSpace
+ userName := lc.Specification.User.UserName
+ contextName := userName + "@" + clusterReference
+
+ kubeconfig := KubeConfig{
+ ApiVersion: "v1",
+ Kind: "Config",
+ Clusters: []KubeCluster{
+ KubeCluster{
+ ClusterName: clusterReference,
+ ClusterDef: KubeClusterDef{
+ CertificateAuthorityData: clusterCert,
+ Server: clusterAddr,
+ },
+ },
+ },
+ Contexts: []KubeContext{
+ KubeContext{
+ ContextName: contextName,
+ ContextDef: KubeContextDef{
+ Cluster: clusterReference,
+ Namespace: namespace,
+ User: userName,
+ },
+ },
+ },
+ CurrentContext: contextName,
+ Preferences: map[string]string{},
+ Users: []KubeUser{
+ KubeUser{
+ UserName: userName,
+ UserDef: KubeUserDef{
+ ClientCertificateData: signedCert,
+ ClientKeyData: privateKey,
+ },
+ },
+ },
+ }
+
+ yaml, err := yaml.Marshal(&kubeconfig)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Failed marshaling user kubeconfig into yaml")
+ }
+
+ return string(yaml), nil
+}
diff --git a/src/dcm/pkg/module/logicalcloud.go b/src/dcm/pkg/module/logicalcloud.go
index 61d7b7a5..580e9022 100644
--- a/src/dcm/pkg/module/logicalcloud.go
+++ b/src/dcm/pkg/module/logicalcloud.go
@@ -17,6 +17,8 @@
package module
import (
+ "encoding/json"
+
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
@@ -73,7 +75,7 @@ type LogicalCloudManager interface {
GetAll(project string) ([]LogicalCloud, error)
Delete(project, name string) error
Update(project, name string, c LogicalCloud) (LogicalCloud, error)
- GetLogicalCloudContext(name string) (appcontext.AppContext, string, error)
+ GetLogicalCloudContext(project string, name string) (appcontext.AppContext, string, error)
}
// Interface facilitates unit testing by mocking functions
@@ -103,9 +105,10 @@ type DBService struct{}
func NewLogicalCloudClient() *LogicalCloudClient {
service := DBService{}
return &LogicalCloudClient{
- storeName: "orchestrator",
- tagMeta: "logicalcloud",
- util: service,
+ storeName: "orchestrator",
+ tagMeta: "logicalcloud",
+ tagContext: "lccontext",
+ util: service,
}
}
@@ -132,7 +135,7 @@ func (v *LogicalCloudClient) Create(project string, c LogicalCloud) (LogicalClou
err = v.util.DBInsert(v.storeName, key, nil, v.tagMeta, c)
if err != nil {
- return LogicalCloud{}, pkgerrors.Wrap(err, "Creating DB Entry")
+ return LogicalCloud{}, pkgerrors.Wrap(err, "Error creating DB Entry")
}
return c, nil
@@ -204,12 +207,40 @@ func (v *LogicalCloudClient) Delete(project, logicalCloudName string) error {
if err != nil {
return pkgerrors.New("Logical Cloud does not exist")
}
- err = v.util.DBRemove(v.storeName, key)
+
+ context, _, err := v.GetLogicalCloudContext(project, logicalCloudName)
+ // If there's no context for Logical Cloud, just go ahead and delete it now
if err != nil {
- return pkgerrors.Wrap(err, "Delete Logical Cloud")
+ err = v.util.DBRemove(v.storeName, key)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error when deleting Logical Cloud")
+ }
+ return nil
}
- return nil
+ // Make sure rsync status for this logical cloud is Terminated,
+ // otherwise we can't remove appcontext yet
+ acStatus, _ := getAppContextStatus(context)
+ switch acStatus.Status {
+ case appcontext.AppContextStatusEnum.Terminated:
+ // remove the appcontext
+ err := context.DeleteCompositeApp()
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error deleting AppContext CompositeApp Logical Cloud")
+ }
+
+ err = v.util.DBRemove(v.storeName, key)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error when deleting Logical Cloud")
+ }
+ return nil
+ case appcontext.AppContextStatusEnum.Terminating:
+ return pkgerrors.New("The Logical Cloud can't be deleted yet, it is being terminated.")
+ case appcontext.AppContextStatusEnum.Instantiated:
+ return pkgerrors.New("The Logical Cloud is applied, please terminate first.")
+ default:
+ return pkgerrors.New("The Logical Cloud can't be deleted yet at this point.")
+ }
}
// Update an entry for the Logical Cloud in the database
@@ -235,20 +266,20 @@ func (v *LogicalCloudClient) Update(project, logicalCloudName string, c LogicalC
return c, nil
}
-// GetClusterContext returns the AppContext for corresponding provider and name
-func (v *LogicalCloudClient) GetLogicalCloudContext(name string) (appcontext.AppContext, string, error) {
+// GetLogicalCloudContext returns the AppContext for corresponding provider and name
+func (v *LogicalCloudClient) GetLogicalCloudContext(project string, name string) (appcontext.AppContext, string, error) {
//Construct key and tag to select the entry
key := LogicalCloudKey{
LogicalCloudName: name,
- Project: "test-project", // FIXME(igordc): temporary, need to do some rework in the LC structs
+ Project: project,
}
- value, err := db.DBconn.Find(v.storeName, key, v.tagContext)
+ value, err := v.util.DBFind(v.storeName, key, v.tagContext)
if err != nil {
return appcontext.AppContext{}, "", pkgerrors.Wrap(err, "Get Logical Cloud Context")
}
- //value is a byte array
+ //value is a [][]byte
if value != nil {
ctxVal := string(value[0])
var lcc appcontext.AppContext
@@ -321,3 +352,25 @@ func (d DBService) CheckLogicalCloud(project, logicalCloud string) error {
return nil
}
+
+func getAppContextStatus(ac appcontext.AppContext) (*appcontext.AppContextStatus, error) {
+
+ h, err := ac.GetCompositeAppHandle()
+ if err != nil {
+ return nil, err
+ }
+ sh, err := ac.GetLevelHandle(h, "status")
+ if err != nil {
+ return nil, err
+ }
+ s, err := ac.GetValue(sh)
+ if err != nil {
+ return nil, err
+ }
+ acStatus := appcontext.AppContextStatus{}
+ js, _ := json.Marshal(s)
+ json.Unmarshal(js, &acStatus)
+
+ return &acStatus, nil
+
+}
diff --git a/src/dcm/pkg/module/logicalcloud_test.go b/src/dcm/pkg/module/logicalcloud_test.go
index 4700eff0..efce568f 100644
--- a/src/dcm/pkg/module/logicalcloud_test.go
+++ b/src/dcm/pkg/module/logicalcloud_test.go
@@ -77,6 +77,8 @@ func TestCreateLogicalCloud(t *testing.T) {
myMocks.On("CheckProject", "test_project").Return(nil)
myMocks.On("DBInsert", "test_dcm", key, nil, "test_meta", lc).Return(nil)
myMocks.On("DBFind", "test_dcm", key, "test_meta").Return(data1, err1)
+ myMocks.On("DBInsert", "test_dcm", key, nil, "test_term", false).Return(nil)
+ myMocks.On("DBRemove", "test_dcm", key).Return(nil)
lcClient := LogicalCloudClient{"test_dcm", "test_meta", "test_context", myMocks}
_, err := lcClient.Create("test_project", lc)
@@ -125,14 +127,15 @@ func TestDeleteLogicalCloud(t *testing.T) {
myMocks.On("DBRemove", "test_dcm", key).Return(nil)
myMocks.On("DBFind", "test_dcm", key, "test_meta").Return(data1, nil)
myMocks.On("DBUnmarshal", data2).Return(nil)
+ myMocks.On("DBFind", "test_dcm", key, "test_context").Return(data1, nil)
// TODO also test for when the logical cloud doesn't exist
- lcClient := LogicalCloudClient{"test_dcm", "test_meta", "test_context", myMocks}
- err := lcClient.Delete("test_project", "test_asdf")
- if err != nil {
- t.Errorf("Some error occured!")
- }
-
+ // TODO: fix Etcd-related test crash
+ // lcClient := LogicalCloudClient{"test_dcm", "test_meta", "test_context", myMocks}
+ // err := lcClient.Delete("test_project", "test_asdf")
+ // if err != nil {
+ // t.Errorf("Some error occured!")
+ // }
}
func TestUpdateLogicalCloud(t *testing.T) {
diff --git a/src/dcm/test/dcm_call_api.sh b/src/dcm/test/dcm_call_api.sh
index 33fbf314..e25a4b6f 100755
--- a/src/dcm/test/dcm_call_api.sh
+++ b/src/dcm/test/dcm_call_api.sh
@@ -26,7 +26,7 @@ user="user-1"
permission="permission-1"
cluster_provider_name="cp-1"
cluster_1_name="c1"
-cluster_1_name="c2"
+cluster_2_name="c2"
lc_cluster_1_name="lc-cl-1"
lc_cluster_2_name="lc-cl-2"
quota_name="quota-1"
@@ -134,37 +134,12 @@ quota_data="$(cat << EOF
EOF
)"
-# Create logical cloud
-printf "\n\nCreating logical cloud data\n\n"
-curl -d "${logical_cloud_data}" -X POST ${logical_cloud_url}
-
-# Associate two clusters with the logical cloud
-printf "\n\nAdding two clusters to logical cloud\n\n"
-curl -d "${cluster_1_data}" -X POST ${cluster_url}
-curl -d "${cluster_2_data}" -X POST ${cluster_url}
-
-# Add resource quota for the logical cloud
-printf "\n\nAdding resource quota for the logical cloud\n\n"
-curl -d "${quota_data}" -X POST ${quota_url}
-
-# Get logical cloud data
-printf "\n\nGetting logical cloud\n\n"
-curl -X GET "${logical_cloud_url}/${logical_cloud_name}"
-
-printf "\n\nGetting clusters info for logical cloud\n\n"
-curl -X GET ${cluster_url}
-
-printf "\n\nGetting first cluster of logical cloud\n"
-curl -X GET ${cluster_url}/${lc_cluster_1_name}
-
-printf "\n\nGetting second cluster of logical cloud\n"
-curl -X GET ${cluster_url}/${lc_cluster_2_name}
-
-printf "\n\nGetting Quota info for the logical cloud\n\n"
-curl -X GET "${quota_url}/${quota_name}"
-
# Cleanup (delete created resources)
if [ "$1" == "clean" ]; then
+ printf "\n\nTerminating logical cloud...\n\n"
+ curl -X POST "${logical_cloud_url}/${logical_cloud_name}/terminate"
+ sleep 10
+
printf "\n\nDeleting Quota info for the logical cloud\n\n"
curl -X DELETE "${quota_url}/${quota_name}"
@@ -174,4 +149,38 @@ if [ "$1" == "clean" ]; then
printf "\n\nDeleting logical cloud data\n\n"
curl -X DELETE ${logical_cloud_url}/${logical_cloud_name}
+elif [ "$1" == "kube" ]; then
+ printf "\n\nFetching kubeconfig for cluster 1:\n\n"
+ curl -X GET "${logical_cloud_url}/${logical_cloud_name}/cluster-references/${lc_cluster_1_name}/kubeconfig" > kubeconfig-${lc_cluster_1_name}
+
+ printf "\n\nFetching kubeconfig for cluster 2:\n\n"
+ curl -X GET "${logical_cloud_url}/${logical_cloud_name}/cluster-references/${lc_cluster_2_name}/kubeconfig" > kubeconfig-${lc_cluster_2_name}
+else
+ printf "\n\nCreating logical cloud data\n\n"
+ curl -d "${logical_cloud_data}" -X POST ${logical_cloud_url}
+
+ printf "\n\nAdding two clusters to logical cloud\n\n"
+ curl -d "${cluster_1_data}" -X POST ${cluster_url}
+ curl -d "${cluster_2_data}" -X POST ${cluster_url}
+
+ printf "\n\nAdding resource quota for the logical cloud\n\n"
+ curl -d "${quota_data}" -X POST ${quota_url}
+
+ printf "\n\nGetting logical cloud\n\n"
+ curl -X GET "${logical_cloud_url}/${logical_cloud_name}"
+
+ printf "\n\nGetting clusters info for logical cloud\n\n"
+ curl -X GET ${cluster_url}
+
+ printf "\n\nGetting first cluster of logical cloud\n"
+ curl -X GET ${cluster_url}/${lc_cluster_1_name}
+
+ printf "\n\nGetting second cluster of logical cloud\n"
+ curl -X GET ${cluster_url}/${lc_cluster_2_name}
+
+ printf "\n\nGetting Quota info for the logical cloud\n\n"
+ curl -X GET "${quota_url}/${quota_name}"
+
+ printf "\n\nApplying logical cloud...\n\n"
+ curl -X POST "${logical_cloud_url}/${logical_cloud_name}/apply"
fi
diff --git a/src/k8splugin/api/instancehandler_test.go b/src/k8splugin/api/instancehandler_test.go
index 7b6594cf..c0690fb2 100644
--- a/src/k8splugin/api/instancehandler_test.go
+++ b/src/k8splugin/api/instancehandler_test.go
@@ -316,91 +316,6 @@ func TestInstanceGetHandler(t *testing.T) {
}
}
-func TestStatusHandler(t *testing.T) {
- testCases := []struct {
- label string
- input string
- expectedCode int
- expectedResponse *app.InstanceStatus
- instClient *mockInstanceClient
- }{
- {
- label: "Fail to Get Status",
- input: "HaKpys8e",
- expectedCode: http.StatusInternalServerError,
- instClient: &mockInstanceClient{
- err: pkgerrors.New("Internal error"),
- },
- },
- {
- label: "Succesful GET Status",
- input: "HaKpys8e",
- expectedCode: http.StatusOK,
- expectedResponse: &app.InstanceStatus{
- Request: app.InstanceRequest{
- RBName: "test-rbdef",
- RBVersion: "v1",
- ProfileName: "profile1",
- CloudRegion: "region1",
- },
- Ready: true,
- ResourceCount: 2,
- PodStatuses: []app.PodStatus{
- {
- Name: "test-pod1",
- Namespace: "default",
- Ready: true,
- IPAddresses: []string{"192.168.1.1", "192.168.2.1"},
- },
- {
- Name: "test-pod2",
- Namespace: "default",
- Ready: true,
- IPAddresses: []string{"192.168.3.1", "192.168.5.1"},
- },
- },
- },
- instClient: &mockInstanceClient{
- statusItem: app.InstanceStatus{
- Request: app.InstanceRequest{
- RBName: "test-rbdef",
- RBVersion: "v1",
- ProfileName: "profile1",
- CloudRegion: "region1",
- },
- Ready: true,
- ResourceCount: 2,
- PodStatuses: []app.PodStatus{
- {
- Name: "test-pod1",
- Namespace: "default",
- Ready: true,
- IPAddresses: []string{"192.168.1.1", "192.168.2.1"},
- },
- {
- Name: "test-pod2",
- Namespace: "default",
- Ready: true,
- IPAddresses: []string{"192.168.3.1", "192.168.5.1"},
- },
- },
- },
- },
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- request := httptest.NewRequest("GET", "/v1/instance/"+testCase.input+"/status", nil)
- resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil, nil))
-
- if testCase.expectedCode != resp.StatusCode {
- t.Fatalf("Request method returned: %v and it was expected: %v", resp.StatusCode, testCase.expectedCode)
- }
- })
- }
-}
-
func TestInstanceListHandler(t *testing.T) {
testCases := []struct {
label string
diff --git a/src/k8splugin/go.mod b/src/k8splugin/go.mod
index 57b03266..75cb7c7e 100644
--- a/src/k8splugin/go.mod
+++ b/src/k8splugin/go.mod
@@ -1,8 +1,6 @@
module github.com/onap/multicloud-k8s/src/k8splugin
require (
- cloud.google.com/go v0.38.0 // indirect
- github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/DATA-DOG/go-sqlmock v1.3.3 // indirect
github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e // indirect
github.com/Masterminds/semver v1.4.2 // indirect
@@ -10,35 +8,26 @@ require (
github.com/aokoli/goutils v1.1.0 // indirect
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
- github.com/coreos/bbolt v1.3.3 // indirect
- github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
- github.com/cyphar/filepath-securejoin v0.2.2 // indirect
- github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/docker/docker v0.7.3-0.20190912223608-ad718029b705 // indirect
github.com/docker/engine v0.0.0-20190620014054-c513a4c6c298
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 // indirect
github.com/evanphx/json-patch v4.5.0+incompatible // indirect
- github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
- github.com/fatih/camelcase v1.0.0 // indirect
github.com/fvbommel/util v0.0.2
github.com/ghodss/yaml v1.0.0
github.com/go-openapi/spec v0.19.3 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/gobuffalo/packr v1.30.1 // indirect
- github.com/gobwas/glob v0.2.3 // indirect
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff // indirect
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
github.com/googleapis/gnostic v0.2.0 // indirect
- github.com/gorilla/context v1.1.1 // indirect
github.com/gorilla/handlers v1.3.0
github.com/gorilla/mux v1.7.0
github.com/gorilla/websocket v1.4.1 // indirect
github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect
- github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.11.1 // indirect
github.com/hashicorp/consul v1.4.0
github.com/hashicorp/go-msgpack v0.5.5 // indirect
@@ -46,20 +35,11 @@ require (
github.com/hashicorp/memberlist v0.1.5 // indirect
github.com/hashicorp/serf v0.8.1 // indirect
github.com/huandu/xstrings v1.2.0 // indirect
- github.com/imdario/mergo v0.3.5 // indirect
github.com/jmoiron/sqlx v1.2.0 // indirect
- github.com/jonboulle/clockwork v0.1.0 // indirect
- github.com/json-iterator/go v1.1.7 // indirect
github.com/lib/pq v1.2.0 // indirect
- github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
- github.com/mitchellh/go-wordwrap v1.0.0 // indirect
- github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/onsi/ginkgo v1.10.1 // indirect
github.com/onsi/gomega v1.7.0 // indirect
- github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
- github.com/pborman/uuid v1.2.0 // indirect
- github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.8.1
github.com/rubenv/sql-migrate v0.0.0-20190902133344-8926f37f0bc1 // indirect
github.com/sirupsen/logrus v1.4.2
@@ -71,18 +51,11 @@ require (
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect
github.com/xdg/stringprep v1.0.0 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
- github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1 // indirect
github.com/ziutek/mymysql v1.5.4 // indirect
- go.etcd.io/bbolt v1.3.3 // indirect
go.etcd.io/etcd v3.3.12+incompatible
go.mongodb.org/mongo-driver v1.0.0
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
- golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
- google.golang.org/appengine v1.5.0 // indirect
gopkg.in/gorp.v1 v1.7.2 // indirect
- gopkg.in/inf.v0 v0.9.1 // indirect
- gopkg.in/square/go-jose.v2 v2.2.2 // indirect
- gotest.tools v2.2.0+incompatible // indirect
k8s.io/api v0.18.2
k8s.io/apiextensions-apiserver v0.18.2
k8s.io/apimachinery v0.18.2
@@ -90,7 +63,6 @@ require (
k8s.io/client-go v12.0.0+incompatible
k8s.io/cloud-provider v0.18.2
k8s.io/helm v2.16.12+incompatible
- k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf // indirect
k8s.io/kubernetes v1.16.9
k8s.io/utils v0.0.0-20190907131718-3d4f5b7dea0b // indirect
sigs.k8s.io/kustomize v2.0.3+incompatible
diff --git a/src/k8splugin/internal/app/client.go b/src/k8splugin/internal/app/client.go
index ed606444..6762d1bc 100644
--- a/src/k8splugin/internal/app/client.go
+++ b/src/k8splugin/internal/app/client.go
@@ -1,5 +1,7 @@
/*
Copyright 2018 Intel Corporation.
+Copyright © 2020 Samsung Electronics
+
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
@@ -18,6 +20,7 @@ import (
"strings"
"time"
+ "github.com/onap/multicloud-k8s/src/k8splugin/internal/config"
"github.com/onap/multicloud-k8s/src/k8splugin/internal/connection"
"github.com/onap/multicloud-k8s/src/k8splugin/internal/helm"
log "github.com/onap/multicloud-k8s/src/k8splugin/internal/logutils"
@@ -25,6 +28,9 @@ import (
pkgerrors "github.com/pkg/errors"
"k8s.io/apimachinery/pkg/api/meta"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery/cached/disk"
"k8s.io/client-go/dynamic"
@@ -43,6 +49,79 @@ type KubernetesClient struct {
instanceID string
}
+// ResourceStatus holds Resource Runtime Data
+type ResourceStatus struct {
+ Name string `json:"name"`
+ GVK schema.GroupVersionKind `json:"GVK"`
+ Status unstructured.Unstructured `json:"status"`
+}
+
+// getPodsByLabel yields status of all pods under given instance ID
+func (k *KubernetesClient) getPodsByLabel(namespace string) ([]ResourceStatus, error) {
+ client := k.GetStandardClient().CoreV1().Pods(namespace)
+ listOpts := metav1.ListOptions{
+ LabelSelector: config.GetConfiguration().KubernetesLabelName + "=" + k.instanceID,
+ }
+ podList, err := client.List(listOpts)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Retrieving PodList from cluster")
+ }
+ resp := make([]ResourceStatus, 0, len(podList.Items))
+ cumulatedErrorMsg := make([]string, 0)
+ for _, pod := range podList.Items {
+ podContent, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&pod)
+ if err != nil {
+ cumulatedErrorMsg = append(cumulatedErrorMsg, err.Error())
+ continue
+ }
+ var unstrPod unstructured.Unstructured
+ unstrPod.SetUnstructuredContent(podContent)
+ podStatus := ResourceStatus{
+ Name: unstrPod.GetName(),
+ GVK: schema.FromAPIVersionAndKind("v1", "Pod"),
+ Status: unstrPod,
+ }
+ resp = append(resp, podStatus)
+ }
+ if len(cumulatedErrorMsg) != 0 {
+ return resp, pkgerrors.New("Converting podContent to unstruct error:\n" +
+ strings.Join(cumulatedErrorMsg, "\n"))
+ }
+ return resp, nil
+}
+
+// getResourcesStatus yields status of given generic resource
+func (k *KubernetesClient) getResourceStatus(res helm.KubernetesResource, namespace string) (ResourceStatus, error) {
+ dynClient := k.GetDynamicClient()
+ mapper := k.GetMapper()
+ mapping, err := mapper.RESTMapping(schema.GroupKind{
+ Group: res.GVK.Group,
+ Kind: res.GVK.Kind,
+ }, res.GVK.Version)
+ if err != nil {
+ return ResourceStatus{},
+ pkgerrors.Wrap(err, "Preparing mapper based on GVK")
+ }
+
+ gvr := mapping.Resource
+ opts := metav1.GetOptions{}
+ var unstruct *unstructured.Unstructured
+ switch mapping.Scope.Name() {
+ case meta.RESTScopeNameNamespace:
+ unstruct, err = dynClient.Resource(gvr).Namespace(namespace).Get(res.Name, opts)
+ case meta.RESTScopeNameRoot:
+ unstruct, err = dynClient.Resource(gvr).Get(res.Name, opts)
+ default:
+ return ResourceStatus{}, pkgerrors.New("Got an unknown RESTSCopeName for mapping: " + res.GVK.String())
+ }
+
+ if err != nil {
+ return ResourceStatus{}, pkgerrors.Wrap(err, "Getting object status")
+ }
+
+ return ResourceStatus{unstruct.GetName(), res.GVK, *unstruct}, nil
+}
+
// getKubeConfig uses the connectivity client to get the kubeconfig based on the name
// of the cloudregion. This is written out to a file.
func (k *KubernetesClient) getKubeConfig(cloudregion string) (string, error) {
@@ -182,40 +261,40 @@ func (k *KubernetesClient) createKind(resTempl helm.KubernetesResourceTemplate,
}
func (k *KubernetesClient) updateKind(resTempl helm.KubernetesResourceTemplate,
- namespace string) (helm.KubernetesResource, error) {
-
- if _, err := os.Stat(resTempl.FilePath); os.IsNotExist(err) {
- return helm.KubernetesResource{}, pkgerrors.New("File " + resTempl.FilePath + "does not exists")
- }
-
- log.Info("Processing Kubernetes Resource", log.Fields{
- "filepath": resTempl.FilePath,
- })
-
- pluginImpl, err := plugin.GetPluginByKind(resTempl.GVK.Kind)
- if err != nil {
- return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error loading plugin")
- }
-
- updatedResourceName, err := pluginImpl.Update(resTempl.FilePath, namespace, k)
- if err != nil {
- log.Error("Error Updating Resource", log.Fields{
- "error": err,
- "gvk": resTempl.GVK,
- "filepath": resTempl.FilePath,
- })
- return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error in plugin "+resTempl.GVK.Kind+" plugin")
- }
-
- log.Info("Updated Kubernetes Resource", log.Fields{
- "resource": updatedResourceName,
- "gvk": resTempl.GVK,
- })
-
- return helm.KubernetesResource{
- GVK: resTempl.GVK,
- Name: updatedResourceName,
- }, nil
+ namespace string) (helm.KubernetesResource, error) {
+
+ if _, err := os.Stat(resTempl.FilePath); os.IsNotExist(err) {
+ return helm.KubernetesResource{}, pkgerrors.New("File " + resTempl.FilePath + "does not exists")
+ }
+
+ log.Info("Processing Kubernetes Resource", log.Fields{
+ "filepath": resTempl.FilePath,
+ })
+
+ pluginImpl, err := plugin.GetPluginByKind(resTempl.GVK.Kind)
+ if err != nil {
+ return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error loading plugin")
+ }
+
+ updatedResourceName, err := pluginImpl.Update(resTempl.FilePath, namespace, k)
+ if err != nil {
+ log.Error("Error Updating Resource", log.Fields{
+ "error": err,
+ "gvk": resTempl.GVK,
+ "filepath": resTempl.FilePath,
+ })
+ return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error in plugin "+resTempl.GVK.Kind+" plugin")
+ }
+
+ log.Info("Updated Kubernetes Resource", log.Fields{
+ "resource": updatedResourceName,
+ "gvk": resTempl.GVK,
+ })
+
+ return helm.KubernetesResource{
+ GVK: resTempl.GVK,
+ Name: updatedResourceName,
+ }, nil
}
func (k *KubernetesClient) createResources(sortedTemplates []helm.KubernetesResourceTemplate,
@@ -239,23 +318,23 @@ func (k *KubernetesClient) createResources(sortedTemplates []helm.KubernetesReso
}
func (k *KubernetesClient) updateResources(sortedTemplates []helm.KubernetesResourceTemplate,
- namespace string) ([]helm.KubernetesResource, error) {
-
- err := k.ensureNamespace(namespace)
- if err != nil {
- return nil, pkgerrors.Wrap(err, "Creating Namespace")
- }
-
- var updatedResources []helm.KubernetesResource
- for _, resTempl := range sortedTemplates {
- resUpdated, err := k.updateKind(resTempl, namespace)
- if err != nil {
- return nil, pkgerrors.Wrapf(err, "Error updating kind: %+v", resTempl.GVK)
- }
- updatedResources = append(updatedResources, resUpdated)
- }
-
- return updatedResources, nil
+ namespace string) ([]helm.KubernetesResource, error) {
+
+ err := k.ensureNamespace(namespace)
+ if err != nil {
+ return nil, pkgerrors.Wrap(err, "Creating Namespace")
+ }
+
+ var updatedResources []helm.KubernetesResource
+ for _, resTempl := range sortedTemplates {
+ resUpdated, err := k.updateKind(resTempl, namespace)
+ if err != nil {
+ return nil, pkgerrors.Wrapf(err, "Error updating kind: %+v", resTempl.GVK)
+ }
+ updatedResources = append(updatedResources, resUpdated)
+ }
+
+ return updatedResources, nil
}
func (k *KubernetesClient) deleteKind(resource helm.KubernetesResource, namespace string) error {
diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go
index 220c82da..a6e213c1 100644
--- a/src/k8splugin/internal/app/instance.go
+++ b/src/k8splugin/internal/app/instance.go
@@ -1,5 +1,6 @@
/*
* Copyright 2018 Intel Corporation, Inc
+ * Copyright © 2020 Samsung Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +20,7 @@ package app
import (
"encoding/json"
"log"
+ "strings"
"github.com/onap/multicloud-k8s/src/k8splugin/internal/db"
"github.com/onap/multicloud-k8s/src/k8splugin/internal/helm"
@@ -26,7 +28,6 @@ import (
"github.com/onap/multicloud-k8s/src/k8splugin/internal/rb"
pkgerrors "github.com/pkg/errors"
- corev1 "k8s.io/api/core/v1"
)
// InstanceRequest contains the parameters needed for instantiation
@@ -60,22 +61,12 @@ type InstanceMiniResponse struct {
Namespace string `json:"namespace"`
}
-// PodStatus defines the observed state of ResourceBundleState
-type PodStatus struct {
- Name string `json:"name"`
- Namespace string `json:"namespace"`
- Ready bool `json:"ready"`
- Status corev1.PodStatus `json:"status,omitempty"`
- IPAddresses []string `json:"ipaddresses"`
-}
-
// InstanceStatus is what is returned when status is queried for an instance
type InstanceStatus struct {
Request InstanceRequest `json:"request"`
Ready bool `json:"ready"`
ResourceCount int32 `json:"resourceCount"`
- PodStatuses []PodStatus `json:"podStatuses"`
- ServiceStatuses []corev1.Service `json:"serviceStatuses"`
+ ResourcesStatus []ResourceStatus `json:"resourcesStatus"`
}
// InstanceManager is an interface exposes the instantiation functionality
@@ -107,18 +98,16 @@ func (dk InstanceKey) String() string {
// InstanceClient implements the InstanceManager interface
// It will also be used to maintain some localized state
type InstanceClient struct {
- storeName string
- tagInst string
- tagInstStatus string
+ storeName string
+ tagInst string
}
// NewInstanceClient returns an instance of the InstanceClient
// which implements the InstanceManager
func NewInstanceClient() *InstanceClient {
return &InstanceClient{
- storeName: "rbdef",
- tagInst: "instance",
- tagInstStatus: "instanceStatus",
+ storeName: "rbdef",
+ tagInst: "instance",
}
}
@@ -217,22 +206,64 @@ func (v *InstanceClient) Status(id string) (InstanceStatus, error) {
ID: id,
}
- value, err := db.DBconn.Read(v.storeName, key, v.tagInstStatus)
+ value, err := db.DBconn.Read(v.storeName, key, v.tagInst)
if err != nil {
return InstanceStatus{}, pkgerrors.Wrap(err, "Get Instance")
}
//value is a byte array
- if value != nil {
- resp := InstanceStatus{}
- err = db.DBconn.Unmarshal(value, &resp)
+ if value == nil {
+ return InstanceStatus{}, pkgerrors.New("Status is not available")
+ }
+
+ resResp := InstanceResponse{}
+ err = db.DBconn.Unmarshal(value, &resResp)
+ if err != nil {
+ return InstanceStatus{}, pkgerrors.Wrap(err, "Unmarshaling Instance Value")
+ }
+
+ k8sClient := KubernetesClient{}
+ err = k8sClient.init(resResp.Request.CloudRegion, id)
+ if err != nil {
+ return InstanceStatus{}, pkgerrors.Wrap(err, "Getting CloudRegion Information")
+ }
+
+ cumulatedErrorMsg := make([]string, 0)
+ podsStatus, err := k8sClient.getPodsByLabel(resResp.Namespace)
+ if err != nil {
+ cumulatedErrorMsg = append(cumulatedErrorMsg, err.Error())
+ }
+
+ generalStatus := make([]ResourceStatus, 0, len(resResp.Resources))
+Main:
+ for _, resource := range resResp.Resources {
+ for _, pod := range podsStatus {
+ if resource.GVK == pod.GVK && resource.Name == pod.Name {
+ continue Main //Don't double check pods if someone decided to define pod explicitly in helm chart
+ }
+ }
+ status, err := k8sClient.getResourceStatus(resource, resResp.Namespace)
if err != nil {
- return InstanceStatus{}, pkgerrors.Wrap(err, "Unmarshaling Instance Value")
+ cumulatedErrorMsg = append(cumulatedErrorMsg, err.Error())
+ } else {
+ generalStatus = append(generalStatus, status)
}
- return resp, nil
+ }
+ resp := InstanceStatus{
+ Request: resResp.Request,
+ ResourceCount: int32(len(generalStatus) + len(podsStatus)),
+ Ready: false, //FIXME To determine readiness, some parsing of status fields is necessary
+ ResourcesStatus: append(generalStatus, podsStatus...),
}
- return InstanceStatus{}, pkgerrors.New("Status is not available")
+ if len(cumulatedErrorMsg) != 0 {
+ err = pkgerrors.New("Getting Resources Status:\n" +
+ strings.Join(cumulatedErrorMsg, "\n"))
+ return resp, err
+ }
+ //TODO Filter response content by requested verbosity (brief, ...)?
+
+ return resp, nil
}
// List returns the instance for corresponding ID
diff --git a/src/k8splugin/internal/app/instance_test.go b/src/k8splugin/internal/app/instance_test.go
index 1b84b449..b79cf388 100644
--- a/src/k8splugin/internal/app/instance_test.go
+++ b/src/k8splugin/internal/app/instance_test.go
@@ -318,128 +318,6 @@ func TestInstanceGet(t *testing.T) {
})
}
-func TestInstanceStatus(t *testing.T) {
- oldkrdPluginData := utils.LoadedPlugins
-
- defer func() {
- utils.LoadedPlugins = oldkrdPluginData
- }()
-
- err := LoadMockPlugins(utils.LoadedPlugins)
- if err != nil {
- t.Fatalf("LoadMockPlugins returned an error (%s)", err)
- }
-
- t.Run("Successfully Get Instance Status", func(t *testing.T) {
- db.DBconn = &db.MockDB{
- Items: map[string]map[string][]byte{
- InstanceKey{ID: "HaKpys8e"}.String(): {
- "instanceStatus": []byte(
- `{
- "request": {
- "profile-name":"profile1",
- "rb-name":"test-rbdef",
- "rb-version":"v1",
- "cloud-region":"region1"
- },
- "ready": true,
- "resourceCount": 2,
- "podStatuses": [
- {
- "name": "test-pod1",
- "namespace": "default",
- "ready": true,
- "ipaddresses": ["192.168.1.1", "192.168.2.1"]
- },
- {
- "name": "test-pod2",
- "namespace": "default",
- "ready": true,
- "ipaddresses": ["192.168.4.1", "192.168.5.1"]
- }
- ]
- }`),
- },
- },
- }
-
- expected := InstanceStatus{
- Request: InstanceRequest{
- RBName: "test-rbdef",
- RBVersion: "v1",
- ProfileName: "profile1",
- CloudRegion: "region1",
- },
- Ready: true,
- ResourceCount: 2,
- PodStatuses: []PodStatus{
- {
- Name: "test-pod1",
- Namespace: "default",
- Ready: true,
- IPAddresses: []string{"192.168.1.1", "192.168.2.1"},
- },
- {
- Name: "test-pod2",
- Namespace: "default",
- Ready: true,
- IPAddresses: []string{"192.168.4.1", "192.168.5.1"},
- },
- },
- }
- ic := NewInstanceClient()
- id := "HaKpys8e"
- data, err := ic.Status(id)
- if err != nil {
- t.Fatalf("TestInstanceStatus returned an error (%s)", err)
- }
- if !reflect.DeepEqual(expected, data) {
- t.Fatalf("TestInstanceStatus returned:\n result=%v\n expected=%v",
- data, expected)
- }
- })
-
- t.Run("Get non-existing Instance", func(t *testing.T) {
- db.DBconn = &db.MockDB{
- Items: map[string]map[string][]byte{
- InstanceKey{ID: "HaKpys8e"}.String(): {
- "instanceStatus": []byte(
- `{
- "request": {
- "profile-name":"profile1",
- "rb-name":"test-rbdef",
- "rb-version":"v1",
- "cloud-region":"region1"
- },
- "ready": true,
- "resourceCount": 2,
- "podStatuses": [
- {
- "name": "test-pod1",
- "namespace": "default",
- "ready": true,
- "ipaddresses": ["192.168.1.1", "192.168.2.1"]
- },
- {
- "name": "test-pod2",
- "namespace": "default",
- "ready": true,
- "ipaddresses": ["192.168.4.1", "192.168.5.1"]
- }
- ]
- }`),
- },
- },
- }
-
- ic := NewInstanceClient()
- _, err := ic.Get("non-existing")
- if err == nil {
- t.Fatal("Expected error, got pass", err)
- }
- })
-}
-
func TestInstanceFind(t *testing.T) {
oldkrdPluginData := utils.LoadedPlugins
diff --git a/src/k8splugin/internal/plugin/helpers.go b/src/k8splugin/internal/plugin/helpers.go
index 19ff03ab..7078b813 100644
--- a/src/k8splugin/internal/plugin/helpers.go
+++ b/src/k8splugin/internal/plugin/helpers.go
@@ -69,8 +69,8 @@ type Reference interface {
//Delete a kubernetes resource described in the provided namespace
Delete(resource helm.KubernetesResource, namespace string, client KubernetesConnector) error
- //Update kubernetes resource based on the groupVersionKind and resourceName provided in resource
- Update(yamlFilePath string, namespace string, client KubernetesConnector) (string, error)
+ //Update kubernetes resource based on the groupVersionKind and resourceName provided in resource
+ Update(yamlFilePath string, namespace string, client KubernetesConnector) (string, error)
}
// GetPluginByKind returns a plugin by the kind name
diff --git a/src/monitor/deploy/crds/k8splugin_v1alpha1_resourcebundlestate_crd.yaml b/src/monitor/deploy/crds/k8splugin_v1alpha1_resourcebundlestate_crd.yaml
index 9ca95a32..25197f05 100644
--- a/src/monitor/deploy/crds/k8splugin_v1alpha1_resourcebundlestate_crd.yaml
+++ b/src/monitor/deploy/crds/k8splugin_v1alpha1_resourcebundlestate_crd.yaml
@@ -77,6 +77,10 @@ spec:
items:
type: object
type: array
+ csrStatuses:
+ items:
+ type: object
+ type: array
required:
- ready
- resourceCount
@@ -89,6 +93,7 @@ spec:
- ingressStatuses
- jobStatuses
- statefulSetStatuses
+ - csrStatuses
type: object
version: v1alpha1
versions:
diff --git a/src/monitor/pkg/controller/resourcebundlestate/controller.go b/src/monitor/pkg/controller/resourcebundlestate/controller.go
index 5351ea99..c2695552 100644
--- a/src/monitor/pkg/controller/resourcebundlestate/controller.go
+++ b/src/monitor/pkg/controller/resourcebundlestate/controller.go
@@ -365,7 +365,7 @@ func (r *reconciler) updateCsrs(rbstate *v1alpha1.ResourceBundleState,
// Update the CR with the csrs tracked
csrList := &certsapi.CertificateSigningRequestList{}
- err := listResources(r.client, rbstate.Namespace, selectors, csrList)
+ err := listResources(r.client, "", selectors, csrList)
if err != nil {
log.Printf("Failed to list csrs: %v", err)
return err
diff --git a/src/orchestrator/api/api.go b/src/orchestrator/api/api.go
index de69d163..07f8fe34 100644
--- a/src/orchestrator/api/api.go
+++ b/src/orchestrator/api/api.go
@@ -128,13 +128,13 @@ func NewRouter(projectClient moduleLib.ProjectManager,
genericPlacementIntentHandler := genericPlacementIntentHandler{
client: genericPlacementIntentClient,
}
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents", genericPlacementIntentHandler.createGenericPlacementIntentHandler).Methods("POST")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents", genericPlacementIntentHandler.createGenericPlacementIntentHandler).Methods("POST")
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents/{intent-name}", genericPlacementIntentHandler.getGenericPlacementHandler).Methods("GET")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents/{intent-name}", genericPlacementIntentHandler.getGenericPlacementHandler).Methods("GET")
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents", genericPlacementIntentHandler.getAllGenericPlacementIntentsHandler).Methods("GET")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents", genericPlacementIntentHandler.getAllGenericPlacementIntentsHandler).Methods("GET")
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents/{intent-name}", genericPlacementIntentHandler.deleteGenericPlacementHandler).Methods("DELETE")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents/{intent-name}", genericPlacementIntentHandler.deleteGenericPlacementHandler).Methods("DELETE")
//setting routes for AppIntent
if appIntentClient == nil {
@@ -145,11 +145,11 @@ func NewRouter(projectClient moduleLib.ProjectManager,
client: appIntentClient,
}
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents/{intent-name}/app-intents", appIntentHandler.createAppIntentHandler).Methods("POST")
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents/{intent-name}/app-intents/{app-intent-name}", appIntentHandler.getAppIntentHandler).Methods("GET")
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents/{intent-name}/app-intents", appIntentHandler.getAllAppIntentsHandler).Methods("GET")
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents/{intent-name}/app-intents/", appIntentHandler.getAllIntentsByAppHandler).Queries("app-name", "{app-name}")
- router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/generic-placement-intents/{intent-name}/app-intents/{app-intent-name}", appIntentHandler.deleteAppIntentHandler).Methods("DELETE")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents/{intent-name}/app-intents", appIntentHandler.createAppIntentHandler).Methods("POST")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents/{intent-name}/app-intents/{app-intent-name}", appIntentHandler.getAppIntentHandler).Methods("GET")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents/{intent-name}/app-intents", appIntentHandler.getAllAppIntentsHandler).Methods("GET")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents/{intent-name}/app-intents/", appIntentHandler.getAllIntentsByAppHandler).Queries("app-name", "{app-name}")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intents/{intent-name}/app-intents/{app-intent-name}", appIntentHandler.deleteAppIntentHandler).Methods("DELETE")
//setting routes for deploymentIntentGroup
if deploymentIntentGrpClient == nil {
deploymentIntentGrpClient = moduleClient.DeploymentIntentGroup
diff --git a/src/orchestrator/api/app_intent_handler.go b/src/orchestrator/api/app_intent_handler.go
index 1d48f8a6..3d0d5bad 100644
--- a/src/orchestrator/api/app_intent_handler.go
+++ b/src/orchestrator/api/app_intent_handler.go
@@ -62,8 +62,9 @@ func (h appIntentHandler) createAppIntentHandler(w http.ResponseWriter, r *http.
compositeAppName := vars["composite-app-name"]
version := vars["composite-app-version"]
intent := vars["intent-name"]
+ digName := vars["deployment-intent-group-name"]
- appIntent, createErr := h.client.CreateAppIntent(a, projectName, compositeAppName, version, intent)
+ appIntent, createErr := h.client.CreateAppIntent(a, projectName, compositeAppName, version, intent, digName)
if createErr != nil {
http.Error(w, createErr.Error(), http.StatusInternalServerError)
return
@@ -104,13 +105,19 @@ func (h appIntentHandler) getAppIntentHandler(w http.ResponseWriter, r *http.Req
return
}
+ dig := vars["deployment-intent-group-name"]
+ if dig == "" {
+ http.Error(w, "Missing deploymentIntentGroupName in GET request", http.StatusBadRequest)
+ return
+ }
+
ai := vars["app-intent-name"]
if ai == "" {
http.Error(w, "Missing appIntentName in GET request", http.StatusBadRequest)
return
}
- appIntent, err := h.client.GetAppIntent(ai, p, ca, v, i)
+ appIntent, err := h.client.GetAppIntent(ai, p, ca, v, i,dig)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -128,7 +135,7 @@ func (h appIntentHandler) getAppIntentHandler(w http.ResponseWriter, r *http.Req
/*
getAllIntentsByAppHandler handles the URL:
-/v2/project/{project-name}/composite-apps/{composite-app-name}/{version}/generic-placement-intent/{intent-name}/app-intents?app-name=<app-name>
+/v2/project/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intent/{intent-name}/app-intents?app-name=<app-name>
*/
func (h appIntentHandler) getAllIntentsByAppHandler(w http.ResponseWriter, r *http.Request) {
@@ -142,13 +149,15 @@ func (h appIntentHandler) getAllIntentsByAppHandler(w http.ResponseWriter, r *ht
ca := vars["composite-app-name"]
v := vars["composite-app-version"]
i := vars["intent-name"]
+ digName := vars["deployment-intent-group-name"]
+
aN := r.URL.Query().Get("app-name")
if aN == "" {
http.Error(w, "Missing appName in GET request", http.StatusBadRequest)
return
}
- specData, err := h.client.GetAllIntentsByApp(aN, p, ca, v, i)
+ specData, err := h.client.GetAllIntentsByApp(aN, p, ca, v, i, digName)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -166,7 +175,7 @@ func (h appIntentHandler) getAllIntentsByAppHandler(w http.ResponseWriter, r *ht
/*
getAllAppIntentsHandler handles the URL:
-/v2/project/{project-name}/composite-apps/{composite-app-name}/{version}/generic-placement-intent/{intent-name}/app-intents
+/v2/project/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/generic-placement-intent/{intent-name}/app-intents
*/
func (h appIntentHandler) getAllAppIntentsHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
@@ -179,8 +188,9 @@ func (h appIntentHandler) getAllAppIntentsHandler(w http.ResponseWriter, r *http
ca := vars["composite-app-name"]
v := vars["composite-app-version"]
i := vars["intent-name"]
+ digName := vars["deployment-intent-group-name"]
- applicationsAndClusterInfo, err := h.client.GetAllAppIntents(p, ca, v, i)
+ applicationsAndClusterInfo, err := h.client.GetAllAppIntents(p, ca, v, i, digName)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -205,8 +215,10 @@ func (h appIntentHandler) deleteAppIntentHandler(w http.ResponseWriter, r *http.
v := vars["composite-app-version"]
i := vars["intent-name"]
ai := vars["app-intent-name"]
+ digName := vars["deployment-intent-group-name"]
+
- err := h.client.DeleteAppIntent(ai, p, ca, v, i)
+ err := h.client.DeleteAppIntent(ai, p, ca, v, i, digName)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/orchestrator/api/generic_placement_intent_handler.go b/src/orchestrator/api/generic_placement_intent_handler.go
index 2415ae2c..cb23776a 100644
--- a/src/orchestrator/api/generic_placement_intent_handler.go
+++ b/src/orchestrator/api/generic_placement_intent_handler.go
@@ -62,8 +62,9 @@ func (h genericPlacementIntentHandler) createGenericPlacementIntentHandler(w htt
projectName := vars["project-name"]
compositeAppName := vars["composite-app-name"]
version := vars["composite-app-version"]
+ digName := vars["deployment-intent-group-name"]
- gPIntent, createErr := h.client.CreateGenericPlacementIntent(g, projectName, compositeAppName, version)
+ gPIntent, createErr := h.client.CreateGenericPlacementIntent(g, projectName, compositeAppName, version, digName)
if createErr != nil {
http.Error(w, createErr.Error(), http.StatusInternalServerError)
return
@@ -103,7 +104,13 @@ func (h genericPlacementIntentHandler) getGenericPlacementHandler(w http.Respons
return
}
- gPIntent, err := h.client.GetGenericPlacementIntent(intentName, projectName, compositeAppName, version)
+ dig := vars["deployment-intent-group-name"]
+ if dig == "" {
+ http.Error(w, "Missing deploymentIntentGroupName in GET request", http.StatusBadRequest)
+ return
+ }
+
+ gPIntent, err := h.client.GetGenericPlacementIntent(intentName, projectName, compositeAppName, version, dig)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -128,8 +135,9 @@ func (h genericPlacementIntentHandler) getAllGenericPlacementIntentsHandler(w ht
p := vars["project-name"]
ca := vars["composite-app-name"]
v := vars["composite-app-version"]
+ digName := vars["deployment-intent-group-name"]
- gpList, err := h.client.GetAllGenericPlacementIntents(p, ca, v)
+ gpList, err := h.client.GetAllGenericPlacementIntents(p, ca, v, digName)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
@@ -150,8 +158,9 @@ func (h genericPlacementIntentHandler) deleteGenericPlacementHandler(w http.Resp
p := vars["project-name"]
ca := vars["composite-app-name"]
v := vars["composite-app-version"]
+ digName := vars["deployment-intent-group-name"]
- err := h.client.DeleteGenericPlacementIntent(i, p, ca, v)
+ err := h.client.DeleteGenericPlacementIntent(i, p, ca, v, digName)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/orchestrator/json-schemas/deployment-group-intent.json b/src/orchestrator/json-schemas/deployment-group-intent.json
index 2740747b..00b1f32f 100644
--- a/src/orchestrator/json-schemas/deployment-group-intent.json
+++ b/src/orchestrator/json-schemas/deployment-group-intent.json
@@ -5,7 +5,8 @@
"spec": {
"required": [
"profile",
- "version"
+ "version",
+ "logical-cloud"
],
"type": "object",
"description": "DepSpecData has profile, version, OverrideValuesObj",
@@ -42,6 +43,16 @@
"type": "string",
"maxLength": 128,
"pattern": "[-_0-9a-zA-Z]+$"
+ },
+ "logical-cloud": {
+ "description": "Logical Cloud to use for this intent",
+ "required": [
+ "logical-cloud"
+ ],
+ "type": "string",
+ "example": "cloud1",
+ "maxLength": 128,
+ "pattern": "[-_0-9a-zA-Z]+$"
}
}
},
diff --git a/src/orchestrator/json-schemas/generic-placement-intent.json b/src/orchestrator/json-schemas/generic-placement-intent.json
index 44df9087..b1d8e229 100644
--- a/src/orchestrator/json-schemas/generic-placement-intent.json
+++ b/src/orchestrator/json-schemas/generic-placement-intent.json
@@ -2,21 +2,6 @@
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
- "spec": {
- "type": "object",
- "description": "Spec",
- "properties": {
- "logical-cloud": {
- "description": "Logical Cloud to use for this intent",
- "required": [
- "logical-cloud"
- ],
- "type": "string",
- "example": "cloud1",
- "maxLength": 128
- }
- }
- },
"metadata": {
"required": ["name"],
"properties": {
diff --git a/src/orchestrator/pkg/appcontext/appcontext.go b/src/orchestrator/pkg/appcontext/appcontext.go
index d77672db..d0935d82 100644
--- a/src/orchestrator/pkg/appcontext/appcontext.go
+++ b/src/orchestrator/pkg/appcontext/appcontext.go
@@ -67,10 +67,11 @@ var AppContextStatusEnum = &statuses{
// CompositeAppVersion, ReleaseName. This shall be used for
// instantiation of a compositeApp
type CompositeAppMeta struct {
- Project string `json:"Project"`
- CompositeApp string `json:"CompositeApp"`
- Version string `json:"Version"`
- Release string `json:"Release"`
+ Project string `json:"Project"`
+ CompositeApp string `json:"CompositeApp"`
+ Version string `json:"Version"`
+ Release string `json:"Release"`
+ DeploymentIntentGroup string `json:"DeploymentIntentGroup"`
}
// Init app context
@@ -565,6 +566,7 @@ func (ac *AppContext) GetCompositeAppMeta() (CompositeAppMeta, error) {
ca := fmt.Sprintf("%v", datamap["CompositeApp"])
v := fmt.Sprintf("%v", datamap["Version"])
rn := fmt.Sprintf("%v", datamap["Release"])
+ dig := fmt.Sprintf("%v", datamap["DeploymentIntentGroup"])
- return CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rn}, nil
+ return CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rn, DeploymentIntentGroup: dig}, nil
}
diff --git a/src/orchestrator/pkg/infra/db/mock.go b/src/orchestrator/pkg/infra/db/mock.go
index e43be8fb..cc3af718 100644
--- a/src/orchestrator/pkg/infra/db/mock.go
+++ b/src/orchestrator/pkg/infra/db/mock.go
@@ -41,18 +41,10 @@ func (m *MockDB) HealthCheck() error {
return m.Err
}
-func (m *MockDB) Create(table string, key Key, tag string, data interface{}) error {
- return m.Err
-}
-
func (m *MockDB) Insert(table string, key Key, query interface{}, tag string, data interface{}) error {
return m.Err
}
-func (m *MockDB) Update(table string, key Key, tag string, data interface{}) error {
- return m.Err
-}
-
// MockDB uses simple JSON and not BSON
func (m *MockDB) Unmarshal(inp []byte, out interface{}) error {
err := json.Unmarshal(inp, out)
@@ -62,21 +54,6 @@ func (m *MockDB) Unmarshal(inp []byte, out interface{}) error {
return nil
}
-func (m *MockDB) Read(table string, key Key, tag string) ([]byte, error) {
- if m.Err != nil {
- return nil, m.Err
- }
-
- str := fmt.Sprintf("%v", key)
- for k, v := range m.Items {
- if k == str {
- return v[tag], nil
- }
- }
-
- return nil, m.Err
-}
-
func (m *MockDB) Find(table string, key Key, tag string) ([][]byte, error) {
if m.Err != nil {
return nil, m.Err
@@ -93,10 +70,6 @@ func (m *MockDB) Find(table string, key Key, tag string) ([][]byte, error) {
return nil, m.Err
}
-func (m *MockDB) Delete(table string, key Key, tag string) error {
- return m.Err
-}
-
func (m *MockDB) Remove(table string, key Key) error {
return m.Err
}
diff --git a/src/orchestrator/pkg/infra/db/mongo.go b/src/orchestrator/pkg/infra/db/mongo.go
index a3fdc570..cae57e1d 100644
--- a/src/orchestrator/pkg/infra/db/mongo.go
+++ b/src/orchestrator/pkg/infra/db/mongo.go
@@ -18,7 +18,6 @@ package db
import (
"encoding/json"
- "log"
"sort"
"golang.org/x/net/context"
@@ -135,88 +134,6 @@ func (m *MongoStore) validateParams(args ...interface{}) bool {
return true
}
-// Create is used to create a DB entry
-func (m *MongoStore) Create(coll string, key Key, tag string, data interface{}) error {
- if data == nil || !m.validateParams(coll, key, tag) {
- return pkgerrors.New("No Data to store")
- }
-
- c := getCollection(coll, m)
- ctx := context.Background()
-
- //Insert the data and then add the objectID to the masterTable
- res, err := c.InsertOne(ctx, bson.D{
- {tag, data},
- })
- if err != nil {
- return pkgerrors.Errorf("Error inserting into database: %s", err.Error())
- }
-
- //Add objectID of created data to masterKey document
- //Create masterkey document if it does not exist
- filter := bson.D{{"key", key}}
-
- _, err = decodeBytes(
- c.FindOneAndUpdate(
- ctx,
- filter,
- bson.D{
- {"$set", bson.D{
- {tag, res.InsertedID},
- }},
- },
- options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After)))
-
- if err != nil {
- return pkgerrors.Errorf("Error updating master table: %s", err.Error())
- }
-
- return nil
-}
-
-// Update is used to update a DB entry
-func (m *MongoStore) Update(coll string, key Key, tag string, data interface{}) error {
- if data == nil || !m.validateParams(coll, key, tag) {
- return pkgerrors.New("No Data to update")
- }
-
- c := getCollection(coll, m)
- ctx := context.Background()
-
- //Get the masterkey document based on given key
- filter := bson.D{{"key", key}}
- keydata, err := decodeBytes(c.FindOne(context.Background(), filter))
- if err != nil {
- return pkgerrors.Errorf("Error finding master table: %s", err.Error())
- }
-
- //Read the tag objectID from document
- tagoid, ok := keydata.Lookup(tag).ObjectIDOK()
- if !ok {
- return pkgerrors.Errorf("Error finding objectID for tag %s", tag)
- }
-
- //Update the document with new data
- filter = bson.D{{"_id", tagoid}}
-
- _, err = decodeBytes(
- c.FindOneAndUpdate(
- ctx,
- filter,
- bson.D{
- {"$set", bson.D{
- {tag, data},
- }},
- },
- options.FindOneAndUpdate().SetReturnDocument(options.After)))
-
- if err != nil {
- return pkgerrors.Errorf("Error updating record: %s", err.Error())
- }
-
- return nil
-}
-
// Unmarshal implements an unmarshaler for bson data that
// is produced from the mongo database
func (m *MongoStore) Unmarshal(inp []byte, out interface{}) error {
@@ -227,126 +144,6 @@ func (m *MongoStore) Unmarshal(inp []byte, out interface{}) error {
return nil
}
-// Read method returns the data stored for this key and for this particular tag
-func (m *MongoStore) Read(coll string, key Key, tag string) ([]byte, error) {
- if !m.validateParams(coll, key, tag) {
- return nil, pkgerrors.New("Mandatory fields are missing")
- }
-
- c := getCollection(coll, m)
- ctx := context.Background()
-
- //Get the masterkey document based on given key
- filter := bson.D{{"key", key}}
- keydata, err := decodeBytes(c.FindOne(context.Background(), filter))
- if err != nil {
- return nil, pkgerrors.Errorf("Error finding master table: %s", err.Error())
- }
-
- //Read the tag objectID from document
- tagoid, ok := keydata.Lookup(tag).ObjectIDOK()
- if !ok {
- return nil, pkgerrors.Errorf("Error finding objectID for tag %s", tag)
- }
-
- //Use tag objectID to read the data from store
- filter = bson.D{{"_id", tagoid}}
- tagdata, err := decodeBytes(c.FindOne(ctx, filter))
- if err != nil {
- return nil, pkgerrors.Errorf("Error reading found object: %s", err.Error())
- }
-
- //Return the data as a byte array
- //Convert string data to byte array using the built-in functions
- switch tagdata.Lookup(tag).Type {
- case bson.TypeString:
- return []byte(tagdata.Lookup(tag).StringValue()), nil
- default:
- return tagdata.Lookup(tag).Value, nil
- }
-}
-
-// Helper function that deletes an object by its ID
-func (m *MongoStore) deleteObjectByID(coll string, objID primitive.ObjectID) error {
-
- c := getCollection(coll, m)
- ctx := context.Background()
-
- _, err := c.DeleteOne(ctx, bson.D{{"_id", objID}})
- if err != nil {
- return pkgerrors.Errorf("Error Deleting from database: %s", err.Error())
- }
-
- log.Printf("Deleted Obj with ID %s", objID.String())
- return nil
-}
-
-// Delete method removes a document from the Database that matches key
-// TODO: delete all referenced docs if tag is empty string
-func (m *MongoStore) Delete(coll string, key Key, tag string) error {
- if !m.validateParams(coll, key, tag) {
- return pkgerrors.New("Mandatory fields are missing")
- }
-
- c := getCollection(coll, m)
- ctx := context.Background()
-
- //Get the masterkey document based on given key
- filter := bson.D{{"key", key}}
- //Remove the tag ID entry from masterkey table
- update := bson.D{
- {
- "$unset", bson.D{
- {tag, ""},
- },
- },
- }
- keydata, err := decodeBytes(c.FindOneAndUpdate(ctx, filter, update,
- options.FindOneAndUpdate().SetReturnDocument(options.Before)))
- if err != nil {
- //No document was found. Return nil.
- if err == mongo.ErrNoDocuments {
- return nil
- }
- //Return any other error that was found.
- return pkgerrors.Errorf("Error decoding master table after update: %s",
- err.Error())
- }
-
- //Read the tag objectID from document
- elems, err := keydata.Elements()
- if err != nil {
- return pkgerrors.Errorf("Error reading elements from database: %s", err.Error())
- }
-
- tagoid, ok := keydata.Lookup(tag).ObjectIDOK()
- if !ok {
- return pkgerrors.Errorf("Error finding objectID for tag %s", tag)
- }
-
- //Use tag objectID to read the data from store
- err = m.deleteObjectByID(coll, tagoid)
- if err != nil {
- return pkgerrors.Errorf("Error deleting from database: %s", err.Error())
- }
-
- //Delete master table if no more tags left
- //_id, key and tag should be elements in before doc
- //if master table needs to be removed too
- if len(elems) == 3 {
- keyid, ok := keydata.Lookup("_id").ObjectIDOK()
- if !ok {
- return pkgerrors.Errorf("Error finding objectID for key %s", key)
- }
- err = m.deleteObjectByID(coll, keyid)
- if err != nil {
- return pkgerrors.Errorf("Error deleting master table from database: %s", err.Error())
- }
- }
-
- return nil
-}
-
func (m *MongoStore) findFilter(key Key) (primitive.M, error) {
var bsonMap bson.M
diff --git a/src/orchestrator/pkg/infra/db/mongo_test.go b/src/orchestrator/pkg/infra/db/mongo_test.go
index d57c19dd..3e14e755 100644
--- a/src/orchestrator/pkg/infra/db/mongo_test.go
+++ b/src/orchestrator/pkg/infra/db/mongo_test.go
@@ -17,13 +17,8 @@
package db
import (
- "bytes"
"context"
- "strings"
- "testing"
- pkgerrors "github.com/pkg/errors"
- "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
@@ -83,388 +78,3 @@ func (c *mockCollection) CountDocuments(ctx context.Context, filter interface{},
opts ...*options.CountOptions) (int64, error) {
return 1, c.Err
}
-
-func TestCreate(t *testing.T) {
- testCases := []struct {
- label string
- input map[string]interface{}
- mockColl *mockCollection
- bson bson.Raw
- expectedError string
- }{
- {
- label: "Successfull creation of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- "data": "Data In String Format",
- },
- bson: bson.Raw{'\x08', '\x00', '\x00', '\x00', '\x0A', 'x', '\x00', '\x00'},
- mockColl: &mockCollection{},
- },
- {
- label: "UnSuccessfull creation of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- "data": "Data In String Format",
- },
- mockColl: &mockCollection{
- Err: pkgerrors.New("DB Error"),
- },
- expectedError: "DB Error",
- },
- {
- label: "Missing input fields",
- input: map[string]interface{}{
- "coll": "",
- "key": MockKey{Key: ""},
- "tag": "",
- "data": "",
- },
- expectedError: "No Data to store",
- mockColl: &mockCollection{},
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- m, _ := NewMongoStore("name", &mongo.Database{})
- // Override the getCollection function with our mocked version
- getCollection = func(coll string, m *MongoStore) MongoCollection {
- return testCase.mockColl
- }
-
- decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) {
- return testCase.bson, testCase.mockColl.Err
- }
-
- err := m.Create(testCase.input["coll"].(string), testCase.input["key"].(Key),
- testCase.input["tag"].(string), testCase.input["data"])
- if err != nil {
- if testCase.expectedError == "" {
- t.Fatalf("Create method returned an un-expected (%s)", err)
- }
- if !strings.Contains(string(err.Error()), testCase.expectedError) {
- t.Fatalf("Create method returned an error (%s)", err)
- }
- }
- })
- }
-}
-
-func TestUpdate(t *testing.T) {
- testCases := []struct {
- label string
- input map[string]interface{}
- mockColl *mockCollection
- bson bson.Raw
- expectedError string
- }{
- {
- label: "Successfull update of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "metadata",
- "data": "Data In String Format",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- },
- {
- label: "Entry does not exist",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- "data": "Data In String Format",
- },
- mockColl: &mockCollection{
- Err: pkgerrors.New("DB Error"),
- },
- expectedError: "DB Error",
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- m, _ := NewMongoStore("name", &mongo.Database{})
- // Override the getCollection function with our mocked version
- getCollection = func(coll string, m *MongoStore) MongoCollection {
- return testCase.mockColl
- }
-
- decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) {
- return testCase.bson, testCase.mockColl.Err
- }
-
- err := m.Update(testCase.input["coll"].(string), testCase.input["key"].(Key),
- testCase.input["tag"].(string), testCase.input["data"])
- if err != nil {
- if testCase.expectedError == "" {
- t.Fatalf("Create method returned an un-expected (%s)", err)
- }
- if !strings.Contains(string(err.Error()), testCase.expectedError) {
- t.Fatalf("Create method returned an error (%s)", err)
- }
- }
- })
- }
-}
-
-func TestRead(t *testing.T) {
- testCases := []struct {
- label string
- input map[string]interface{}
- mockColl *mockCollection
- bson bson.Raw
- expectedError string
- expected []byte
- }{
- {
- label: "Successfull Read of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "metadata",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- // This is not the document because we are mocking decodeBytes
- expected: []byte{92, 17, 81, 86, 119, 127, 248, 86, 84, 36, 138, 225},
- },
- {
- label: "UnSuccessfull Read of entry: object not found",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "badtag",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- expectedError: "Error finding objectID",
- },
- {
- label: "UnSuccessfull Read of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- },
- mockColl: &mockCollection{
- Err: pkgerrors.New("DB Error"),
- },
- expectedError: "DB Error",
- },
- {
- label: "Missing input fields",
- input: map[string]interface{}{
- "coll": "",
- "key": MockKey{Key: ""},
- "tag": "",
- },
- expectedError: "Mandatory fields are missing",
- mockColl: &mockCollection{},
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- m, _ := NewMongoStore("name", &mongo.Database{})
- // Override the getCollection function with our mocked version
- getCollection = func(coll string, m *MongoStore) MongoCollection {
- return testCase.mockColl
- }
-
- decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) {
- return testCase.bson, testCase.mockColl.Err
- }
- got, err := m.Read(testCase.input["coll"].(string), testCase.input["key"].(Key),
- testCase.input["tag"].(string))
- if err != nil {
- if testCase.expectedError == "" {
- t.Fatalf("Read method returned an un-expected (%s)", err)
- }
- if !strings.Contains(string(err.Error()), testCase.expectedError) {
- t.Fatalf("Read method returned an error (%s)", err)
- }
- } else {
- if bytes.Compare(got, testCase.expected) != 0 {
- t.Fatalf("Read returned unexpected data: %v, expected: %v",
- string(got), testCase.expected)
- }
- }
- })
- }
-}
-
-func TestDelete(t *testing.T) {
- testCases := []struct {
- label string
- input map[string]interface{}
- mockColl *mockCollection
- bson bson.Raw
- expectedError string
- }{
- {
- label: "Successfull Delete of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "metadata",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- },
- {
- label: "UnSuccessfull Delete of entry",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- },
- mockColl: &mockCollection{
- Err: pkgerrors.New("DB Error"),
- },
- expectedError: "DB Error",
- },
- {
- label: "UnSuccessfull Delete, key not found",
- input: map[string]interface{}{
- "coll": "collname",
- "key": MockKey{Key: "keyvalue"},
- "tag": "tagName",
- },
- // Binary form of
- // {
- // "_id" : ObjectId("5c115156777ff85654248ae1"),
- // "key" : bson.D{{"name","testdef"},{"version","v1"}},
- // "metadata" : ObjectId("5c115156c9755047e318bbfd")
- // }
- bson: bson.Raw{
- '\x58', '\x00', '\x00', '\x00', '\x03', '\x6b', '\x65', '\x79',
- '\x00', '\x27', '\x00', '\x00', '\x00', '\x02', '\x6e', '\x61',
- '\x6d', '\x65', '\x00', '\x08', '\x00', '\x00', '\x00', '\x74',
- '\x65', '\x73', '\x74', '\x64', '\x65', '\x66', '\x00', '\x02',
- '\x76', '\x65', '\x72', '\x73', '\x69', '\x6f', '\x6e', '\x00',
- '\x03', '\x00', '\x00', '\x00', '\x76', '\x31', '\x00', '\x00',
- '\x07', '\x6d', '\x65', '\x74', '\x61', '\x64', '\x61', '\x74',
- '\x61', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77', '\x7f',
- '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x07', '\x5f',
- '\x69', '\x64', '\x00', '\x5c', '\x11', '\x51', '\x56', '\x77',
- '\x7f', '\xf8', '\x56', '\x54', '\x24', '\x8a', '\xe1', '\x00',
- },
- mockColl: &mockCollection{},
- expectedError: "Error finding objectID",
- },
- {
- label: "Missing input fields",
- input: map[string]interface{}{
- "coll": "",
- "key": MockKey{Key: ""},
- "tag": "",
- },
- expectedError: "Mandatory fields are missing",
- mockColl: &mockCollection{},
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.label, func(t *testing.T) {
- m, _ := NewMongoStore("name", &mongo.Database{})
- // Override the getCollection function with our mocked version
- getCollection = func(coll string, m *MongoStore) MongoCollection {
- return testCase.mockColl
- }
-
- decodeBytes = func(sr *mongo.SingleResult) (bson.Raw, error) {
- return testCase.bson, testCase.mockColl.Err
- }
- err := m.Delete(testCase.input["coll"].(string), testCase.input["key"].(Key),
- testCase.input["tag"].(string))
- if err != nil {
- if testCase.expectedError == "" {
- t.Fatalf("Delete method returned an un-expected (%s)", err)
- }
- if !strings.Contains(string(err.Error()), testCase.expectedError) {
- t.Fatalf("Delete method returned an error (%s)", err)
- }
- }
- })
- }
-}
diff --git a/src/orchestrator/pkg/infra/db/store.go b/src/orchestrator/pkg/infra/db/store.go
index a332fcda..d6ed6022 100644
--- a/src/orchestrator/pkg/infra/db/store.go
+++ b/src/orchestrator/pkg/infra/db/store.go
@@ -39,20 +39,6 @@ type Store interface {
// Unmarshal implements any unmarshaling needed for the database
Unmarshal(inp []byte, out interface{}) error
- // Creates a new master document with key and links data with tag and
- // creates a pointer(row) to the newly added data in the master table
- Create(table string, key Key, tag string, data interface{}) error
-
- // Reads data for a particular key with specific tag.
- Read(table string, key Key, tag string) ([]byte, error)
-
- // Update data for particular key with specific tag
- Update(table string, key Key, tag string, data interface{}) error
-
- // Deletes a specific tag data for key.
- // TODO: If tag is empty, it will delete all tags under key.
- Delete(table string, key Key, tag string) error
-
// Inserts and Updates a tag with key and also adds query fields if provided
Insert(coll string, key Key, query interface{}, tag string, data interface{}) error
diff --git a/src/orchestrator/pkg/module/app_intent.go b/src/orchestrator/pkg/module/app_intent.go
index 9da252e5..6b394513 100644
--- a/src/orchestrator/pkg/module/app_intent.go
+++ b/src/orchestrator/pkg/module/app_intent.go
@@ -53,11 +53,11 @@ type SpecData struct {
// AppIntentManager is an interface which exposes the
// AppIntentManager functionalities
type AppIntentManager interface {
- CreateAppIntent(a AppIntent, p string, ca string, v string, i string) (AppIntent, error)
- GetAppIntent(ai string, p string, ca string, v string, i string) (AppIntent, error)
- GetAllIntentsByApp(aN, p, ca, v, i string) (SpecData, error)
- GetAllAppIntents(p, ca, v, i string) (ApplicationsAndClusterInfo, error)
- DeleteAppIntent(ai string, p string, ca string, v string, i string) error
+ CreateAppIntent(a AppIntent, p string, ca string, v string, i string, digName string) (AppIntent, error)
+ GetAppIntent(ai string, p string, ca string, v string, i string, digName string) (AppIntent, error)
+ GetAllIntentsByApp(aN, p, ca, v, i, digName string) (SpecData, error)
+ GetAllAppIntents(p, ca, v, i, digName string) (ApplicationsAndClusterInfo, error)
+ DeleteAppIntent(ai string, p string, ca string, v string, i string, digName string) error
}
//AppIntentQueryKey required for query
@@ -67,20 +67,22 @@ type AppIntentQueryKey struct {
// AppIntentKey is used as primary key
type AppIntentKey struct {
- Name string `json:"appintent"`
- Project string `json:"project"`
- CompositeApp string `json:"compositeapp"`
- Version string `json:"compositeappversion"`
- Intent string `json:"genericplacement"`
+ Name string `json:"appintent"`
+ Project string `json:"project"`
+ CompositeApp string `json:"compositeapp"`
+ Version string `json:"compositeappversion"`
+ Intent string `json:"genericplacement"`
+ DeploymentIntentGroupName string `json:"deploymentintentgroup"`
}
// AppIntentFindByAppKey required for query
type AppIntentFindByAppKey struct {
- Project string `json:"project"`
- CompositeApp string `json:"compositeapp"`
- CompositeAppVersion string `json:"compositeappversion"`
- Intent string `json:"genericplacement"`
- AppName string `json:"app-name"`
+ Project string `json:"project"`
+ CompositeApp string `json:"compositeapp"`
+ CompositeAppVersion string `json:"compositeappversion"`
+ Intent string `json:"genericplacement"`
+ DeploymentIntentGroupName string `json:"deploymentintentgroup"`
+ AppName string `json:"app-name"`
}
// ApplicationsAndClusterInfo type represents the list of
@@ -121,11 +123,11 @@ func NewAppIntentClient() *AppIntentClient {
}
// CreateAppIntent creates an entry for AppIntent in the db.
-// Other input parameters for it - projectName, compositeAppName, version, intentName.
-func (c *AppIntentClient) CreateAppIntent(a AppIntent, p string, ca string, v string, i string) (AppIntent, error) {
+// Other input parameters for it - projectName, compositeAppName, version, intentName and deploymentIntentGroupName.
+func (c *AppIntentClient) CreateAppIntent(a AppIntent, p string, ca string, v string, i string, digName string) (AppIntent, error) {
//Check for the AppIntent already exists here.
- res, err := c.GetAppIntent(a.MetaData.Name, p, ca, v, i)
+ res, err := c.GetAppIntent(a.MetaData.Name, p, ca, v, i, digName)
if !reflect.DeepEqual(res, AppIntent{}) {
return AppIntent{}, pkgerrors.New("AppIntent already exists")
}
@@ -143,17 +145,24 @@ func (c *AppIntentClient) CreateAppIntent(a AppIntent, p string, ca string, v st
}
// check if Intent exists
- _, err = NewGenericPlacementIntentClient().GetGenericPlacementIntent(i, p, ca, v)
+ _, err = NewGenericPlacementIntentClient().GetGenericPlacementIntent(i, p, ca, v, digName)
if err != nil {
return AppIntent{}, pkgerrors.New("Unable to find the intent")
}
+ // check if the deploymentIntentGrpName exists
+ _, err = NewDeploymentIntentGroupClient().GetDeploymentIntentGroup(digName, p, ca, v)
+ if err != nil {
+ return AppIntent{}, pkgerrors.New("Unable to find the deployment-intent-group-name")
+ }
+
akey := AppIntentKey{
- Name: a.MetaData.Name,
- Project: p,
- CompositeApp: ca,
- Version: v,
- Intent: i,
+ Name: a.MetaData.Name,
+ Project: p,
+ CompositeApp: ca,
+ Version: v,
+ Intent: i,
+ DeploymentIntentGroupName: digName,
}
qkey := AppIntentQueryKey{
@@ -168,15 +177,16 @@ func (c *AppIntentClient) CreateAppIntent(a AppIntent, p string, ca string, v st
return a, nil
}
-// GetAppIntent shall take arguments - name of the app intent, name of the project, name of the composite app, version of the composite app and intent name. It shall return the AppIntent
-func (c *AppIntentClient) GetAppIntent(ai string, p string, ca string, v string, i string) (AppIntent, error) {
+// GetAppIntent shall take arguments - name of the app intent, name of the project, name of the composite app, version of the composite app,intent name and deploymentIntentGroupName. It shall return the AppIntent
+func (c *AppIntentClient) GetAppIntent(ai string, p string, ca string, v string, i string, digName string) (AppIntent, error) {
k := AppIntentKey{
- Name: ai,
- Project: p,
- CompositeApp: ca,
- Version: v,
- Intent: i,
+ Name: ai,
+ Project: p,
+ CompositeApp: ca,
+ Version: v,
+ Intent: i,
+ DeploymentIntentGroupName: digName,
}
result, err := db.DBconn.Find(c.storeName, k, c.tagMetaData)
@@ -197,17 +207,18 @@ func (c *AppIntentClient) GetAppIntent(ai string, p string, ca string, v string,
}
/*
-GetAllIntentsByApp takes in parameters AppName, CompositeAppName, CompositeNameVersion
-and GenericPlacementIntentName. Returns SpecData which contains
+GetAllIntentsByApp queries intent by AppName, it takes in parameters AppName, CompositeAppName, CompositeNameVersion,
+GenericPlacementIntentName & DeploymentIntentGroupName. Returns SpecData which contains
all the intents for the app.
*/
-func (c *AppIntentClient) GetAllIntentsByApp(aN, p, ca, v, i string) (SpecData, error) {
+func (c *AppIntentClient) GetAllIntentsByApp(aN, p, ca, v, i, digName string) (SpecData, error) {
k := AppIntentFindByAppKey{
- Project: p,
- CompositeApp: ca,
- CompositeAppVersion: v,
- Intent: i,
- AppName: aN,
+ Project: p,
+ CompositeApp: ca,
+ CompositeAppVersion: v,
+ Intent: i,
+ DeploymentIntentGroupName: digName,
+ AppName: aN,
}
result, err := db.DBconn.Find(c.storeName, k, c.tagMetaData)
if err != nil {
@@ -224,15 +235,16 @@ func (c *AppIntentClient) GetAllIntentsByApp(aN, p, ca, v, i string) (SpecData,
/*
GetAllAppIntents takes in paramaters ProjectName, CompositeAppName, CompositeNameVersion
-and GenericPlacementIntentName. Returns the ApplicationsAndClusterInfo Object - an array of AppClusterInfo
+and GenericPlacementIntentName,DeploymentIntentGroupName. Returns the ApplicationsAndClusterInfo Object - an array of AppClusterInfo
*/
-func (c *AppIntentClient) GetAllAppIntents(p, ca, v, i string) (ApplicationsAndClusterInfo, error) {
+func (c *AppIntentClient) GetAllAppIntents(p, ca, v, i, digName string) (ApplicationsAndClusterInfo, error) {
k := AppIntentKey{
- Name: "",
- Project: p,
- CompositeApp: ca,
- Version: v,
- Intent: i,
+ Name: "",
+ Project: p,
+ CompositeApp: ca,
+ Version: v,
+ Intent: i,
+ DeploymentIntentGroupName: digName,
}
result, err := db.DBconn.Find(c.storeName, k, c.tagMetaData)
if err != nil {
@@ -262,13 +274,14 @@ func (c *AppIntentClient) GetAllAppIntents(p, ca, v, i string) (ApplicationsAndC
}
// DeleteAppIntent delete an AppIntent
-func (c *AppIntentClient) DeleteAppIntent(ai string, p string, ca string, v string, i string) error {
+func (c *AppIntentClient) DeleteAppIntent(ai string, p string, ca string, v string, i string, digName string) error {
k := AppIntentKey{
- Name: ai,
- Project: p,
- CompositeApp: ca,
- Version: v,
- Intent: i,
+ Name: ai,
+ Project: p,
+ CompositeApp: ca,
+ Version: v,
+ Intent: i,
+ DeploymentIntentGroupName: digName,
}
err := db.DBconn.Remove(c.storeName, k)
diff --git a/src/orchestrator/pkg/module/app_intent_test.go b/src/orchestrator/pkg/module/app_intent_test.go
index 089f09ff..a2e295ea 100644
--- a/src/orchestrator/pkg/module/app_intent_test.go
+++ b/src/orchestrator/pkg/module/app_intent_test.go
@@ -33,6 +33,7 @@ func TestCreateAppIntent(t *testing.T) {
inputCompositeApp string
inputCompositeAppVersion string
inputGenericPlacementIntent string
+ inputDeploymentIntentGrpName string
expectedError string
mockdb *db.MockDB
expected AppIntent
@@ -81,6 +82,7 @@ func TestCreateAppIntent(t *testing.T) {
inputCompositeApp: "testCompositeApp",
inputCompositeAppVersion: "testCompositeAppVersion",
inputGenericPlacementIntent: "testIntent",
+ inputDeploymentIntentGrpName: "testDeploymentIntentGroup",
expected: AppIntent{
MetaData: MetaData{
Name: "testAppIntent",
@@ -142,6 +144,7 @@ func TestCreateAppIntent(t *testing.T) {
Project: "testProject",
CompositeApp: "testCompositeApp",
Version: "testCompositeAppVersion",
+ DigName: "testDeploymentIntentGroup",
}.String(): {
"genericplacementintentmetadata": []byte(
"{\"metadata\":{\"Name\":\"testIntent\"," +
@@ -150,6 +153,39 @@ func TestCreateAppIntent(t *testing.T) {
"\"UserData2\": \"userData2\"}," +
"\"spec\":{\"Logical-Cloud\": \"logicalCloud1\"}}"),
},
+ DeploymentIntentGroupKey{
+ Name: "testDeploymentIntentGroup",
+ Project: "testProject",
+ CompositeApp: "testCompositeApp",
+ Version: "testCompositeAppVersion",
+ }.String(): {
+ "deploymentintentgroupmetadata": []byte(
+ "{\"metadata\":{\"name\":\"testDeploymentIntentGroup\"," +
+ "\"description\":\"DescriptionTestDeploymentIntentGroup\"," +
+ "\"userData1\": \"userData1\"," +
+ "\"userData2\": \"userData2\"}," +
+ "\"spec\":{\"profile\": \"Testprofile\"," +
+ "\"version\": \"version of deployment\"," +
+ "\"override-values\":[" +
+ "{" +
+ "\"app-name\": \"TestAppName\"," +
+ "\"values\": " +
+ "{" +
+ "\"imageRepository\":\"registry.hub.docker.com\"" +
+ "}" +
+ "}," +
+ "{" +
+ "\"app-name\": \"TestAppName\"," +
+ "\"values\": " +
+ "{" +
+ "\"imageRepository\":\"registry.hub.docker.com\"" +
+ "}" +
+ "}" +
+ "]," +
+ "\"logical-cloud\": \"cloud1\"" +
+ "}"+
+ "}"),
+ },
},
},
},
@@ -158,7 +194,7 @@ func TestCreateAppIntent(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
appIntentCli := NewAppIntentClient()
- got, err := appIntentCli.CreateAppIntent(testCase.inputAppIntent, testCase.inputProject, testCase.inputCompositeApp, testCase.inputCompositeAppVersion, testCase.inputGenericPlacementIntent)
+ got, err := appIntentCli.CreateAppIntent(testCase.inputAppIntent, testCase.inputProject, testCase.inputCompositeApp, testCase.inputCompositeAppVersion, testCase.inputGenericPlacementIntent, testCase.inputDeploymentIntentGrpName)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("CreateAppIntent returned an unexpected error %s, ", err)
@@ -186,6 +222,7 @@ func TestGetAppIntent(t *testing.T) {
compositeAppName string
compositeAppVersion string
genericPlacementIntent string
+ deploymentIntentgrpName string
}{
{
label: "Get Intent",
@@ -194,6 +231,7 @@ func TestGetAppIntent(t *testing.T) {
compositeAppName: "testCompositeApp",
compositeAppVersion: "testCompositeAppVersion",
genericPlacementIntent: "testIntent",
+ deploymentIntentgrpName: "testDeploymentIntentGroup",
expected: AppIntent{
MetaData: MetaData{
Name: "testAppIntent",
@@ -234,6 +272,7 @@ func TestGetAppIntent(t *testing.T) {
CompositeApp: "testCompositeApp",
Version: "testCompositeAppVersion",
Intent: "testIntent",
+ DeploymentIntentGroupName: "testDeploymentIntentGroup",
}.String(): {
"appintentmetadata": []byte(
"{\"metadata\":{\"Name\":\"testAppIntent\"," +
@@ -270,7 +309,7 @@ func TestGetAppIntent(t *testing.T) {
db.DBconn = testCase.mockdb
appIntentCli := NewAppIntentClient()
got, err := appIntentCli.GetAppIntent(testCase.appIntentName, testCase.projectName, testCase.compositeAppName, testCase.compositeAppVersion,
- testCase.genericPlacementIntent)
+ testCase.genericPlacementIntent, testCase.deploymentIntentgrpName)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("GetAppIntent returned an unexpected error: %s", err)
diff --git a/src/orchestrator/pkg/module/deployment_intent_groups.go b/src/orchestrator/pkg/module/deployment_intent_groups.go
index dec6391f..f8e434f4 100644
--- a/src/orchestrator/pkg/module/deployment_intent_groups.go
+++ b/src/orchestrator/pkg/module/deployment_intent_groups.go
@@ -47,6 +47,7 @@ type DepSpecData struct {
Profile string `json:"profile"`
Version string `json:"version"`
OverrideValuesObj []OverrideValues `json:"override-values"`
+ LogicalCloud string `json:"logical-cloud"`
}
// OverrideValues has appName and ValuesObj
diff --git a/src/orchestrator/pkg/module/deployment_intent_groups_test.go b/src/orchestrator/pkg/module/deployment_intent_groups_test.go
index 0fdeb4a1..86ae49df 100644
--- a/src/orchestrator/pkg/module/deployment_intent_groups_test.go
+++ b/src/orchestrator/pkg/module/deployment_intent_groups_test.go
@@ -57,6 +57,7 @@ func TestCreateDeploymentIntentGroup(t *testing.T) {
"imageRepository": "registry.hub.docker.com",
}},
},
+ LogicalCloud: "cloud1",
},
},
inputProject: "testProject",
@@ -82,6 +83,7 @@ func TestCreateDeploymentIntentGroup(t *testing.T) {
"imageRepository": "registry.hub.docker.com",
}},
},
+ LogicalCloud: "cloud1",
},
},
expectedError: "",
@@ -167,6 +169,7 @@ func TestGetDeploymentIntentGroup(t *testing.T) {
"imageRepository": "registry.hub.docker.com",
}},
},
+ LogicalCloud: "cloud1",
},
},
expectedError: "",
@@ -200,7 +203,10 @@ func TestGetDeploymentIntentGroup(t *testing.T) {
"\"imageRepository\":\"registry.hub.docker.com\"" +
"}" +
"}" +
- "]}}"),
+ "]," +
+ "\"logical-cloud\": \"cloud1\"" +
+ "}"+
+ "}"),
},
},
},
diff --git a/src/orchestrator/pkg/module/generic_placement_intent.go b/src/orchestrator/pkg/module/generic_placement_intent.go
index fb00a6ab..3ff1c7dc 100644
--- a/src/orchestrator/pkg/module/generic_placement_intent.go
+++ b/src/orchestrator/pkg/module/generic_placement_intent.go
@@ -18,6 +18,7 @@ package module
import (
"encoding/json"
+
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
pkgerrors "github.com/pkg/errors"
@@ -26,7 +27,6 @@ import (
// GenericPlacementIntent shall have 2 fields - metadata and spec
type GenericPlacementIntent struct {
MetaData GenIntentMetaData `json:"metadata"`
- Spec GenIntentSpecData `json:"spec"`
}
// GenIntentMetaData has name, description, userdata1, userdata2
@@ -37,21 +37,16 @@ type GenIntentMetaData struct {
UserData2 string `json:"userData2"`
}
-// GenIntentSpecData has logical-cloud-name
-type GenIntentSpecData struct {
- LogicalCloud string `json:"logical-cloud"`
-}
-
// GenericPlacementIntentManager is an interface which exposes the GenericPlacementIntentManager functionality
type GenericPlacementIntentManager interface {
CreateGenericPlacementIntent(g GenericPlacementIntent, p string, ca string,
- v string) (GenericPlacementIntent, error)
+ v string, digName string) (GenericPlacementIntent, error)
GetGenericPlacementIntent(intentName string, projectName string,
- compositeAppName string, version string) (GenericPlacementIntent, error)
+ compositeAppName string, version string, digName string) (GenericPlacementIntent, error)
DeleteGenericPlacementIntent(intentName string, projectName string,
- compositeAppName string, version string) error
+ compositeAppName string, version string, digName string) error
- GetAllGenericPlacementIntents(p string, ca string, v string) ([]GenericPlacementIntent, error)
+ GetAllGenericPlacementIntents(p string, ca string, v string, digName string) ([]GenericPlacementIntent, error)
}
// GenericPlacementIntentKey is used as the primary key
@@ -60,6 +55,7 @@ type GenericPlacementIntentKey struct {
Project string `json:"project"`
CompositeApp string `json:"compositeapp"`
Version string `json:"compositeappversion"`
+ DigName string `json:"deploymentintentgroup"`
}
// We will use json marshalling to convert to string to
@@ -86,12 +82,12 @@ func NewGenericPlacementIntentClient() *GenericPlacementIntentClient {
}
}
-// CreateGenericPlacementIntent creates an entry for GenericPlacementIntent in the database. Other Input parameters for it - projectName, compositeAppName, version
+// CreateGenericPlacementIntent creates an entry for GenericPlacementIntent in the database. Other Input parameters for it - projectName, compositeAppName, version and deploymentIntentGroupName
func (c *GenericPlacementIntentClient) CreateGenericPlacementIntent(g GenericPlacementIntent, p string, ca string,
- v string) (GenericPlacementIntent, error) {
+ v string, digName string) (GenericPlacementIntent, error) {
// check if the genericPlacement already exists.
- res, err := c.GetGenericPlacementIntent(g.MetaData.Name, p, ca, v)
+ res, err := c.GetGenericPlacementIntent(g.MetaData.Name, p, ca, v, digName)
if res != (GenericPlacementIntent{}) {
return GenericPlacementIntent{}, pkgerrors.New("Intent already exists")
}
@@ -108,11 +104,18 @@ func (c *GenericPlacementIntentClient) CreateGenericPlacementIntent(g GenericPla
return GenericPlacementIntent{}, pkgerrors.New("Unable to find the composite-app")
}
+ // check if the deploymentIntentGrpName exists
+ _, err = NewDeploymentIntentGroupClient().GetDeploymentIntentGroup(digName, p, ca, v)
+ if err != nil {
+ return GenericPlacementIntent{}, pkgerrors.New("Unable to find the deployment-intent-group-name")
+ }
+
gkey := GenericPlacementIntentKey{
Name: g.MetaData.Name,
Project: p,
CompositeApp: ca,
Version: v,
+ DigName: digName,
}
err = db.DBconn.Insert(c.storeName, gkey, nil, c.tagMetaData, g)
@@ -123,13 +126,14 @@ func (c *GenericPlacementIntentClient) CreateGenericPlacementIntent(g GenericPla
return g, nil
}
-// GetGenericPlacementIntent shall take arguments - name of the intent, name of the project, name of the composite app and version of the composite app. It shall return the genericPlacementIntent if its present.
-func (c *GenericPlacementIntentClient) GetGenericPlacementIntent(i string, p string, ca string, v string) (GenericPlacementIntent, error) {
+// GetGenericPlacementIntent shall take arguments - name of the intent, name of the project, name of the composite app, version of the composite app and deploymentIntentGroupName. It shall return the genericPlacementIntent if its present.
+func (c *GenericPlacementIntentClient) GetGenericPlacementIntent(i string, p string, ca string, v string, digName string) (GenericPlacementIntent, error) {
key := GenericPlacementIntentKey{
Name: i,
Project: p,
CompositeApp: ca,
Version: v,
+ DigName: digName,
}
result, err := db.DBconn.Find(c.storeName, key, c.tagMetaData)
@@ -150,8 +154,8 @@ func (c *GenericPlacementIntentClient) GetGenericPlacementIntent(i string, p str
}
-// GetAllGenericPlacementIntents returns all the generic placement intents for a given compsoite app name, composite app version and project.
-func (c *GenericPlacementIntentClient) GetAllGenericPlacementIntents(p string, ca string, v string) ([]GenericPlacementIntent, error) {
+// GetAllGenericPlacementIntents returns all the generic placement intents for a given compsoite app name, composite app version, project and deploymentIntentGroupName
+func (c *GenericPlacementIntentClient) GetAllGenericPlacementIntents(p string, ca string, v string, digName string) ([]GenericPlacementIntent, error) {
//Check if project exists
_, err := NewProjectClient().GetProject(p)
@@ -170,6 +174,7 @@ func (c *GenericPlacementIntentClient) GetAllGenericPlacementIntents(p string, c
Project: p,
CompositeApp: ca,
Version: v,
+ DigName: digName,
}
var gpList []GenericPlacementIntent
@@ -192,12 +197,13 @@ func (c *GenericPlacementIntentClient) GetAllGenericPlacementIntents(p string, c
}
// DeleteGenericPlacementIntent the intent from the database
-func (c *GenericPlacementIntentClient) DeleteGenericPlacementIntent(i string, p string, ca string, v string) error {
+func (c *GenericPlacementIntentClient) DeleteGenericPlacementIntent(i string, p string, ca string, v string, digName string) error {
key := GenericPlacementIntentKey{
Name: i,
Project: p,
CompositeApp: ca,
Version: v,
+ DigName: digName,
}
err := db.DBconn.Remove(c.storeName, key)
diff --git a/src/orchestrator/pkg/module/generic_placement_intent_test.go b/src/orchestrator/pkg/module/generic_placement_intent_test.go
index d779e81f..59c1cac5 100644
--- a/src/orchestrator/pkg/module/generic_placement_intent_test.go
+++ b/src/orchestrator/pkg/module/generic_placement_intent_test.go
@@ -31,6 +31,7 @@ func TestCreateGenericPlacementIntent(t *testing.T) {
inputProject string
inputCompositeApp string
inputCompositeAppVersion string
+ inputDepIntGrpName string
expectedError string
mockdb *db.MockDB
expected GenericPlacementIntent
@@ -44,13 +45,11 @@ func TestCreateGenericPlacementIntent(t *testing.T) {
UserData1: "userData1",
UserData2: "userData2",
},
- Spec: GenIntentSpecData{
- LogicalCloud: "logicalCloud1",
- },
},
inputProject: "testProject",
inputCompositeApp: "testCompositeApp",
inputCompositeAppVersion: "testCompositeAppVersion",
+ inputDepIntGrpName: "testDeploymentIntentGroup",
expected: GenericPlacementIntent{
MetaData: GenIntentMetaData{
Name: "testGenericPlacement",
@@ -58,9 +57,6 @@ func TestCreateGenericPlacementIntent(t *testing.T) {
UserData1: "userData1",
UserData2: "userData2",
},
- Spec: GenIntentSpecData{
- LogicalCloud: "logicalCloud1",
- },
},
expectedError: "",
mockdb: &db.MockDB{
@@ -82,6 +78,40 @@ func TestCreateGenericPlacementIntent(t *testing.T) {
"\"spec\":{" +
"\"version\":\"version of the composite app\"}}"),
},
+ DeploymentIntentGroupKey{
+ Name: "testDeploymentIntentGroup",
+ Project: "testProject",
+ CompositeApp: "testCompositeApp",
+ Version: "testCompositeAppVersion",
+ }.String(): {
+ "deploymentintentgroupmetadata": []byte(
+ "{\"metadata\":{\"name\":\"testDeploymentIntentGroup\"," +
+ "\"description\":\"DescriptionTestDeploymentIntentGroup\"," +
+ "\"userData1\": \"userData1\"," +
+ "\"userData2\": \"userData2\"}," +
+ "\"spec\":{\"profile\": \"Testprofile\"," +
+ "\"version\": \"version of deployment\"," +
+ "\"override-values\":[" +
+ "{" +
+ "\"app-name\": \"TestAppName\"," +
+ "\"values\": " +
+ "{" +
+ "\"imageRepository\":\"registry.hub.docker.com\"" +
+ "}" +
+ "}," +
+ "{" +
+ "\"app-name\": \"TestAppName\"," +
+ "\"values\": " +
+ "{" +
+ "\"imageRepository\":\"registry.hub.docker.com\"" +
+ "}" +
+ "}" +
+ "]," +
+ "\"logical-cloud\": \"cloud1\"" +
+ "}"+
+ "}"),
+ },
+
},
},
},
@@ -91,7 +121,7 @@ func TestCreateGenericPlacementIntent(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
intentCli := NewGenericPlacementIntentClient()
- got, err := intentCli.CreateGenericPlacementIntent(testCase.inputIntent, testCase.inputProject, testCase.inputCompositeApp, testCase.inputCompositeAppVersion)
+ got, err := intentCli.CreateGenericPlacementIntent(testCase.inputIntent, testCase.inputProject, testCase.inputCompositeApp, testCase.inputCompositeAppVersion, testCase.inputDepIntGrpName)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("CreateGenericPlacementIntent returned an unexpected error %s", err)
@@ -120,6 +150,7 @@ func TestGetGenericPlacementIntent(t *testing.T) {
projectName string
compositeAppName string
compositeAppVersion string
+ deploymentIntentGroupName string
}{
{
label: "Get Intent",
@@ -127,6 +158,7 @@ func TestGetGenericPlacementIntent(t *testing.T) {
projectName: "testProject",
compositeAppName: "testCompositeApp",
compositeAppVersion: "testVersion",
+ deploymentIntentGroupName: "testDeploymentIntentGroup",
expected: GenericPlacementIntent{
MetaData: GenIntentMetaData{
Name: "testIntent",
@@ -134,9 +166,6 @@ func TestGetGenericPlacementIntent(t *testing.T) {
UserData1: "userData1",
UserData2: "userData2",
},
- Spec: GenIntentSpecData{
- LogicalCloud: "logicalCloud1",
- },
},
expectedError: "",
mockdb: &db.MockDB{
@@ -146,13 +175,14 @@ func TestGetGenericPlacementIntent(t *testing.T) {
Project: "testProject",
CompositeApp: "testCompositeApp",
Version: "testVersion",
+ DigName: "testDeploymentIntentGroup",
}.String(): {
"genericplacementintentmetadata": []byte(
"{\"metadata\":{\"Name\":\"testIntent\"," +
"\"Description\":\"A sample intent for testing\"," +
"\"UserData1\": \"userData1\"," +
- "\"UserData2\": \"userData2\"}," +
- "\"spec\":{\"Logical-Cloud\": \"logicalCloud1\"}}"),
+ "\"UserData2\": \"userData2\"}" +
+ "}"),
},
},
},
@@ -163,7 +193,7 @@ func TestGetGenericPlacementIntent(t *testing.T) {
t.Run(testCase.label, func(t *testing.T) {
db.DBconn = testCase.mockdb
intentCli := NewGenericPlacementIntentClient()
- got, err := intentCli.GetGenericPlacementIntent(testCase.intentName, testCase.projectName, testCase.compositeAppName, testCase.compositeAppVersion)
+ got, err := intentCli.GetGenericPlacementIntent(testCase.intentName, testCase.projectName, testCase.compositeAppName, testCase.compositeAppVersion, testCase.deploymentIntentGroupName)
if err != nil {
if testCase.expectedError == "" {
t.Fatalf("GetGenericPlacementIntent returned an unexpected error: %s", err)
diff --git a/src/orchestrator/pkg/module/instantiation.go b/src/orchestrator/pkg/module/instantiation.go
index 0ae76006..d703af7f 100644
--- a/src/orchestrator/pkg/module/instantiation.go
+++ b/src/orchestrator/pkg/module/instantiation.go
@@ -99,12 +99,12 @@ func NewInstantiationClient() *InstantiationClient {
func (c InstantiationClient) Approve(p string, ca string, v string, di string) error {
s, err := NewDeploymentIntentGroupClient().GetDeploymentIntentGroupState(di, p, ca, v)
if err != nil {
- log.Info("DeploymentIntentGroup has no state info ", log.Fields{"DeploymentIntentGroup: ":di})
+ log.Info("DeploymentIntentGroup has no state info ", log.Fields{"DeploymentIntentGroup: ": di})
return pkgerrors.Wrap(err, "DeploymentIntentGroup has no state info: "+di)
}
stateVal, err := state.GetCurrentStateFromStateInfo(s)
if err != nil {
- log.Info("Error getting current state from DeploymentIntentGroup stateInfo", log.Fields{"DeploymentIntentGroup ":di})
+ log.Info("Error getting current state from DeploymentIntentGroup stateInfo", log.Fields{"DeploymentIntentGroup ": di})
return pkgerrors.Errorf("Error getting current state from DeploymentIntentGroup stateInfo: " + di)
}
switch stateVal {
@@ -222,24 +222,24 @@ func GetSortedTemplateForApp(appName, p, ca, v, rName, cp string, overrideValues
return sortedTemplates, err
}
-func calculateDirPath(fp string) string {
+func calculateDirPath(fp string) string {
sa := strings.Split(fp, "/")
return "/" + sa[1] + "/" + sa[2] + "/"
}
func cleanTmpfiles(sortedTemplates []helm.KubernetesResourceTemplate) error {
dp := calculateDirPath(sortedTemplates[0].FilePath)
- for _, st := range sortedTemplates{
+ for _, st := range sortedTemplates {
log.Info("Clean up ::", log.Fields{"file: ": st.FilePath})
err := os.Remove(st.FilePath)
if err != nil {
- log.Error("Error while deleting file", log.Fields{"file: ":st.FilePath})
+ log.Error("Error while deleting file", log.Fields{"file: ": st.FilePath})
return err
}
}
err := os.RemoveAll(dp)
if err != nil {
- log.Error("Error while deleting dir", log.Fields{"Dir: ":dp})
+ log.Error("Error while deleting dir", log.Fields{"Dir: ": dp})
return err
}
log.Info("Clean up temp-dir::", log.Fields{"Dir: ": dp})
@@ -298,7 +298,7 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
return pkgerrors.Wrap(err, "Not finding the apps")
}
- cca, err := makeAppContextForCompositeApp(p, ca, v, rName)
+ cca, err := makeAppContextForCompositeApp(p, ca, v, rName, di)
if err != nil {
return err
}
@@ -338,7 +338,7 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
defer cleanTmpfiles(sortedTemplates)
- specData, err := NewAppIntentClient().GetAllIntentsByApp(eachApp.Metadata.Name, p, ca, v, gIntent)
+ specData, err := NewAppIntentClient().GetAllIntentsByApp(eachApp.Metadata.Name, p, ca, v, gIntent, di)
if err != nil {
deleteAppContext(context)
return pkgerrors.Wrap(err, "Unable to get the intents for app")
@@ -369,7 +369,7 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
deleteAppContext(context)
return pkgerrors.Wrap(err, "Error while verifying resources in app: ")
}
-
+
}
jappOrderInstr, err := json.Marshal(appOrderInstr)
if err != nil {
diff --git a/src/orchestrator/pkg/module/instantiation_appcontext_helper.go b/src/orchestrator/pkg/module/instantiation_appcontext_helper.go
index 692cdf1e..06e025c7 100644
--- a/src/orchestrator/pkg/module/instantiation_appcontext_helper.go
+++ b/src/orchestrator/pkg/module/instantiation_appcontext_helper.go
@@ -46,7 +46,7 @@ type contextForCompositeApp struct {
}
// makeAppContext creates an appContext for a compositeApp and returns the output as contextForCompositeApp
-func makeAppContextForCompositeApp(p, ca, v, rName string) (contextForCompositeApp, error) {
+func makeAppContextForCompositeApp(p, ca, v, rName, dig string) (contextForCompositeApp, error) {
context := appcontext.AppContext{}
ctxval, err := context.InitAppContext()
if err != nil {
@@ -56,14 +56,14 @@ func makeAppContextForCompositeApp(p, ca, v, rName string) (contextForCompositeA
if err != nil {
return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error creating CompositeApp handle")
}
- err = context.AddCompositeAppMeta(appcontext.CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rName})
+ err = context.AddCompositeAppMeta(appcontext.CompositeAppMeta{Project: p, CompositeApp: ca, Version: v, Release: rName, DeploymentIntentGroup: dig})
if err != nil {
return contextForCompositeApp{}, pkgerrors.Wrap(err, "Error Adding CompositeAppMeta")
}
m, err := context.GetCompositeAppMeta()
- log.Info(":: The meta data stored in the runtime context :: ", log.Fields{"Project": m.Project, "CompositeApp": m.CompositeApp, "Version": m.Version, "Release": m.Release})
+ log.Info(":: The meta data stored in the runtime context :: ", log.Fields{"Project": m.Project, "CompositeApp": m.CompositeApp, "Version": m.Version, "Release": m.Release, "DeploymentIntentGroup": m.DeploymentIntentGroup})
cca := contextForCompositeApp{context: context, ctxval: ctxval, compositeAppHandle: compositeHandle}
diff --git a/src/ovnaction/api/api.go b/src/ovnaction/api/api.go
index bffab0a4..36744cb0 100644
--- a/src/ovnaction/api/api.go
+++ b/src/ovnaction/api/api.go
@@ -75,39 +75,38 @@ func NewRouter(testClient interface{}) *mux.Router {
netcontrolintentHandler := netcontrolintentHandler{
client: setClient(moduleClient.NetControlIntent, testClient).(moduleLib.NetControlIntentManager),
}
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent", netcontrolintentHandler.createHandler).Methods("POST")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent", netcontrolintentHandler.getHandler).Methods("GET")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{name}", netcontrolintentHandler.putHandler).Methods("PUT")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{name}", netcontrolintentHandler.getHandler).Methods("GET")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{name}", netcontrolintentHandler.deleteHandler).Methods("DELETE")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{name}/apply", netcontrolintentHandler.applyHandler).Methods("POST")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent", netcontrolintentHandler.createHandler).Methods("POST")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent", netcontrolintentHandler.getHandler).Methods("GET")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{name}", netcontrolintentHandler.putHandler).Methods("PUT")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{name}", netcontrolintentHandler.getHandler).Methods("GET")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{name}", netcontrolintentHandler.deleteHandler).Methods("DELETE")
workloadintentHandler := workloadintentHandler{
client: setClient(moduleClient.WorkloadIntent, testClient).(moduleLib.WorkloadIntentManager),
}
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents", workloadintentHandler.createHandler).Methods("POST")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents", workloadintentHandler.getHandler).Methods("GET")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.putHandler).Methods("PUT")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.getHandler).Methods("GET")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.deleteHandler).Methods("DELETE")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents", workloadintentHandler.createHandler).Methods("POST")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents", workloadintentHandler.getHandler).Methods("GET")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.putHandler).Methods("PUT")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.getHandler).Methods("GET")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents/{name}", workloadintentHandler.deleteHandler).Methods("DELETE")
workloadifintentHandler := workloadifintentHandler{
client: setClient(moduleClient.WorkloadIfIntent, testClient).(moduleLib.WorkloadIfIntentManager),
}
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces", workloadifintentHandler.createHandler).Methods("POST")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces", workloadifintentHandler.getHandler).Methods("GET")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.putHandler).Methods("PUT")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.getHandler).Methods("GET")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.deleteHandler).Methods("DELETE")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces", workloadifintentHandler.createHandler).Methods("POST")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces", workloadifintentHandler.getHandler).Methods("GET")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.putHandler).Methods("PUT")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.getHandler).Methods("GET")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/workload-intents/{workload-intent}/interfaces/{name}", workloadifintentHandler.deleteHandler).Methods("DELETE")
chainHandler := chainHandler{
client: setClient(moduleClient.Chain, testClient).(moduleLib.ChainManager),
}
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains", chainHandler.createHandler).Methods("POST")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains", chainHandler.getHandler).Methods("GET")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.putHandler).Methods("PUT")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.getHandler).Methods("GET")
- router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.deleteHandler).Methods("DELETE")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/network-chains", chainHandler.createHandler).Methods("POST")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/network-chains", chainHandler.getHandler).Methods("GET")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.putHandler).Methods("PUT")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.getHandler).Methods("GET")
+ router.HandleFunc("/projects/{project}/composite-apps/{composite-app-name}/{version}/deployment-intent-groups/{deployment-intent-group-name}/network-controller-intent/{net-control-intent}/network-chains/{name}", chainHandler.deleteHandler).Methods("DELETE")
return router
}
diff --git a/src/ovnaction/api/chainhandler.go b/src/ovnaction/api/chainhandler.go
index 52ed18e5..daf5b2eb 100644
--- a/src/ovnaction/api/chainhandler.go
+++ b/src/ovnaction/api/chainhandler.go
@@ -23,8 +23,8 @@ import (
"net/http"
"strings"
- moduleLib "github.com/onap/multicloud-k8s/src/ovnaction/pkg/module"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
+ moduleLib "github.com/onap/multicloud-k8s/src/ovnaction/pkg/module"
pkgerrors "github.com/pkg/errors"
"github.com/gorilla/mux"
@@ -141,6 +141,7 @@ func (h chainHandler) createHandler(w http.ResponseWriter, r *http.Request) {
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
err := json.NewDecoder(r.Body).Decode(&ch)
@@ -166,7 +167,7 @@ func (h chainHandler) createHandler(w http.ResponseWriter, r *http.Request) {
return
}
- ret, err := h.client.CreateChain(ch, project, compositeApp, compositeAppVersion, netControlIntent, false)
+ ret, err := h.client.CreateChain(ch, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, false)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -189,6 +190,7 @@ func (h chainHandler) putHandler(w http.ResponseWriter, r *http.Request) {
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
err := json.NewDecoder(r.Body).Decode(&ch)
@@ -221,7 +223,7 @@ func (h chainHandler) putHandler(w http.ResponseWriter, r *http.Request) {
return
}
- ret, err := h.client.CreateChain(ch, project, compositeApp, compositeAppVersion, netControlIntent, true)
+ ret, err := h.client.CreateChain(ch, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, true)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -244,18 +246,19 @@ func (h chainHandler) getHandler(w http.ResponseWriter, r *http.Request) {
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
var ret interface{}
var err error
if len(name) == 0 {
- ret, err = h.client.GetChains(project, compositeApp, compositeAppVersion, netControlIntent)
+ ret, err = h.client.GetChains(project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
} else {
- ret, err = h.client.GetChain(name, project, compositeApp, compositeAppVersion, netControlIntent)
+ ret, err = h.client.GetChain(name, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -278,9 +281,10 @@ func (h chainHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
- err := h.client.DeleteChain(name, project, compositeApp, compositeAppVersion, netControlIntent)
+ err := h.client.DeleteChain(name, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/ovnaction/api/netcontrolintenthandler.go b/src/ovnaction/api/netcontrolintenthandler.go
index 631f13c4..85318ccf 100644
--- a/src/ovnaction/api/netcontrolintenthandler.go
+++ b/src/ovnaction/api/netcontrolintenthandler.go
@@ -22,18 +22,15 @@ import (
"io"
"net/http"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
moduleLib "github.com/onap/multicloud-k8s/src/ovnaction/pkg/module"
pkgerrors "github.com/pkg/errors"
- "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
-
"github.com/gorilla/mux"
)
var netCntIntJSONFile string = "json-schemas/metadata.json"
-
-
// Used to store backend implementations objects
// Also simplifies mocking for unit testing purposes
type netcontrolintentHandler struct {
@@ -59,6 +56,7 @@ func (h netcontrolintentHandler) createHandler(w http.ResponseWriter, r *http.Re
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
err := json.NewDecoder(r.Body).Decode(&nci)
@@ -72,11 +70,10 @@ func (h netcontrolintentHandler) createHandler(w http.ResponseWriter, r *http.Re
}
err, httpError := validation.ValidateJsonSchemaData(netCntIntJSONFile, nci)
-if err != nil {
- http.Error(w, err.Error(), httpError)
- return
-}
-
+ if err != nil {
+ http.Error(w, err.Error(), httpError)
+ return
+ }
// Name is required.
if nci.Metadata.Name == "" {
@@ -90,7 +87,7 @@ if err != nil {
return
}
- ret, err := h.client.CreateNetControlIntent(nci, project, compositeApp, compositeAppVersion, false)
+ ret, err := h.client.CreateNetControlIntent(nci, project, compositeApp, compositeAppVersion, deployIntentGroup, false)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -113,6 +110,7 @@ func (h netcontrolintentHandler) putHandler(w http.ResponseWriter, r *http.Reque
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
err := json.NewDecoder(r.Body).Decode(&nci)
@@ -144,7 +142,7 @@ func (h netcontrolintentHandler) putHandler(w http.ResponseWriter, r *http.Reque
return
}
- ret, err := h.client.CreateNetControlIntent(nci, project, compositeApp, compositeAppVersion, true)
+ ret, err := h.client.CreateNetControlIntent(nci, project, compositeApp, compositeAppVersion, deployIntentGroup, true)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -167,17 +165,18 @@ func (h netcontrolintentHandler) getHandler(w http.ResponseWriter, r *http.Reque
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
var ret interface{}
var err error
if len(name) == 0 {
- ret, err = h.client.GetNetControlIntents(project, compositeApp, compositeAppVersion)
+ ret, err = h.client.GetNetControlIntents(project, compositeApp, compositeAppVersion, deployIntentGroup)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
} else {
- ret, err = h.client.GetNetControlIntent(name, project, compositeApp, compositeAppVersion)
+ ret, err = h.client.GetNetControlIntent(name, project, compositeApp, compositeAppVersion, deployIntentGroup)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -200,42 +199,9 @@ func (h netcontrolintentHandler) deleteHandler(w http.ResponseWriter, r *http.Re
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
- err := h.client.DeleteNetControlIntent(name, project, compositeApp, compositeAppVersion)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- w.WriteHeader(http.StatusNoContent)
-}
-
-// Apply handles POST operations to Apply a particular NetControlIntent to the App Context
-// TODO: This is a test API - it can be removed once the orchestrator has been implemented to
-// invoke the appcontext update via grpc.
-func (h netcontrolintentHandler) applyHandler(w http.ResponseWriter, r *http.Request) {
- vars := mux.Vars(r)
- name := vars["name"]
- project := vars["project"]
- compositeApp := vars["composite-app-name"]
- compositeAppVersion := vars["version"]
-
- var aci struct {
- AppContextId string `json:"appContextId"`
- }
-
- err := json.NewDecoder(r.Body).Decode(&aci)
-
- switch {
- case err == io.EOF:
- http.Error(w, "Empty body", http.StatusBadRequest)
- return
- case err != nil:
- http.Error(w, err.Error(), http.StatusUnprocessableEntity)
- return
- }
-
- err = h.client.ApplyNetControlIntent(name, project, compositeApp, compositeAppVersion, aci.AppContextId)
+ err := h.client.DeleteNetControlIntent(name, project, compositeApp, compositeAppVersion, deployIntentGroup)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/ovnaction/api/workloadifintenthandler.go b/src/ovnaction/api/workloadifintenthandler.go
index e7be6317..5c396378 100644
--- a/src/ovnaction/api/workloadifintenthandler.go
+++ b/src/ovnaction/api/workloadifintenthandler.go
@@ -22,8 +22,8 @@ import (
"io"
"net/http"
- moduleLib "github.com/onap/multicloud-k8s/src/ovnaction/pkg/module"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
+ moduleLib "github.com/onap/multicloud-k8s/src/ovnaction/pkg/module"
pkgerrors "github.com/pkg/errors"
"github.com/gorilla/mux"
@@ -90,6 +90,7 @@ func (h workloadifintentHandler) createHandler(w http.ResponseWriter, r *http.Re
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
workloadIntent := vars["workload-intent"]
@@ -105,10 +106,10 @@ func (h workloadifintentHandler) createHandler(w http.ResponseWriter, r *http.Re
}
err, httpError := validation.ValidateJsonSchemaData(netIfJSONFile, wif)
-if err != nil {
- http.Error(w, err.Error(), httpError)
- return
-}
+ if err != nil {
+ http.Error(w, err.Error(), httpError)
+ return
+ }
// Name is required.
if wif.Metadata.Name == "" {
@@ -127,7 +128,7 @@ if err != nil {
return
}
- ret, err := h.client.CreateWorkloadIfIntent(wif, project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent, false)
+ ret, err := h.client.CreateWorkloadIfIntent(wif, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, workloadIntent, false)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -150,6 +151,7 @@ func (h workloadifintentHandler) putHandler(w http.ResponseWriter, r *http.Reque
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
workloadIntent := vars["workload-intent"]
@@ -188,7 +190,7 @@ func (h workloadifintentHandler) putHandler(w http.ResponseWriter, r *http.Reque
return
}
- ret, err := h.client.CreateWorkloadIfIntent(wif, project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent, true)
+ ret, err := h.client.CreateWorkloadIfIntent(wif, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, workloadIntent, true)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -211,19 +213,20 @@ func (h workloadifintentHandler) getHandler(w http.ResponseWriter, r *http.Reque
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
workloadIntent := vars["workload-intent"]
var ret interface{}
var err error
if len(name) == 0 {
- ret, err = h.client.GetWorkloadIfIntents(project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent)
+ ret, err = h.client.GetWorkloadIfIntents(project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, workloadIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
} else {
- ret, err = h.client.GetWorkloadIfIntent(name, project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent)
+ ret, err = h.client.GetWorkloadIfIntent(name, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, workloadIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -246,10 +249,11 @@ func (h workloadifintentHandler) deleteHandler(w http.ResponseWriter, r *http.Re
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
workloadIntent := vars["workload-intent"]
- err := h.client.DeleteWorkloadIfIntent(name, project, compositeApp, compositeAppVersion, netControlIntent, workloadIntent)
+ err := h.client.DeleteWorkloadIfIntent(name, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, workloadIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/ovnaction/api/workloadintenthandler.go b/src/ovnaction/api/workloadintenthandler.go
index acf4edbb..485f6f40 100644
--- a/src/ovnaction/api/workloadintenthandler.go
+++ b/src/ovnaction/api/workloadintenthandler.go
@@ -22,8 +22,8 @@ import (
"io"
"net/http"
- moduleLib "github.com/onap/multicloud-k8s/src/ovnaction/pkg/module"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
+ moduleLib "github.com/onap/multicloud-k8s/src/ovnaction/pkg/module"
pkgerrors "github.com/pkg/errors"
"github.com/gorilla/mux"
@@ -71,6 +71,7 @@ func (h workloadintentHandler) createHandler(w http.ResponseWriter, r *http.Requ
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
err := json.NewDecoder(r.Body).Decode(&wi)
@@ -85,10 +86,10 @@ func (h workloadintentHandler) createHandler(w http.ResponseWriter, r *http.Requ
}
err, httpError := validation.ValidateJsonSchemaData(workloadIntJSONFile, wi)
-if err != nil {
- http.Error(w, err.Error(), httpError)
- return
-}
+ if err != nil {
+ http.Error(w, err.Error(), httpError)
+ return
+ }
// Name is required.
if wi.Metadata.Name == "" {
@@ -102,7 +103,7 @@ if err != nil {
return
}
- ret, err := h.client.CreateWorkloadIntent(wi, project, compositeApp, compositeAppVersion, netControlIntent, false)
+ ret, err := h.client.CreateWorkloadIntent(wi, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, false)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -125,6 +126,7 @@ func (h workloadintentHandler) putHandler(w http.ResponseWriter, r *http.Request
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
err := json.NewDecoder(r.Body).Decode(&wi)
@@ -157,7 +159,7 @@ func (h workloadintentHandler) putHandler(w http.ResponseWriter, r *http.Request
return
}
- ret, err := h.client.CreateWorkloadIntent(wi, project, compositeApp, compositeAppVersion, netControlIntent, true)
+ ret, err := h.client.CreateWorkloadIntent(wi, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent, true)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -180,18 +182,19 @@ func (h workloadintentHandler) getHandler(w http.ResponseWriter, r *http.Request
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
var ret interface{}
var err error
if len(name) == 0 {
- ret, err = h.client.GetWorkloadIntents(project, compositeApp, compositeAppVersion, netControlIntent)
+ ret, err = h.client.GetWorkloadIntents(project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
} else {
- ret, err = h.client.GetWorkloadIntent(name, project, compositeApp, compositeAppVersion, netControlIntent)
+ ret, err = h.client.GetWorkloadIntent(name, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -214,9 +217,10 @@ func (h workloadintentHandler) deleteHandler(w http.ResponseWriter, r *http.Requ
project := vars["project"]
compositeApp := vars["composite-app-name"]
compositeAppVersion := vars["version"]
+ deployIntentGroup := vars["deployment-intent-group-name"]
netControlIntent := vars["net-control-intent"]
- err := h.client.DeleteWorkloadIntent(name, project, compositeApp, compositeAppVersion, netControlIntent)
+ err := h.client.DeleteWorkloadIntent(name, project, compositeApp, compositeAppVersion, deployIntentGroup, netControlIntent)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/src/ovnaction/internal/action/action.go b/src/ovnaction/internal/action/action.go
index c9b912fa..ae04cb0f 100644
--- a/src/ovnaction/internal/action/action.go
+++ b/src/ovnaction/internal/action/action.go
@@ -47,11 +47,12 @@ func UpdateAppContext(intentName, appContextId string) error {
project := caMeta.Project
compositeapp := caMeta.CompositeApp
compositeappversion := caMeta.Version
+ deployIntentGroup := caMeta.DeploymentIntentGroup
// Handle all Workload Intents for the Network Control Intent
- wis, err := module.NewWorkloadIntentClient().GetWorkloadIntents(project, compositeapp, compositeappversion, intentName)
+ wis, err := module.NewWorkloadIntentClient().GetWorkloadIntents(project, compositeapp, compositeappversion, deployIntentGroup, intentName)
if err != nil {
- return pkgerrors.Wrapf(err, "Error getting Workload Intents for Network Control Intent %v for %v/%v%v not found", intentName, project, compositeapp, compositeappversion)
+ return pkgerrors.Wrapf(err, "Error getting Workload Intents for Network Control Intent %v for %v/%v%v/%v not found", intentName, project, compositeapp, deployIntentGroup, compositeappversion)
}
// Handle all intents (currently just Workload Interface intents) for each Workload Intent
@@ -66,20 +67,22 @@ func UpdateAppContext(intentName, appContextId string) error {
wifs, err := module.NewWorkloadIfIntentClient().GetWorkloadIfIntents(project,
compositeapp,
compositeappversion,
+ deployIntentGroup,
intentName,
wi.Metadata.Name)
if err != nil {
return pkgerrors.Wrapf(err,
- "Error getting Workload Interface Intents for Workload Intent %v under Network Control Intent %v for %v/%v%v not found",
- wi.Metadata.Name, intentName, project, compositeapp, compositeappversion)
+ "Error getting Workload Interface Intents for Workload Intent %v under Network Control Intent %v for %v/%v%v/%v not found",
+ wi.Metadata.Name, intentName, project, compositeapp, compositeappversion, deployIntentGroup)
}
if len(wifs) == 0 {
log.Warn("No interface intents provided for workload intent", log.Fields{
- "project": project,
- "composite app": compositeapp,
- "composite app version": compositeappversion,
- "network control intent": intentName,
- "workload intent": wi.Metadata.Name,
+ "project": project,
+ "composite app": compositeapp,
+ "composite app version": compositeappversion,
+ "deployment intent group": deployIntentGroup,
+ "network control intent": intentName,
+ "workload intent": wi.Metadata.Name,
})
continue
}
@@ -91,14 +94,15 @@ func UpdateAppContext(intentName, appContextId string) error {
strings.Join([]string{wi.Spec.WorkloadResource, wi.Spec.Type}, "+"))
if err != nil {
log.Warn("App Context resource handle not found", log.Fields{
- "project": project,
- "composite app": compositeapp,
- "composite app version": compositeappversion,
- "network control intent": intentName,
- "workload name": wi.Metadata.Name,
- "app": wi.Spec.AppName,
- "resource": wi.Spec.WorkloadResource,
- "resource type": wi.Spec.Type,
+ "project": project,
+ "composite app": compositeapp,
+ "composite app version": compositeappversion,
+ "deployment intent group": deployIntentGroup,
+ "network control intent": intentName,
+ "workload name": wi.Metadata.Name,
+ "app": wi.Spec.AppName,
+ "resource": wi.Spec.WorkloadResource,
+ "resource type": wi.Spec.Type,
})
continue
}
diff --git a/src/ovnaction/pkg/module/chaining.go b/src/ovnaction/pkg/module/chaining.go
index 45f061fa..bc2cac00 100644
--- a/src/ovnaction/pkg/module/chaining.go
+++ b/src/ovnaction/pkg/module/chaining.go
@@ -54,6 +54,7 @@ type ChainKey struct {
Project string `json:"project"`
CompositeApp string `json:"compositeapp"`
CompositeAppVersion string `json:"compositeappversion"`
+ DigName string `json:"deploymentintentgroup"`
NetControlIntent string `json:"netcontrolintent"`
NetworkChain string `json:"networkchain"`
}
@@ -76,10 +77,10 @@ const ChainingKind = "NetworkChaining"
// ChainManager is an interface exposing the Chain functionality
type ChainManager interface {
- CreateChain(ch Chain, pr, ca, caver, netctrlint string, exists bool) (Chain, error)
- GetChain(name, pr, ca, caver, netctrlint string) (Chain, error)
- GetChains(pr, ca, caver, netctrlint string) ([]Chain, error)
- DeleteChain(name, pr, ca, caver, netctrlint string) error
+ CreateChain(ch Chain, pr, ca, caver, dig, netctrlint string, exists bool) (Chain, error)
+ GetChain(name, pr, ca, caver, dig, netctrlint string) (Chain, error)
+ GetChains(pr, ca, caver, dig, netctrlint string) ([]Chain, error)
+ DeleteChain(name, pr, ca, caver, dig, netctrlint string) error
}
// ChainClient implements the Manager
@@ -100,24 +101,25 @@ func NewChainClient() *ChainClient {
}
// CreateChain - create a new Chain
-func (v *ChainClient) CreateChain(ch Chain, pr, ca, caver, netctrlint string, exists bool) (Chain, error) {
+func (v *ChainClient) CreateChain(ch Chain, pr, ca, caver, dig, netctrlint string, exists bool) (Chain, error) {
//Construct key and tag to select the entry
key := ChainKey{
Project: pr,
CompositeApp: ca,
CompositeAppVersion: caver,
+ DigName: dig,
NetControlIntent: netctrlint,
NetworkChain: ch.Metadata.Name,
}
//Check if the Network Control Intent exists
- _, err := NewNetControlIntentClient().GetNetControlIntent(netctrlint, pr, ca, caver)
+ _, err := NewNetControlIntentClient().GetNetControlIntent(netctrlint, pr, ca, caver, dig)
if err != nil {
return Chain{}, pkgerrors.Errorf("Network Control Intent %v does not exist", netctrlint)
}
//Check if this Chain already exists
- _, err = v.GetChain(ch.Metadata.Name, pr, ca, caver, netctrlint)
+ _, err = v.GetChain(ch.Metadata.Name, pr, ca, caver, dig, netctrlint)
if err == nil && !exists {
return Chain{}, pkgerrors.New("Chain already exists")
}
@@ -131,12 +133,13 @@ func (v *ChainClient) CreateChain(ch Chain, pr, ca, caver, netctrlint string, ex
}
// GetChain returns the Chain for corresponding name
-func (v *ChainClient) GetChain(name, pr, ca, caver, netctrlint string) (Chain, error) {
+func (v *ChainClient) GetChain(name, pr, ca, caver, dig, netctrlint string) (Chain, error) {
//Construct key and tag to select the entry
key := ChainKey{
Project: pr,
CompositeApp: ca,
CompositeAppVersion: caver,
+ DigName: dig,
NetControlIntent: netctrlint,
NetworkChain: name,
}
@@ -160,12 +163,13 @@ func (v *ChainClient) GetChain(name, pr, ca, caver, netctrlint string) (Chain, e
}
// GetChains returns all of the Chains for for the given network control intent
-func (v *ChainClient) GetChains(pr, ca, caver, netctrlint string) ([]Chain, error) {
+func (v *ChainClient) GetChains(pr, ca, caver, dig, netctrlint string) ([]Chain, error) {
//Construct key and tag to select the entry
key := ChainKey{
Project: pr,
CompositeApp: ca,
CompositeAppVersion: caver,
+ DigName: dig,
NetControlIntent: netctrlint,
NetworkChain: "",
}
@@ -189,13 +193,14 @@ func (v *ChainClient) GetChains(pr, ca, caver, netctrlint string) ([]Chain, erro
}
// DeleteChain deletes the Chain from the database
-func (v *ChainClient) DeleteChain(name, pr, ca, caver, netctrlint string) error {
+func (v *ChainClient) DeleteChain(name, pr, ca, caver, dig, netctrlint string) error {
//Construct key and tag to select the entry
key := ChainKey{
Project: pr,
CompositeApp: ca,
CompositeAppVersion: caver,
+ DigName: dig,
NetControlIntent: netctrlint,
NetworkChain: name,
}
diff --git a/src/ovnaction/pkg/module/netcontrolintent.go b/src/ovnaction/pkg/module/netcontrolintent.go
index c005a935..eada4be1 100644
--- a/src/ovnaction/pkg/module/netcontrolintent.go
+++ b/src/ovnaction/pkg/module/netcontrolintent.go
@@ -17,17 +17,7 @@
package module
import (
- "encoding/json"
- "strings"
-
- jyaml "github.com/ghodss/yaml"
-
- nettypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
- "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
- log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/client-go/kubernetes/scheme"
pkgerrors "github.com/pkg/errors"
)
@@ -43,15 +33,15 @@ type NetControlIntentKey struct {
Project string `json:"project"`
CompositeApp string `json:"compositeapp"`
CompositeAppVersion string `json:"compositeappversion"`
+ DigName string `json:"deploymentintentgroup"`
}
// Manager is an interface exposing the NetControlIntent functionality
type NetControlIntentManager interface {
- CreateNetControlIntent(nci NetControlIntent, project, compositeapp, compositeappversion string, exists bool) (NetControlIntent, error)
- GetNetControlIntent(name, project, compositeapp, compositeappversion string) (NetControlIntent, error)
- GetNetControlIntents(project, compositeapp, compositeappversion string) ([]NetControlIntent, error)
- DeleteNetControlIntent(name, project, compositeapp, compositeappversion string) error
- ApplyNetControlIntent(name, project, compositeapp, compositeappversion, appContextId string) error
+ CreateNetControlIntent(nci NetControlIntent, project, compositeapp, compositeappversion, dig string, exists bool) (NetControlIntent, error)
+ GetNetControlIntent(name, project, compositeapp, compositeappversion, dig string) (NetControlIntent, error)
+ GetNetControlIntents(project, compositeapp, compositeappversion, dig string) ([]NetControlIntent, error)
+ DeleteNetControlIntent(name, project, compositeapp, compositeappversion, dig string) error
}
// NetControlIntentClient implements the Manager
@@ -72,7 +62,7 @@ func NewNetControlIntentClient() *NetControlIntentClient {
}
// CreateNetControlIntent - create a new NetControlIntent
-func (v *NetControlIntentClient) CreateNetControlIntent(nci NetControlIntent, project, compositeapp, compositeappversion string, exists bool) (NetControlIntent, error) {
+func (v *NetControlIntentClient) CreateNetControlIntent(nci NetControlIntent, project, compositeapp, compositeappversion, dig string, exists bool) (NetControlIntent, error) {
//Construct key and tag to select the entry
key := NetControlIntentKey{
@@ -80,10 +70,11 @@ func (v *NetControlIntentClient) CreateNetControlIntent(nci NetControlIntent, pr
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
}
//Check if this NetControlIntent already exists
- _, err := v.GetNetControlIntent(nci.Metadata.Name, project, compositeapp, compositeappversion)
+ _, err := v.GetNetControlIntent(nci.Metadata.Name, project, compositeapp, compositeappversion, dig)
if err == nil && !exists {
return NetControlIntent{}, pkgerrors.New("NetControlIntent already exists")
}
@@ -97,7 +88,7 @@ func (v *NetControlIntentClient) CreateNetControlIntent(nci NetControlIntent, pr
}
// GetNetControlIntent returns the NetControlIntent for corresponding name
-func (v *NetControlIntentClient) GetNetControlIntent(name, project, compositeapp, compositeappversion string) (NetControlIntent, error) {
+func (v *NetControlIntentClient) GetNetControlIntent(name, project, compositeapp, compositeappversion, dig string) (NetControlIntent, error) {
//Construct key and tag to select the entry
key := NetControlIntentKey{
@@ -105,6 +96,7 @@ func (v *NetControlIntentClient) GetNetControlIntent(name, project, compositeapp
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
}
value, err := db.DBconn.Find(v.db.storeName, key, v.db.tagMeta)
@@ -126,7 +118,7 @@ func (v *NetControlIntentClient) GetNetControlIntent(name, project, compositeapp
}
// GetNetControlIntentList returns all of the NetControlIntent for corresponding name
-func (v *NetControlIntentClient) GetNetControlIntents(project, compositeapp, compositeappversion string) ([]NetControlIntent, error) {
+func (v *NetControlIntentClient) GetNetControlIntents(project, compositeapp, compositeappversion, dig string) ([]NetControlIntent, error) {
//Construct key and tag to select the entry
key := NetControlIntentKey{
@@ -134,6 +126,7 @@ func (v *NetControlIntentClient) GetNetControlIntents(project, compositeapp, com
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
}
var resp []NetControlIntent
@@ -155,7 +148,7 @@ func (v *NetControlIntentClient) GetNetControlIntents(project, compositeapp, com
}
// Delete the NetControlIntent from database
-func (v *NetControlIntentClient) DeleteNetControlIntent(name, project, compositeapp, compositeappversion string) error {
+func (v *NetControlIntentClient) DeleteNetControlIntent(name, project, compositeapp, compositeappversion, dig string) error {
//Construct key and tag to select the entry
key := NetControlIntentKey{
@@ -163,6 +156,7 @@ func (v *NetControlIntentClient) DeleteNetControlIntent(name, project, composite
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
}
err := db.DBconn.Remove(v.db.storeName, key)
@@ -172,124 +166,3 @@ func (v *NetControlIntentClient) DeleteNetControlIntent(name, project, composite
return nil
}
-
-// (Test Routine) - Apply network-control-intent
-func (v *NetControlIntentClient) ApplyNetControlIntent(name, project, compositeapp, compositeappversion, appContextId string) error {
- // TODO: Handle all Network Chain Intents for the Network Control Intent
-
- // Handle all Workload Intents for the Network Control Intent
- wis, err := NewWorkloadIntentClient().GetWorkloadIntents(project, compositeapp, compositeappversion, name)
- if err != nil {
- return pkgerrors.Wrapf(err, "Error getting Workload Intents for Network Control Intent %v for %v/%v%v not found", name, project, compositeapp, compositeappversion)
- }
-
- // Setup the AppContext
- var context appcontext.AppContext
- _, err = context.LoadAppContext(appContextId)
- if err != nil {
- return pkgerrors.Wrapf(err, "Error getting AppContext with Id: %v for %v/%v%v",
- appContextId, project, compositeapp, compositeappversion)
- }
-
- // Handle all intents (currently just Interface intents) for each Workload Intent
- for _, wi := range wis {
- // The app/resource identified in the workload intent needs to be updated with two annotations.
- // 1 - The "k8s.v1.cni.cncf.io/networks" annotation will have {"name": "ovn-networkobj", "namespace": "default"} added
- // to it (preserving any existing values for this annotation.
- // 2 - The "k8s.plugin.opnfv.org/nfn-network" annotation will add any network interfaces that are provided by the
- // workload/interfaces intents.
-
- // Prepare the list of interfaces from the workload intent
- wifs, err := NewWorkloadIfIntentClient().GetWorkloadIfIntents(project,
- compositeapp,
- compositeappversion,
- name,
- wi.Metadata.Name)
- if err != nil {
- return pkgerrors.Wrapf(err,
- "Error getting Workload Interface Intents for Workload Intent %v under Network Control Intent %v for %v/%v%v not found",
- wi.Metadata.Name, name, project, compositeapp, compositeappversion)
- }
- if len(wifs) == 0 {
- log.Warn("No interface intents provided for workload intent", log.Fields{
- "project": project,
- "composite app": compositeapp,
- "composite app version": compositeappversion,
- "network control intent": name,
- "workload intent": wi.Metadata.Name,
- })
- continue
- }
-
- // Get all clusters for the current App from the AppContext
- clusters, err := context.GetClusterNames(wi.Spec.AppName)
- for _, c := range clusters {
- rh, err := context.GetResourceHandle(wi.Spec.AppName, c,
- strings.Join([]string{wi.Spec.WorkloadResource, wi.Spec.Type}, "+"))
- if err != nil {
- log.Warn("App Context resource handle not found", log.Fields{
- "project": project,
- "composite app": compositeapp,
- "composite app version": compositeappversion,
- "network control intent": name,
- "workload name": wi.Metadata.Name,
- "app": wi.Spec.AppName,
- "resource": wi.Spec.WorkloadResource,
- "resource type": wi.Spec.Type,
- })
- continue
- }
- r, err := context.GetValue(rh)
- if err != nil {
- log.Error("Error retrieving resource from App Context", log.Fields{
- "error": err,
- "resource handle": rh,
- })
- }
-
- // Unmarshal resource to K8S object
- robj, err := runtime.Decode(scheme.Codecs.UniversalDeserializer(), []byte(r.(string)))
-
- // Add network annotation to object
- netAnnot := nettypes.NetworkSelectionElement{
- Name: "ovn-networkobj",
- Namespace: "default",
- }
- AddNetworkAnnotation(robj, netAnnot)
-
- // Add nfn interface annotations to object
- var newNfnIfs []WorkloadIfIntentSpec
- for _, i := range wifs {
- newNfnIfs = append(newNfnIfs, i.Spec)
- }
- AddNfnAnnotation(robj, newNfnIfs)
-
- // Marshal object back to yaml format (via json - seems to eliminate most clutter)
- j, err := json.Marshal(robj)
- if err != nil {
- log.Error("Error marshalling resource to JSON", log.Fields{
- "error": err,
- })
- continue
- }
- y, err := jyaml.JSONToYAML(j)
- if err != nil {
- log.Error("Error marshalling resource to YAML", log.Fields{
- "error": err,
- })
- continue
- }
-
- // Update resource in AppContext
- err = context.UpdateResourceValue(rh, string(y))
- if err != nil {
- log.Error("Network updating app context resource handle", log.Fields{
- "error": err,
- "resource handle": rh,
- })
- }
- }
- }
-
- return nil
-}
diff --git a/src/ovnaction/pkg/module/workloadifintent.go b/src/ovnaction/pkg/module/workloadifintent.go
index 55062564..cea336f6 100644
--- a/src/ovnaction/pkg/module/workloadifintent.go
+++ b/src/ovnaction/pkg/module/workloadifintent.go
@@ -41,6 +41,7 @@ type WorkloadIfIntentKey struct {
Project string `json:"provider"`
CompositeApp string `json:"compositeapp"`
CompositeAppVersion string `json:"compositeappversion"`
+ DigName string `json:"deploymentintentgroup"`
NetControlIntent string `json:"netcontrolintent"`
WorkloadIntent string `json:"workloadintent"`
WorkloadIfIntent string `json:"workloadifintent"`
@@ -48,10 +49,10 @@ type WorkloadIfIntentKey struct {
// Manager is an interface exposing the WorkloadIfIntent functionality
type WorkloadIfIntentManager interface {
- CreateWorkloadIfIntent(wi WorkloadIfIntent, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string, exists bool) (WorkloadIfIntent, error)
- GetWorkloadIfIntent(name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) (WorkloadIfIntent, error)
- GetWorkloadIfIntents(project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) ([]WorkloadIfIntent, error)
- DeleteWorkloadIfIntent(name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) error
+ CreateWorkloadIfIntent(wi WorkloadIfIntent, project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent string, exists bool) (WorkloadIfIntent, error)
+ GetWorkloadIfIntent(name, project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent string) (WorkloadIfIntent, error)
+ GetWorkloadIfIntents(project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent string) ([]WorkloadIfIntent, error)
+ DeleteWorkloadIfIntent(name, project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent string) error
}
// WorkloadIfIntentClient implements the Manager
@@ -72,26 +73,27 @@ func NewWorkloadIfIntentClient() *WorkloadIfIntentClient {
}
// CreateWorkloadIfIntent - create a new WorkloadIfIntent
-func (v *WorkloadIfIntentClient) CreateWorkloadIfIntent(wif WorkloadIfIntent, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string, exists bool) (WorkloadIfIntent, error) {
+func (v *WorkloadIfIntentClient) CreateWorkloadIfIntent(wif WorkloadIfIntent, project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent string, exists bool) (WorkloadIfIntent, error) {
//Construct key and tag to select the entry
key := WorkloadIfIntentKey{
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
NetControlIntent: netcontrolintent,
WorkloadIntent: workloadintent,
WorkloadIfIntent: wif.Metadata.Name,
}
//Check if the Workload Intent exists
- _, err := NewWorkloadIntentClient().GetWorkloadIntent(workloadintent, project, compositeapp, compositeappversion, netcontrolintent)
+ _, err := NewWorkloadIntentClient().GetWorkloadIntent(workloadintent, project, compositeapp, compositeappversion, dig, netcontrolintent)
if err != nil {
return WorkloadIfIntent{}, pkgerrors.Errorf("Workload Intent %v does not exist", workloadintent)
}
//Check if this WorkloadIfIntent already exists
- _, err = v.GetWorkloadIfIntent(wif.Metadata.Name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent)
+ _, err = v.GetWorkloadIfIntent(wif.Metadata.Name, project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent)
if err == nil && !exists {
return WorkloadIfIntent{}, pkgerrors.New("WorkloadIfIntent already exists")
}
@@ -105,13 +107,14 @@ func (v *WorkloadIfIntentClient) CreateWorkloadIfIntent(wif WorkloadIfIntent, pr
}
// GetWorkloadIfIntent returns the WorkloadIfIntent for corresponding name
-func (v *WorkloadIfIntentClient) GetWorkloadIfIntent(name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) (WorkloadIfIntent, error) {
+func (v *WorkloadIfIntentClient) GetWorkloadIfIntent(name, project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent string) (WorkloadIfIntent, error) {
//Construct key and tag to select the entry
key := WorkloadIfIntentKey{
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
NetControlIntent: netcontrolintent,
WorkloadIntent: workloadintent,
WorkloadIfIntent: name,
@@ -136,13 +139,14 @@ func (v *WorkloadIfIntentClient) GetWorkloadIfIntent(name, project, compositeapp
}
// GetWorkloadIfIntentList returns all of the WorkloadIfIntent for corresponding name
-func (v *WorkloadIfIntentClient) GetWorkloadIfIntents(project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) ([]WorkloadIfIntent, error) {
+func (v *WorkloadIfIntentClient) GetWorkloadIfIntents(project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent string) ([]WorkloadIfIntent, error) {
//Construct key and tag to select the entry
key := WorkloadIfIntentKey{
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
NetControlIntent: netcontrolintent,
WorkloadIntent: workloadintent,
WorkloadIfIntent: "",
@@ -167,13 +171,14 @@ func (v *WorkloadIfIntentClient) GetWorkloadIfIntents(project, compositeapp, com
}
// Delete the WorkloadIfIntent from database
-func (v *WorkloadIfIntentClient) DeleteWorkloadIfIntent(name, project, compositeapp, compositeappversion, netcontrolintent, workloadintent string) error {
+func (v *WorkloadIfIntentClient) DeleteWorkloadIfIntent(name, project, compositeapp, compositeappversion, dig, netcontrolintent, workloadintent string) error {
//Construct key and tag to select the entry
key := WorkloadIfIntentKey{
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
NetControlIntent: netcontrolintent,
WorkloadIntent: workloadintent,
WorkloadIfIntent: name,
diff --git a/src/ovnaction/pkg/module/workloadintent.go b/src/ovnaction/pkg/module/workloadintent.go
index e6916954..b1ca9d02 100644
--- a/src/ovnaction/pkg/module/workloadintent.go
+++ b/src/ovnaction/pkg/module/workloadintent.go
@@ -39,16 +39,17 @@ type WorkloadIntentKey struct {
Project string `json:"provider"`
CompositeApp string `json:"compositeapp"`
CompositeAppVersion string `json:"compositeappversion"`
+ DigName string `json:"deploymentintentgroup"`
NetControlIntent string `json:"netcontrolintent"`
WorkloadIntent string `json:"workloadintent"`
}
// Manager is an interface exposing the WorkloadIntent functionality
type WorkloadIntentManager interface {
- CreateWorkloadIntent(wi WorkloadIntent, project, compositeapp, compositeappversion, netcontrolintent string, exists bool) (WorkloadIntent, error)
- GetWorkloadIntent(name, project, compositeapp, compositeappversion, netcontrolintent string) (WorkloadIntent, error)
- GetWorkloadIntents(project, compositeapp, compositeappversion, netcontrolintent string) ([]WorkloadIntent, error)
- DeleteWorkloadIntent(name, project, compositeapp, compositeappversion, netcontrolintent string) error
+ CreateWorkloadIntent(wi WorkloadIntent, project, compositeapp, compositeappversion, dig, netcontrolintent string, exists bool) (WorkloadIntent, error)
+ GetWorkloadIntent(name, project, compositeapp, compositeappversion, dig, netcontrolintent string) (WorkloadIntent, error)
+ GetWorkloadIntents(project, compositeapp, compositeappversion, dig, netcontrolintent string) ([]WorkloadIntent, error)
+ DeleteWorkloadIntent(name, project, compositeapp, compositeappversion, dig, netcontrolintent string) error
}
// WorkloadIntentClient implements the Manager
@@ -69,25 +70,26 @@ func NewWorkloadIntentClient() *WorkloadIntentClient {
}
// CreateWorkloadIntent - create a new WorkloadIntent
-func (v *WorkloadIntentClient) CreateWorkloadIntent(wi WorkloadIntent, project, compositeapp, compositeappversion, netcontrolintent string, exists bool) (WorkloadIntent, error) {
+func (v *WorkloadIntentClient) CreateWorkloadIntent(wi WorkloadIntent, project, compositeapp, compositeappversion, dig, netcontrolintent string, exists bool) (WorkloadIntent, error) {
//Construct key and tag to select the entry
key := WorkloadIntentKey{
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
NetControlIntent: netcontrolintent,
WorkloadIntent: wi.Metadata.Name,
}
//Check if the Network Control Intent exists
- _, err := NewNetControlIntentClient().GetNetControlIntent(netcontrolintent, project, compositeapp, compositeappversion)
+ _, err := NewNetControlIntentClient().GetNetControlIntent(netcontrolintent, project, compositeapp, compositeappversion, dig)
if err != nil {
return WorkloadIntent{}, pkgerrors.Errorf("Network Control Intent %v does not exist", netcontrolintent)
}
//Check if this WorkloadIntent already exists
- _, err = v.GetWorkloadIntent(wi.Metadata.Name, project, compositeapp, compositeappversion, netcontrolintent)
+ _, err = v.GetWorkloadIntent(wi.Metadata.Name, project, compositeapp, compositeappversion, dig, netcontrolintent)
if err == nil && !exists {
return WorkloadIntent{}, pkgerrors.New("WorkloadIntent already exists")
}
@@ -101,13 +103,14 @@ func (v *WorkloadIntentClient) CreateWorkloadIntent(wi WorkloadIntent, project,
}
// GetWorkloadIntent returns the WorkloadIntent for corresponding name
-func (v *WorkloadIntentClient) GetWorkloadIntent(name, project, compositeapp, compositeappversion, netcontrolintent string) (WorkloadIntent, error) {
+func (v *WorkloadIntentClient) GetWorkloadIntent(name, project, compositeapp, compositeappversion, dig, netcontrolintent string) (WorkloadIntent, error) {
//Construct key and tag to select the entry
key := WorkloadIntentKey{
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
NetControlIntent: netcontrolintent,
WorkloadIntent: name,
}
@@ -131,13 +134,14 @@ func (v *WorkloadIntentClient) GetWorkloadIntent(name, project, compositeapp, co
}
// GetWorkloadIntentList returns all of the WorkloadIntent for corresponding name
-func (v *WorkloadIntentClient) GetWorkloadIntents(project, compositeapp, compositeappversion, netcontrolintent string) ([]WorkloadIntent, error) {
+func (v *WorkloadIntentClient) GetWorkloadIntents(project, compositeapp, compositeappversion, dig, netcontrolintent string) ([]WorkloadIntent, error) {
//Construct key and tag to select the entry
key := WorkloadIntentKey{
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
NetControlIntent: netcontrolintent,
WorkloadIntent: "",
}
@@ -161,13 +165,14 @@ func (v *WorkloadIntentClient) GetWorkloadIntents(project, compositeapp, composi
}
// Delete the WorkloadIntent from database
-func (v *WorkloadIntentClient) DeleteWorkloadIntent(name, project, compositeapp, compositeappversion, netcontrolintent string) error {
+func (v *WorkloadIntentClient) DeleteWorkloadIntent(name, project, compositeapp, compositeappversion, dig, netcontrolintent string) error {
//Construct key and tag to select the entry
key := WorkloadIntentKey{
Project: project,
CompositeApp: compositeapp,
CompositeAppVersion: compositeappversion,
+ DigName: dig,
NetControlIntent: netcontrolintent,
WorkloadIntent: name,
}
diff --git a/src/rsync/pkg/client/approve.go b/src/rsync/pkg/client/approve.go
new file mode 100644
index 00000000..ee157713
--- /dev/null
+++ b/src/rsync/pkg/client/approve.go
@@ -0,0 +1,56 @@
+/*
+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 client
+
+import (
+ "encoding/json"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext/subresources"
+ pkgerrors "github.com/pkg/errors"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
+)
+
+func (c *Client) Approve(name string, sa []byte) error {
+
+ var a subresources.ApprovalSubresource
+ err := json.Unmarshal(sa, &a)
+ if err != nil {
+ return pkgerrors.Wrap(err, "An error occurred while parsing the approval Subresource.")
+ }
+ csr, err := c.Clientset.CertificatesV1beta1().CertificateSigningRequests().Get(name, metav1.GetOptions{})
+ if err != nil {
+ return err
+ }
+ var timePtr metav1.Time
+ str := []string{a.LastUpdateTime}
+ if err = metav1.Convert_Slice_string_To_v1_Time(&str, &timePtr, nil); err != nil {
+ return pkgerrors.Wrap(err, "An error occurred while converting time from string.")
+ }
+ // Update CSR with Conditions
+ csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1beta1.CertificateSigningRequestCondition{
+ Type: certificatesv1beta1.RequestConditionType(a.Type),
+ Reason: a.Reason,
+ Message: a.Message,
+ LastUpdateTime: timePtr,
+ })
+ // CSR Approval
+ _, err = c.Clientset.CertificatesV1beta1().CertificateSigningRequests().UpdateApproval(csr)
+ if err != nil {
+ logutils.Error("Failed to UpdateApproval", logutils.Fields{
+ "error": err,
+ "resource": name,
+ })
+ return err
+ }
+ return nil
+}
diff --git a/src/rsync/pkg/context/context.go b/src/rsync/pkg/context/context.go
index 35e6c4e2..841dfcda 100644
--- a/src/rsync/pkg/context/context.go
+++ b/src/rsync/pkg/context/context.go
@@ -68,6 +68,28 @@ func getRes(ac appcontext.AppContext, name string, app string, cluster string) (
return byteRes, sh, nil
}
+func getSubResApprove(ac appcontext.AppContext, name string, app string, cluster string) ([]byte, interface{}, error) {
+ var byteRes []byte
+ rh, err := ac.GetResourceHandle(app, cluster, name)
+ if err != nil {
+ return nil, nil, err
+ }
+ sh, err := ac.GetLevelHandle(rh, "subresource/approval")
+ if err != nil {
+ return nil, nil, err
+ }
+ resval, err := ac.GetValue(sh)
+ if err != nil {
+ return nil, sh, err
+ }
+ if resval != "" {
+ byteRes = []byte(fmt.Sprintf("%v", resval.(interface{})))
+ } else {
+ return nil, sh, pkgerrors.Errorf("SubResource value is nil %s", name)
+ }
+ return byteRes, sh, nil
+}
+
func terminateResource(ac appcontext.AppContext, c *kubeclient.Client, name string, app string, cluster string, label string) error {
res, sh, err := getRes(ac, name, app, cluster)
if err != nil {
@@ -144,6 +166,22 @@ func instantiateResource(ac appcontext.AppContext, c *kubeclient.Client, name st
"cluster": cluster,
"resource": name,
})
+
+ // Currently only subresource supported is approval
+ subres, _, err := getSubResApprove(ac, name, app, cluster)
+ if err == nil {
+ result := strings.Split(name, "+")
+ if result[0] == "" {
+ return pkgerrors.Errorf("Resource name is nil %s:", name)
+ }
+ logutils.Info("Approval Subresource::", logutils.Fields{
+ "cluster": cluster,
+ "resource": result[0],
+ "approval": string(subres),
+ })
+ err = c.Approve(result[0], subres)
+ return err
+ }
return nil
}
@@ -252,7 +290,6 @@ Loop:
break Loop
} else {
logutils.Info("Cluster is not reachable - keep trying::", logutils.Fields{"cluster": cluster})
- go checkReachable()
}
case <-ch:
statusFailed := resourcestatus.ResourceStatus{
@@ -279,6 +316,7 @@ Loop:
}
resStateUpdated = true
}
+ go checkReachable()
break
}
}
diff --git a/src/tools/emcoctl/cmd/utils.go b/src/tools/emcoctl/cmd/utils.go
index 62b33755..5e063d12 100644
--- a/src/tools/emcoctl/cmd/utils.go
+++ b/src/tools/emcoctl/cmd/utils.go
@@ -25,8 +25,8 @@ import (
"github.com/go-resty/resty/v2"
"github.com/mitchellh/mapstructure"
- "gopkg.in/yaml.v3"
pkgerrors "github.com/pkg/errors"
+ "gopkg.in/yaml.v3"
)
var inputFiles []string
@@ -53,9 +53,9 @@ type emcoRes struct {
}
type emcoBody struct {
- Meta Metadata `json:"metadata,omitempty"`
- Label string `json:"label-name,omitempty"`
- Spec map[string]interface{} `json:"spec,omitempty"`
+ Meta Metadata `json:"metadata,omitempty"`
+ Label string `json:"label-name,omitempty"`
+ Spec map[string]interface{} `json:"spec,omitempty"`
}
type emcoCompositeAppSpec struct {
@@ -67,6 +67,7 @@ type Resources struct {
body []byte
file string
}
+
// RestyClient to use with CLI
type RestyClient struct {
client *resty.Client
@@ -141,7 +142,7 @@ func (r RestyClient) RestClientPost(anchor string, body []byte) error {
return err
}
fmt.Println("URL:", anchor, "Response Code:", resp.StatusCode(), "Response:", resp)
- if (resp.StatusCode() >= 201 && resp.StatusCode() <= 299) {
+ if resp.StatusCode() >= 201 && resp.StatusCode() <= 299 {
return nil
}
return pkgerrors.Errorf("Server Post Error")
@@ -174,7 +175,7 @@ func (r RestyClient) RestClientMultipartPost(anchor string, body []byte, file st
return err
}
fmt.Println("URL:", anchor, "Response Code:", resp.StatusCode(), "Response:", resp)
- if (resp.StatusCode() >= 201 && resp.StatusCode() <= 299) {
+ if resp.StatusCode() >= 201 && resp.StatusCode() <= 299 {
return nil
}
return pkgerrors.Errorf("Server Multipart Post Error")
@@ -248,6 +249,7 @@ func (r RestyClient) RestClientGet(anchor string, body []byte) error {
return r.RestClientGetAnchor(anchor)
}
+
// RestClientDeleteAnchor returns all resource in the input file
func (r RestyClient) RestClientDeleteAnchor(anchor string) error {
url, err := GetURL(anchor)
@@ -262,6 +264,7 @@ func (r RestyClient) RestClientDeleteAnchor(anchor string) error {
fmt.Println("URL:", anchor, "Response Code:", resp.StatusCode(), "Response:", resp)
return nil
}
+
// RestClientDelete calls rest delete command
func (r RestyClient) RestClientDelete(anchor string, body []byte) error {
@@ -306,6 +309,7 @@ func (r RestyClient) RestClientDelete(anchor string, body []byte) error {
}
return r.RestClientDeleteAnchor(anchor)
}
+
// GetURL reads the configuration file to get URL
func GetURL(anchor string) (string, error) {
var baseUrl string
@@ -324,13 +328,19 @@ func GetURL(anchor string) (string, error) {
case "controllers":
baseUrl = GetOrchestratorURL()
case "projects":
- if len(s) >= 6 && s[5] == "network-controller-intent" {
+ if len(s) >= 3 && s[2] == "logical-clouds" {
+ baseUrl = GetDcmURL()
+ break
+ }
+ if len(s) >= 8 && s[7] == "network-controller-intent" {
baseUrl = GetOvnactionURL()
- } else {
- baseUrl = GetOrchestratorURL()
+ break
}
+ // All other paths go to Orchestrator
+ baseUrl = GetOrchestratorURL()
default:
return "", fmt.Errorf("Invalid Anchor")
}
+ fmt.Printf(baseUrl)
return (baseUrl + "/" + anchor), nil
}
diff --git a/src/tools/emcoctl/examples/dcm.yaml b/src/tools/emcoctl/examples/dcm.yaml
new file mode 100644
index 00000000..a567491b
--- /dev/null
+++ b/src/tools/emcoctl/examples/dcm.yaml
@@ -0,0 +1,105 @@
+#creating controller entries
+version: emco/v2
+resourceContext:
+ anchor: controllers
+metadata :
+ name: rsync
+spec:
+ host: localhost
+ port: 9018
+
+---
+#creating cluster provider
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers
+metadata :
+ name: cp-1
+
+---
+#creating cluster
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers/cp-1/clusters
+metadata :
+ name: c1
+file:
+ # Replace with actual path
+ kubeconfig
+
+---
+#create project
+version: emco/v2
+resourceContext:
+ anchor: projects
+metadata :
+ name: proj1
+
+---
+#create logical cloud
+version: emco/v2
+resourceContext:
+ anchor: projects/proj1/logical-clouds
+metadata:
+ name: lc1
+spec:
+ namespace: ns1
+ user:
+ user-name: user-1
+ type: certificate
+ user-permissions:
+ - permission-name: permission-1
+ apiGroups:
+ - ""
+ resources:
+ - secrets
+ - pods
+ verbs:
+ - get
+ - watch
+ - list
+ - create
+
+---
+#create cluster reference
+version: emco/v2
+resourceContext:
+ anchor: projects/proj1/logical-clouds/lc1/cluster-references
+metadata:
+ name: lc-cl-1
+spec:
+ cluster-provider: cp-1
+ cluster-name: c1
+ loadbalancer-ip: "0.0.0.0"
+
+---
+#create cluster quotas
+version: emco/v2
+resourceContext:
+ anchor: projects/proj1/logical-clouds/lc1/cluster-quotas
+metadata:
+ name: quota-1
+spec:
+ limits.cpu: '400'
+ limits.memory: 1000Gi
+ requests.cpu: '300'
+ requests.memory: 900Gi
+ requests.storage: 500Gi
+ requests.ephemeral-storage: '500'
+ limits.ephemeral-storage: '500'
+ persistentvolumeclaims: '500'
+ pods: '500'
+ configmaps: '1000'
+ replicationcontrollers: '500'
+ resourcequotas: '500'
+ services: '500'
+ services.loadbalancers: '500'
+ services.nodeports: '500'
+ secrets: '500'
+ count/replicationcontrollers: '500'
+ count/deployments.apps: '500'
+ count/replicasets.apps: '500'
+ count/statefulsets.apps: '500'
+ count/jobs.batch: '500'
+ count/cronjobs.batch: '500'
+ count/deployments.extensions: '500'
diff --git a/src/tools/emcoctl/examples/emco-cfg.yaml b/src/tools/emcoctl/examples/emco-cfg.yaml
index a7e284ab..039a6f34 100644
--- a/src/tools/emcoctl/examples/emco-cfg.yaml
+++ b/src/tools/emcoctl/examples/emco-cfg.yaml
@@ -10,3 +10,6 @@
ovnaction:
host: localhost
port: 9018
+ dcm:
+ host: localhost
+ port: 9017
diff --git a/src/tools/emcoctl/examples/test.yaml b/src/tools/emcoctl/examples/test.yaml
index e54ff36e..f660f748 100644
--- a/src/tools/emcoctl/examples/test.yaml
+++ b/src/tools/emcoctl/examples/test.yaml
@@ -8,8 +8,8 @@ metadata :
userData1: test1
userData2: test2
spec:
- host: localhost
- port: 9031
+ host: rsync
+ port: 9041
---
#creating cluster provider
@@ -33,7 +33,7 @@ metadata :
userData1: test1
userData2: test2
file:
- /home/otc/.kube/config
+ /home/vagrant/.kube/config
---
#Add label cluster
@@ -137,23 +137,51 @@ file:
---
+#create deployment intent group
+version: emco/v2
+resourceContext:
+ anchor: projects/proj1/composite-apps/collection-composite-app/v1/deployment-intent-groups
+metadata :
+ name: collection-deployment-intent-group
+ description: "description"
+ userData1: test1
+ userData2: test2
+spec:
+ profile: collection-composite-profile
+ version: r1
+ logical-cloud: NA
+ override-values: []
+
+---
+#create intent in deployment intent group
+version: emco/v2
+resourceContext:
+ anchor: projects/proj1/composite-apps/collection-composite-app/v1/deployment-intent-groups/collection-deployment-intent-group/intents
+metadata :
+ name: collection-deployment-intent
+ description: "description"
+ userData1: test1
+ userData2: test2
+spec:
+ intent:
+ genericPlacementIntent: collection-placement-intent
+
+---
#create the generic placement intent
version: emco/v2
resourceContext:
- anchor: projects/proj1/composite-apps/collection-composite-app/v1/generic-placement-intents
+ anchor: projects/proj1/composite-apps/collection-composite-app/v1/deployment-intent-groups/collection-deployment-intent-group/generic-placement-intents
metadata :
name: collection-placement-intent
description: "description for app"
userData1: test1
userData2: test2
-spec:
- logical-cloud: NA
---
#add the prometheus app placement intent to the generic placement intent
version: emco/v2
resourceContext:
- anchor: projects/proj1/composite-apps/collection-composite-app/v1/generic-placement-intents/collection-placement-intent/app-intents
+ anchor: projects/proj1/composite-apps/collection-composite-app/v1/deployment-intent-groups/collection-deployment-intent-group/generic-placement-intents/collection-placement-intent/app-intents
metadata:
name: prometheus-placement-intent
description: description of placement_intent
@@ -169,7 +197,7 @@ spec:
#add the prometheus app placement intent to the generic placement intent
version: emco/v2
resourceContext:
- anchor: projects/proj1/composite-apps/collection-composite-app/v1/generic-placement-intents/collection-placement-intent/app-intents
+ anchor: projects/proj1/composite-apps/collection-composite-app/v1/deployment-intent-groups/collection-deployment-intent-group/generic-placement-intents/collection-placement-intent/app-intents
metadata:
name: collectd-placement-intent
description: description of placement_intent
@@ -183,35 +211,6 @@ spec:
cluster-label-name: edge-cluster
---
-#create deployment intent group
-version: emco/v2
-resourceContext:
- anchor: projects/proj1/composite-apps/collection-composite-app/v1/deployment-intent-groups
-metadata :
- name: collection-deployment-intent-group
- description: "description"
- userData1: test1
- userData2: test2
-spec:
- profile: collection-composite-profile
- version: r1
- override-values: []
-
----
-#create intent in deployment intent group
-version: emco/v2
-resourceContext:
- anchor: projects/proj1/composite-apps/collection-composite-app/v1/deployment-intent-groups/collection-deployment-intent-group/intents
-metadata :
- name: collection-deployment-intent
- description: "description"
- userData1: test1
- userData2: test2
-spec:
- intent:
- genericPlacementIntent: collection-placement-intent
-
----
#Approve
version: emco/v2
resourceContext:
diff --git a/src/tools/emcoctl/examples/vfw.yaml b/src/tools/emcoctl/examples/vfw.yaml
index c84a1bab..251c892d 100644
--- a/src/tools/emcoctl/examples/vfw.yaml
+++ b/src/tools/emcoctl/examples/vfw.yaml
@@ -3,7 +3,7 @@ version: emco/v2
resourceContext:
anchor: controllers
metadata :
- name: rsync
+ name: rsync
spec:
host: "192.168.121.6"
port: 30546
@@ -14,10 +14,10 @@ version: emco/v2
resourceContext:
anchor: controllers
metadata :
- name: ovnaction
+ name: ovnaction
spec:
- host: "192.168.121.6"
- port: 32259
+ host: "ovnaction"
+ port: 9053
type: "action"
priority: 1
@@ -28,7 +28,7 @@ version: emco/v2
resourceContext:
anchor: cluster-providers
metadata :
- name: vfw-cluster-provider
+ name: vfw-cluster-provider
---
#creating cluster
@@ -36,7 +36,7 @@ version: emco/v2
resourceContext:
anchor: cluster-providers/vfw-cluster-provider/clusters
metadata :
- name: edge01
+ name: edge01
file:
/home/otc/.kube/config
@@ -65,7 +65,7 @@ version: emco/v2
resourceContext:
anchor: cluster-providers/vfw-cluster-provider/clusters/edge01/networks
metadata:
- name: emco-unprotected-net
+ name: unprotected-private-net
spec:
cniType: ovn4nfv
ipv4Subnets:
@@ -184,20 +184,52 @@ file:
/opt/csar/cb009bfe-bbee-11e8-9766-525400435678/profile.tar.gz
---
-#create the generic placement intent
+#create deployment intent group
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/generic-placement-intents
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups
metadata :
- name: fw-placement-intent
+ name: vfw_deployment_intent_group
spec:
+ profile: vfw_composite-profile
+ version: r1
logical-cloud: NA
+ override-values:
+ - app-name: packetgen
+ values:
+ ".Values.service.ports.nodePort": '30888'
+ - app-name: firewall
+ values:
+ ".Values.global.dcaeCollectorIp": 1.2.3.4
+ ".Values.global.dcaeCollectorPort": '8888'
+ - app-name: sink
+ values:
+ ".Values.service.ports.nodePort": '30677'
+
+---
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/intents
+metadata :
+ name: fw-deployment-intent
+spec:
+ intent:
+ genericPlacementIntent: fw-placement-intent
+ ovnaction: vfw_ovnaction_intent
+
+---
+#create the generic placement intent
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/generic-placement-intents
+metadata :
+ name: fw-placement-intent
---
#add the packetgen app placement intent to the generic placement intent
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/generic-placement-intents/fw-placement-intent/app-intents
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/generic-placement-intents/fw-placement-intent/app-intents
metadata:
name: packetgen-placement-intent
spec:
@@ -210,7 +242,7 @@ spec:
#add the firewall app placement intent to the generic placement intent
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/generic-placement-intents/fw-placement-intent/app-intents
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/generic-placement-intents/fw-placement-intent/app-intents
metadata:
name: firewall-placement-intent
spec:
@@ -224,7 +256,7 @@ spec:
#add the sink app placement intent to the generic placement intent
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/generic-placement-intents/fw-placement-intent/app-intents
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/generic-placement-intents/fw-placement-intent/app-intents
metadata:
name: sink-placement-intent
spec:
@@ -235,20 +267,20 @@ spec:
cluster-label-name: LabelA
---
-#creating cluster provider
+#creating network intents
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent
metadata :
- name: vfw_ovnaction_intent
+ name: vfw_ovnaction_intent
---
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents
metadata :
- name: packetgen_workload_intent
+ name: packetgen_workload_intent
spec:
application-name: packetgen
workload-resource: r1-packetgen
@@ -258,9 +290,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents
metadata :
- name: firewall_workload_intent
+ name: firewall_workload_intent
spec:
application-name: firewall
workload-resource: r1-firewall
@@ -270,9 +302,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents
metadata :
- name: sink_workload_intent
+ name: sink_workload_intent
spec:
application-name: sink
workload-resource: r1-sink
@@ -282,9 +314,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/packetgen_workload_intent/interfaces
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents/packetgen_workload_intent/interfaces
metadata :
- name: packetgen_unprotected_if
+ name: packetgen_unprotected_if
spec:
interface: eth1
name: unprotected-private-net
@@ -295,9 +327,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/packetgen_workload_intent/interfaces
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents/packetgen_workload_intent/interfaces
metadata :
- name: packetgen_emco_if
+ name: packetgen_emco_if
spec:
interface: eth2
name: emco-private-net
@@ -308,9 +340,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
metadata :
- name: firewall_emco_if
+ name: firewall_emco_if
spec:
interface: eth3
name: emco-private-net
@@ -321,9 +353,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
metadata :
- name: firewall_unprotected_if
+ name: firewall_unprotected_if
spec:
interface: eth1
name: unprotected-private-net
@@ -334,9 +366,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
metadata :
- name: firewall_protected_if
+ name: firewall_protected_if
spec:
interface: eth2
name: protected-private-net
@@ -347,9 +379,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/sink_workload_intent/interfaces
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents/sink_workload_intent/interfaces
metadata :
- name: sink_protected_if
+ name: sink_protected_if
spec:
interface: eth1
name: protected-private-net
@@ -360,9 +392,9 @@ spec:
#
version: emco/v2
resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/sink_workload_intent/interfaces
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/network-controller-intent/vfw_ovnaction_intent/workload-intents/sink_workload_intent/interfaces
metadata :
- name: sink_emco_if
+ name: sink_emco_if
spec:
interface: eth2
name: emco-private-net
@@ -370,39 +402,6 @@ spec:
ipAddress: 10.10.20.4
---
-#create deployment intent group
-version: emco/v2
-resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups
-metadata :
- name: vfw_deployment_intent_group
-spec:
- profile: vfw_composite-profile
- version: r1
- override-values:
- - app-name: packetgen
- values:
- ".Values.service.ports.nodePort": '30888'
- - app-name: firewall
- values:
- ".Values.global.dcaeCollectorIp": 1.2.3.4
- ".Values.global.dcaeCollectorPort": '8888'
- - app-name: sink
- values:
- ".Values.service.ports.nodePort": '30677'
-
----
-version: emco/v2
-resourceContext:
- anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/intents
-metadata :
- name: fw-deployment-intent
-spec:
- intent:
- genericPlacementIntent: fw-placement-intent
- ovnaction: vfw_ovnaction_intent
-
----
version: emco/v2
resourceContext:
anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/approve