blob: 172fa2cfd3da5d610599e9499b944ad99fc0599d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 parsers
import (
"github.com/apache/incubator-openwhisk-client-go/whisk"
"github.com/apache/incubator-openwhisk-wskdeploy/utils"
)
// structs that denotes the sample manifest.yaml, wrapped yaml.v2
func NewYAMLParser() *YAMLParser {
return &YAMLParser{}
}
type ParseYaml interface {
Unmarshal(input []byte, deploy *YAML) error
Marshal(manifest *YAML) (output []byte, err error)
//Compose Package entity according to yaml content
ComposePackages(manifestpath string) ([]*whisk.Package, error)
// Compose Action entities according to yaml content
ComposeActions(manifestpath string) ([]*whisk.Action, error)
// Compose Trigger entities according to deployment and manifest yaml content
ComposeTriggers(manifestpath string, deploymentpath string) ([]*whisk.Trigger, error)
// Compose Rule entities according to yaml content
ComposeRules(manifestpath string) ([]*whisk.Rule, error)
}
type YAMLParser struct {
manifests []*YAML
lastID uint32
}
type Action struct {
//mapping to wsk.Action.Version
Version string `yaml:"version"` //used in manifest.yaml
Location string `yaml:"location"` //deprecated, used in manifest.yaml
Function string `yaml:"function"` //used in manifest.yaml
Runtime string `yaml:"runtime,omitempty"` //used in manifest.yaml
//mapping to wsk.Action.Namespace
Namespace string `yaml:"namespace"` //used in deployment.yaml
Credential string `yaml:"credential"` //used in deployment.yaml
Inputs map[string]Parameter `yaml:"inputs"` //used in both manifest.yaml and deployment.yaml
Outputs map[string]Parameter `yaml:"outputs"` //used in manifest.yaml
//mapping to wsk.Action.Name
Name string
Annotations map[string]interface{} `yaml:"annotations,omitempty"`
//Parameters map[string]interface{} `yaml:parameters` // used in manifest.yaml
ExposedUrl string `yaml:"exposedUrl"` // used in manifest.yaml
Webexport string `yaml:"web-export"` // used in manifest.yaml
Main string `yaml:"main"` // used in manifest.yaml
Limits *Limits `yaml:"limits"` // used in manifest.yaml
}
type Limits struct {
Timeout *int `yaml:"timeout,omitempty"` //in ms, [100 ms,300000ms]
Memory *int `yaml:"memorySize,omitempty"` //in MB, [128 MB,512 MB]
Logsize *int `yaml:"logSize,omitempty"` //in MB, [0MB,10MB]
ConcurrentActivations *int `yaml:"concurrentActivations,omitempty"` //not changeable via APIs
UserInvocationRate *int `yaml:"userInvocationRate,omitempty"` //not changeable via APIs
CodeSize *int `yaml:"codeSize,omitempty"` //not changeable via APIs
ParameterSize *int `yaml:"parameterSize,omitempty"` //not changeable via APIs
}
type Sequence struct {
Actions string `yaml:"actions"` //used in manifest.yaml
Annotations map[string]interface{} `yaml:"annotations,omitempty"`
}
type Dependency struct {
Version string `yaml: "version, omitempty"`
Location string `yaml: "location, omitempty"`
Inputs map[string]Parameter `yaml:"inputs"`
Annotations map[string]interface{} `yaml:"annotations"`
}
type Parameter struct {
Type string `yaml:"type,omitempty"`
Description string `yaml:"description,omitempty"`
Value interface{} `yaml:"value,omitempty"` // JSON Value
Required bool `yaml:"required,omitempty"`
Default interface{} `yaml:"default,omitempty"`
Status string `yaml:"status,omitempty"`
Schema interface{} `yaml:"schema,omitempty"`
multiline bool
}
type Trigger struct {
//mapping to ????
Feed string `yaml:"feed"` //used in manifest.yaml
//mapping to wsk.Trigger.Namespace
Namespace string `yaml:"namespace"` //used in deployment.yaml
Credential string `yaml:"credential"` //used in deployment.yaml
Inputs map[string]Parameter `yaml:"inputs"` //used in deployment.yaml
//mapping to wsk.Trigger.Name
Name string
Annotations map[string]interface{} `yaml:"annotations,omitempty"`
Source string `yaml:source` // deprecated, used in manifest.yaml
//Parameters map[string]interface{} `yaml:parameters` // used in manifest.yaml
}
type Feed struct {
Namespace string `yaml:"namespace"` //used in deployment.yaml
Credential string `yaml:"credential"` //used in both manifest.yaml and deployment.yaml
Inputs map[string]string `yaml:"inputs"` //used in deployment.yaml
Location string `yaml:"location"` //used in manifest.yaml
Action string `yaml:"action"` //used in manifest.yaml
//TODO: need to define operation structure
Operations map[string]interface{} `yaml:"operations"` //used in manifest.yaml
Name string
}
type Rule struct {
//mapping to wsk.Rule.Trigger
Trigger string `yaml:"trigger"` //used in manifest.yaml
//mapping to wsk.Rule.Action
Action string `yaml:"action"` //used in manifest.yaml
Rule string `yaml:"rule"` //used in manifest.yaml
//mapping to wsk.Rule.Name
Name string
}
type Repository struct {
Url string `yaml:"url"`
Description string `yaml:"description,omitempty"`
Credential string `yaml:"credential,omitempty"`
}
type Package struct {
//mapping to wsk.SentPackageNoPublish.Name
Packagename string `yaml:"name"` //used in manifest.yaml
//mapping to wsk.SentPackageNoPublish.Version
Version string `yaml:"version"` //used in manifest.yaml, mandatory
License string `yaml:"license"` //used in manifest.yaml, mandatory
Repositories []Repository `yaml:"repositories,omitempty"`
Dependencies map[string]Dependency `yaml: dependencies` //used in manifest.yaml
//mapping to wsk.SentPackageNoPublish.Namespace
Namespace string `yaml:"namespace"` //used in both manifest.yaml and deployment.yaml
Credential string `yaml:"credential"` //used in both manifest.yaml and deployment.yaml
ApiHost string `yaml:"apiHost"` //used in both manifest.yaml and deployment.yaml
Actions map[string]Action `yaml:"actions"` //used in both manifest.yaml and deployment.yaml
Triggers map[string]Trigger `yaml:"triggers"` //used in both manifest.yaml and deployment.yaml
Feeds map[string]Feed `yaml:"feeds"` //used in both manifest.yaml and deployment.yaml
Rules map[string]Rule `yaml:"rules"` //used in both manifest.yaml and deployment.yaml
Inputs map[string]Parameter `yaml:"inputs"` //deprecated, used in deployment.yaml
Sequences map[string]Sequence `yaml:"sequences"`
Annotations map[string]interface{} `yaml:"annotations,omitempty"`
//Parameters map[string]interface{} `yaml: parameters` // used in manifest.yaml
Apis map[string]map[string]map[string]map[string]string `yaml:"apis"` //used in manifest.yaml
}
type Project struct {
Name string `yaml:"name"` //used in deployment.yaml
Namespace string `yaml:"namespace"` //used in deployment.yaml
Credential string `yaml:"credential"`
ApiHost string `yaml:"apiHost"`
Version string `yaml:"version"`
Packages map[string]Package `yaml:"packages"` //used in deployment.yaml
Package Package `yaml:"package"` // being deprecated, used in deployment.yaml
}
type YAML struct {
Application Project `yaml:"application"` //used in deployment.yaml (being deprecated)
Project Project `yaml:"project"` //used in deployment.yaml
Packages map[string]Package `yaml:"packages"` //used in deployment.yaml
Package Package `yaml:"package"`
Filepath string //file path of the yaml file
}
// function to return Project or Application depending on what is specified in
// manifest and deployment files
func (yaml *YAML) GetProject() Project {
if yaml.Application.Name == "" {
return yaml.Project
}
return yaml.Application
}
func convertSinglePackageName(packageName string) string {
if len(packageName) != 0 {
packageNameEnv := utils.GetEnvVar(packageName)
if str, ok := packageNameEnv.(string); ok {
return str
} else {
return packageName
}
}
return packageName
}
func convertPackageName(packageMap map[string]Package) map[string]Package {
packages := make(map[string]Package)
for packName, depPacks := range packageMap {
name := packName
packageName := utils.GetEnvVar(packName)
if str, ok := packageName.(string); ok {
name = str
}
depPacks.Packagename = convertSinglePackageName(depPacks.Packagename)
packages[name] = depPacks
}
return packages
}
func ReadEnvVariable(yaml *YAML) *YAML {
if yaml.Application.Name != "" {
yaml.Application.Package.Packagename = convertSinglePackageName(yaml.Application.Package.Packagename)
yaml.Package.Packagename = convertSinglePackageName(yaml.Package.Packagename)
yaml.Application.Packages = convertPackageName(yaml.Application.Packages)
} else {
yaml.Project.Package.Packagename = convertSinglePackageName(yaml.Project.Package.Packagename)
yaml.Package.Packagename = convertSinglePackageName(yaml.Package.Packagename)
yaml.Project.Packages = convertPackageName(yaml.Project.Packages)
}
yaml.Packages = convertPackageName(yaml.Packages)
return yaml
}
//********************Trigger functions*************************//
//add the key/value array as the annotations of the trigger.
func (trigger *Trigger) ComposeWskTrigger(kvarr []whisk.KeyValue) *whisk.Trigger {
wsktrigger := new(whisk.Trigger)
wsktrigger.Name = trigger.Name
wsktrigger.Namespace = trigger.Namespace
pub := false
wsktrigger.Publish = &pub
wsktrigger.Annotations = kvarr
return wsktrigger
}
//********************Rule functions*************************//
func (rule *Rule) ComposeWskRule() *whisk.Rule {
wskrule := new(whisk.Rule)
wskrule.Name = rule.Name
//wskrule.Namespace = rule.Namespace
pub := false
wskrule.Publish = &pub
wskrule.Trigger = rule.Trigger
wskrule.Action = rule.Action
return wskrule
}
//********************Package functions*************************//
func (pkg *Package) ComposeWskPackage() *whisk.Package {
wskpag := new(whisk.Package)
wskpag.Name = pkg.Packagename
wskpag.Namespace = pkg.Namespace
pub := false
wskpag.Publish = &pub
wskpag.Version = pkg.Version
return wskpag
}
func (pkg *Package) GetActionList() []Action {
var s1 []Action = make([]Action, 0)
for action_name, action := range pkg.Actions {
action.Name = action_name
s1 = append(s1, action)
}
return s1
}
func (pkg *Package) GetTriggerList() []Trigger {
var s1 []Trigger = make([]Trigger, 0)
for trigger_name, trigger := range pkg.Triggers {
trigger.Name = trigger_name
s1 = append(s1, trigger)
}
return s1
}
func (pkg *Package) GetRuleList() []Rule {
var s1 []Rule = make([]Rule, 0)
for rule_name, rule := range pkg.Rules {
rule.Name = rule_name
s1 = append(s1, rule)
}
return s1
}
//This is for parse the deployment yaml file.
func (pkg *Package) GetFeedList() []Feed {
var s1 []Feed = make([]Feed, 0)
for feed_name, feed := range pkg.Feeds {
feed.Name = feed_name
s1 = append(s1, feed)
}
return s1
}
// This is for parse the manifest yaml file.
func (pkg *Package) GetApis() []*whisk.Api {
var apis = make([]*whisk.Api, 0)
for k, v := range pkg.Apis {
var apiName string = k
for k, v := range v {
var gatewayBasePath string = k
for k, v := range v {
var gatewayRelPath string = k
for k, v := range v {
api := &whisk.Api{}
api.ApiName = apiName
api.GatewayBasePath = gatewayBasePath
api.GatewayRelPath = gatewayRelPath
action := &whisk.ApiAction{}
action.Name = k
action.BackendMethod = v
api.Action = action
apis = append(apis, api)
}
}
}
}
return apis
}