This is an automated email from the ASF dual-hosted git repository. mrutkowski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-wskdeploy.git
The following commit(s) were added to refs/heads/master by this push: new 5d0529d Adding packages support for dependencies in manifest file (#527) 5d0529d is described below commit 5d0529d4b1622d2e239e780eb47298f191996e53 Author: Priti Desai <pde...@us.ibm.com> AuthorDate: Wed Sep 20 19:27:27 2017 -0700 Adding packages support for dependencies in manifest file (#527) --- deployers/manifestreader.go | 9 +- deployers/servicedeployer.go | 1787 ++++++++++---------- parsers/manifest_parser.go | 28 +- parsers/manifest_parser_test.go | 7 +- .../validate-packages-in-manifest/manifest.yaml | 14 +- 5 files changed, 944 insertions(+), 901 deletions(-) diff --git a/deployers/manifestreader.go b/deployers/manifestreader.go index 0a8ec28..bed3230 100644 --- a/deployers/manifestreader.go +++ b/deployers/manifestreader.go @@ -66,7 +66,7 @@ func (reader *ManifestReader) InitRootPackage(manifestParser *parsers.YAMLParser func (deployer *ManifestReader) HandleYaml(sdeployer *ServiceDeployer, manifestParser *parsers.YAMLParser, manifest *parsers.ManifestYAML) error { var err error - deps, err := manifestParser.ComposeDependencies(manifest, deployer.serviceDeployer.ProjectPath, deployer.serviceDeployer.ManifestPath) + deps, err := manifestParser.ComposeDependenciesFromAllPackages(manifest, deployer.serviceDeployer.ProjectPath, deployer.serviceDeployer.ManifestPath) if err != nil { return utils.NewInputYamlFormatError(err.Error()) } @@ -131,7 +131,12 @@ func (deployer *ManifestReader) HandleYaml(sdeployer *ServiceDeployer, manifestP } func (reader *ManifestReader) SetDependencies(deps map[string]utils.DependencyRecord) error { - for depName, dep := range deps { + for name, dep := range deps { + n := strings.Split(name, ":") + depName := n[1] + if (depName == "") { + return nil + } if !dep.IsBinding && !reader.IsUndeploy { if _, exists := reader.serviceDeployer.DependencyMaster[depName]; !exists { // dependency diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go index ac57c2d..c969931 100644 --- a/deployers/servicedeployer.go +++ b/deployers/servicedeployer.go @@ -18,49 +18,49 @@ package deployers import ( - "bufio" - "fmt" - "os" - "path" - "strings" - "sync" - "strconv" - - "github.com/apache/incubator-openwhisk-client-go/whisk" - "github.com/apache/incubator-openwhisk-wskdeploy/parsers" - "github.com/apache/incubator-openwhisk-wskdeploy/utils" - "github.com/apache/incubator-openwhisk-wskdeploy/wski18n" + "bufio" + "fmt" + "os" + "path" + "strconv" + "strings" + "sync" + + "github.com/apache/incubator-openwhisk-client-go/whisk" + "github.com/apache/incubator-openwhisk-wskdeploy/parsers" + "github.com/apache/incubator-openwhisk-wskdeploy/utils" + "github.com/apache/incubator-openwhisk-wskdeploy/wski18n" ) type DeploymentApplication struct { - Packages map[string]*DeploymentPackage - Triggers map[string]*whisk.Trigger - Rules map[string]*whisk.Rule - Apis map[string]*whisk.ApiCreateRequest + Packages map[string]*DeploymentPackage + Triggers map[string]*whisk.Trigger + Rules map[string]*whisk.Rule + Apis map[string]*whisk.ApiCreateRequest } func NewDeploymentApplication() *DeploymentApplication { - var dep DeploymentApplication - dep.Packages = make(map[string]*DeploymentPackage) - dep.Triggers = make(map[string]*whisk.Trigger) - dep.Rules = make(map[string]*whisk.Rule) - dep.Apis = make(map[string]*whisk.ApiCreateRequest) - return &dep + var dep DeploymentApplication + dep.Packages = make(map[string]*DeploymentPackage) + dep.Triggers = make(map[string]*whisk.Trigger) + dep.Rules = make(map[string]*whisk.Rule) + dep.Apis = make(map[string]*whisk.ApiCreateRequest) + return &dep } type DeploymentPackage struct { - Package *whisk.Package - Dependencies map[string]utils.DependencyRecord - Actions map[string]utils.ActionRecord - Sequences map[string]utils.ActionRecord + Package *whisk.Package + Dependencies map[string]utils.DependencyRecord + Actions map[string]utils.ActionRecord + Sequences map[string]utils.ActionRecord } func NewDeploymentPackage() *DeploymentPackage { - var dep DeploymentPackage - dep.Dependencies = make(map[string]utils.DependencyRecord) - dep.Actions = make(map[string]utils.ActionRecord) - dep.Sequences = make(map[string]utils.ActionRecord) - return &dep + var dep DeploymentPackage + dep.Dependencies = make(map[string]utils.DependencyRecord) + dep.Actions = make(map[string]utils.ActionRecord) + dep.Sequences = make(map[string]utils.ActionRecord) + return &dep } // ServiceDeployer defines a prototype service deployer. @@ -70,1031 +70,1036 @@ func NewDeploymentPackage() *DeploymentPackage { // 3. Collect information about the source code files in the working directory // 4. Create a deployment plan to create OpenWhisk service type ServiceDeployer struct { - Deployment *DeploymentApplication - Client *whisk.Client - mt sync.RWMutex - RootPackageName string - IsInteractive bool - IsDefault bool - ManifestPath string - ProjectPath string - DeploymentPath string - // whether to deploy the action under the package - DeployActionInPackage bool - InteractiveChoice bool - ClientConfig *whisk.Config - DependencyMaster map[string]utils.DependencyRecord + Deployment *DeploymentApplication + Client *whisk.Client + mt sync.RWMutex + RootPackageName string + IsInteractive bool + IsDefault bool + ManifestPath string + ProjectPath string + DeploymentPath string + // whether to deploy the action under the package + DeployActionInPackage bool + InteractiveChoice bool + ClientConfig *whisk.Config + DependencyMaster map[string]utils.DependencyRecord } // NewServiceDeployer is a Factory to create a new ServiceDeployer func NewServiceDeployer() *ServiceDeployer { - var dep ServiceDeployer - dep.Deployment = NewDeploymentApplication() - dep.IsInteractive = true - dep.DeployActionInPackage = true - dep.DependencyMaster = make(map[string]utils.DependencyRecord) + var dep ServiceDeployer + dep.Deployment = NewDeploymentApplication() + dep.IsInteractive = true + dep.DeployActionInPackage = true + dep.DependencyMaster = make(map[string]utils.DependencyRecord) - return &dep + return &dep } // Check if the manifest yaml could be parsed by Manifest Parser. // Check if the deployment yaml could be parsed by Manifest Parser. func (deployer *ServiceDeployer) Check() { - ps := parsers.NewYAMLParser() - if utils.FileExists(deployer.DeploymentPath) { - ps.ParseDeployment(deployer.DeploymentPath) - } - ps.ParseManifest(deployer.ManifestPath) - // add more schema check or manifest/deployment consistency checks here if - // necessary + ps := parsers.NewYAMLParser() + if utils.FileExists(deployer.DeploymentPath) { + ps.ParseDeployment(deployer.DeploymentPath) + } + ps.ParseManifest(deployer.ManifestPath) + // add more schema check or manifest/deployment consistency checks here if + // necessary } func (deployer *ServiceDeployer) ConstructDeploymentPlan() error { - var manifestReader = NewManfiestReader(deployer) - manifestReader.IsUndeploy = false - var err error - manifest, manifestParser, err := manifestReader.ParseManifest() - if err != nil { - return err - } - - deployer.RootPackageName = manifest.Package.Packagename - - manifestReader.InitRootPackage(manifestParser, manifest) - - if deployer.IsDefault == true { - fileReader := NewFileSystemReader(deployer) - fileActions, err := fileReader.ReadProjectDirectory(manifest) - if err != nil { - return err - } - fileReader.SetFileActions(fileActions) - } - - // process manifest file - err = manifestReader.HandleYaml(deployer, manifestParser, manifest) - if err != nil { - return err - } - - // process deploymet file - if utils.FileExists(deployer.DeploymentPath) { - var deploymentReader = NewDeploymentReader(deployer) - err = deploymentReader.HandleYaml() - if err != nil { - return err - } - - deploymentReader.BindAssets() - } - - return err + var manifestReader = NewManfiestReader(deployer) + manifestReader.IsUndeploy = false + var err error + manifest, manifestParser, err := manifestReader.ParseManifest() + if err != nil { + return err + } + + deployer.RootPackageName = manifest.Package.Packagename + + manifestReader.InitRootPackage(manifestParser, manifest) + + if deployer.IsDefault == true { + fileReader := NewFileSystemReader(deployer) + fileActions, err := fileReader.ReadProjectDirectory(manifest) + if err != nil { + return err + } + fileReader.SetFileActions(fileActions) + } + + // process manifest file + err = manifestReader.HandleYaml(deployer, manifestParser, manifest) + if err != nil { + return err + } + + // process deploymet file + if utils.FileExists(deployer.DeploymentPath) { + var deploymentReader = NewDeploymentReader(deployer) + err = deploymentReader.HandleYaml() + if err != nil { + return err + } + + deploymentReader.BindAssets() + } + + return err } func (deployer *ServiceDeployer) ConstructUnDeploymentPlan() (*DeploymentApplication, error) { - var manifestReader = NewManfiestReader(deployer) - manifestReader.IsUndeploy = true - var err error - manifest, manifestParser, err := manifestReader.ParseManifest() - if err != nil { - return deployer.Deployment, err - } - - deployer.RootPackageName = manifest.Package.Packagename - manifestReader.InitRootPackage(manifestParser, manifest) - - // process file system - if deployer.IsDefault == true { - fileReader := NewFileSystemReader(deployer) - fileActions, err := fileReader.ReadProjectDirectory(manifest) - if err != nil { - return deployer.Deployment, err - } - - err = fileReader.SetFileActions(fileActions) - if err != nil { - return deployer.Deployment, err - } - - } - - // process manifest file - err = manifestReader.HandleYaml(deployer, manifestParser, manifest) - if err != nil { - return deployer.Deployment, err - } - - // process deployment file - if utils.FileExists(deployer.DeploymentPath) { - var deploymentReader = NewDeploymentReader(deployer) - err = deploymentReader.HandleYaml() - if err != nil { - return deployer.Deployment, err - } - - deploymentReader.BindAssets() - } - - verifiedPlan := deployer.Deployment - - return verifiedPlan, err + var manifestReader = NewManfiestReader(deployer) + manifestReader.IsUndeploy = true + var err error + manifest, manifestParser, err := manifestReader.ParseManifest() + if err != nil { + return deployer.Deployment, err + } + + deployer.RootPackageName = manifest.Package.Packagename + manifestReader.InitRootPackage(manifestParser, manifest) + + // process file system + if deployer.IsDefault == true { + fileReader := NewFileSystemReader(deployer) + fileActions, err := fileReader.ReadProjectDirectory(manifest) + if err != nil { + return deployer.Deployment, err + } + + err = fileReader.SetFileActions(fileActions) + if err != nil { + return deployer.Deployment, err + } + + } + + // process manifest file + err = manifestReader.HandleYaml(deployer, manifestParser, manifest) + if err != nil { + return deployer.Deployment, err + } + + // process deployment file + if utils.FileExists(deployer.DeploymentPath) { + var deploymentReader = NewDeploymentReader(deployer) + err = deploymentReader.HandleYaml() + if err != nil { + return deployer.Deployment, err + } + + deploymentReader.BindAssets() + } + + verifiedPlan := deployer.Deployment + + return verifiedPlan, err } // Use reflect util to deploy everything in this service deployer // TODO(TBD): according to some planning? func (deployer *ServiceDeployer) Deploy() error { - if deployer.IsInteractive == true { - deployer.printDeploymentAssets(deployer.Deployment) - reader := bufio.NewReader(os.Stdin) - fmt.Print("Do you really want to deploy this? (y/N): ") - - text, _ := reader.ReadString('\n') - text = strings.TrimSpace(text) - - if text == "" { - text = "n" - } - - if strings.EqualFold(text, "y") || strings.EqualFold(text, "yes") { - deployer.InteractiveChoice = true - if err := deployer.deployAssets(); err != nil { - errString := wski18n.T("Deployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets.\n") - whisk.Debug(whisk.DbgError, errString) - return err - } - - utils.PrintOpenWhiskOutput(wski18n.T("Deployment completed successfully.\n")) - return nil - - } else { - deployer.InteractiveChoice = false - utils.PrintOpenWhiskOutput(wski18n.T("OK. Cancelling deployment.\n")) - return nil - } - } - - // non-interactive - if err := deployer.deployAssets(); err != nil { - errString := wski18n.T("Deployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets.\n") - whisk.Debug(whisk.DbgError, errString) - return err - } - - utils.PrintOpenWhiskOutput(wski18n.T("Deployment completed successfully.\n")) - return nil + if deployer.IsInteractive == true { + deployer.printDeploymentAssets(deployer.Deployment) + reader := bufio.NewReader(os.Stdin) + fmt.Print("Do you really want to deploy this? (y/N): ") + + text, _ := reader.ReadString('\n') + text = strings.TrimSpace(text) + + if text == "" { + text = "n" + } + + if strings.EqualFold(text, "y") || strings.EqualFold(text, "yes") { + deployer.InteractiveChoice = true + if err := deployer.deployAssets(); err != nil { + errString := wski18n.T("Deployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets.\n") + whisk.Debug(whisk.DbgError, errString) + return err + } + + utils.PrintOpenWhiskOutput(wski18n.T("Deployment completed successfully.\n")) + return nil + + } else { + deployer.InteractiveChoice = false + utils.PrintOpenWhiskOutput(wski18n.T("OK. Cancelling deployment.\n")) + return nil + } + } + + // non-interactive + if err := deployer.deployAssets(); err != nil { + errString := wski18n.T("Deployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets.\n") + whisk.Debug(whisk.DbgError, errString) + return err + } + + utils.PrintOpenWhiskOutput(wski18n.T("Deployment completed successfully.\n")) + return nil } func (deployer *ServiceDeployer) deployAssets() error { - if err := deployer.DeployPackages(); err != nil { - return err - } + if err := deployer.DeployPackages(); err != nil { + return err + } - if err := deployer.DeployDependencies(); err != nil { - return err - } + if err := deployer.DeployDependencies(); err != nil { + return err + } - if err := deployer.DeployActions(); err != nil { - return err - } + if err := deployer.DeployActions(); err != nil { + return err + } - if err := deployer.DeploySequences(); err != nil { - return err - } + if err := deployer.DeploySequences(); err != nil { + return err + } - if err := deployer.DeployTriggers(); err != nil { - return err - } + if err := deployer.DeployTriggers(); err != nil { + return err + } - if err := deployer.DeployRules(); err != nil { - return err - } + if err := deployer.DeployRules(); err != nil { + return err + } - if err := deployer.DeployApis(); err != nil { - return err - } + if err := deployer.DeployApis(); err != nil { + return err + } - - return nil + return nil } func (deployer *ServiceDeployer) DeployDependencies() error { - for _, pack := range deployer.Deployment.Packages { - for depName, depRecord := range pack.Dependencies { - output := wski18n.T("Deploying dependency {{.output}} ...", - map[string]interface{}{"output": depName}) - whisk.Debug(whisk.DbgInfo, output) - - if depRecord.IsBinding { - bindingPackage := new(whisk.BindingPackage) - bindingPackage.Namespace = pack.Package.Namespace - bindingPackage.Name = depName - pub := false - bindingPackage.Publish = &pub - - qName, err := utils.ParseQualifiedName(depRecord.Location, pack.Package.Namespace) - if err != nil { - return err - } - bindingPackage.Binding = whisk.Binding{qName.Namespace, qName.EntityName} - - bindingPackage.Parameters = depRecord.Parameters - bindingPackage.Annotations = depRecord.Annotations - - error := deployer.createBinding(bindingPackage) - if error != nil { - return error - } else { - output := wski18n.T("Dependency {{.output}} has been successfully deployed.\n", - map[string]interface{}{"output": depName}) - whisk.Debug(whisk.DbgInfo, output) - } - - } else { - depServiceDeployer, err := deployer.getDependentDeployer(depName, depRecord) - if err != nil { - return err - } - - err = depServiceDeployer.ConstructDeploymentPlan() - if err != nil { - return err - } - - if err := depServiceDeployer.deployAssets(); err != nil { - errString := wski18n.T("Deployment of dependency {{.depName}} did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets.\n", - map[string]interface{}{"depName": depName}) - utils.PrintOpenWhiskErrorMessage(errString) - return err - } - - // if the RootPackageName is different from depName - // create a binding to the origin package - if (depServiceDeployer.RootPackageName != depName) { - bindingPackage := new(whisk.BindingPackage) - bindingPackage.Namespace = pack.Package.Namespace - bindingPackage.Name = depName - pub := false - bindingPackage.Publish = &pub - - qName, err := utils.ParseQualifiedName(depServiceDeployer.RootPackageName, depServiceDeployer.Deployment.Packages[depServiceDeployer.RootPackageName].Package.Namespace) - if err != nil { - return err - } - - bindingPackage.Binding = whisk.Binding{qName.Namespace, qName.EntityName} - - bindingPackage.Parameters = depRecord.Parameters - bindingPackage.Annotations = depRecord.Annotations - - err = deployer.createBinding(bindingPackage) - if err != nil { - return err - } else { - output := wski18n.T("Dependency {{.output}} has been successfully deployed.\n", - map[string]interface{}{"output": depName}) - whisk.Debug(whisk.DbgInfo, output) - } - } - } - } - } - - return nil + for _, pack := range deployer.Deployment.Packages { + for depName, depRecord := range pack.Dependencies { + output := wski18n.T("Deploying dependency {{.output}} ...", + map[string]interface{}{"output": depName}) + whisk.Debug(whisk.DbgInfo, output) + + if depRecord.IsBinding { + bindingPackage := new(whisk.BindingPackage) + bindingPackage.Namespace = pack.Package.Namespace + bindingPackage.Name = depName + pub := false + bindingPackage.Publish = &pub + + qName, err := utils.ParseQualifiedName(depRecord.Location, pack.Package.Namespace) + if err != nil { + return err + } + bindingPackage.Binding = whisk.Binding{qName.Namespace, qName.EntityName} + + bindingPackage.Parameters = depRecord.Parameters + bindingPackage.Annotations = depRecord.Annotations + + error := deployer.createBinding(bindingPackage) + if error != nil { + return error + } else { + output := wski18n.T("Dependency {{.output}} has been successfully deployed.\n", + map[string]interface{}{"output": depName}) + whisk.Debug(whisk.DbgInfo, output) + } + + } else { + depServiceDeployer, err := deployer.getDependentDeployer(depName, depRecord) + if err != nil { + return err + } + + err = depServiceDeployer.ConstructDeploymentPlan() + if err != nil { + return err + } + + if err := depServiceDeployer.deployAssets(); err != nil { + errString := wski18n.T("Deployment of dependency {{.depName}} did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets.\n", + map[string]interface{}{"depName": depName}) + utils.PrintOpenWhiskErrorMessage(errString) + return err + } + + // if the RootPackageName is different from depName + // create a binding to the origin package + if depServiceDeployer.RootPackageName != depName { + bindingPackage := new(whisk.BindingPackage) + bindingPackage.Namespace = pack.Package.Namespace + bindingPackage.Name = depName + pub := false + bindingPackage.Publish = &pub + + qName, err := utils.ParseQualifiedName(depServiceDeployer.RootPackageName, depServiceDeployer.Deployment.Packages[depServiceDeployer.RootPackageName].Package.Namespace) + if err != nil { + return err + } + + bindingPackage.Binding = whisk.Binding{qName.Namespace, qName.EntityName} + + bindingPackage.Parameters = depRecord.Parameters + bindingPackage.Annotations = depRecord.Annotations + + err = deployer.createBinding(bindingPackage) + if err != nil { + return err + } else { + output := wski18n.T("Dependency {{.output}} has been successfully deployed.\n", + map[string]interface{}{"output": depName}) + whisk.Debug(whisk.DbgInfo, output) + } + } + } + } + } + + return nil } func (deployer *ServiceDeployer) DeployPackages() error { - for _, pack := range deployer.Deployment.Packages { - err := deployer.createPackage(pack.Package) - if err != nil { - return err - } - } - return nil + for _, pack := range deployer.Deployment.Packages { + err := deployer.createPackage(pack.Package) + if err != nil { + return err + } + } + return nil } // Deploy Sequences into OpenWhisk func (deployer *ServiceDeployer) DeploySequences() error { - for _, pack := range deployer.Deployment.Packages { - for _, action := range pack.Sequences { - error := deployer.createAction(pack.Package.Name, action.Action) - if error != nil { - return error - } - } - } - return nil + for _, pack := range deployer.Deployment.Packages { + for _, action := range pack.Sequences { + error := deployer.createAction(pack.Package.Name, action.Action) + if error != nil { + return error + } + } + } + return nil } // Deploy Actions into OpenWhisk func (deployer *ServiceDeployer) DeployActions() error { - for _, pack := range deployer.Deployment.Packages { - for _, action := range pack.Actions { - err := deployer.createAction(pack.Package.Name, action.Action) - if err != nil { - return err - } - } - } - return nil + for _, pack := range deployer.Deployment.Packages { + for _, action := range pack.Actions { + err := deployer.createAction(pack.Package.Name, action.Action) + if err != nil { + return err + } + } + } + return nil } // Deploy Triggers into OpenWhisk func (deployer *ServiceDeployer) DeployTriggers() error { - for _, trigger := range deployer.Deployment.Triggers { - - if feedname, isFeed := utils.IsFeedAction(trigger); isFeed { - error := deployer.createFeedAction(trigger, feedname) - if error != nil { - return error - } - } else { - error := deployer.createTrigger(trigger) - if error != nil { - return error - } - } - - } - return nil + for _, trigger := range deployer.Deployment.Triggers { + + if feedname, isFeed := utils.IsFeedAction(trigger); isFeed { + error := deployer.createFeedAction(trigger, feedname) + if error != nil { + return error + } + } else { + error := deployer.createTrigger(trigger) + if error != nil { + return error + } + } + + } + return nil } // Deploy Rules into OpenWhisk func (deployer *ServiceDeployer) DeployRules() error { - for _, rule := range deployer.Deployment.Rules { - error := deployer.createRule(rule) - if error != nil { - return error - } - } - return nil + for _, rule := range deployer.Deployment.Rules { + error := deployer.createRule(rule) + if error != nil { + return error + } + } + return nil } // Deploy Apis into OpenWhisk func (deployer *ServiceDeployer) DeployApis() error { - for _, api := range deployer.Deployment.Apis { - error := deployer.createApi(api) - if error != nil { - return error - } - } - return nil + for _, api := range deployer.Deployment.Apis { + error := deployer.createApi(api) + if error != nil { + return error + } + } + return nil } func (deployer *ServiceDeployer) createBinding(packa *whisk.BindingPackage) error { - output := wski18n.T("Deploying package binding {{.output}} ...", - map[string]interface{}{"output": packa.Name}) - whisk.Debug(whisk.DbgInfo, output) - _, _, err := deployer.Client.Packages.Insert(packa, true) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error creating package binding with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } else { - output := wski18n.T("Package binding {{.output}} has been successfully deployed.\n", - map[string]interface{}{"output": packa.Name}) - whisk.Debug(whisk.DbgInfo, output) - } - return nil + output := wski18n.T("Deploying package binding {{.output}} ...", + map[string]interface{}{"output": packa.Name}) + whisk.Debug(whisk.DbgInfo, output) + _, _, err := deployer.Client.Packages.Insert(packa, true) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error creating package binding with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } else { + output := wski18n.T("Package binding {{.output}} has been successfully deployed.\n", + map[string]interface{}{"output": packa.Name}) + whisk.Debug(whisk.DbgInfo, output) + } + return nil } func (deployer *ServiceDeployer) createPackage(packa *whisk.Package) error { - output := wski18n.T("Deploying package {{.output}} ...", - map[string]interface{}{"output": packa.Name}) - whisk.Debug(whisk.DbgInfo, output) - _, _, err := deployer.Client.Packages.Insert(packa, true) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error creating package with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } else { - output := wski18n.T("Package {{.output}} has been successfully deployed.\n", - map[string]interface{}{"output": packa.Name}) - whisk.Debug(whisk.DbgInfo, output) - } - return nil + output := wski18n.T("Deploying package {{.output}} ...", + map[string]interface{}{"output": packa.Name}) + whisk.Debug(whisk.DbgInfo, output) + _, _, err := deployer.Client.Packages.Insert(packa, true) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error creating package with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } else { + output := wski18n.T("Package {{.output}} has been successfully deployed.\n", + map[string]interface{}{"output": packa.Name}) + whisk.Debug(whisk.DbgInfo, output) + } + return nil } func (deployer *ServiceDeployer) createTrigger(trigger *whisk.Trigger) error { - output := wski18n.T("Deploying trigger {{.output}} ...", - map[string]interface{}{"output": trigger.Name}) - whisk.Debug(whisk.DbgInfo, output) - _, _, err := deployer.Client.Triggers.Insert(trigger, true) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error creating trigger with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } else { - output := wski18n.T("Trigger {{.output}} has been successfully deployed.\n", - map[string]interface{}{"output": trigger.Name}) - whisk.Debug(whisk.DbgInfo, output) - } - return nil + output := wski18n.T("Deploying trigger {{.output}} ...", + map[string]interface{}{"output": trigger.Name}) + whisk.Debug(whisk.DbgInfo, output) + _, _, err := deployer.Client.Triggers.Insert(trigger, true) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error creating trigger with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } else { + output := wski18n.T("Trigger {{.output}} has been successfully deployed.\n", + map[string]interface{}{"output": trigger.Name}) + whisk.Debug(whisk.DbgInfo, output) + } + return nil } func (deployer *ServiceDeployer) createFeedAction(trigger *whisk.Trigger, feedName string) error { - output := wski18n.T("Deploying trigger feed {{.output}} ...", - map[string]interface{}{"output": trigger.Name}) - whisk.Debug(whisk.DbgInfo, output) - // to hold and modify trigger parameters, not passed by ref? - params := make(map[string]interface{}) - - // check for strings that are JSON - for _, keyVal := range trigger.Parameters { - params[keyVal.Key] = keyVal.Value - } - - params["authKey"] = deployer.ClientConfig.AuthToken - params["lifecycleEvent"] = "CREATE" - params["triggerName"] = "/" + deployer.Client.Namespace + "/" + trigger.Name - - pub := true - t := &whisk.Trigger{ - Name: trigger.Name, - Annotations: trigger.Annotations, - Publish: &pub, - } - - _, _, err := deployer.Client.Triggers.Insert(t, true) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error creating trigger with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } else { - - qName, err := utils.ParseQualifiedName(feedName, deployer.ClientConfig.Namespace) - if err != nil { - return err - } - - namespace := deployer.Client.Namespace - deployer.Client.Namespace = qName.Namespace - _, _, err = deployer.Client.Actions.Invoke(qName.EntityName, params, true, false) - deployer.Client.Namespace = namespace - - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error creating trigger feed with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } - } - output = wski18n.T("Trigger feed {{.output}} has been successfully deployed.\n", - map[string]interface{}{"output": trigger.Name}) - whisk.Debug(whisk.DbgInfo, output) - return nil + output := wski18n.T("Deploying trigger feed {{.output}} ...", + map[string]interface{}{"output": trigger.Name}) + whisk.Debug(whisk.DbgInfo, output) + // to hold and modify trigger parameters, not passed by ref? + params := make(map[string]interface{}) + + // check for strings that are JSON + for _, keyVal := range trigger.Parameters { + params[keyVal.Key] = keyVal.Value + } + + params["authKey"] = deployer.ClientConfig.AuthToken + params["lifecycleEvent"] = "CREATE" + params["triggerName"] = "/" + deployer.Client.Namespace + "/" + trigger.Name + + pub := true + t := &whisk.Trigger{ + Name: trigger.Name, + Annotations: trigger.Annotations, + Publish: &pub, + } + + _, _, err := deployer.Client.Triggers.Insert(t, true) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error creating trigger with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } else { + + qName, err := utils.ParseQualifiedName(feedName, deployer.ClientConfig.Namespace) + if err != nil { + return err + } + + namespace := deployer.Client.Namespace + deployer.Client.Namespace = qName.Namespace + _, _, err = deployer.Client.Actions.Invoke(qName.EntityName, params, true, false) + deployer.Client.Namespace = namespace + + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error creating trigger feed with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } + } + output = wski18n.T("Trigger feed {{.output}} has been successfully deployed.\n", + map[string]interface{}{"output": trigger.Name}) + whisk.Debug(whisk.DbgInfo, output) + return nil } func (deployer *ServiceDeployer) createRule(rule *whisk.Rule) error { - // The rule's trigger should include the namespace with pattern /namespace/trigger - rule.Trigger = deployer.getQualifiedName(rule.Trigger.(string), deployer.ClientConfig.Namespace) - // The rule's action should include the namespace and package - // with pattern /namespace/package/action - // TODO(TBD): please refer https://github.com/openwhisk/openwhisk/issues/1577 - - // if it contains a slash, then the action is qualified by a package name - if strings.Contains(rule.Action.(string), "/") { - rule.Action = deployer.getQualifiedName(rule.Action.(string), deployer.ClientConfig.Namespace) - } else { - // if not, we assume the action is inside the root package - rule.Action = deployer.getQualifiedName(strings.Join([]string{deployer.RootPackageName, rule.Action.(string)}, "/"), deployer.ClientConfig.Namespace) - } - output := wski18n.T("Deploying rule {{.output}} ...", - map[string]interface{}{"output": rule.Name}) - whisk.Debug(whisk.DbgInfo, output) - - _, _, err := deployer.Client.Rules.Insert(rule, true) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error creating rule with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } - - _, _, err = deployer.Client.Rules.SetState(rule.Name, "active") - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error setting the status of rule with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } - output = wski18n.T("Rule {{.output}} has been successfully deployed.\n", - map[string]interface{}{"output": rule.Name}) - whisk.Debug(whisk.DbgInfo, output) - return nil + // The rule's trigger should include the namespace with pattern /namespace/trigger + rule.Trigger = deployer.getQualifiedName(rule.Trigger.(string), deployer.ClientConfig.Namespace) + // The rule's action should include the namespace and package + // with pattern /namespace/package/action + // TODO(TBD): please refer https://github.com/openwhisk/openwhisk/issues/1577 + + // if it contains a slash, then the action is qualified by a package name + if strings.Contains(rule.Action.(string), "/") { + rule.Action = deployer.getQualifiedName(rule.Action.(string), deployer.ClientConfig.Namespace) + } else { + // if not, we assume the action is inside the root package + rule.Action = deployer.getQualifiedName(strings.Join([]string{deployer.RootPackageName, rule.Action.(string)}, "/"), deployer.ClientConfig.Namespace) + } + output := wski18n.T("Deploying rule {{.output}} ...", + map[string]interface{}{"output": rule.Name}) + whisk.Debug(whisk.DbgInfo, output) + + _, _, err := deployer.Client.Rules.Insert(rule, true) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error creating rule with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } + + _, _, err = deployer.Client.Rules.SetState(rule.Name, "active") + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error setting the status of rule with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } + output = wski18n.T("Rule {{.output}} has been successfully deployed.\n", + map[string]interface{}{"output": rule.Name}) + whisk.Debug(whisk.DbgInfo, output) + return nil } // Utility function to call go-whisk framework to make action func (deployer *ServiceDeployer) createAction(pkgname string, action *whisk.Action) error { - // call ActionService through the Client - if deployer.DeployActionInPackage { - // the action will be created under package with pattern 'packagename/actionname' - action.Name = strings.Join([]string{pkgname, action.Name}, "/") - } - output := wski18n.T("Deploying action {{.output}} ...", - map[string]interface{}{"output": action.Name}) - whisk.Debug(whisk.DbgInfo, output) - - _, _, err := deployer.Client.Actions.Insert(action, true) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error creating action with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } else { - output := wski18n.T("Action {{.output}} has been successfully deployed.\n", - map[string]interface{}{"output": action.Name}) - whisk.Debug(whisk.DbgInfo, output) - } - return nil + // call ActionService through the Client + if deployer.DeployActionInPackage { + // the action will be created under package with pattern 'packagename/actionname' + action.Name = strings.Join([]string{pkgname, action.Name}, "/") + } + output := wski18n.T("Deploying action {{.output}} ...", + map[string]interface{}{"output": action.Name}) + whisk.Debug(whisk.DbgInfo, output) + + _, _, err := deployer.Client.Actions.Insert(action, true) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error creating action with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } else { + output := wski18n.T("Action {{.output}} has been successfully deployed.\n", + map[string]interface{}{"output": action.Name}) + whisk.Debug(whisk.DbgInfo, output) + } + return nil } // create api (API Gateway functionality) func (deployer *ServiceDeployer) createApi(api *whisk.ApiCreateRequest) error { - _, _, err := deployer.Client.Apis.Insert(api, nil, true) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error creating api with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } - return nil + _, _, err := deployer.Client.Apis.Insert(api, nil, true) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error creating api with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } + return nil } func (deployer *ServiceDeployer) UnDeploy(verifiedPlan *DeploymentApplication) error { - if deployer.IsInteractive == true { - deployer.printDeploymentAssets(verifiedPlan) - reader := bufio.NewReader(os.Stdin) + if deployer.IsInteractive == true { + deployer.printDeploymentAssets(verifiedPlan) + reader := bufio.NewReader(os.Stdin) - fmt.Print("Do you really want to undeploy this? (y/N): ") + fmt.Print("Do you really want to undeploy this? (y/N): ") - text, _ := reader.ReadString('\n') - text = strings.TrimSpace(text) + text, _ := reader.ReadString('\n') + text = strings.TrimSpace(text) - if text == "" { - text = "n" - } + if text == "" { + text = "n" + } - if strings.EqualFold(text, "y") || strings.EqualFold(text, "yes") { - deployer.InteractiveChoice = true + if strings.EqualFold(text, "y") || strings.EqualFold(text, "yes") { + deployer.InteractiveChoice = true - if err := deployer.unDeployAssets(verifiedPlan); err != nil { - utils.PrintOpenWhiskErrorMessage(wski18n.T("Undeployment did not complete sucessfully.\n")) - return err - } + if err := deployer.unDeployAssets(verifiedPlan); err != nil { + utils.PrintOpenWhiskErrorMessage(wski18n.T("Undeployment did not complete sucessfully.\n")) + return err + } - utils.PrintOpenWhiskOutput(wski18n.T("Deployment removed successfully.\n")) - return nil + utils.PrintOpenWhiskOutput(wski18n.T("Deployment removed successfully.\n")) + return nil - } else { - deployer.InteractiveChoice = false - utils.PrintOpenWhiskOutput(wski18n.T("OK. Canceling undeployment.\n")) - return nil - } - } + } else { + deployer.InteractiveChoice = false + utils.PrintOpenWhiskOutput(wski18n.T("OK. Canceling undeployment.\n")) + return nil + } + } - // non-interactive - if err := deployer.unDeployAssets(verifiedPlan); err != nil { - errString := wski18n.T("Undeployment did not complete sucessfully.\n") - whisk.Debug(whisk.DbgError, errString) - return err - } + // non-interactive + if err := deployer.unDeployAssets(verifiedPlan); err != nil { + errString := wski18n.T("Undeployment did not complete sucessfully.\n") + whisk.Debug(whisk.DbgError, errString) + return err + } - utils.PrintOpenWhiskOutput(wski18n.T("Deployment removed successfully.\n")) - return nil + utils.PrintOpenWhiskOutput(wski18n.T("Deployment removed successfully.\n")) + return nil } func (deployer *ServiceDeployer) unDeployAssets(verifiedPlan *DeploymentApplication) error { - if err := deployer.UnDeployActions(verifiedPlan); err != nil { - return err - } + if err := deployer.UnDeployActions(verifiedPlan); err != nil { + return err + } - if err := deployer.UnDeploySequences(verifiedPlan); err != nil { - return err - } + if err := deployer.UnDeploySequences(verifiedPlan); err != nil { + return err + } - if err := deployer.UnDeployTriggers(verifiedPlan); err != nil { - return err - } + if err := deployer.UnDeployTriggers(verifiedPlan); err != nil { + return err + } - if err := deployer.UnDeployRules(verifiedPlan); err != nil { - return err - } + if err := deployer.UnDeployRules(verifiedPlan); err != nil { + return err + } - if err := deployer.UnDeployPackages(verifiedPlan); err != nil { - return err - } + if err := deployer.UnDeployPackages(verifiedPlan); err != nil { + return err + } - if err := deployer.UnDeployDependencies(); err != nil { - return err - } + if err := deployer.UnDeployDependencies(); err != nil { + return err + } - return nil + return nil } func (deployer *ServiceDeployer) UnDeployDependencies() error { - for _, pack := range deployer.Deployment.Packages { - for depName, depRecord := range pack.Dependencies { - output := wski18n.T("Undeploying dependency {{.depName}} ...", - map[string]interface{}{"depName": depName}) - whisk.Debug(whisk.DbgInfo, output) - - if depRecord.IsBinding { - _, err := deployer.Client.Packages.Delete(depName) - if err != nil { - return err - } - } else { - - depServiceDeployer, err := deployer.getDependentDeployer(depName, depRecord) - if err != nil { - return err - } - - plan, err := depServiceDeployer.ConstructUnDeploymentPlan() - if err != nil { - return err - } - - // delete binding pkg if the origin package name is different - if (depServiceDeployer.RootPackageName != depName) { - _, err := deployer.Client.Packages.Delete(depName) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error deleting binding package with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } - } - - if err := depServiceDeployer.unDeployAssets(plan); err != nil { - errString := wski18n.T("Undeployment of dependency {{.depName}} did not complete sucessfully.\n", - map[string]interface{}{"depName": depName}) - whisk.Debug(whisk.DbgError, errString) - return err - } - } - output = wski18n.T("Dependency {{.depName}} has been successfully undeployed.\n", - map[string]interface{}{"depName": depName}) - whisk.Debug(whisk.DbgInfo, output) - } - } - - return nil + for _, pack := range deployer.Deployment.Packages { + for depName, depRecord := range pack.Dependencies { + output := wski18n.T("Undeploying dependency {{.depName}} ...", + map[string]interface{}{"depName": depName}) + whisk.Debug(whisk.DbgInfo, output) + + if depRecord.IsBinding { + _, err := deployer.Client.Packages.Delete(depName) + if err != nil { + return err + } + } else { + + depServiceDeployer, err := deployer.getDependentDeployer(depName, depRecord) + if err != nil { + return err + } + + plan, err := depServiceDeployer.ConstructUnDeploymentPlan() + if err != nil { + return err + } + + // delete binding pkg if the origin package name is different + if depServiceDeployer.RootPackageName != depName { + if _, _, ok := deployer.Client.Packages.Get(depName); ok == nil { + _, err := deployer.Client.Packages.Delete(depName) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error deleting binding package with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } + } + } + + if err := depServiceDeployer.unDeployAssets(plan); err != nil { + errString := wski18n.T("Undeployment of dependency {{.depName}} did not complete sucessfully.\n", + map[string]interface{}{"depName": depName}) + whisk.Debug(whisk.DbgError, errString) + return err + } + } + output = wski18n.T("Dependency {{.depName}} has been successfully undeployed.\n", + map[string]interface{}{"depName": depName}) + whisk.Debug(whisk.DbgInfo, output) + } + } + + return nil } func (deployer *ServiceDeployer) UnDeployPackages(deployment *DeploymentApplication) error { - for _, pack := range deployment.Packages { - err := deployer.deletePackage(pack.Package) - if err != nil { - return err - } - } - return nil + for _, pack := range deployment.Packages { + err := deployer.deletePackage(pack.Package) + if err != nil { + return err + } + } + return nil } func (deployer *ServiceDeployer) UnDeploySequences(deployment *DeploymentApplication) error { - for _, pack := range deployment.Packages { - for _, action := range pack.Sequences { - err := deployer.deleteAction(pack.Package.Name, action.Action) - if err != nil { - return err - } - } - } - return nil + for _, pack := range deployment.Packages { + for _, action := range pack.Sequences { + err := deployer.deleteAction(pack.Package.Name, action.Action) + if err != nil { + return err + } + } + } + return nil } // DeployActions into OpenWhisk func (deployer *ServiceDeployer) UnDeployActions(deployment *DeploymentApplication) error { - for _, pack := range deployment.Packages { - for _, action := range pack.Actions { - err := deployer.deleteAction(pack.Package.Name, action.Action) - if err != nil { - return err - } - } - } - return nil + for _, pack := range deployment.Packages { + for _, action := range pack.Actions { + err := deployer.deleteAction(pack.Package.Name, action.Action) + if err != nil { + return err + } + } + } + return nil } // Deploy Triggers into OpenWhisk func (deployer *ServiceDeployer) UnDeployTriggers(deployment *DeploymentApplication) error { - for _, trigger := range deployment.Triggers { - if feedname, isFeed := utils.IsFeedAction(trigger); isFeed { - err := deployer.deleteFeedAction(trigger, feedname) - if err != nil { - return err - } - } else { - err := deployer.deleteTrigger(trigger) - if err != nil { - return err - } - } - } - - return nil + for _, trigger := range deployment.Triggers { + if feedname, isFeed := utils.IsFeedAction(trigger); isFeed { + err := deployer.deleteFeedAction(trigger, feedname) + if err != nil { + return err + } + } else { + err := deployer.deleteTrigger(trigger) + if err != nil { + return err + } + } + } + + return nil } // Deploy Rules into OpenWhisk func (deployer *ServiceDeployer) UnDeployRules(deployment *DeploymentApplication) error { - for _, rule := range deployment.Rules { - err := deployer.deleteRule(rule) - if err != nil { - return err - } - } - return nil + for _, rule := range deployment.Rules { + err := deployer.deleteRule(rule) + if err != nil { + return err + } + } + return nil } func (deployer *ServiceDeployer) deletePackage(packa *whisk.Package) error { - output := wski18n.T("Removing package {{.package}} ...", - map[string]interface{}{"package": packa.Name}) - whisk.Debug(whisk.DbgInfo, output) - _, err := deployer.Client.Packages.Delete(packa.Name) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error deleting package with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } - return nil + output := wski18n.T("Removing package {{.package}} ...", + map[string]interface{}{"package": packa.Name}) + whisk.Debug(whisk.DbgInfo, output) + if _, _, ok := deployer.Client.Packages.Get(packa.Name); ok == nil { + _, err := deployer.Client.Packages.Delete(packa.Name) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error deleting package with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } + } + return nil } func (deployer *ServiceDeployer) deleteTrigger(trigger *whisk.Trigger) error { - output := wski18n.T("Removing trigger {{.trigger}} ...", - map[string]interface{}{"trigger": trigger.Name}) - whisk.Debug(whisk.DbgInfo, output) - _, _, err := deployer.Client.Triggers.Delete(trigger.Name) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error deleting trigger with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } else { - output := wski18n.T("Trigger {{.trigger}} has been removed.\n", - map[string]interface{}{"trigger": trigger.Name}) - whisk.Debug(whisk.DbgInfo, output) - } - return nil + output := wski18n.T("Removing trigger {{.trigger}} ...", + map[string]interface{}{"trigger": trigger.Name}) + whisk.Debug(whisk.DbgInfo, output) + _, _, err := deployer.Client.Triggers.Delete(trigger.Name) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error deleting trigger with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } else { + output := wski18n.T("Trigger {{.trigger}} has been removed.\n", + map[string]interface{}{"trigger": trigger.Name}) + whisk.Debug(whisk.DbgInfo, output) + } + return nil } func (deployer *ServiceDeployer) deleteFeedAction(trigger *whisk.Trigger, feedName string) error { - params := make(whisk.KeyValueArr, 0) - params = append(params, whisk.KeyValue{Key: "authKey", Value: deployer.ClientConfig.AuthToken}) - params = append(params, whisk.KeyValue{Key: "lifecycleEvent", Value: "DELETE"}) - params = append(params, whisk.KeyValue{Key: "triggerName", Value: "/" + deployer.Client.Namespace + "/" + trigger.Name}) - - trigger.Parameters = nil - - _, _, err := deployer.Client.Triggers.Delete(trigger.Name) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error deleting trigger with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } else { - parameters := make(map[string]interface{}) - for _, keyVal := range params { - parameters[keyVal.Key] = keyVal.Value - } - - qName, err := utils.ParseQualifiedName(feedName, deployer.ClientConfig.Namespace) - if err != nil { - return err - } - - namespace := deployer.Client.Namespace - deployer.Client.Namespace = qName.Namespace - _, _, err = deployer.Client.Actions.Invoke(qName.EntityName, parameters, true, true) - deployer.Client.Namespace = namespace - - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error deleting trigger feed with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - - } - } - return nil + params := make(whisk.KeyValueArr, 0) + params = append(params, whisk.KeyValue{Key: "authKey", Value: deployer.ClientConfig.AuthToken}) + params = append(params, whisk.KeyValue{Key: "lifecycleEvent", Value: "DELETE"}) + params = append(params, whisk.KeyValue{Key: "triggerName", Value: "/" + deployer.Client.Namespace + "/" + trigger.Name}) + + trigger.Parameters = nil + + _, _, err := deployer.Client.Triggers.Delete(trigger.Name) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error deleting trigger with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } else { + parameters := make(map[string]interface{}) + for _, keyVal := range params { + parameters[keyVal.Key] = keyVal.Value + } + + qName, err := utils.ParseQualifiedName(feedName, deployer.ClientConfig.Namespace) + if err != nil { + return err + } + + namespace := deployer.Client.Namespace + deployer.Client.Namespace = qName.Namespace + _, _, err = deployer.Client.Actions.Invoke(qName.EntityName, parameters, true, true) + deployer.Client.Namespace = namespace + + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error deleting trigger feed with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + + } + } + return nil } func (deployer *ServiceDeployer) deleteRule(rule *whisk.Rule) error { - output := wski18n.T("Removing rule {{.rule}} ...", - map[string]interface{}{"rule": rule.Name}) - whisk.Debug(whisk.DbgInfo, output) - _, _, err := deployer.Client.Rules.SetState(rule.Name, "inactive") - - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error setting the status of rule with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } else { - - _, err = deployer.Client.Rules.Delete(rule.Name) - - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error deleting rule with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - } - } - output = wski18n.T("Rule {{.rule}} has been removed.\n", - map[string]interface{}{"rule": rule.Name}) - whisk.Debug(whisk.DbgInfo, output) - return nil + output := wski18n.T("Removing rule {{.rule}} ...", + map[string]interface{}{"rule": rule.Name}) + whisk.Debug(whisk.DbgInfo, output) + _, _, err := deployer.Client.Rules.SetState(rule.Name, "inactive") + + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error setting the status of rule with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } else { + + _, err = deployer.Client.Rules.Delete(rule.Name) + + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error deleting rule with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + } + } + output = wski18n.T("Rule {{.rule}} has been removed.\n", + map[string]interface{}{"rule": rule.Name}) + whisk.Debug(whisk.DbgInfo, output) + return nil } // Utility function to call go-whisk framework to make action func (deployer *ServiceDeployer) deleteAction(pkgname string, action *whisk.Action) error { - // call ActionService Thru Client - if deployer.DeployActionInPackage { - // the action will be deleted under package with pattern 'packagename/actionname' - action.Name = strings.Join([]string{pkgname, action.Name}, "/") - } - - output := wski18n.T("Removing action {{.action}} ...", - map[string]interface{}{"action": action.Name}) - whisk.Debug(whisk.DbgInfo, output) - - _, err := deployer.Client.Actions.Delete(action.Name) - if err != nil { - wskErr := err.(*whisk.WskError) - errString := wski18n.T("Got error deleting action with error message: {{.err}} and error code: {{.code}}.\n", - map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) - whisk.Debug(whisk.DbgError, errString) - return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) - - } - output = wski18n.T("Action {{.action}} has been removed.\n", - map[string]interface{}{"action": action.Name}) - whisk.Debug(whisk.DbgInfo, output) - return nil + // call ActionService Thru Client + if deployer.DeployActionInPackage { + // the action will be deleted under package with pattern 'packagename/actionname' + action.Name = strings.Join([]string{pkgname, action.Name}, "/") + } + + output := wski18n.T("Removing action {{.action}} ...", + map[string]interface{}{"action": action.Name}) + whisk.Debug(whisk.DbgInfo, output) + + if _, _, ok := deployer.Client.Actions.Get(action.Name); ok == nil { + _, err := deployer.Client.Actions.Delete(action.Name) + if err != nil { + wskErr := err.(*whisk.WskError) + errString := wski18n.T("Got error deleting action with error message: {{.err}} and error code: {{.code}}.\n", + map[string]interface{}{"err": wskErr.Error(), "code": strconv.Itoa(wskErr.ExitCode)}) + whisk.Debug(whisk.DbgError, errString) + return utils.NewWhiskClientError(wskErr.Error(), wskErr.ExitCode) + + } + output = wski18n.T("Action {{.action}} has been removed.\n", + map[string]interface{}{"action": action.Name}) + whisk.Debug(whisk.DbgInfo, output) + } + return nil } // from whisk go client func (deployer *ServiceDeployer) getQualifiedName(name string, namespace string) string { - if strings.HasPrefix(name, "/") { - return name - } else if strings.HasPrefix(namespace, "/") { - return fmt.Sprintf("%s/%s", namespace, name) - } else { - if len(namespace) == 0 { - namespace = deployer.ClientConfig.Namespace - } - return fmt.Sprintf("/%s/%s", namespace, name) - } + if strings.HasPrefix(name, "/") { + return name + } else if strings.HasPrefix(namespace, "/") { + return fmt.Sprintf("%s/%s", namespace, name) + } else { + if len(namespace) == 0 { + namespace = deployer.ClientConfig.Namespace + } + return fmt.Sprintf("/%s/%s", namespace, name) + } } func (deployer *ServiceDeployer) printDeploymentAssets(assets *DeploymentApplication) { - // pretty ASCII OpenWhisk graphic - utils.PrintOpenWhiskOutputln(" ____ ___ _ _ _ _ _\n /\\ \\ / _ \\ _ __ ___ _ __ | | | | |__ (_)___| | __\n /\\ /__\\ \\ | | | | '_ \\ / _ \\ '_ \\| | | | '_ \\| / __| |/ /\n / \\____ \\ / | |_| | |_) | __/ | | | |/\\| | | | | \\__ \\ <\n \\ \\ / \\/ \\___/| .__/ \\___|_| |_|__/\\__|_| |_|_|___/_|\\_\\ \n \\___\\/ |_|\n") - - utils.PrintOpenWhiskOutputln("Packages:") - for _, pack := range assets.Packages { - utils.PrintOpenWhiskOutputln("Name: " + pack.Package.Name) - utils.PrintOpenWhiskOutputln(" bindings: ") - for _, p := range pack.Package.Parameters { - jsonValue, err := utils.PrettyJSON(p.Value) - if err != nil { - fmt.Printf(" - %s : %s\n", p.Key, "Unknown value") - } else { - fmt.Printf(" - %s : %v\n", p.Key, jsonValue) - } - } - - for key, dep := range pack.Dependencies { - utils.PrintOpenWhiskOutputln(" * dependency: " + key) - utils.PrintOpenWhiskOutputln(" location: " + dep.Location) - if !dep.IsBinding { - utils.PrintOpenWhiskOutputln(" local path: " + dep.ProjectPath) - } - } - - utils.PrintOpenWhiskOutputln("") - - for _, action := range pack.Actions { - utils.PrintOpenWhiskOutputln(" * action: " + action.Action.Name) - utils.PrintOpenWhiskOutputln(" bindings: ") - for _, p := range action.Action.Parameters { - jsonValue, err := utils.PrettyJSON(p.Value) - if err != nil { - fmt.Printf(" - %s : %s\n", p.Key, "Unknown value") - } else { - fmt.Printf(" - %s : %v\n", p.Key, jsonValue) - } - } - utils.PrintOpenWhiskOutputln(" annotations: ") - for _, p := range action.Action.Annotations { - fmt.Printf(" - %s : %v\n", p.Key, p.Value) - - } - } - - utils.PrintOpenWhiskOutputln("") - for _, action := range pack.Sequences { - utils.PrintOpenWhiskOutputln(" * sequence: " + action.Action.Name) - } - - utils.PrintOpenWhiskOutputln("") - } - - utils.PrintOpenWhiskOutputln("Triggers:") - for _, trigger := range assets.Triggers { - utils.PrintOpenWhiskOutputln("* trigger: " + trigger.Name) - utils.PrintOpenWhiskOutputln(" bindings: ") - - for _, p := range trigger.Parameters { - jsonValue, err := utils.PrettyJSON(p.Value) - if err != nil { - fmt.Printf(" - %s : %s\n", p.Key, "Unknown value") - } else { - fmt.Printf(" - %s : %v\n", p.Key, jsonValue) - } - } - - utils.PrintOpenWhiskOutputln(" annotations: ") - for _, p := range trigger.Annotations { - - value := "?" - if str, ok := p.Value.(string); ok { - value = str - } - utils.PrintOpenWhiskOutputln(" - name: " + p.Key + " value: " + value) - } - } - - utils.PrintOpenWhiskOutputln("\n Rules") - for _, rule := range assets.Rules { - utils.PrintOpenWhiskOutputln("* rule: " + rule.Name) - utils.PrintOpenWhiskOutputln(" - trigger: " + rule.Trigger.(string) + "\n - action: " + rule.Action.(string)) - } - - utils.PrintOpenWhiskOutputln("") + // pretty ASCII OpenWhisk graphic + utils.PrintOpenWhiskOutputln(" ____ ___ _ _ _ _ _\n /\\ \\ / _ \\ _ __ ___ _ __ | | | | |__ (_)___| | __\n /\\ /__\\ \\ | | | | '_ \\ / _ \\ '_ \\| | | | '_ \\| / __| |/ /\n / \\____ \\ / | |_| | |_) | __/ | | | |/\\| | | | | \\__ \\ <\n \\ \\ / \\/ \\___/| .__/ \\___|_| |_|__/\\__|_| |_|_|___/_|\\_\\ \n \\___\\/ |_|\n") + + utils.PrintOpenWhiskOutputln("Packages:") + for _, pack := range assets.Packages { + utils.PrintOpenWhiskOutputln("Name: " + pack.Package.Name) + utils.PrintOpenWhiskOutputln(" bindings: ") + for _, p := range pack.Package.Parameters { + jsonValue, err := utils.PrettyJSON(p.Value) + if err != nil { + fmt.Printf(" - %s : %s\n", p.Key, "Unknown value") + } else { + fmt.Printf(" - %s : %v\n", p.Key, jsonValue) + } + } + + for key, dep := range pack.Dependencies { + utils.PrintOpenWhiskOutputln(" * dependency: " + key) + utils.PrintOpenWhiskOutputln(" location: " + dep.Location) + if !dep.IsBinding { + utils.PrintOpenWhiskOutputln(" local path: " + dep.ProjectPath) + } + } + + utils.PrintOpenWhiskOutputln("") + + for _, action := range pack.Actions { + utils.PrintOpenWhiskOutputln(" * action: " + action.Action.Name) + utils.PrintOpenWhiskOutputln(" bindings: ") + for _, p := range action.Action.Parameters { + jsonValue, err := utils.PrettyJSON(p.Value) + if err != nil { + fmt.Printf(" - %s : %s\n", p.Key, "Unknown value") + } else { + fmt.Printf(" - %s : %v\n", p.Key, jsonValue) + } + } + utils.PrintOpenWhiskOutputln(" annotations: ") + for _, p := range action.Action.Annotations { + fmt.Printf(" - %s : %v\n", p.Key, p.Value) + + } + } + + utils.PrintOpenWhiskOutputln("") + for _, action := range pack.Sequences { + utils.PrintOpenWhiskOutputln(" * sequence: " + action.Action.Name) + } + + utils.PrintOpenWhiskOutputln("") + } + + utils.PrintOpenWhiskOutputln("Triggers:") + for _, trigger := range assets.Triggers { + utils.PrintOpenWhiskOutputln("* trigger: " + trigger.Name) + utils.PrintOpenWhiskOutputln(" bindings: ") + + for _, p := range trigger.Parameters { + jsonValue, err := utils.PrettyJSON(p.Value) + if err != nil { + fmt.Printf(" - %s : %s\n", p.Key, "Unknown value") + } else { + fmt.Printf(" - %s : %v\n", p.Key, jsonValue) + } + } + + utils.PrintOpenWhiskOutputln(" annotations: ") + for _, p := range trigger.Annotations { + + value := "?" + if str, ok := p.Value.(string); ok { + value = str + } + utils.PrintOpenWhiskOutputln(" - name: " + p.Key + " value: " + value) + } + } + + utils.PrintOpenWhiskOutputln("\n Rules") + for _, rule := range assets.Rules { + utils.PrintOpenWhiskOutputln("* rule: " + rule.Name) + utils.PrintOpenWhiskOutputln(" - trigger: " + rule.Trigger.(string) + "\n - action: " + rule.Action.(string)) + } + + utils.PrintOpenWhiskOutputln("") } func (deployer *ServiceDeployer) getDependentDeployer(depName string, depRecord utils.DependencyRecord) (*ServiceDeployer, error) { - depServiceDeployer := NewServiceDeployer() - projectPath := path.Join(depRecord.ProjectPath, depName+"-"+depRecord.Version) - if len(depRecord.SubFolder)>0 { - projectPath = path.Join(projectPath,depRecord.SubFolder) - } - manifestPath := utils.GetManifestFilePath(projectPath) - deploymentPath := utils.GetDeploymentFilePath(projectPath) - depServiceDeployer.ProjectPath = projectPath - depServiceDeployer.ManifestPath = manifestPath - depServiceDeployer.DeploymentPath = deploymentPath - depServiceDeployer.IsInteractive = true - - depServiceDeployer.Client = deployer.Client - depServiceDeployer.ClientConfig = deployer.ClientConfig - - depServiceDeployer.DependencyMaster = deployer.DependencyMaster - - // share the master dependency list - depServiceDeployer.DependencyMaster = deployer.DependencyMaster - - return depServiceDeployer, nil + depServiceDeployer := NewServiceDeployer() + projectPath := path.Join(depRecord.ProjectPath, depName+"-"+depRecord.Version) + if len(depRecord.SubFolder) > 0 { + projectPath = path.Join(projectPath, depRecord.SubFolder) + } + manifestPath := utils.GetManifestFilePath(projectPath) + deploymentPath := utils.GetDeploymentFilePath(projectPath) + depServiceDeployer.ProjectPath = projectPath + depServiceDeployer.ManifestPath = manifestPath + depServiceDeployer.DeploymentPath = deploymentPath + depServiceDeployer.IsInteractive = true + + depServiceDeployer.Client = deployer.Client + depServiceDeployer.ClientConfig = deployer.ClientConfig + + depServiceDeployer.DependencyMaster = deployer.DependencyMaster + + // share the master dependency list + depServiceDeployer.DependencyMaster = deployer.DependencyMaster + + return depServiceDeployer, nil } diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go index d1665eb..ccaff6b 100644 --- a/parsers/manifest_parser.go +++ b/parsers/manifest_parser.go @@ -101,11 +101,30 @@ func (dm *YAMLParser) ParseManifest(manifestPath string) (*ManifestYAML, error) return &maniyaml, nil } -func (dm *YAMLParser) ComposeDependencies(mani *ManifestYAML, projectPath string, filePath string) (map[string]utils.DependencyRecord, error) { +func (dm *YAMLParser) ComposeDependenciesFromAllPackages(manifest *ManifestYAML, projectPath string, filePath string) (map[string]utils.DependencyRecord, error) { + dependencies := make(map[string]utils.DependencyRecord) + if manifest.Package.Packagename != "" { + return dm.ComposeDependencies(manifest.Package, projectPath, filePath, manifest.Package.Packagename) + } else if manifest.Packages != nil { + for n, p := range manifest.Packages { + d, err := dm.ComposeDependencies(p, projectPath, filePath, n) + if err == nil { + for k, v := range d { + dependencies[k] = v + } + } else { + return nil, err + } + } + } + return dependencies, nil +} + +func (dm *YAMLParser) ComposeDependencies(pkg Package, projectPath string, filePath string, packageName string) (map[string]utils.DependencyRecord, error) { var errorParser error depMap := make(map[string]utils.DependencyRecord) - for key, dependency := range mani.Package.Dependencies { + for key, dependency := range pkg.Dependencies { version := dependency.Version if version == "" { version = "master" @@ -158,7 +177,8 @@ func (dm *YAMLParser) ComposeDependencies(mani *ManifestYAML, projectPath string } packDir := path.Join(projectPath, "Packages") - depMap[key] = utils.NewDependencyRecord(packDir, mani.Package.Packagename, location, version, keyValArrParams, keyValArrAnot, isBinding) + depName := packageName + ":" + key + depMap[depName] = utils.NewDependencyRecord(packDir, packageName, location, version, keyValArrParams, keyValArrAnot, isBinding) } return depMap, nil @@ -217,7 +237,7 @@ func (dm *YAMLParser) ComposePackage(pkg Package, packageName string, filePath s return pag, nil } -func (dm *YAMLParser) ComposeSequencesFromAllPackages(namespace string, mani *ManifestYAML) (ar []utils.ActionRecord, err error) { +func (dm *YAMLParser) ComposeSequencesFromAllPackages(namespace string, mani *ManifestYAML) ([]utils.ActionRecord, error) { var s1 []utils.ActionRecord = make([]utils.ActionRecord, 0) if mani.Package.Packagename != "" { return dm.ComposeSequences(namespace, mani.Package.Sequences, mani.Package.Packagename) diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go index e9e9d8b..ed6ecbe 100644 --- a/parsers/manifest_parser_test.go +++ b/parsers/manifest_parser_test.go @@ -29,6 +29,7 @@ import ( "path/filepath" "reflect" "strconv" + "strings" ) // Test 1: validate manifest_parser:Unmarshal() method with a sample manifest in NodeJS @@ -1205,7 +1206,7 @@ func TestComposeDependencies(t *testing.T) { // read and parse manifest.yaml file p := NewYAMLParser() m, _ := p.ParseManifest(tmpfile.Name()) - depdList, err := p.ComposeDependencies(m, "/project_folder", tmpfile.Name()) + depdList, err := p.ComposeDependenciesFromAllPackages(m, "/project_folder", tmpfile.Name()) if err != nil { assert.Fail(t, "Failed to compose rules") } @@ -1213,7 +1214,9 @@ func TestComposeDependencies(t *testing.T) { for depdy_name, depdy := range depdList { assert.Equal(t, "helloworld", depdy.Packagename, "Failed to set dependecy isbinding") assert.Equal(t, "/project_folder/Packages", depdy.ProjectPath, "Failed to set dependecy isbinding") - switch depdy_name { + d := strings.Split(depdy_name, ":") + assert.NotEqual(t, d[1], "", "Failed to get dependency name") + switch d[1] { case "myhelloworld": assert.Equal(t, "https://github.com/user/repo/folder", depdy.Location, "Failed to set dependecy location") assert.Equal(t, false, depdy.IsBinding, "Failed to set dependecy isbinding") diff --git a/tests/src/integration/validate-packages-in-manifest/manifest.yaml b/tests/src/integration/validate-packages-in-manifest/manifest.yaml index 81679f6..0c9cec4 100644 --- a/tests/src/integration/validate-packages-in-manifest/manifest.yaml +++ b/tests/src/integration/validate-packages-in-manifest/manifest.yaml @@ -1,5 +1,10 @@ packages: packageNodeJS: + dependencies: + hellowhisk: + location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk + myhelloworlds: + location: github.com/apache/incubator-openwhisk-test/packages/helloworlds actions: helloNodejs-1: function: actions/hello.js @@ -30,7 +35,7 @@ packages: description: location of a person sequences: helloworldnodejs-series: - actions: helloNodejs-1, helloNodejs-2, helloNodejs-3 + actions: helloNodejs-1, helloNodejs-2, helloNodejs-3, hellowhisk/greeting, hellowhisk/httpGet, myhelloworlds/hello-js triggers: triggerNodeJS: rules: @@ -38,6 +43,11 @@ packages: trigger: triggerNodeJS action: helloworldnodejs-series packagePython: + dependencies: + hellowhisk: + location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk + helloworlds: + location: github.com/apache/incubator-openwhisk-test/packages/helloworlds actions: helloPython-1: function: actions/hello.py @@ -66,7 +76,7 @@ packages: runtime: python sequences: helloworldpython-series: - actions: helloPython-1, helloPython-2, helloPython-3 + actions: helloPython-1, helloPython-2, helloPython-3, hellowhisk/greeting, hellowhisk/httpGet, helloworlds/hello-js triggers: triggerPython: rules: -- To stop receiving notification emails like this one, please contact ['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].