aboutsummaryrefslogtreecommitdiffstats
path: root/src/orchestrator/pkg/module
diff options
context:
space:
mode:
authorEric Multanen <eric.w.multanen@intel.com>2020-08-07 12:04:15 -0700
committerEric Multanen <eric.w.multanen@intel.com>2020-08-11 19:30:59 -0700
commit709d6d17a3b2f8bc9d46034295bd7c5a7fb76107 (patch)
treec028ad152f5cf50e4991ba1388561b2c83f1fca8 /src/orchestrator/pkg/module
parente7061c31f693f0ee60040a67baaa3935c64786cb (diff)
Add appcontext state, status and resource status
Add support in the AppContext for managing an AppContext (composite app level) status value. Also adds support for tracking rsync status at the resource level. A mechanism for tracking history at the controlling resource level (i.e. DeploymentGroupIntnt or Cluster) is added, in part, so that all AppContexts associated can be deleted when the resource is eventually deleted. Issue-ID: MULTICLOUD-1042 Change-Id: I3d0a9a97ea45ca11f9f873104476e4b67521e56a Signed-off-by: Eric Multanen <eric.w.multanen@intel.com>
Diffstat (limited to 'src/orchestrator/pkg/module')
-rw-r--r--src/orchestrator/pkg/module/deployment_intent_groups.go33
-rw-r--r--src/orchestrator/pkg/module/instantiation.go147
-rw-r--r--src/orchestrator/pkg/module/instantiation_appcontext_helper.go12
3 files changed, 130 insertions, 62 deletions
diff --git a/src/orchestrator/pkg/module/deployment_intent_groups.go b/src/orchestrator/pkg/module/deployment_intent_groups.go
index d017c1e9..f9829853 100644
--- a/src/orchestrator/pkg/module/deployment_intent_groups.go
+++ b/src/orchestrator/pkg/module/deployment_intent_groups.go
@@ -19,6 +19,7 @@ package module
import (
"encoding/json"
"reflect"
+ "time"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db"
"github.com/onap/multicloud-k8s/src/orchestrator/pkg/state"
@@ -135,12 +136,15 @@ func (c *DeploymentIntentGroupClient) CreateDeploymentIntentGroup(d DeploymentIn
}
// Add the stateInfo record
- stateInfo := state.StateInfo{
+ s := state.StateInfo{}
+ a := state.ActionEntry{
State: state.StateEnum.Created,
ContextId: "",
+ TimeStamp: time.Now(),
}
+ s.Actions = append(s.Actions, a)
- err = db.DBconn.Insert(c.storeName, gkey, nil, c.tagState, stateInfo)
+ err = db.DBconn.Insert(c.storeName, gkey, nil, c.tagState, s)
if err != nil {
return DeploymentIntentGroup{}, pkgerrors.Wrap(err, "Error updating the stateInfo of the DeploymentIntentGroup: "+d.MetaData.Name)
}
@@ -252,10 +256,33 @@ func (c *DeploymentIntentGroupClient) DeleteDeploymentIntentGroup(di string, p s
Version: v,
}
s, err := c.GetDeploymentIntentGroupState(di, p, ca, v)
- if err == nil && s.State == state.StateEnum.Instantiated {
+ if err != nil {
+ return pkgerrors.Errorf("Error getting stateInfo from DeploymentIntentGroup: " + di)
+ }
+
+ stateVal, err := state.GetCurrentStateFromStateInfo(s)
+ if err != nil {
+ return pkgerrors.Errorf("Error getting current state from DeploymentIntentGroup stateInfo: " + di)
+ }
+
+ if stateVal == state.StateEnum.Instantiated {
return pkgerrors.Errorf("DeploymentIntentGroup must be terminated before it can be deleted " + di)
}
+ // remove the app contexts associated with thie Deployment Intent Group
+ if stateVal == state.StateEnum.Terminated {
+ for _, id := range state.GetContextIdsFromStateInfo(s) {
+ context, err := state.GetAppContextFromId(id)
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error getting appcontext from Deployment Intent Group StateInfo")
+ }
+ err = context.DeleteCompositeApp()
+ if err != nil {
+ return pkgerrors.Wrap(err, "Error deleting appcontext for Deployment Intent Group")
+ }
+ }
+ }
+
err = db.DBconn.Remove(c.storeName, k)
if err != nil {
return pkgerrors.Wrap(err, "Error deleting DeploymentIntentGroup entry")
diff --git a/src/orchestrator/pkg/module/instantiation.go b/src/orchestrator/pkg/module/instantiation.go
index 9c0c9e31..08250d16 100644
--- a/src/orchestrator/pkg/module/instantiation.go
+++ b/src/orchestrator/pkg/module/instantiation.go
@@ -20,6 +20,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
+ "time"
rb "github.com/onap/multicloud-k8s/src/monitor/pkg/apis/k8splugin/v1alpha1"
gpic "github.com/onap/multicloud-k8s/src/orchestrator/pkg/gpic"
@@ -100,7 +101,11 @@ func (c InstantiationClient) Approve(p string, ca string, v string, di string) e
if err != nil {
return pkgerrors.Wrap(err, "DeploymentIntentGroup has no state info: "+di)
}
- switch s.State {
+ stateVal, err := state.GetCurrentStateFromStateInfo(s)
+ if err != nil {
+ return pkgerrors.Errorf("Error getting current state from DeploymentIntentGroup stateInfo: " + di)
+ }
+ switch stateVal {
case state.StateEnum.Approved:
return nil
case state.StateEnum.Terminated:
@@ -108,11 +113,11 @@ func (c InstantiationClient) Approve(p string, ca string, v string, di string) e
case state.StateEnum.Created:
break
case state.StateEnum.Applied:
- return pkgerrors.Errorf("DeploymentIntentGroup is in an invalid state" + s.State)
+ return pkgerrors.Errorf("DeploymentIntentGroup is in an invalid state" + stateVal)
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)
+ return pkgerrors.Errorf("DeploymentIntentGroup is in an unknown state" + stateVal)
}
key := DeploymentIntentGroupKey{
@@ -121,12 +126,14 @@ func (c InstantiationClient) Approve(p string, ca string, v string, di string) e
CompositeApp: ca,
Version: v,
}
- stateInfo := state.StateInfo{
+ a := state.ActionEntry{
State: state.StateEnum.Approved,
ContextId: "",
+ TimeStamp: time.Now(),
}
+ s.Actions = append(s.Actions, a)
- err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, stateInfo)
+ err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, s)
if err != nil {
return pkgerrors.Wrap(err, "Error updating the stateInfo of the DeploymentIntentGroup: "+di)
}
@@ -229,7 +236,11 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
if err != nil {
return pkgerrors.Errorf("Error retrieving DeploymentIntentGroup stateInfo: " + di)
}
- switch s.State {
+ stateVal, err := state.GetCurrentStateFromStateInfo(s)
+ if err != nil {
+ return pkgerrors.Errorf("Error getting current state from DeploymentIntentGroup stateInfo: " + di)
+ }
+ switch stateVal {
case state.StateEnum.Approved:
break
case state.StateEnum.Terminated:
@@ -241,7 +252,7 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
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)
+ return pkgerrors.Errorf("DeploymentIntentGroup is in an unknown state" + stateVal)
}
rName := dIGrp.Spec.Version //rName is releaseName
@@ -286,6 +297,7 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
sortedTemplates, err := GetSortedTemplateForApp(eachApp.Metadata.Name, p, ca, v, rName, cp, overrideValues)
if err != nil {
+ deleteAppContext(context)
return pkgerrors.Wrap(err, "Unable to get the sorted templates for app")
}
@@ -293,16 +305,19 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
resources, err := getResources(sortedTemplates)
if err != nil {
+ deleteAppContext(context)
return pkgerrors.Wrapf(err, "Unable to get the resources for app :: %s", eachApp.Metadata.Name)
}
specData, err := NewAppIntentClient().GetAllIntentsByApp(eachApp.Metadata.Name, p, ca, v, gIntent)
if err != nil {
+ deleteAppContext(context)
return pkgerrors.Wrap(err, "Unable to get the intents for app")
}
// listOfClusters shall have both mandatoryClusters and optionalClusters where the app needs to be installed.
listOfClusters, err := gpic.IntentResolver(specData.Intent)
if err != nil {
+ deleteAppContext(context)
return pkgerrors.Wrap(err, "Unable to get the intents resolved for app")
}
@@ -312,85 +327,100 @@ func (c InstantiationClient) Instantiate(p string, ca string, v string, di strin
// Add an app to the app context
apphandle, err := context.AddApp(compositeHandle, eachApp.Metadata.Name)
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
- log.Info(":: Error Cleaning up AppContext compositeApp failure ::", log.Fields{"Error": cleanuperr.Error(), "AppName": eachApp.Metadata.Name})
- }
+ deleteAppContext(context)
return pkgerrors.Wrap(err, "Error adding App to AppContext")
}
err = addClustersToAppContext(listOfClusters, context, apphandle, resources)
if err != nil {
- log.Info(":: Error while adding cluster and resources to app ::", log.Fields{"Error": err.Error(), "AppName": eachApp.Metadata.Name})
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error while adding cluster and resources to app")
}
err = verifyResources(listOfClusters, context, resources, eachApp.Metadata.Name)
if err != nil {
- log.Info(":: Error while verifying resources in app ::", log.Fields{"Error": err.Error(), "AppName": eachApp.Metadata.Name})
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error while verifying resources in app: ")
}
-
}
- jappOrderInstr, _ := json.Marshal(appOrderInstr)
+ jappOrderInstr, err := json.Marshal(appOrderInstr)
+ if err != nil {
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error marshalling app order instruction")
+ }
appDepInstr.Appdep = appdep
- jappDepInstr, _ := json.Marshal(appDepInstr)
- context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr))
- context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr))
- //END: storing into etcd
-
- // BEGIN:: save the context in the orchestrator db record
- key := DeploymentIntentGroupKey{
- Name: di,
- Project: p,
- CompositeApp: ca,
- Version: v,
+ jappDepInstr, err := json.Marshal(appDepInstr)
+ if err != nil {
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error marshalling app dependency instruction")
}
- stateInfo := state.StateInfo{
- State: state.StateEnum.Instantiated,
- ContextId: ctxval.(string),
+ _, err = context.AddInstruction(compositeHandle, "app", "order", string(jappOrderInstr))
+ if err != nil {
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error adding app dependency instruction")
}
- err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, stateInfo)
+ _, err = context.AddInstruction(compositeHandle, "app", "dependency", string(jappDepInstr))
if err != nil {
- cleanuperr := context.DeleteCompositeApp()
- if cleanuperr != nil {
-
- log.Info(":: Error Cleaning up AppContext while saving context in the db for GPIntent ::", log.Fields{"Error": cleanuperr.Error(), "GPIntent": gIntent, "DeploymentIntentGroup": di, "CompositeApp": ca, "CompositeAppVersion": v, "Project": p})
- }
- return pkgerrors.Wrap(err, "Error adding AppContext to DB")
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error adding app dependency instruction")
}
- // END:: save the context in the orchestrator db record
+ //END: storing into etcd
// BEGIN: scheduler code
pl, mapOfControllers, err := getPrioritizedControllerList(p, ca, v, di)
if err != nil {
- return err
+ return pkgerrors.Wrap(err, "Error adding getting prioritized controller list")
}
log.Info("Priority Based List ", log.Fields{"PlacementControllers::": pl.pPlaCont,
"ActionControllers::": pl.pActCont, "mapOfControllers::": mapOfControllers})
err = callGrpcForControllerList(pl.pPlaCont, mapOfControllers, ctxval)
if err != nil {
- return err
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error calling gRPC for placement controller list")
}
err = deleteExtraClusters(allApps, context)
if err != nil {
- return err
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error deleting extra clusters")
}
err = callGrpcForControllerList(pl.pActCont, mapOfControllers, ctxval)
if err != nil {
- return err
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error calling gRPC for action controller list")
}
-
// END: Scheduler code
// BEGIN : Rsync code
err = callRsyncInstall(ctxval)
if err != nil {
- return err
+ deleteAppContext(context)
+ return pkgerrors.Wrap(err, "Error calling rsync")
}
// END : Rsyc code
- log.Info(":: Done with instantiation... ::", log.Fields{"CompositeAppName": ca})
+ // BEGIN:: save the context in the orchestrator db record
+ key := DeploymentIntentGroupKey{
+ Name: di,
+ Project: p,
+ CompositeApp: ca,
+ Version: v,
+ }
+ a := state.ActionEntry{
+ State: state.StateEnum.Instantiated,
+ ContextId: ctxval.(string),
+ TimeStamp: time.Now(),
+ }
+ s.Actions = append(s.Actions, a)
+ err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, s)
+ if err != nil {
+ log.Warn(":: Error updating DeploymentIntentGroup state in DB ::", log.Fields{"Error": err.Error(), "GPIntent": gIntent, "DeploymentIntentGroup": di, "CompositeApp": ca, "CompositeAppVersion": v, "Project": p, "AppContext": ctxval.(string)})
+ return pkgerrors.Wrap(err, "Error adding DeploymentIntentGroup state to DB")
+ }
+ // END:: save the context in the orchestrator db record
+
+ log.Info(":: Done with instantiation call to rsync... ::", log.Fields{"CompositeAppName": ca})
return err
}
@@ -406,7 +436,8 @@ func (c InstantiationClient) Status(p string, ca string, v string, di string) (S
return StatusData{}, pkgerrors.Wrap(err, "deploymentIntentGroup not found: "+di)
}
- ac, err := state.GetAppContextFromStateInfo(s)
+ currentCtxId := state.GetLastContextIdFromStateInfo(s)
+ ac, err := state.GetAppContextFromId(currentCtxId)
if err != nil {
return StatusData{}, pkgerrors.Wrap(err, "AppContext for deploymentIntentGroup not found: "+di)
}
@@ -430,7 +461,7 @@ func (c InstantiationClient) Status(p string, ca string, v string, di string) (S
}
for _, cluster := range clusters {
- handle, err := ac.GetStatusHandle(app.Metadata.Name, cluster)
+ handle, err := ac.GetClusterStatusHandle(app.Metadata.Name, cluster)
if err != nil {
log.Info(":: No status handle for cluster, app ::",
log.Fields{"Cluster": cluster, "AppName": app.Metadata.Name, "Error": err})
@@ -470,23 +501,21 @@ func (c InstantiationClient) Terminate(p string, ca string, v string, di string)
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)
+ stateVal, err := state.GetCurrentStateFromStateInfo(s)
if err != nil {
- return pkgerrors.Wrap(err, "AppContext for deploymentIntentGroup not found: "+di)
+ return pkgerrors.Errorf("Error getting current state from DeploymentIntentGroup stateInfo: " + di)
}
- err = callRsyncUninstall(s.ContextId)
- if err != nil {
- return err
+ if stateVal != state.StateEnum.Instantiated {
+ return pkgerrors.Errorf("DeploymentIntentGroup is not instantiated" + di)
}
- err = ac.DeleteCompositeApp()
+ currentCtxId := state.GetLastContextIdFromStateInfo(s)
+ err = callRsyncUninstall(currentCtxId)
if err != nil {
- return pkgerrors.Wrap(err, "Error deleting the app context for DeploymentIntentGroup: "+di)
+ return err
}
key := DeploymentIntentGroupKey{
@@ -495,12 +524,14 @@ func (c InstantiationClient) Terminate(p string, ca string, v string, di string)
CompositeApp: ca,
Version: v,
}
- stateInfo := state.StateInfo{
+ a := state.ActionEntry{
State: state.StateEnum.Terminated,
- ContextId: "",
+ ContextId: currentCtxId,
+ TimeStamp: time.Now(),
}
+ s.Actions = append(s.Actions, a)
- err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, stateInfo)
+ err = db.DBconn.Insert(c.db.storeName, key, nil, c.db.tagState, s)
if err != nil {
return pkgerrors.Wrap(err, "Error updating the stateInfo of the DeploymentIntentGroup: "+di)
}
diff --git a/src/orchestrator/pkg/module/instantiation_appcontext_helper.go b/src/orchestrator/pkg/module/instantiation_appcontext_helper.go
index 9ace81b6..692cdf1e 100644
--- a/src/orchestrator/pkg/module/instantiation_appcontext_helper.go
+++ b/src/orchestrator/pkg/module/instantiation_appcontext_helper.go
@@ -71,6 +71,16 @@ func makeAppContextForCompositeApp(p, ca, v, rName string) (contextForCompositeA
}
+// deleteAppContext removes an appcontext
+func deleteAppContext(ct appcontext.AppContext) error {
+ err := ct.DeleteCompositeApp()
+ if err != nil {
+ log.Warn(":: Error deleting AppContext ::", log.Fields{"Error": err})
+ return pkgerrors.Wrapf(err, "Error Deleteing AppContext")
+ }
+ return nil
+}
+
// getResources shall take in the sorted templates and output the resources
// which consists of name(name+kind) and filecontent
func getResources(st []helm.KubernetesResourceTemplate) ([]resource, error) {
@@ -208,7 +218,7 @@ func verifyResources(l gpic.ClusterList, ct appcontext.AppContext, resources []r
for _, res := range resources {
rh, err := ct.GetResourceHandle(appName, cn, res.name)
if err != nil {
- return pkgerrors.Wrapf(err, "Error getting resoure handle for resource :: %s, app:: %s, cluster :: %s, groupName :: %s", appName, res.name, cn, gn)
+ return pkgerrors.Wrapf(err, "Error getting resource handle for resource :: %s, app:: %s, cluster :: %s, groupName :: %s", appName, res.name, cn, gn)
}
log.Info(":: GetResourceHandle ::", log.Fields{"ResourceHandler": rh, "appName": appName, "Cluster": cn, "Resource": res.name})
}