aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRitu Sood <ritu.sood@intel.com>2020-08-29 01:27:53 -0700
committerRitu Sood <ritu.sood@intel.com>2020-09-02 13:59:58 -0700
commitd8ed6e76a40b8942c2b56c623dcc097d734e3dca (patch)
treefe5712061d02d1d971b84cbc2f2f7bca68666cfd
parentd14246bb9a2c8874f9925c45322d678a93584adb (diff)
Update CLI with complete get implementation
CLI updated with get functionality. Also adding vFw test case Issue-ID: MULTICLOUD-1065 Signed-off-by: Ritu Sood <ritu.sood@intel.com> Change-Id: I7bd22aca9fac9cb7b1f4c93d0ffad5b07b62cced
-rw-r--r--src/tools/emcoctl/Readme.md23
-rw-r--r--src/tools/emcoctl/cmd/apply.go7
-rw-r--r--src/tools/emcoctl/cmd/config.go14
-rw-r--r--src/tools/emcoctl/cmd/delete.go20
-rw-r--r--src/tools/emcoctl/cmd/get.go17
-rw-r--r--src/tools/emcoctl/cmd/getall.go39
-rw-r--r--src/tools/emcoctl/cmd/root.go7
-rw-r--r--src/tools/emcoctl/cmd/utils.go101
-rw-r--r--src/tools/emcoctl/examples/emco-cfg.yaml8
-rw-r--r--src/tools/emcoctl/examples/vfw.yaml408
10 files changed, 536 insertions, 108 deletions
diff --git a/src/tools/emcoctl/Readme.md b/src/tools/emcoctl/Readme.md
index bf07e563..ecbcf4de 100644
--- a/src/tools/emcoctl/Readme.md
+++ b/src/tools/emcoctl/Readme.md
@@ -54,20 +54,33 @@ This command will apply the resources in the file. The user is responsible to en
`$ emcoctl apply -f filename.yaml`
+For applying resources that don't have a json body anchor can be provided as an arguement
+
+`$ emcoctl apply <anchor>`
+
+`$ emcoctl apply projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/instantiate`
+
+
2. Get Emco Resources
-Get the resources in the input file. This command will use the metadata name to get the resource.
+Get the resources in the input file. This command will use the metadata name in each of the resources in the file to get information about the resource.
`$ emcoctl get -f filename.yaml`
+For getting information for one resource anchor can be provided as an arguement
+
+`$ emcoctl get <anchor>`
+
+`$ emcoctl get projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group`
+
3. Delete Emco Resources
-Delete resources in the file. The emcoctl will start deleting resources in the reverse order than given in the file to maintain hierarchy. This command will use the metadata name to delete the resource.
+Delete resources in the file. The emcoctl will start deleting resources in the reverse order than given in the file to maintain hierarchy. This command will use the metadata name in each of the resources in the file to delete the resource..
`$ emcoctl delete -f filename.yaml`
-4. Get all Emco Resources
+For deleting one resource anchor can be provided as an arguement
-Get all for the resources in the file.
+`$ emcoctl delete <anchor>`
-`$ emcoctl getall -f filename.yaml`
+`$ emcoctl delete projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group`
diff --git a/src/tools/emcoctl/cmd/apply.go b/src/tools/emcoctl/cmd/apply.go
index f451a614..cf494bc4 100644
--- a/src/tools/emcoctl/cmd/apply.go
+++ b/src/tools/emcoctl/cmd/apply.go
@@ -24,9 +24,8 @@ import (
// applyCmd represents the apply command
var applyCmd = &cobra.Command{
Use: "apply",
- Short: "apply(Post) the resources from input file or url(with body) from command line",
+ Short: "apply(Post) the resources from input file or url(without body) from command line",
Run: func(cmd *cobra.Command, args []string) {
- fmt.Println("apply called")
c := NewRestClient()
if len(inputFiles) > 0 {
resources := readResources()
@@ -46,7 +45,6 @@ var applyCmd = &cobra.Command{
}
}
} else if len(args) >= 1 {
- fmt.Println(args[0])
c.RestClientPost(args[0], []byte{})
} else {
fmt.Println("Error: No args ")
@@ -55,8 +53,7 @@ var applyCmd = &cobra.Command{
}
func init() {
- fmt.Println("INIT ")
rootCmd.AddCommand(applyCmd)
applyCmd.Flags().StringSliceVarP(&inputFiles, "filename", "f", []string{}, "Filename of the input file")
- applyCmd.Flags().StringSliceVarP(&valuesFiles, "values", "v", []string{}, "Values to go with the file")
+ //applyCmd.Flags().StringSliceVarP(&valuesFiles, "values", "v", []string{}, "Values to go with the file")
}
diff --git a/src/tools/emcoctl/cmd/config.go b/src/tools/emcoctl/cmd/config.go
index c5e44660..8af1cc28 100644
--- a/src/tools/emcoctl/cmd/config.go
+++ b/src/tools/emcoctl/cmd/config.go
@@ -39,6 +39,20 @@ const urlVersion string = "v2"
const urlPrefix string = "http://"
var Configurations EmcoConfigurations
+// SetDefaultConfiguration default configuration if t
+func SetDefaultConfiguration() {
+ Configurations.Orchestrator.Host = "localhost"
+ Configurations.Orchestrator.Port = 9015
+ Configurations.Clm.Host = "localhost"
+ Configurations.Clm.Port = 9061
+ Configurations.Ncm.Host = "localhost"
+ Configurations.Ncm.Port = 9031
+ Configurations.Dcm.Host = "localhost"
+ Configurations.Dcm.Port = 0
+ Configurations.OvnAction.Host = "localhost"
+ Configurations.OvnAction.Port = 9051
+}
+
// GetOrchestratorURL Url for Orchestrator
func GetOrchestratorURL() string {
if Configurations.Orchestrator.Host == "" || Configurations.Orchestrator.Port == 0 {
diff --git a/src/tools/emcoctl/cmd/delete.go b/src/tools/emcoctl/cmd/delete.go
index d6dbfe34..faa52b5b 100644
--- a/src/tools/emcoctl/cmd/delete.go
+++ b/src/tools/emcoctl/cmd/delete.go
@@ -1,5 +1,5 @@
/*
-Copyright © 2020 Intel Corp
+Copyright © 2020 Intel Corp
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,9 +24,8 @@ import (
// deleteCmd represents the delete command
var deleteCmd = &cobra.Command{
Use: "delete",
- Short: "Delete resources in input file or commandline",
+ Short: "Delete the resources from input file or url from command line",
Run: func(cmd *cobra.Command, args []string) {
- fmt.Println("delete called")
c := NewRestClient()
if len(inputFiles) > 0 {
resources := readResources()
@@ -35,23 +34,14 @@ var deleteCmd = &cobra.Command{
c.RestClientDelete(res.anchor, res.body)
}
} else if len(args) >= 1 {
- fmt.Println(args[0])
- c.RestClientDelete(args[0], nil)
+ c.RestClientDeleteAnchor(args[0])
+ } else {
+ fmt.Println("Error: No args ")
}
},
}
func init() {
rootCmd.AddCommand(deleteCmd)
-
- // Here you will define your flags and configuration settings.
-
- // Cobra supports Persistent Flags which will work for this command
- // and all subcommands, e.g.:
- // deleteCmd.PersistentFlags().String("foo", "", "A help for foo")
-
- // Cobra supports local flags which will only run when this command
- // is called directly, e.g.:
- // deleteCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
deleteCmd.Flags().StringSliceVarP(&inputFiles, "filename", "f", []string{}, "Filename of the input file")
}
diff --git a/src/tools/emcoctl/cmd/get.go b/src/tools/emcoctl/cmd/get.go
index 2cc96dc4..124ceec7 100644
--- a/src/tools/emcoctl/cmd/get.go
+++ b/src/tools/emcoctl/cmd/get.go
@@ -24,17 +24,24 @@ import (
// getCmd represents the get command
var getCmd = &cobra.Command{
Use: "get",
- Short: "Get the resource(s) based on the URL",
+ Short: "Get the resources from input file or url from command line",
Run: func(cmd *cobra.Command, args []string) {
- fmt.Println("get called")
c := NewRestClient()
- if len(args) >= 1 {
- fmt.Println(args[0])
- c.RestClientGet(args[0])
+ if len(inputFiles) > 0 {
+ resources := readResources()
+ c := NewRestClient()
+ for _, res := range resources {
+ c.RestClientGet(res.anchor, res.body)
+ }
+ } else if len(args) >= 1 {
+ c.RestClientGetAnchor(args[0])
+ } else {
+ fmt.Println("Error: No args ")
}
},
}
func init() {
rootCmd.AddCommand(getCmd)
+ getCmd.Flags().StringSliceVarP(&inputFiles, "filename", "f", []string{}, "Filename of the input file")
}
diff --git a/src/tools/emcoctl/cmd/getall.go b/src/tools/emcoctl/cmd/getall.go
deleted file mode 100644
index 329b2582..00000000
--- a/src/tools/emcoctl/cmd/getall.go
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-Copyright © 2020 Intel Corp
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-package cmd
-
-import (
- "github.com/spf13/cobra"
-)
-
-// getallCmd represents the getall command
-var getallCmd = &cobra.Command{
- Use: "getall",
- Short: "Get all resources in the file provided",
- Run: func(cmd *cobra.Command, args []string) {
- resources := readResources()
- c := NewRestClient()
- for _, res := range resources {
- c.RestClientGetAll(res.anchor)
- }
- },
-}
-
-func init() {
- rootCmd.AddCommand(getallCmd)
- // Here you will define your flags and configuration settings.
- getallCmd.Flags().StringSliceVarP(&inputFiles, "filename", "f", []string{}, "Filename of the input file")
-}
diff --git a/src/tools/emcoctl/cmd/root.go b/src/tools/emcoctl/cmd/root.go
index 4c1ac19f..7648606a 100644
--- a/src/tools/emcoctl/cmd/root.go
+++ b/src/tools/emcoctl/cmd/root.go
@@ -38,7 +38,6 @@ var rootCmd = &cobra.Command{
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
- fmt.Println("Test")
fmt.Println(err)
os.Exit(1)
}
@@ -55,7 +54,7 @@ func init() {
// initConfig reads in config file and ENV variables if set.
func initConfig() {
- cfgFile = "emco-cfg.yaml"
+
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
@@ -66,7 +65,6 @@ func initConfig() {
fmt.Println(err)
os.Exit(1)
}
- fmt.Println(home)
// Search config in home directory with name ".emco" (without extension).
viper.AddConfigPath(home)
viper.SetConfigName(".emco")
@@ -81,5 +79,8 @@ func initConfig() {
if err != nil {
fmt.Printf("Unable to decode into struct, %v", err)
}
+ } else {
+ fmt.Println("Warning: No Configuration File found. Using defaults")
+ SetDefaultConfiguration()
}
} \ No newline at end of file
diff --git a/src/tools/emcoctl/cmd/utils.go b/src/tools/emcoctl/cmd/utils.go
index 34063eee..62b33755 100644
--- a/src/tools/emcoctl/cmd/utils.go
+++ b/src/tools/emcoctl/cmd/utils.go
@@ -179,12 +179,30 @@ func (r RestyClient) RestClientMultipartPost(anchor string, body []byte, file st
}
return pkgerrors.Errorf("Server Multipart Post Error")
}
-// RestClientGetAll returns all resource in the input file
-func (r RestyClient) RestClientGetAll(anchor string) error {
+
+// RestClientGetAnchor returns get data from anchor
+func (r RestyClient) RestClientGetAnchor(anchor string) error {
url, err := GetURL(anchor)
if err != nil {
return err
}
+ s := strings.Split(anchor, "/")
+ if len(s) >= 3 {
+ a := s[len(s)-2]
+ // Determine if multipart
+ if a == "apps" || a == "profiles" || a == "clusters" {
+ // Supports only getting metadata
+ resp, err := r.client.R().
+ SetHeader("Accept", "application/json").
+ Get(url)
+ if err != nil {
+ fmt.Println(err)
+ return err
+ }
+ fmt.Println("URL:", anchor, "Response Code:", resp.StatusCode(), "Response:", resp)
+ return nil
+ }
+ }
resp, err := r.client.R().
Get(url)
if err != nil {
@@ -194,34 +212,58 @@ func (r RestyClient) RestClientGetAll(anchor string) error {
fmt.Println("URL:", anchor, "Response Code:", resp.StatusCode(), "Response:", resp)
return nil
}
+
// RestClientGet gets resource
-func (r RestyClient) RestClientGet(anchor string) error {
+func (r RestyClient) RestClientGet(anchor string, body []byte) error {
+ if anchor == "" {
+ return pkgerrors.Errorf("Anchor can't be empty")
+ }
s := strings.Split(anchor, "/")
- a := s[len(s)-2]
- // Determine if multipart
- if a == "apps" || a == "profiles" || a == "clusters" {
- url, err := GetURL(anchor)
- if err != nil {
- return err
- }
- // Supports only getting metadata
- resp, err := r.client.R().
- SetHeader("Accept", "application/json").
- Get(url)
- if err != nil {
- fmt.Println(err)
- return err
+ a := s[len(s)-1]
+ if a == "instantiate" || a == "apply" || a == "approve" || a == "terminate" {
+ // No get for these
+ return nil
+ }
+ var e emcoBody
+ err := json.Unmarshal(body, &e)
+ if err != nil {
+ fmt.Println(err)
+ return err
+ }
+ if e.Meta.Name != "" {
+ name := e.Meta.Name
+ anchor = anchor + "/" + name
+ if a == "composite-apps" {
+ var cav emcoCompositeAppSpec
+ err := mapstructure.Decode(e.Spec, &cav)
+ if err != nil {
+ fmt.Println("mapstruct error")
+ return err
+ }
+ anchor = anchor + "/" + cav.Version
}
- fmt.Println("URL:", anchor, "Response Code:", resp.StatusCode(), "Response:", resp)
- } else {
- r.RestClientGetAll(anchor)
+ } else if e.Label != "" {
+ anchor = anchor + "/" + e.Label
}
+ return r.RestClientGetAnchor(anchor)
+}
+// RestClientDeleteAnchor returns all resource in the input file
+func (r RestyClient) RestClientDeleteAnchor(anchor string) error {
+ url, err := GetURL(anchor)
+ if err != nil {
+ return err
+ }
+ resp, err := r.client.R().Delete(url)
+ if err != nil {
+ fmt.Println(err)
+ return err
+ }
+ fmt.Println("URL:", anchor, "Response Code:", resp.StatusCode(), "Response:", resp)
return nil
}
// RestClientDelete calls rest delete command
func (r RestyClient) RestClientDelete(anchor string, body []byte) error {
- var url string
s := strings.Split(anchor, "/")
a := s[len(s)-1]
@@ -229,13 +271,11 @@ func (r RestyClient) RestClientDelete(anchor string, body []byte) error {
// Change instantiate to destroy
s[len(s)-1] = "terminate"
anchor = strings.Join(s[:], "/")
- fmt.Println("URL:", anchor)
return r.RestClientPost(anchor, []byte{})
} else if a == "apply" {
// Change apply to terminate
s[len(s)-1] = "terminate"
anchor = strings.Join(s[:], "/")
- fmt.Println("URL:", anchor)
return r.RestClientPost(anchor, []byte{})
} else if a == "approve" || a == "status" {
// Approve and status doesn't have delete
@@ -261,19 +301,10 @@ func (r RestyClient) RestClientDelete(anchor string, body []byte) error {
}
anchor = anchor + "/" + cav.Version
}
+ } else if e.Label != "" {
+ anchor = anchor + "/" + e.Label
}
- url, err = GetURL(anchor)
- if err != nil {
- return err
- }
- resp, err := r.client.R().
- Delete(url)
- if err != nil {
- fmt.Println(err)
- return err
- }
- fmt.Println("URL:", anchor, "Response Code:", resp.StatusCode())
- return nil
+ return r.RestClientDeleteAnchor(anchor)
}
// GetURL reads the configuration file to get URL
func GetURL(anchor string) (string, error) {
diff --git a/src/tools/emcoctl/examples/emco-cfg.yaml b/src/tools/emcoctl/examples/emco-cfg.yaml
index f2790654..c1703def 100644
--- a/src/tools/emcoctl/examples/emco-cfg.yaml
+++ b/src/tools/emcoctl/examples/emco-cfg.yaml
@@ -3,4 +3,10 @@
port: 9015
clm:
host: localhost
- port: 9061 \ No newline at end of file
+ port: 9061
+ ncm:
+ host: localhost
+ port: 9031
+ ovnaction:
+ host: localhost
+ port: 9051 \ No newline at end of file
diff --git a/src/tools/emcoctl/examples/vfw.yaml b/src/tools/emcoctl/examples/vfw.yaml
new file mode 100644
index 00000000..b5df4834
--- /dev/null
+++ b/src/tools/emcoctl/examples/vfw.yaml
@@ -0,0 +1,408 @@
+#creating controller entries
+version: emco/v2
+resourceContext:
+ anchor: controllers
+metadata :
+ name: rsync
+spec:
+ host: "192.168.121.6"
+ port: 30546
+---
+
+#creating controller entries
+version: emco/v2
+resourceContext:
+ anchor: controllers
+metadata :
+ name: ovnaction
+spec:
+ host: "192.168.121.6"
+ port: 32259
+ type: "action"
+ priority: 1
+
+---
+
+#creating cluster provider
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers
+metadata :
+ name: vfw-cluster-provider
+
+---
+#creating cluster
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers/vfw-cluster-provider/clusters
+metadata :
+ name: edge01
+file:
+ kubeconfig
+
+---
+#Add label cluster
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers/vfw-cluster-provider/clusters/edge01/labels
+label-name: LabelA
+
+---
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers/vfw-cluster-provider/clusters/edge01/networks
+metadata:
+ name: emco-private-net
+spec:
+ cniType: ovn4nfv
+ ipv4Subnets:
+ - subnet: 10.10.20.0/24
+ name: subnet1
+ gateway: 10.10.20.1/24
+
+---
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers/vfw-cluster-provider/clusters/edge01/networks
+metadata:
+ name: emco-unprotected-net
+spec:
+ cniType: ovn4nfv
+ ipv4Subnets:
+ - subnet: 192.168.10.0/24
+ name: subnet1
+ gateway: 192.168.10.1/24
+
+---
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers/vfw-cluster-provider/clusters/edge01/networks
+metadata:
+ name: protected-private-net
+spec:
+ cniType: ovn4nfv
+ ipv4Subnets:
+ - subnet: 192.168.20.0/24
+ name: subnet1
+ gateway: 192.168.20.1/24
+
+---
+version: emco/v2
+resourceContext:
+ anchor: cluster-providers/vfw-cluster-provider/clusters/edge01/apply
+
+---
+#create project
+version: emco/v2
+resourceContext:
+ anchor: projects
+metadata :
+ name: testvfw
+
+---
+#creating collection composite app entry
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps
+metadata :
+ name: compositevfw
+spec:
+ version: v1
+
+---
+#adding prometheus app to the composite app
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/apps
+metadata :
+ name: packetgen
+file:
+ /home/vagrant/multicloud-k8s/kud/demo/composite-firewall/packetgen.tar.gz
+
+---
+#adding prometheus app to the composite app
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/apps
+metadata :
+ name: firewall
+file:
+ /home/vagrant/multicloud-k8s/kud/demo/composite-firewall/firewall.tar.gz
+
+---
+#adding collectd app to the composite app
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/apps
+metadata :
+ name: sink
+file:
+ /home/vagrant/multicloud-k8s/kud/demo/composite-firewall/sink.tar.gz
+
+---
+#creating collection composite profile entry
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/composite-profiles
+metadata :
+ name: vfw_composite-profile
+
+---
+#adding prometheus app profiles to the composite profile
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/composite-profiles/vfw_composite-profile/profiles
+metadata :
+ name: packetgen-profile
+spec:
+ app-name: packetgen
+file:
+ /home/vagrant/multicloud-k8s/kud/demo/composite-firewall/profile.tar.gz
+
+---
+#adding firewall app profiles to the composite profile
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/composite-profiles/vfw_composite-profile/profiles
+metadata :
+ name: firewall-profile
+spec:
+ app-name: firewall
+file:
+ /home/vagrant/multicloud-k8s/kud/demo/composite-firewall/profile.tar.gz
+
+---
+#adding firewall app profiles to the composite profile
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/composite-profiles/vfw_composite-profile/profiles
+metadata :
+ name: sink-profile
+spec:
+ app-name: sink
+file:
+ /home/vagrant/multicloud-k8s/kud/demo/composite-firewall/profile.tar.gz
+
+---
+#create the generic placement intent
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/generic-placement-intents
+metadata :
+ name: fw-placement-intent
+spec:
+ logical-cloud: NA
+
+---
+#add the prometheus app placement intent to the generic placement intent
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/generic-placement-intents/fw-placement-intent/app-intents
+metadata:
+ name: packetgen-placement-intent
+spec:
+ app-name: packetgen
+ intent:
+ allOf:
+ - provider-name: vfw-cluster-provider
+ cluster-label-name: LabelA
+---
+#add the prometheus app placement intent to the generic placement intent
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/generic-placement-intents/fw-placement-intent/app-intents
+metadata:
+ name: firewall-placement-intent
+spec:
+ app-name: firewall
+ intent:
+ allOf:
+ - provider-name: vfw-cluster-provider
+ cluster-label-name: LabelA
+
+---
+#add the prometheus app placement intent to the generic placement intent
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/generic-placement-intents/fw-placement-intent/app-intents
+metadata:
+ name: sink-placement-intent
+spec:
+ app-name: sink
+ intent:
+ allOf:
+ - provider-name: vfw-cluster-provider
+ cluster-label-name: LabelA
+
+---
+#creating cluster provider
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent
+metadata :
+ name: vfw_ovnaction_intent
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents
+metadata :
+ name: packetgen_workload_intent
+spec:
+ application-name: packetgen
+ workload-resource: r1-packetgen
+ type: Deployment
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents
+metadata :
+ name: firewall_workload_intent
+spec:
+ application-name: firewall
+ workload-resource: r1-firewall
+ type: Deployment
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents
+metadata :
+ name: sink_workload_intent
+spec:
+ application-name: sink
+ workload-resource: r1-sink
+ type: Deployment
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/packetgen_workload_intent/interfaces
+metadata :
+ name: packetgen_unprotected_if
+spec:
+ interface: eth1
+ name: unprotected-private-net
+ defaultGateway: "false"
+ ipAddress: 192.168.10.2
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/packetgen_workload_intent/interfaces
+metadata :
+ name: packetgen_emco_if
+spec:
+ interface: eth2
+ name: emco-private-net
+ defaultGateway: "false"
+ ipAddress: 10.10.20.2
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
+metadata :
+ name: firewall_emco_if
+spec:
+ interface: eth3
+ name: emco-private-net
+ defaultGateway: "false"
+ ipAddress: 10.10.20.3
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
+metadata :
+ name: firewall_unprotected_if
+spec:
+ interface: eth1
+ name: unprotected-private-net
+ defaultGateway: "false"
+ ipAddress: 192.168.10.3
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/firewall_workload_intent/interfaces
+metadata :
+ name: firewall_protected_if
+spec:
+ interface: eth2
+ name: protected-private-net
+ defaultGateway: "false"
+ ipAddress: 192.168.20.2
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/sink_workload_intent/interfaces
+metadata :
+ name: sink_protected_if
+spec:
+ interface: eth1
+ name: protected-private-net
+ defaultGateway: "false"
+ ipAddress: 192.168.20.3
+
+---
+#
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/network-controller-intent/vfw_ovnaction_intent/workload-intents/sink_workload_intent/interfaces
+metadata :
+ name: sink_emco_if
+spec:
+ interface: eth2
+ name: emco-private-net
+ defaultGateway: "false"
+ ipAddress: 10.10.20.4
+
+---
+#create deployment intent group
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups
+metadata :
+ name: vfw_deployment_intent_group
+spec:
+ profile: vfw_composite-profile
+ version: r1
+ override-values:
+ - app-name: packetgen
+ values:
+ ".Values.service.ports.nodePort": '30888'
+ - app-name: firewall
+ values:
+ ".Values.global.dcaeCollectorIp": 1.2.3.4
+ ".Values.global.dcaeCollectorPort": '8888'
+ - app-name: sink
+ values:
+ ".Values.service.ports.nodePort": '30677'
+
+---
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/intents
+metadata :
+ name: fw-deployment-intent
+spec:
+ intent:
+ genericPlacementIntent: fw-placement-intent
+ ovnaction: vfw_ovnaction_intent
+
+---
+version: emco/v2
+resourceContext:
+ anchor: projects/testvfw/composite-apps/compositevfw/v1/deployment-intent-groups/vfw_deployment_intent_group/approve