summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajamohan Raj <rajamohan.raj@intel.com>2020-04-15 18:45:47 +0000
committerRajamohan Raj <rajamohan.raj@intel.com>2020-04-17 23:33:04 +0000
commit6e0b4df46f51f9793f2d88626234edaaf9992403 (patch)
tree1c91022afe63ee3643ff5a1246a28236e5d33c32
parent1c3a22e3de0dd24b4161ae8b34794627620a208b (diff)
Added intentResolver
IntentResolver shall collect the clusterdetails for each of the app where it needs to be deployed. This shall be called by the instantiation code. Issue-ID: MULTICLOUD-1041 Signed-off-by: Rajamohan Raj <rajamohan.raj@intel.com> Change-Id: I7d29901e46a5349ef502786c187c1c88bea61a12
-rwxr-xr-xkud/tests/plugin_collection_v2.sh11
-rw-r--r--src/orchestrator/api/add_intents_handler.go1
-rw-r--r--src/orchestrator/api/composite_profilehandler_test.go2
-rw-r--r--src/orchestrator/api/projecthandler_test.go4
-rw-r--r--src/orchestrator/pkg/gpic/gpic.go120
-rw-r--r--src/orchestrator/pkg/infra/contextdb/mock.go2
-rw-r--r--src/orchestrator/pkg/module/add_intents.go5
-rw-r--r--src/orchestrator/pkg/module/app.go1
-rw-r--r--src/orchestrator/pkg/module/app_intent.go33
-rw-r--r--src/orchestrator/pkg/module/app_intent_test.go23
-rw-r--r--src/orchestrator/pkg/module/instantiation.go50
11 files changed, 196 insertions, 56 deletions
diff --git a/kud/tests/plugin_collection_v2.sh b/kud/tests/plugin_collection_v2.sh
index 3351d8fc..09dec5c4 100755
--- a/kud/tests/plugin_collection_v2.sh
+++ b/kud/tests/plugin_collection_v2.sh
@@ -42,7 +42,7 @@ project_description="test_project_description"
userData1="user1"
userData2="user2"
-composite_app_name="test_composite_app"
+composite_app_name="test_composite_app_collection"
composite_app_description="test_project_description"
composite_app_version="test_composite_app_version"
app1_helm_path="$CSAR_DIR/$csar_id/collectd.tar.gz"
@@ -58,7 +58,8 @@ app2_desc="prometheus_desc"
main_composite_profile_name="main_composite_profile"
sub_composite_profile_name1="test_composite_profile1"
sub_composite_profile_name2="test_composite_profile2"
-composite_profile_description="test_composite_profile_description"
+main_composite_profile_description="main_composite_profile_description"
+sub_composite_profile_description="sub_composite_profile_description"
genericPlacementIntentName="test_gen_placement_intent1"
genericPlacementIntentDesc="test_gen_placement_intent_desc"
@@ -175,7 +176,7 @@ payload="$(cat <<EOF
{
"metadata":{
"name":"${main_composite_profile_name}",
- "description":"${composite_profile_description}",
+ "description":"${main_composite_profile_description}",
"userData1":"${userData1}",
"userData2":"${userData2}"
}
@@ -192,7 +193,7 @@ payload="$(cat <<EOF
{
"metadata":{
"name":"${sub_composite_profile_name1}",
- "description":"${composite_profile_description}",
+ "description":"${sub_composite_profile_description}",
"userData1":"${userData1}",
"userData2":"${userData2}"
},
@@ -212,7 +213,7 @@ payload="$(cat <<EOF
{
"metadata":{
"name":"${sub_composite_profile_name2}",
- "description":"${composite_profile_description}",
+ "description":"${sub_composite_profile_description}",
"userData1":"${userData1}",
"userData2":"${userData2}"
},
diff --git a/src/orchestrator/api/add_intents_handler.go b/src/orchestrator/api/add_intents_handler.go
index fbf9007d..ac8b400d 100644
--- a/src/orchestrator/api/add_intents_handler.go
+++ b/src/orchestrator/api/add_intents_handler.go
@@ -94,7 +94,6 @@ func (h intentHandler) getIntentByNameHandler(w http.ResponseWriter, r *http.Req
return
}
-
mapOfIntents, err := h.client.GetIntentByName(iN, p, ca, v, di)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
diff --git a/src/orchestrator/api/composite_profilehandler_test.go b/src/orchestrator/api/composite_profilehandler_test.go
index 42b9b3a1..ec3ec24b 100644
--- a/src/orchestrator/api/composite_profilehandler_test.go
+++ b/src/orchestrator/api/composite_profilehandler_test.go
@@ -105,7 +105,7 @@ func Test_compositeProfileHandler_createHandler(t *testing.T) {
cProfClient: &mockCompositeProfileManager{
//Items that will be returned by the mocked Client
Items: []moduleLib.CompositeProfile{
- moduleLib.CompositeProfile{
+ {
Metadata: moduleLib.CompositeProfileMetadata{
Name: "testCompositeProfile",
Description: "Test CompositeProfile used for unit testing",
diff --git a/src/orchestrator/api/projecthandler_test.go b/src/orchestrator/api/projecthandler_test.go
index 5e820aa2..0212e57a 100644
--- a/src/orchestrator/api/projecthandler_test.go
+++ b/src/orchestrator/api/projecthandler_test.go
@@ -95,7 +95,7 @@ func TestProjectCreateHandler(t *testing.T) {
projectClient: &mockProjectManager{
//Items that will be returned by the mocked Client
Items: []moduleLib.Project{
- moduleLib.Project{
+ {
MetaData: moduleLib.ProjectMetaData{
Name: "testProject",
Description: "Test Project used for unit testing",
@@ -163,7 +163,7 @@ func TestProjectGetHandler(t *testing.T) {
name: "testProject",
projectClient: &mockProjectManager{
Items: []moduleLib.Project{
- moduleLib.Project{
+ {
MetaData: moduleLib.ProjectMetaData{
Name: "testProject",
Description: "Test Project used for unit testing",
diff --git a/src/orchestrator/pkg/gpic/gpic.go b/src/orchestrator/pkg/gpic/gpic.go
new file mode 100644
index 00000000..f02e5352
--- /dev/null
+++ b/src/orchestrator/pkg/gpic/gpic.go
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package gpic
+
+/*
+ gpic stands for GenericPlacementIntent Controller.
+ This file pertains to the implementation and handling of generic placement intents
+*/
+
+import (
+ "log"
+ ncmmodule "github.com/onap/multicloud-k8s/src/ncm/pkg/module"
+ pkgerrors "github.com/pkg/errors"
+)
+
+// Clusters has 1 field - a list of ClusterNames
+type Clusters struct {
+ ClustersWithName []ClusterWithName
+}
+
+// ClusterWithName has two fields - ProviderName and ClusterName
+type ClusterWithName struct {
+ ProviderName string
+ ClusterName string
+}
+
+// ClusterWithLabel has two fields - ProviderName and ClusterLabel
+type ClusterWithLabel struct {
+ ProviderName string
+ ClusterLabel string
+}
+
+// IntentStruc consists of AllOfArray and AnyOfArray
+type IntentStruc struct {
+ AllOfArray []AllOf `json:"allOf,omitempty"`
+ AnyOfArray []AnyOf `json:"anyOf,omitempty"`
+}
+
+// AllOf consists if ProviderName, ClusterName, ClusterLabelName and AnyOfArray. Any of them can be empty
+type AllOf struct {
+ ProviderName string `json:"provider-name,omitempty"`
+ ClusterName string `json:"cluster-name,omitempty"`
+ ClusterLabelName string `json:"cluster-label-name,omitempty"`
+ AnyOfArray []AnyOf `json:"anyOf,omitempty"`
+}
+
+// AnyOf consists of Array of ProviderName & ClusterLabelNames
+type AnyOf struct {
+ ProviderName string `json:"provider-name,omitempty"`
+ ClusterName string `json:"cluster-name,omitempty"`
+ ClusterLabelName string `json:"cluster-label-name,omitempty"`
+}
+
+// intentResolverHelper helps to populate the cluster lists
+func intentResolverHelper(pn, cn, cln string, clustersWithName []ClusterWithName) ([]ClusterWithName, error) {
+ if cln == "" && cn != "" {
+ eachClusterWithName := ClusterWithName{pn, cn}
+ clustersWithName = append(clustersWithName, eachClusterWithName)
+ log.Printf("Added Cluster: %s ", cn)
+ }
+ if cn == "" && cln != "" {
+ //Finding cluster names for the clusterlabel
+ clusterNamesList, err := ncmmodule.NewClusterClient().GetClustersWithLabel(pn, cln)
+ if err != nil {
+ return []ClusterWithName{}, pkgerrors.Wrap(err, "Error getting clusterLabels")
+ }
+ // Populate the clustersWithName array with the clusternames found above
+ for _, eachClusterName := range clusterNamesList {
+ eachClusterWithPN := ClusterWithName{pn, eachClusterName}
+ clustersWithName = append(clustersWithName, eachClusterWithPN)
+ log.Printf("Added Cluster: %s ", cln)
+ }
+ }
+ return clustersWithName, nil
+}
+
+// IntentResolver shall help to resolve the given intent into 2 lists of clusters where the app need to be deployed.
+func IntentResolver(intent IntentStruc) (Clusters, error) {
+ var clustersWithName []ClusterWithName
+ var err error
+
+ for _, eachAllOf := range intent.AllOfArray {
+ clustersWithName, err = intentResolverHelper(eachAllOf.ProviderName, eachAllOf.ClusterName, eachAllOf.ClusterLabelName, clustersWithName)
+ if err!=nil {
+ return Clusters{}, pkgerrors.Wrap(err, "intentResolverHelper error")
+ }
+ if len(eachAllOf.AnyOfArray) > 0 {
+ for _, eachAnyOf := range eachAllOf.AnyOfArray {
+ clustersWithName, err = intentResolverHelper(eachAnyOf.ProviderName, eachAnyOf.ClusterName, eachAnyOf.ClusterLabelName, clustersWithName)
+ if err!=nil {
+ return Clusters{}, pkgerrors.Wrap(err, "intentResolverHelper error")
+ }
+ }
+ }
+ }
+ if len(intent.AnyOfArray) > 0 {
+ for _, eachAnyOf := range intent.AnyOfArray {
+ clustersWithName, err = intentResolverHelper(eachAnyOf.ProviderName, eachAnyOf.ClusterName, eachAnyOf.ClusterLabelName, clustersWithName)
+ if err!=nil {
+ return Clusters{}, pkgerrors.Wrap(err, "intentResolverHelper error")
+ }
+ }
+ }
+ clusters := Clusters{clustersWithName}
+ return clusters, nil
+}
diff --git a/src/orchestrator/pkg/infra/contextdb/mock.go b/src/orchestrator/pkg/infra/contextdb/mock.go
index fc0f8ff7..9aaed750 100644
--- a/src/orchestrator/pkg/infra/contextdb/mock.go
+++ b/src/orchestrator/pkg/infra/contextdb/mock.go
@@ -47,7 +47,7 @@ func (c *MockEtcd) Delete(key string) error {
func (c *MockEtcd) GetAllKeys(path string) ([]string, error) {
var keys []string
- for k, _ := range c.Items {
+ for k := range c.Items {
keys = append(keys, string(k))
}
return keys, nil
diff --git a/src/orchestrator/pkg/module/add_intents.go b/src/orchestrator/pkg/module/add_intents.go
index a4d677b7..89bf255f 100644
--- a/src/orchestrator/pkg/module/add_intents.go
+++ b/src/orchestrator/pkg/module/add_intents.go
@@ -49,13 +49,11 @@ type IntentSpecData struct {
Intent map[string]string `json:"intent"`
}
-
// ListOfIntents is a list of intents
type ListOfIntents struct {
ListOfIntents []map[string]string `json:"intent"`
}
-
// IntentManager is an interface which exposes the IntentManager functionality
type IntentManager interface {
AddIntent(a Intent, p string, ca string, v string, di string) (Intent, error)
@@ -175,7 +173,6 @@ func (c *IntentClient) GetIntent(i string, p string, ca string, v string, di str
return Intent{}, pkgerrors.New("Error getting Intent")
}
-
/*
GetIntentByName takes in IntentName, projectName, CompositeAppName, CompositeAppVersion
and deploymentIntentGroupName returns the list of intents under the IntentName.
@@ -200,7 +197,6 @@ func (c IntentClient) GetIntentByName(i string, p string, ca string, v string, d
return a.Spec, nil
}
-
/*
GetAllIntents takes in projectName, CompositeAppName, CompositeAppVersion,
DeploymentIntentName . It returns ListOfIntents.
@@ -236,7 +232,6 @@ func (c IntentClient) GetAllIntents(p string, ca string, v string, di string) (L
return ListOfIntents{}, err
}
-
// DeleteIntent deletes a given intent tied to project, composite app and deployment intent group
func (c IntentClient) DeleteIntent(i string, p string, ca string, v string, di string) error {
k := IntentKey{
diff --git a/src/orchestrator/pkg/module/app.go b/src/orchestrator/pkg/module/app.go
index 40659de8..1e1a5974 100644
--- a/src/orchestrator/pkg/module/app.go
+++ b/src/orchestrator/pkg/module/app.go
@@ -38,7 +38,6 @@ type AppMetaData struct {
}
//AppContent contains fileContent
-// TODO : This should have been []byte
type AppContent struct {
FileContent string
}
diff --git a/src/orchestrator/pkg/module/app_intent.go b/src/orchestrator/pkg/module/app_intent.go
index 5f4acb4d..9da252e5 100644
--- a/src/orchestrator/pkg/module/app_intent.go
+++ b/src/orchestrator/pkg/module/app_intent.go
@@ -25,8 +25,8 @@ import (
"encoding/json"
"reflect"
+ gpic "github.com/onap/multicloud-k8s/src/orchestrator/pkg/gpic"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
-
pkgerrors "github.com/pkg/errors"
)
@@ -44,31 +44,10 @@ type MetaData struct {
UserData2 string `json:"userData2"`
}
-// AllOf consists of AnyOfArray and ClusterNames array
-type AllOf struct {
- ProviderName string `json:"provider-name,omitempty"`
- ClusterName string `json:"cluster-name,omitempty"`
- ClusterLabelName string `json:"cluster-label-name,omitempty"`
- AnyOfArray []AnyOf `json:"anyOf,omitempty"`
-}
-
-// AnyOf consists of Array of ProviderName & ClusterLabelNames
-type AnyOf struct {
- ProviderName string `json:"provider-name,omitempty"`
- ClusterName string `json:"cluster-name,omitempty"`
- ClusterLabelName string `json:"cluster-label-name,omitempty"`
-}
-
-// IntentStruc consists of AllOfArray and AnyOfArray
-type IntentStruc struct {
- AllOfArray []AllOf `json:"allOf,omitempty"`
- AnyOfArray []AnyOf `json:"anyOf,omitempty"`
-}
-
// SpecData consists of appName and intent
type SpecData struct {
- AppName string `json:"app-name"`
- Intent IntentStruc `json:"intent"`
+ AppName string `json:"app-name"`
+ Intent gpic.IntentStruc `json:"intent"`
}
// AppIntentManager is an interface which exposes the
@@ -112,9 +91,9 @@ type ApplicationsAndClusterInfo struct {
// AppClusterInfo is a type linking the app and the clusters
// on which they need to be installed.
type AppClusterInfo struct {
- Name string `json:"name"`
- AllOfArray []AllOf `json:"allOf,omitempty"`
- AnyOfArray []AnyOf `json:"anyOf,omitempty"`
+ Name string `json:"name"`
+ AllOfArray []gpic.AllOf `json:"allOf,omitempty"`
+ AnyOfArray []gpic.AnyOf `json:"anyOf,omitempty"`
}
// We will use json marshalling to convert to string to
diff --git a/src/orchestrator/pkg/module/app_intent_test.go b/src/orchestrator/pkg/module/app_intent_test.go
index 726ce0a3..089f09ff 100644
--- a/src/orchestrator/pkg/module/app_intent_test.go
+++ b/src/orchestrator/pkg/module/app_intent_test.go
@@ -21,6 +21,7 @@ import (
"strings"
"testing"
+ gpic "github.com/onap/multicloud-k8s/src/orchestrator/pkg/gpic"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
)
@@ -47,8 +48,8 @@ func TestCreateAppIntent(t *testing.T) {
},
Spec: SpecData{
AppName: "SampleApp",
- Intent: IntentStruc{
- AllOfArray: []AllOf{
+ Intent: gpic.IntentStruc{
+ AllOfArray: []gpic.AllOf{
{
ProviderName: "aws",
ClusterName: "edge1",
@@ -60,7 +61,7 @@ func TestCreateAppIntent(t *testing.T) {
//ClusterLabelName: "edge2",
},
{
- AnyOfArray: []AnyOf{
+ AnyOfArray: []gpic.AnyOf{
{ProviderName: "aws",
ClusterLabelName: "east-us1"},
{ProviderName: "aws",
@@ -71,7 +72,7 @@ func TestCreateAppIntent(t *testing.T) {
},
},
- AnyOfArray: []AnyOf{},
+ AnyOfArray: []gpic.AnyOf{},
},
},
},
@@ -89,8 +90,8 @@ func TestCreateAppIntent(t *testing.T) {
},
Spec: SpecData{
AppName: "SampleApp",
- Intent: IntentStruc{
- AllOfArray: []AllOf{
+ Intent: gpic.IntentStruc{
+ AllOfArray: []gpic.AllOf{
{
ProviderName: "aws",
ClusterName: "edge1",
@@ -102,7 +103,7 @@ func TestCreateAppIntent(t *testing.T) {
//ClusterLabelName: "edge2",
},
{
- AnyOfArray: []AnyOf{
+ AnyOfArray: []gpic.AnyOf{
{ProviderName: "aws",
ClusterLabelName: "east-us1"},
{ProviderName: "aws",
@@ -112,7 +113,7 @@ func TestCreateAppIntent(t *testing.T) {
},
},
},
- AnyOfArray: []AnyOf{},
+ AnyOfArray: []gpic.AnyOf{},
},
},
},
@@ -202,8 +203,8 @@ func TestGetAppIntent(t *testing.T) {
},
Spec: SpecData{
AppName: "SampleApp",
- Intent: IntentStruc{
- AllOfArray: []AllOf{
+ Intent: gpic.IntentStruc{
+ AllOfArray: []gpic.AllOf{
{
ProviderName: "aws",
ClusterName: "edge1",
@@ -213,7 +214,7 @@ func TestGetAppIntent(t *testing.T) {
ClusterName: "edge2",
},
{
- AnyOfArray: []AnyOf{
+ AnyOfArray: []gpic.AnyOf{
{ProviderName: "aws",
ClusterLabelName: "east-us1"},
{ProviderName: "aws",
diff --git a/src/orchestrator/pkg/module/instantiation.go b/src/orchestrator/pkg/module/instantiation.go
index 5fabe81e..56021547 100644
--- a/src/orchestrator/pkg/module/instantiation.go
+++ b/src/orchestrator/pkg/module/instantiation.go
@@ -18,17 +18,22 @@ package module
import (
"fmt"
- "github.com/onap/multicloud-k8s/src/orchestrator/utils/helm"
- pkgerrors "github.com/pkg/errors"
+ gpic "github.com/onap/multicloud-k8s/src/orchestrator/pkg/gpic"
"encoding/base64"
+
+ "github.com/onap/multicloud-k8s/src/orchestrator/utils/helm"
+ pkgerrors "github.com/pkg/errors"
"log"
)
// ManifestFileName is the name given to the manifest file in the profile package
const ManifestFileName = "manifest.yaml"
+// GenericPlacementIntentName denotes the generic placement intent name
+const GenericPlacementIntentName = "generic-placement-intent"
+
// InstantiationClient implements the InstantiationManager
type InstantiationClient struct {
storeName string
@@ -64,6 +69,30 @@ func getOverrideValuesByAppName(ov []OverrideValues, a string) map[string]string
return map[string]string{}
}
+/*
+FindGenericPlacementIntent takes in projectName, CompositeAppName, CompositeAppVersion, DeploymentIntentName
+and returns the name of the genericPlacementIntentName. Returns empty value if string not found.
+*/
+func FindGenericPlacementIntent(p, ca, v, di string) (string, error) {
+ var gi string
+ var found bool
+ iList, err := NewIntentClient().GetAllIntents(p, ca, v, di)
+ if err != nil {
+ return gi, err
+ }
+ for _, eachMap := range iList.ListOfIntents {
+ if gi, found := eachMap[GenericPlacementIntentName]; found {
+ log.Printf("::Name of the generic-placement-intent:: %s", gi)
+ return gi, err
+ }
+ }
+ if found == false {
+ fmt.Println("generic-placement-intent not found !")
+ }
+ return gi, pkgerrors.New("Generic-placement-intent not found")
+
+}
+
// GetSortedTemplateForApp returns the sorted templates.
//It takes in arguments - appName, project, compositeAppName, releaseName, compositeProfileName, array of override values
func GetSortedTemplateForApp(appName, p, ca, v, rName, cp string, overrideValues []OverrideValues) ([]helm.KubernetesResourceTemplate, error) {
@@ -124,6 +153,12 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
overrideValues := dIGrp.Spec.OverrideValuesObj
cp := dIGrp.Spec.Profile
+ gIntent, err := FindGenericPlacementIntent(p, ca, v, di)
+ if err != nil {
+ return err
+ }
+ log.Printf("The name of the GenPlacIntent:: %s", gIntent)
+
log.Printf("dIGrp :: %s, releaseName :: %s and cp :: %s \n", dIGrp.MetaData.Name, rName, cp)
allApps, err := NewAppClient().GetApps(p, ca, v)
if err != nil {
@@ -136,6 +171,17 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
}
log.Printf("Resolved all the templates for app :: %s under the compositeApp...", eachApp.Metadata.Name)
log.Printf("sortedTemplates :: %v ", sortedTemplates)
+
+ specData, err := NewAppIntentClient().GetAllIntentsByApp(eachApp.Metadata.Name, p, ca, v, gIntent)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Unable to get the intents for app")
+ }
+ listOfClusters,err := gpic.IntentResolver(specData.Intent)
+ if err!=nil {
+ return pkgerrors.Wrap(err, "Unable to get the intents resolved for app")
+ }
+ log.Printf("::listOfClusters:: %v", listOfClusters)
+
}
log.Printf("Done with instantiation...")
return err