aboutsummaryrefslogtreecommitdiffstats
path: root/src/orchestrator
diff options
context:
space:
mode:
authorEric Multanen <eric.w.multanen@intel.com>2020-07-22 14:11:05 -0700
committerEric Multanen <eric.w.multanen@intel.com>2020-08-03 15:40:09 -0700
commitb2c23afb03b393b05fe38dd7c54b1de3c42deaf3 (patch)
tree5e845ad676a62e4bde17a6c4a846544164b0ad40 /src/orchestrator
parentd6f900721c81a2c03cb1a21a3d2064e9a69fc4b7 (diff)
Add StateInfo structure synced resources
Add a StateInfo structure to the Cluster and Deployment-Intent-Group resources to keep track of the lifecycle state of these resources. Moved the appcontext id that was being kept into this structure as well. Enabled the approve state (and API) for the deployment intent group. Issue-ID: MULTICLOUD-1042 Signed-off-by: Eric Multanen <eric.w.multanen@intel.com> Change-Id: I36602d8a0658d9d6d37b8799f9a372a7d1042496
Diffstat (limited to 'src/orchestrator')
-rw-r--r--src/orchestrator/api/api.go2
-rw-r--r--src/orchestrator/api/instantiation_handler.go17
-rw-r--r--src/orchestrator/go.mod1
-rw-r--r--src/orchestrator/pkg/module/deployment_intent_groups.go44
-rw-r--r--src/orchestrator/pkg/module/instantiation.go111
-rw-r--r--src/orchestrator/pkg/state/state_helper.go29
-rw-r--r--src/orchestrator/pkg/state/types.go42
7 files changed, 207 insertions, 39 deletions
diff --git a/src/orchestrator/api/api.go b/src/orchestrator/api/api.go
index 03afee28..72b444b7 100644
--- a/src/orchestrator/api/api.go
+++ b/src/orchestrator/api/api.go
@@ -189,6 +189,8 @@ func NewRouter(projectClient moduleLib.ProjectManager,
client: instantiationClient,
}
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/approve", instantiationHandler.approveHandler).Methods("POST")
+ router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/terminate", instantiationHandler.terminateHandler).Methods("POST")
router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/instantiate", instantiationHandler.instantiateHandler).Methods("POST")
router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/terminate", instantiationHandler.terminateHandler).Methods("POST")
router.HandleFunc("/projects/{project-name}/composite-apps/{composite-app-name}/{composite-app-version}/deployment-intent-groups/{deployment-intent-group-name}/status", instantiationHandler.statusHandler).Methods("GET")
diff --git a/src/orchestrator/api/instantiation_handler.go b/src/orchestrator/api/instantiation_handler.go
index ce50e5b8..eeac8a00 100644
--- a/src/orchestrator/api/instantiation_handler.go
+++ b/src/orchestrator/api/instantiation_handler.go
@@ -31,6 +31,23 @@ type instantiationHandler struct {
client moduleLib.InstantiationManager
}
+func (h instantiationHandler) approveHandler(w http.ResponseWriter, r *http.Request) {
+
+ vars := mux.Vars(r)
+ p := vars["project-name"]
+ ca := vars["composite-app-name"]
+ v := vars["composite-app-version"]
+ di := vars["deployment-intent-group-name"]
+
+ iErr := h.client.Approve(p, ca, v, di)
+ if iErr != nil {
+ http.Error(w, iErr.Error(), http.StatusInternalServerError)
+ return
+ }
+ w.WriteHeader(http.StatusAccepted)
+
+}
+
func (h instantiationHandler) instantiateHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
diff --git a/src/orchestrator/go.mod b/src/orchestrator/go.mod
index 22e1aba1..f05343cd 100644
--- a/src/orchestrator/go.mod
+++ b/src/orchestrator/go.mod
@@ -16,7 +16,6 @@ require (
github.com/lib/pq v1.6.0 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
- github.com/onap/multicloud-k8s/src/clm v0.0.0-00010101000000-000000000000
github.com/onap/multicloud-k8s/src/monitor v0.0.0-20200630152613-7c20f73e7c5d
github.com/onap/multicloud-k8s/src/ncm v0.0.0-20200515060444-c77850a75eee
github.com/onap/multicloud-k8s/src/rsync v0.0.0-20200630152613-7c20f73e7c5d
diff --git a/src/orchestrator/pkg/module/deployment_intent_groups.go b/src/orchestrator/pkg/module/deployment_intent_groups.go
index 35b03564..d017c1e9 100644
--- a/src/orchestrator/pkg/module/deployment_intent_groups.go
+++ b/src/orchestrator/pkg/module/deployment_intent_groups.go
@@ -20,8 +20,8 @@ import (
"encoding/json"
"reflect"
- appcontext "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/state"
pkgerrors "github.com/pkg/errors"
)
@@ -62,7 +62,7 @@ type OverrideValues struct {
type DeploymentIntentGroupManager interface {
CreateDeploymentIntentGroup(d DeploymentIntentGroup, p string, ca string, v string) (DeploymentIntentGroup, error)
GetDeploymentIntentGroup(di string, p string, ca string, v string) (DeploymentIntentGroup, error)
- GetDeploymentIntentGroupContext(di string, p string, ca string, v string) (appcontext.AppContext, string, error)
+ GetDeploymentIntentGroupState(di string, p string, ca string, v string) (state.StateInfo, error)
DeleteDeploymentIntentGroup(di string, p string, ca string, v string) error
GetAllDeploymentIntentGroups(p string, ca string, v string) ([]DeploymentIntentGroup, error)
}
@@ -89,7 +89,7 @@ func (dk DeploymentIntentGroupKey) String() string {
type DeploymentIntentGroupClient struct {
storeName string
tagMetaData string
- tagContext string
+ tagState string
}
// NewDeploymentIntentGroupClient return an instance of DeploymentIntentGroupClient which implements DeploymentIntentGroupManager
@@ -97,7 +97,7 @@ func NewDeploymentIntentGroupClient() *DeploymentIntentGroupClient {
return &DeploymentIntentGroupClient{
storeName: "orchestrator",
tagMetaData: "deploymentintentgroupmetadata",
- tagContext: "contextid",
+ tagState: "stateInfo",
}
}
@@ -134,6 +134,17 @@ func (c *DeploymentIntentGroupClient) CreateDeploymentIntentGroup(d DeploymentIn
return DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Create DB entry error")
}
+ // Add the stateInfo record
+ stateInfo := state.StateInfo{
+ State: state.StateEnum.Created,
+ ContextId: "",
+ }
+
+ err = db.DBconn.Insert(c.storeName, gkey, nil, c.tagState, stateInfo)
+ if err != nil {
+ return DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Error updating the stateInfo of the DeploymentIntentGroup: "+d.MetaData.Name)
+ }
+
return d, nil
}
@@ -205,8 +216,8 @@ func (c *DeploymentIntentGroupClient) GetAllDeploymentIntentGroups(p string, ca
}
-// GetDeploymentIntentGroupContext returns the AppContent with a given DeploymentIntentname, project, compositeAppName and version of compositeApp
-func (c *DeploymentIntentGroupClient) GetDeploymentIntentGroupContext(di string, p string, ca string, v string) (appcontext.AppContext, string, error) {
+// GetDeploymentIntentGroupState returns the AppContent with a given DeploymentIntentname, project, compositeAppName and version of compositeApp
+func (c *DeploymentIntentGroupClient) GetDeploymentIntentGroupState(di string, p string, ca string, v string) (state.StateInfo, error) {
key := DeploymentIntentGroupKey{
Name: di,
@@ -215,22 +226,21 @@ func (c *DeploymentIntentGroupClient) GetDeploymentIntentGroupContext(di string,
Version: v,
}
- result, err := db.DBconn.Find(c.storeName, key, c.tagContext)
+ result, err := db.DBconn.Find(c.storeName, key, c.tagState)
if err != nil {
- return appcontext.AppContext{}, "", pkgerrors.Wrap(err, "Get DeploymentIntentGroup Context error")
+ return state.StateInfo{}, pkgerrors.Wrap(err, "Get DeploymentIntentGroup StateInfo error")
}
if result != nil {
- ctxVal := string(result[0])
- var cc appcontext.AppContext
- _, err = cc.LoadAppContext(ctxVal)
+ s := state.StateInfo{}
+ err = db.DBconn.Unmarshal(result[0], &s)
if err != nil {
- return appcontext.AppContext{}, "", pkgerrors.Wrap(err, "Error loading DeploymentIntentGroup Appcontext")
+ return state.StateInfo{}, pkgerrors.Wrap(err, "Unmarshalling DeploymentIntentGroup StateInfo")
}
- return cc, ctxVal, nil
+ return s, nil
}
- return appcontext.AppContext{}, "", pkgerrors.New("Error getting DeploymentIntentGroup AppContext")
+ return state.StateInfo{}, pkgerrors.New("Error getting DeploymentIntentGroup StateInfo")
}
// DeleteDeploymentIntentGroup deletes a DeploymentIntentGroup
@@ -241,9 +251,9 @@ func (c *DeploymentIntentGroupClient) DeleteDeploymentIntentGroup(di string, p s
CompositeApp: ca,
Version: v,
}
- _, _, err := c.GetDeploymentIntentGroupContext(di, p, ca, v)
- if err == nil {
- return pkgerrors.New("DeploymentIntentGroup must be terminated before it can be deleted " + di)
+ s, err := c.GetDeploymentIntentGroupState(di, p, ca, v)
+ if err == nil && s.State == state.StateEnum.Instantiated {
+ return pkgerrors.Errorf("DeploymentIntentGroup must be terminated before it can be deleted " + di)
}
err = db.DBconn.Remove(c.storeName, k)
diff --git a/src/orchestrator/pkg/module/instantiation.go b/src/orchestrator/pkg/module/instantiation.go
index f4e75861..9c0c9e31 100644
--- a/src/orchestrator/pkg/module/instantiation.go
+++ b/src/orchestrator/pkg/module/instantiation.go
@@ -25,6 +25,7 @@ import (
gpic "github.com/onap/multicloud-k8s/src/orchestrator/pkg/gpic"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils"
+ "github.com/onap/multicloud-k8s/src/orchestrator/pkg/state"
"github.com/onap/multicloud-k8s/src/orchestrator/utils/helm"
pkgerrors "github.com/pkg/errors"
)
@@ -71,32 +72,67 @@ type InstantiationKey struct {
// InstantiationManager is an interface which exposes the
// InstantiationManager functionalities
type InstantiationManager interface {
- //ApproveInstantiation(p string, ca string, v string, di string) (error)
+ Approve(p string, ca string, v string, di string) error
Instantiate(p string, ca string, v string, di string) error
Status(p string, ca string, v string, di string) (StatusData, error)
Terminate(p string, ca string, v string, di string) error
}
-// InstantiationClientDbInfo consists of storeName and tagContext
+// InstantiationClientDbInfo consists of storeName and tagState
type InstantiationClientDbInfo struct {
- storeName string // name of the mongodb collection to use for Instantiationclient documents
- tagContext string // attribute key name for context object in App Context
+ storeName string // name of the mongodb collection to use for Instantiationclient documents
+ tagState string // attribute key name for context object in App Context
}
// NewInstantiationClient returns an instance of InstantiationClient
func NewInstantiationClient() *InstantiationClient {
return &InstantiationClient{
db: InstantiationClientDbInfo{
- storeName: "orchestrator",
- tagContext: "contextid",
+ storeName: "orchestrator",
+ tagState: "stateInfo",
},
}
}
-// TODO
-//ApproveInstantiation approves an instantiation
-// func (c InstantiationClient) ApproveInstantiation(p string, ca string, v string, di string) (error){
-// }
+//Approve approves an instantiation
+func (c InstantiationClient) Approve(p string, ca string, v string, di string) error {
+ s, err := NewDeploymentIntentGroupClient().GetDeploymentIntentGroupState(di, p, ca, v)
+ if err != nil {
+ return pkgerrors.Wrap(err, "DeploymentIntentGroup has no state info: "+di)
+ }
+ switch s.State {
+ case state.StateEnum.Approved:
+ return nil
+ case state.StateEnum.Terminated:
+ break
+ case state.StateEnum.Created:
+ break
+ case state.StateEnum.Applied:
+ return pkgerrors.Errorf("DeploymentIntentGroup is in an invalid state" + s.State)
+ case state.StateEnum.Instantiated:
+ return pkgerrors.Errorf("DeploymentIntentGroup has already been instantiated" + di)
+ default:
+ return pkgerrors.Errorf("DeploymentIntentGroup is in an unknown state" + s.State)
+ }
+
+ key := DeploymentIntentGroupKey{
+ Name: di,
+ Project: p,
+ CompositeApp: ca,
+ Version: v,
+ }
+ stateInfo := state.StateInfo{
+ State: state.StateEnum.Approved,
+ ContextId: "",
+ }
+
+ err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, stateInfo)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error updating the stateInfo of the DeploymentIntentGroup: "+di)
+ }
+
+ return nil
+}
func getOverrideValuesByAppName(ov []OverrideValues, a string) map[string]string {
for _, eachOverrideVal := range ov {
@@ -189,9 +225,23 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
return pkgerrors.Wrap(err, "Not finding the deploymentIntentGroup")
}
- _, _, err = NewDeploymentIntentGroupClient().GetDeploymentIntentGroupContext(di, p, ca, v)
- if err == nil {
- return pkgerrors.Errorf("DeploymentIntentGroup has already been instantiated: " + di)
+ s, err := NewDeploymentIntentGroupClient().GetDeploymentIntentGroupState(di, p, ca, v)
+ if err != nil {
+ return pkgerrors.Errorf("Error retrieving DeploymentIntentGroup stateInfo: " + di)
+ }
+ switch s.State {
+ case state.StateEnum.Approved:
+ break
+ case state.StateEnum.Terminated:
+ break // TODO - ideally, should check that all resources have completed being terminated
+ case state.StateEnum.Created:
+ return pkgerrors.Errorf("DeploymentIntentGroup must be Approved before instantiating" + di)
+ case state.StateEnum.Applied:
+ return pkgerrors.Errorf("DeploymentIntentGroup is in an invalid state" + di)
+ case state.StateEnum.Instantiated:
+ return pkgerrors.Errorf("DeploymentIntentGroup has already been instantiated" + di)
+ default:
+ return pkgerrors.Errorf("DeploymentIntentGroup is in an unknown state" + s.State)
}
rName := dIGrp.Spec.Version //rName is releaseName
@@ -292,8 +342,11 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
CompositeApp: ca,
Version: v,
}
-
- err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagContext, ctxval)
+ stateInfo := state.StateInfo{
+ State: state.StateEnum.Instantiated,
+ ContextId: ctxval.(string),
+ }
+ err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, stateInfo)
if err != nil {
cleanuperr := context.DeleteCompositeApp()
if cleanuperr != nil {
@@ -348,11 +401,16 @@ the deployment, which is made available in the appcontext.
*/
func (c InstantiationClient) Status(p string, ca string, v string, di string) (StatusData, error) {
- ac, _, err := NewDeploymentIntentGroupClient().GetDeploymentIntentGroupContext(di, p, ca, v)
+ s, err := NewDeploymentIntentGroupClient().GetDeploymentIntentGroupState(di, p, ca, v)
if err != nil {
return StatusData{}, pkgerrors.Wrap(err, "deploymentIntentGroup not found: "+di)
}
+ ac, err := state.GetAppContextFromStateInfo(s)
+ if err != nil {
+ return StatusData{}, pkgerrors.Wrap(err, "AppContext for deploymentIntentGroup not found: "+di)
+ }
+
// Get all apps in this composite app
allApps, err := NewAppClient().GetApps(p, ca, v)
if err != nil {
@@ -409,12 +467,19 @@ DeploymentIntentName and calls rsync to terminate.
*/
func (c InstantiationClient) Terminate(p string, ca string, v string, di string) error {
- ac, ctxval, err := NewDeploymentIntentGroupClient().GetDeploymentIntentGroupContext(di, p, ca, v)
+ s, err := NewDeploymentIntentGroupClient().GetDeploymentIntentGroupState(di, p, ca, v)
+ if err != nil {
+ return pkgerrors.Wrap(err, "DeploymentIntentGroup has no state info: "+di)
+ } else if s.State != state.StateEnum.Instantiated {
+ return pkgerrors.Errorf("DeploymentIntentGroup is not instantiated" + di)
+ }
+
+ ac, err := state.GetAppContextFromStateInfo(s)
if err != nil {
- return pkgerrors.Wrap(err, "DeploymentIntentGroup has no app context: "+di)
+ return pkgerrors.Wrap(err, "AppContext for deploymentIntentGroup not found: "+di)
}
- err = callRsyncUninstall(ctxval)
+ err = callRsyncUninstall(s.ContextId)
if err != nil {
return err
}
@@ -430,10 +495,14 @@ func (c InstantiationClient) Terminate(p string, ca string, v string, di string)
CompositeApp: ca,
Version: v,
}
+ stateInfo := state.StateInfo{
+ State: state.StateEnum.Terminated,
+ ContextId: "",
+ }
- err = db.DBconn.RemoveTag(c.db.storeName, key, c.db.tagContext)
+ err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, stateInfo)
if err != nil {
- return pkgerrors.Wrap(err, "Error removing the app context tag from DeploymentIntentGroup: "+di)
+ return pkgerrors.Wrap(err, "Error updating the stateInfo of the DeploymentIntentGroup: "+di)
}
return nil
diff --git a/src/orchestrator/pkg/state/state_helper.go b/src/orchestrator/pkg/state/state_helper.go
new file mode 100644
index 00000000..a65cea8d
--- /dev/null
+++ b/src/orchestrator/pkg/state/state_helper.go
@@ -0,0 +1,29 @@
+/*
+ * 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 state
+
+import "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext"
+
+// GetAppContextFromStateInfo loads the appcontext present in the StateInfo input
+func GetAppContextFromStateInfo(s StateInfo) (appcontext.AppContext, error) {
+ var cc appcontext.AppContext
+ _, err := cc.LoadAppContext(s.ContextId)
+ if err != nil {
+ return appcontext.AppContext{}, err
+ }
+ return cc, nil
+}
diff --git a/src/orchestrator/pkg/state/types.go b/src/orchestrator/pkg/state/types.go
new file mode 100644
index 00000000..25fb60d2
--- /dev/null
+++ b/src/orchestrator/pkg/state/types.go
@@ -0,0 +1,42 @@
+/*
+ * 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 state
+
+// StateInfo struct is used to maintain the values for state, contextid, (and other)
+// information about resources which can be instantiated via rsync.
+type StateInfo struct {
+ State StateValue
+ ContextId string
+}
+
+type StateValue = string
+
+type states struct {
+ Created StateValue
+ Approved StateValue
+ Applied StateValue
+ Instantiated StateValue
+ Terminated StateValue
+}
+
+var StateEnum = &states{
+ Created: "Created",
+ Approved: "Approved",
+ Applied: "Applied",
+ Instantiated: "Instantiated",
+ Terminated: "Terminated",
+}