From ea449054815083e254b48c46aad464d054b440e3 Mon Sep 17 00:00:00 2001 From: Tal Liron Date: Wed, 14 Aug 2024 17:50:38 -0500 Subject: [PATCH] Preparation for TOSCA 2.0 --- FAQ.md | 8 +- TUTORIAL.md | 50 +-- clout/README.md | 8 +- examples/{tosca => 1.3}/README.md | 0 examples/{tosca => 1.3}/artifacts.yaml | 0 examples/{tosca => 1.3}/attributes.yaml | 0 examples/{tosca => 1.3}/copy.yaml | 0 examples/{tosca => 1.3}/data-types.yaml | 6 +- examples/{tosca => 1.3}/descriptions.yaml | 0 examples/{tosca => 1.3}/dsl-definitions.yaml | 0 examples/{tosca => 1.3}/functions.yaml | 2 +- examples/{tosca => 1.3}/imports/mongodb.yaml | 0 examples/{tosca => 1.3}/imports/nginx.yaml | 0 .../imports/super-load-balancer.yaml | 0 .../{tosca => 1.3}/inputs-and-outputs.yaml | 0 examples/{tosca => 1.3}/interfaces.yaml | 0 examples/{tosca => 1.3}/metadata.yaml | 0 examples/{tosca => 1.3}/namespaces.yaml | 0 .../{tosca => 1.3}/policies-and-groups.yaml | 0 .../requirements-and-capabilities.yaml | 4 +- examples/{tosca => 1.3}/simple-for-nfv.yaml | 0 .../{tosca => 1.3}/source-and-target.yaml | 0 .../substitution-mapping-client.yaml | 0 .../{tosca => 1.3}/substitution-mapping.yaml | 0 examples/{tosca => 1.3}/unicode.yaml | 0 examples/{tosca => 1.3}/workflows.yaml | 0 examples/2.0/README.md | 60 ++++ examples/2.0/artifacts.yaml | 57 ++++ examples/2.0/attributes.yaml | 49 +++ examples/2.0/copy.yaml | 52 ++++ examples/2.0/data-types.yaml | 294 ++++++++++++++++++ examples/2.0/descriptions.yaml | 70 +++++ examples/2.0/dsl-definitions.yaml | 33 ++ examples/2.0/functions.yaml | 104 +++++++ .../future/_tosca_2_0.yaml} | 0 examples/2.0/imports/cloud.yaml | 6 + examples/2.0/imports/mongodb.yaml | 13 + examples/2.0/imports/nginx.yaml | 13 + examples/2.0/imports/super-load-balancer.yaml | 31 ++ examples/2.0/inputs-and-outputs.yaml | 51 +++ examples/2.0/interfaces.yaml | 175 +++++++++++ examples/2.0/metadata.yaml | 56 ++++ examples/2.0/namespaces.yaml | 49 +++ examples/2.0/policies-and-groups.yaml | 139 +++++++++ .../2.0/requirements-and-capabilities.yaml | 256 +++++++++++++++ examples/2.0/simple-for-nfv.yaml | 48 +++ examples/2.0/source-and-target.yaml | 49 +++ examples/2.0/substitution-mapping-client.yaml | 52 ++++ examples/2.0/substitution-mapping.yaml | 66 ++++ examples/2.0/unicode.yaml | 66 ++++ examples/2.0/workflows.yaml | 90 ++++++ examples/java/README.md | 2 +- examples/javascript/artifacts.yaml | 2 +- examples/javascript/functions.yaml | 2 +- examples/{tosca => }/legacy/tosca_1_0.yaml | 0 examples/{tosca => }/legacy/tosca_1_1.yaml | 0 examples/{tosca => }/legacy/tosca_1_2.yaml | 0 examples/python/README.md | 2 +- examples/ruby/README.md | 2 +- executables/puccini-clout/default.pgo | Bin 2937 -> 2406 bytes executables/puccini-csar/default.pgo | Bin 2308 -> 690 bytes executables/puccini-tosca/default.pgo | Bin 11200 -> 9557 bytes go.mod | 12 +- go.sum | 23 +- library/default.pgo | Bin 11200 -> 9557 bytes puccini_test.go | 54 ++-- scripts/_env | 2 +- scripts/build-wrapper-python | 2 +- scripts/test | 1 + scripts/test-formats | 2 +- scripts/test-git-url | 2 +- scripts/test-https-url | 2 +- scripts/test-java | 2 +- scripts/test-js | 2 +- scripts/test-parse | 2 +- scripts/test-python | 2 +- scripts/test-ruby | 2 +- scripts/test-visualize | 2 +- scripts/test-wasi | 4 +- scripts/test-wasm | 2 +- .../puccini/tosca/plugins/modules/compile.py | 2 +- wrappers/python/description.md | 20 +- wrappers/python/setup.py | 2 +- 83 files changed, 2000 insertions(+), 109 deletions(-) rename examples/{tosca => 1.3}/README.md (100%) rename examples/{tosca => 1.3}/artifacts.yaml (100%) rename examples/{tosca => 1.3}/attributes.yaml (100%) rename examples/{tosca => 1.3}/copy.yaml (100%) rename examples/{tosca => 1.3}/data-types.yaml (98%) rename examples/{tosca => 1.3}/descriptions.yaml (100%) rename examples/{tosca => 1.3}/dsl-definitions.yaml (100%) rename examples/{tosca => 1.3}/functions.yaml (97%) rename examples/{tosca => 1.3}/imports/mongodb.yaml (100%) rename examples/{tosca => 1.3}/imports/nginx.yaml (100%) rename examples/{tosca => 1.3}/imports/super-load-balancer.yaml (100%) rename examples/{tosca => 1.3}/inputs-and-outputs.yaml (100%) rename examples/{tosca => 1.3}/interfaces.yaml (100%) rename examples/{tosca => 1.3}/metadata.yaml (100%) rename examples/{tosca => 1.3}/namespaces.yaml (100%) rename examples/{tosca => 1.3}/policies-and-groups.yaml (100%) rename examples/{tosca => 1.3}/requirements-and-capabilities.yaml (98%) rename examples/{tosca => 1.3}/simple-for-nfv.yaml (100%) rename examples/{tosca => 1.3}/source-and-target.yaml (100%) rename examples/{tosca => 1.3}/substitution-mapping-client.yaml (100%) rename examples/{tosca => 1.3}/substitution-mapping.yaml (100%) rename examples/{tosca => 1.3}/unicode.yaml (100%) rename examples/{tosca => 1.3}/workflows.yaml (100%) create mode 100644 examples/2.0/README.md create mode 100644 examples/2.0/artifacts.yaml create mode 100644 examples/2.0/attributes.yaml create mode 100644 examples/2.0/copy.yaml create mode 100644 examples/2.0/data-types.yaml create mode 100644 examples/2.0/descriptions.yaml create mode 100644 examples/2.0/dsl-definitions.yaml create mode 100644 examples/2.0/functions.yaml rename examples/{tosca/future/tosca_2_0.yaml => 2.0/future/_tosca_2_0.yaml} (100%) create mode 100644 examples/2.0/imports/cloud.yaml create mode 100644 examples/2.0/imports/mongodb.yaml create mode 100644 examples/2.0/imports/nginx.yaml create mode 100644 examples/2.0/imports/super-load-balancer.yaml create mode 100644 examples/2.0/inputs-and-outputs.yaml create mode 100644 examples/2.0/interfaces.yaml create mode 100644 examples/2.0/metadata.yaml create mode 100644 examples/2.0/namespaces.yaml create mode 100644 examples/2.0/policies-and-groups.yaml create mode 100644 examples/2.0/requirements-and-capabilities.yaml create mode 100644 examples/2.0/simple-for-nfv.yaml create mode 100644 examples/2.0/source-and-target.yaml create mode 100644 examples/2.0/substitution-mapping-client.yaml create mode 100644 examples/2.0/substitution-mapping.yaml create mode 100644 examples/2.0/unicode.yaml create mode 100644 examples/2.0/workflows.yaml rename examples/{tosca => }/legacy/tosca_1_0.yaml (100%) rename examples/{tosca => }/legacy/tosca_1_1.yaml (100%) rename examples/{tosca => }/legacy/tosca_1_2.yaml (100%) diff --git a/FAQ.md b/FAQ.md index a8efa5bb..fc734e78 100644 --- a/FAQ.md +++ b/FAQ.md @@ -17,7 +17,7 @@ I know, right? Now imagine writing a parser for it... Not only is it a complex l Please join [OASIS's TOSCA community](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=tosca) to help improve the language! -Meanwhile, Puccini includes [examples](examples/tosca/) of TOSCA's grammatical features with some +Meanwhile, Puccini includes [examples](examples/) of TOSCA's grammatical features with some running commentary. Treat them as your playground. Also, if you have 4 hours to spare, grab some snacks, get comfortable, and watch the author's free online course for TOSCA 1.0: [part 1](https://www.youtube.com/watch?v=aMkqLI6o-58), @@ -115,7 +115,7 @@ processor in Python, Ruby, etc., to do exactly what you need, e.g.: Also check out [yq](https://mikefarah.gitbook.io/yq/), a great little tool for extracting YAML and even performing simple manipulations. Example: - puccini-tosca compile examples/tosca/requirements-and-capabilities.yaml | yq '.vertexes.[]|select(.properties.name=="light6")' + puccini-tosca compile examples/1.3/requirements-and-capabilities.yaml | yq '.vertexes.[]|select(.properties.name=="light6")' ### Can I use text templating instead of TOSCA functions like `get_input`? @@ -147,8 +147,8 @@ requiring Jinja2 template processing, after which the `.j2` extension would be s TOSCA has a feature called "substitution mapping", which is useful for modeling service composition. It is, however, a *design* feature. The implementation is up to your orchestration toolchain. See our examples -[here](examples/tosca/substitution-mapping.yaml) and -[here](examples/tosca/substitution-mapping-client.yaml). +[here](examples/1.3/substitution-mapping.yaml) and +[here](examples/1.3/substitution-mapping-client.yaml). Puccini intentionally does *not* support service composition. Each Clout file is its own graph universe. If you need to create graph edges between vertexes in one Clout file and vertexes in other diff --git a/TUTORIAL.md b/TUTORIAL.md index 19367d30..55461a7c 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -15,7 +15,7 @@ Basic Usage Let's start by compiling a self-contained local file: - puccini-tosca compile examples/tosca/descriptions.yaml + puccini-tosca compile examples/1.3/descriptions.yaml What if the file imports other files? TOSCA `imports` can refer to either absolute URLs or relative URLs ([RFC 1808](https://tools.ietf.org/html/rfc1808)). Note that @@ -47,7 +47,7 @@ or wrap it in single quotes: Puccini can also compile YAML from stdin: - cat examples/tosca/descriptions.yaml | puccini-tosca compile + cat examples/1.3/descriptions.yaml | puccini-tosca compile Be aware that a stdin source does not have a path and thus cannot support relative URLs. @@ -76,45 +76,45 @@ The default output format is YAML but other formats are supported: JSON (and [ARD](https://github.com/tliron/kutil/tree/master/ard/)-compatible extended JSON), XML, CBOR, and MessagePack. Here's ARD-compatible XJSON: - puccini-tosca compile examples/tosca/descriptions.yaml --format=xjson + puccini-tosca compile examples/1.3/descriptions.yaml --format=xjson By default the output is nicely indented and and colorized for human readability. You can turn off prettification if you're interested in the most compact output: - puccini-tosca compile examples/tosca/descriptions.yaml --pretty=false + puccini-tosca compile examples/1.3/descriptions.yaml --pretty=false Note that colorization will *always* be disabled in contexts that do not support it. In other words it will likely only appear in stdout for terminal emulators that support ANSI color codes. However, you can also specifically turn off colorization: - puccini-tosca compile examples/tosca/descriptions.yaml --colorize=false + puccini-tosca compile examples/1.3/descriptions.yaml --colorize=false By default the output is sent to stdout but you can also send it to a file (without colorization): - puccini-tosca compile examples/tosca/descriptions.yaml --output=clout.yaml + puccini-tosca compile examples/1.3/descriptions.yaml --output=clout.yaml Of course if running in a shell you can also redirect stdout to a file (again, without colorization): - puccini-tosca compile examples/tosca/descriptions.yaml > clout.yaml + puccini-tosca compile examples/1.3/descriptions.yaml > clout.yaml You can increase the verbosity of logging using `-v` or even `-vv`: - puccini-tosca compile examples/tosca/descriptions.yaml -vv + puccini-tosca compile examples/1.3/descriptions.yaml -vv By default all the log messages go to stderr but we can send them to a file: - puccini-tosca compile examples/tosca/descriptions.yaml -vv --log=puccini.log + puccini-tosca compile examples/1.3/descriptions.yaml -vv --log=puccini.log cat puccini.log If you only want to see the logs and not the Clout output: - puccini-tosca compile examples/tosca/descriptions.yaml -vv > /dev/null + puccini-tosca compile examples/1.3/descriptions.yaml -vv > /dev/null To suppress all output (if you're only interested in the return error code): - puccini-tosca compile examples/tosca/descriptions.yaml --quiet + puccini-tosca compile examples/1.3/descriptions.yaml --quiet Also note that there is a `puccini-tosca parse` command that provides a lot of internal diagnostic information about the language parser. It's generally @@ -128,7 +128,7 @@ More on Compilation Let's try to compile a TOSCA service template that requires inputs: - puccini-tosca compile examples/tosca/inputs-and-outputs.yaml + puccini-tosca compile examples/1.3/inputs-and-outputs.yaml You'll see that Puccini reported a "problem" regarding the unassigned input. Any and all compilation errors, whether they are syntactical, grammatical, or topological, are @@ -138,11 +138,11 @@ problem reporting is one of its most powerful features. By default problems are reported in a human-readable format. However, like the Clout output, problems can be formatted for easier consumption by other tools: - puccini-tosca compile examples/tosca/inputs-and-outputs.yaml --problems-format=json + puccini-tosca compile examples/1.3/inputs-and-outputs.yaml --problems-format=json Let's set that missing input: - puccini-tosca compile examples/tosca/inputs-and-outputs.yaml --input=ram=1gib + puccini-tosca compile examples/1.3/inputs-and-outputs.yaml --input=ram=1gib In this case the input is a string (actually a TOSCA `scalar-unit.size`), but note that the the input format is YAML, which is also JSON-compatible, so that complex input @@ -152,14 +152,14 @@ you can use the `--input` flag more than once to provide multiple inputs. Inputs can also be loaded from a file (locally or at a URL) as straightforward YAML: echo 'ram: 1 gib' > inputs.yaml - puccini-tosca compile examples/tosca/inputs-and-outputs.yaml --inputs=inputs.yaml + puccini-tosca compile examples/1.3/inputs-and-outputs.yaml --inputs=inputs.yaml By default the compiler will "resolve" the topology, meaning that it will atempt to satisfy all node template requirements and create relationships, thus completing the graph. However, sometimes it may be useful to disable the resolution phase in order to avoid excessive problem reports: - puccini-tosca compile examples/tosca/requirements-and-capabilities.yaml --resolve=false + puccini-tosca compile examples/1.3/requirements-and-capabilities.yaml --resolve=false When you turn off the resolution phase you will indeed see no relationships in the Clout (you'll see that the `edgesOut` for all vertexes is an empty list). @@ -180,14 +180,14 @@ from runtime resources. You can see the call stubs by compiling this example: - puccini-tosca compile examples/tosca/functions.yaml + puccini-tosca compile examples/1.3/functions.yaml You'll notice that the call stubs all have the special `$functionCall` key. How do we call the functions? In Puccini we refer to this as "value coercion". As a convenience we can use the `--coerce` flag to coerce the values during compilation: - puccini-tosca compile examples/tosca/functions.yaml --coerce + puccini-tosca compile examples/1.3/functions.yaml --coerce You'll see that all properties now have their actual values rather than call stubs. @@ -201,19 +201,19 @@ data type. Let's try this example: - puccini-tosca compile examples/tosca/data-types.yaml --coerce + puccini-tosca compile examples/1.3/data-types.yaml --coerce -Now, edit `examples/tosca/data-types.yaml` and break a constraint. For example, the +Now, edit `examples/1.3/data-types.yaml` and break a constraint. For example, the `constrained_string` property requires a minimum length of 2 and a maximum length of 5, so let's set its value to a string with length 6, `ABCDEF` (at line 267), and compile and coerce again: - puccini-tosca compile examples/tosca/data-types.yaml --coerce + puccini-tosca compile examples/1.3/data-types.yaml --coerce You'll see a problem reported telling you exactly which constraint failed and where. Now, let's compile this same file without coercion (the default behavior): - puccini-tosca compile examples/tosca/data-types.yaml + puccini-tosca compile examples/1.3/data-types.yaml The problem was not reported this time. @@ -233,13 +233,13 @@ function and constraint call stubs are implemented. Let's use the `puccini-clout` tool to list these embedded scriptlets: - puccini-tosca compile examples/tosca/requirements-and-capabilities.yaml --output=clout.yaml + puccini-tosca compile examples/1.3/requirements-and-capabilities.yaml --output=clout.yaml puccini-clout scriptlet list clout.yaml Note that `puccini-clout` can also accept Clout input from stdin, allowing us to pipe the two tools: - puccini-tosca compile examples/tosca/requirements-and-capabilities.yaml | puccini-clout scriptlet list + puccini-tosca compile examples/1.3/requirements-and-capabilities.yaml | puccini-clout scriptlet list Let's extract a scriptlet's source code: @@ -270,7 +270,7 @@ the topology: Note another shortcut for `puccini-tosca compile`: you can use the `--exec` flag to execute scriptlets right after compilation, thus skipping the Clout intermediary: - puccini-tosca compile examples/tosca/requirements-and-capabilities.yaml --exec=assets/tosca/profiles/common/1.0/js/visualize.js + puccini-tosca compile examples/1.3/requirements-and-capabilities.yaml --exec=assets/tosca/profiles/common/1.0/js/visualize.js See [here](executables/puccini-clout/) for more information about the `puccini-clout` tool. diff --git a/clout/README.md b/clout/README.md index 3f25f43c..fac1e7cf 100644 --- a/clout/README.md +++ b/clout/README.md @@ -82,7 +82,7 @@ General implementation-specific properties for the whole topology. The difference between `metadata` and `properties` is a matter of convention. Generally, `properties` should be used for data that is implementation-specific while `metadata` should be used for tooling. It is understood that this distinction might not always be clear and thus you should not treat the -two areas differently in terms of state management. +two areas differently in terms of state management. ### `vertexes` (map of string to Vertex) @@ -254,7 +254,7 @@ It may also have the follow optional fields for debugging information: * `typeMetadata`: a map of strings associated with the value's type * `localMetadata`: a map of strings associated with the value itself -Example (generated from [this TOSCA example](../examples/tosca/data-types.yaml)): +Example (generated from [this TOSCA example](../examples/1.3/data-types.yaml)): ```yaml lowercase_string_map: @@ -271,7 +271,7 @@ lowercase_string_map: name: tosca.function.concat path: topology_template.node_templates["data"].properties["lowercase_string_map"]["concat:¶ - recip¶ - ient"] row: 194 - url: file:/Depot/Projects/RedHat/puccini/examples/tosca/data-types.yaml + url: file:/Depot/Projects/RedHat/puccini/examples/1.3/data-types.yaml $primitive: Puccini $meta: type: map @@ -286,7 +286,7 @@ lowercase_string_map: name: tosca.constraint.pattern path: topology_template.node_templates["data"].properties["lowercase_string_map"] row: 194 - url: file:/Depot/Projects/RedHat/puccini/examples/tosca/data-types.yaml + url: file:/Depot/Projects/RedHat/puccini/examples/1.3/data-types.yaml value: type: string ``` diff --git a/examples/tosca/README.md b/examples/1.3/README.md similarity index 100% rename from examples/tosca/README.md rename to examples/1.3/README.md diff --git a/examples/tosca/artifacts.yaml b/examples/1.3/artifacts.yaml similarity index 100% rename from examples/tosca/artifacts.yaml rename to examples/1.3/artifacts.yaml diff --git a/examples/tosca/attributes.yaml b/examples/1.3/attributes.yaml similarity index 100% rename from examples/tosca/attributes.yaml rename to examples/1.3/attributes.yaml diff --git a/examples/tosca/copy.yaml b/examples/1.3/copy.yaml similarity index 100% rename from examples/tosca/copy.yaml rename to examples/1.3/copy.yaml diff --git a/examples/tosca/data-types.yaml b/examples/1.3/data-types.yaml similarity index 98% rename from examples/tosca/data-types.yaml rename to examples/1.3/data-types.yaml index 7c191b34..9e998c4d 100644 --- a/examples/tosca/data-types.yaml +++ b/examples/1.3/data-types.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_3 # To apply the constraints use "--coerce": -# puccini-tosca compile --coerce examples/tosca/data-types.yaml +# puccini-tosca compile --coerce examples/1.3/data-types.yaml metadata: @@ -245,7 +245,7 @@ topology_template: version: 1.2.3.beta-4 # Range is actually quite limited in use: - # * Unsigned integers only + # * Unsigned integers only # * Upper must be >= than lower # You can also use "UNBOUNDED" string for the upper bound, which will be converted to # the maximum uint value @@ -268,7 +268,7 @@ topology_template: 3 - |- - + # Constraints: min length = 2 and max length = 5 # (The length-related constraints work on both strings and lists) constrained_string: ABCDE diff --git a/examples/tosca/descriptions.yaml b/examples/1.3/descriptions.yaml similarity index 100% rename from examples/tosca/descriptions.yaml rename to examples/1.3/descriptions.yaml diff --git a/examples/tosca/dsl-definitions.yaml b/examples/1.3/dsl-definitions.yaml similarity index 100% rename from examples/tosca/dsl-definitions.yaml rename to examples/1.3/dsl-definitions.yaml diff --git a/examples/tosca/functions.yaml b/examples/1.3/functions.yaml similarity index 97% rename from examples/tosca/functions.yaml rename to examples/1.3/functions.yaml index 2415172b..22fd6a63 100644 --- a/examples/tosca/functions.yaml +++ b/examples/1.3/functions.yaml @@ -72,7 +72,7 @@ topology_template: - ::1 # Some functions support special "modelable entity names", such as "SELF": management_port: { get_property: [ SELF, admin_port ] } - # (Also see: examples/tosca/source-and-target.yaml) + # (Also see: examples/1.3/source-and-target.yaml) capabilities: ingress: properties: diff --git a/examples/tosca/imports/mongodb.yaml b/examples/1.3/imports/mongodb.yaml similarity index 100% rename from examples/tosca/imports/mongodb.yaml rename to examples/1.3/imports/mongodb.yaml diff --git a/examples/tosca/imports/nginx.yaml b/examples/1.3/imports/nginx.yaml similarity index 100% rename from examples/tosca/imports/nginx.yaml rename to examples/1.3/imports/nginx.yaml diff --git a/examples/tosca/imports/super-load-balancer.yaml b/examples/1.3/imports/super-load-balancer.yaml similarity index 100% rename from examples/tosca/imports/super-load-balancer.yaml rename to examples/1.3/imports/super-load-balancer.yaml diff --git a/examples/tosca/inputs-and-outputs.yaml b/examples/1.3/inputs-and-outputs.yaml similarity index 100% rename from examples/tosca/inputs-and-outputs.yaml rename to examples/1.3/inputs-and-outputs.yaml diff --git a/examples/tosca/interfaces.yaml b/examples/1.3/interfaces.yaml similarity index 100% rename from examples/tosca/interfaces.yaml rename to examples/1.3/interfaces.yaml diff --git a/examples/tosca/metadata.yaml b/examples/1.3/metadata.yaml similarity index 100% rename from examples/tosca/metadata.yaml rename to examples/1.3/metadata.yaml diff --git a/examples/tosca/namespaces.yaml b/examples/1.3/namespaces.yaml similarity index 100% rename from examples/tosca/namespaces.yaml rename to examples/1.3/namespaces.yaml diff --git a/examples/tosca/policies-and-groups.yaml b/examples/1.3/policies-and-groups.yaml similarity index 100% rename from examples/tosca/policies-and-groups.yaml rename to examples/1.3/policies-and-groups.yaml diff --git a/examples/tosca/requirements-and-capabilities.yaml b/examples/1.3/requirements-and-capabilities.yaml similarity index 98% rename from examples/tosca/requirements-and-capabilities.yaml rename to examples/1.3/requirements-and-capabilities.yaml index a4eff8c7..2b615a59 100644 --- a/examples/tosca/requirements-and-capabilities.yaml +++ b/examples/1.3/requirements-and-capabilities.yaml @@ -6,7 +6,7 @@ tosca_definitions_version: tosca_simple_yaml_1_3 # Note that by default "puccini-tosca compile" will attempt to resolve the topoloy # (meaning: satisfy all requirements) # But it's possible to disable it: -# puccini-tosca compile --resolve=false examples/tosca/requirements-and-capabilities.yaml +# puccini-tosca compile --resolve=false examples/1.3/requirements-and-capabilities.yaml metadata: @@ -170,7 +170,7 @@ topology_template: properties: - frequency: greater_than: 100 # 100 hz - + # You can add a relationship type to the requirement # (If you don't, Puccini creates an empty relationship with no properties) light9: diff --git a/examples/tosca/simple-for-nfv.yaml b/examples/1.3/simple-for-nfv.yaml similarity index 100% rename from examples/tosca/simple-for-nfv.yaml rename to examples/1.3/simple-for-nfv.yaml diff --git a/examples/tosca/source-and-target.yaml b/examples/1.3/source-and-target.yaml similarity index 100% rename from examples/tosca/source-and-target.yaml rename to examples/1.3/source-and-target.yaml diff --git a/examples/tosca/substitution-mapping-client.yaml b/examples/1.3/substitution-mapping-client.yaml similarity index 100% rename from examples/tosca/substitution-mapping-client.yaml rename to examples/1.3/substitution-mapping-client.yaml diff --git a/examples/tosca/substitution-mapping.yaml b/examples/1.3/substitution-mapping.yaml similarity index 100% rename from examples/tosca/substitution-mapping.yaml rename to examples/1.3/substitution-mapping.yaml diff --git a/examples/tosca/unicode.yaml b/examples/1.3/unicode.yaml similarity index 100% rename from examples/tosca/unicode.yaml rename to examples/1.3/unicode.yaml diff --git a/examples/tosca/workflows.yaml b/examples/1.3/workflows.yaml similarity index 100% rename from examples/tosca/workflows.yaml rename to examples/1.3/workflows.yaml diff --git a/examples/2.0/README.md b/examples/2.0/README.md new file mode 100644 index 00000000..7608eebd --- /dev/null +++ b/examples/2.0/README.md @@ -0,0 +1,60 @@ +TOSCA Grammar Examples +====================== + +Here you'll find a nice little playground for learning the basic features of TOSCA. + +Try modifying the files and then see if the service template can still be parsed. + +Did you make a mistake? Puccini should catch all syntactical and grammatical errors and provide you +with a helpful report. + +Syntax +------ + +* [Namespaces](namespaces.yaml) +* [Copy](copy.yaml) +* [DSL Definitions](dsl-definitions.yaml) +* [Unicode](unicode.yaml) + +Data +---- + +* [Data Types](data-types.yaml) +* [Descriptions](descriptions.yaml) +* [Metadata](metadata.yaml) +* [Attributes](attributes.yaml) + +Entities +-------- + +* [Artifacts](artifacts.yaml) +* [Policies and Groups](policies-and-groups.yaml) +* [Inputs and Outputs](inputs-and-outputs.yaml) + +Topology +-------- + +* [Requirements and Capabilities](requirements-and-capabilities.yaml) + +Functions +--------- + +* [Functions](functions.yaml) +* [Source and Target](source-and-target.yaml) + +Orchestration +------------- + +* [Interfaces](interfaces.yaml) +* [Workflows](workflows.yaml) + +Composition +----------- + +* [Substitution Mapping](substitution-mapping.yaml) +* [Substitution Mapping Client](substitution-mapping-client.yaml) + +NFV +--- + +* [Simple for NFV](simple-for-nfv.yaml) diff --git a/examples/2.0/artifacts.yaml b/examples/2.0/artifacts.yaml new file mode 100644 index 00000000..45e26580 --- /dev/null +++ b/examples/2.0/artifacts.yaml @@ -0,0 +1,57 @@ +tosca_definitions_version: tosca_2_0 + +# You can write your own JavaScript scriptlet or chain a processor to extract artifact +# files, upload them, execute them, etc. + +# For an example, see: examples/javascript/artifacts.yaml + +metadata: + + template_name: Artifacts Example + template_author: Puccini + +repositories: + + centos: + url: https://cloud.centos.org/centos/8/x86_64/images/ + +artifact_types: + + QCOW: + properties: + os: + type: string + version: + type: string + mime_type: application/x-qcow + file_ext: [ qcow, qcow2 ] + +node_types: + + Orchestrator: + # When you attach an artifact to a node type it is *not* automatically attached to node templates + # It's just a way to provide default values + artifacts: + image: + type: QCOW + artifact_version: '2' + # You don't have to use a repository like we do here + # Without a repository, path is relative to this file's location, even if it's within a CSAR + repository: centos + # The extension must match our definition at the artifact type + file: CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2 + properties: + os: CentOS + version: '7.0' + +service_template: + + node_templates: + + orchestrator: + type: Orchestrator + artifacts: + # Note that you can attach artifacts here even if they are not defined at the node type + # But if they are, you must use the same artifact type or a derived type + image: + deploy_path: /var/lib/orchestration/images/ diff --git a/examples/2.0/attributes.yaml b/examples/2.0/attributes.yaml new file mode 100644 index 00000000..a5975b11 --- /dev/null +++ b/examples/2.0/attributes.yaml @@ -0,0 +1,49 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: Attributes Example + template_author: Puccini + +node_types: + + Backup: + # Unlike "properties", you can't mark an attribute as required or not + # Attributes are *always* added to the node template, even if they have not been assigned + # If they don't have a "default" value, they will get an automatic, sensible default + # (E.g., a string will get an empty string) + # But this might not always match constraints, which would result in an error + # So in some cases you might have to explicitly assign a default + attributes: + days: + type: list + entry_schema: DayOfWeek + max_size: + description: Max size + type: scalar-unit.size + +data_types: + + DayOfWeek: + derived_from: string + constraints: + - valid_values: [ su, mo, tu, we, th, fr, sa ] + +service_template: + + node_templates: + + backup1: + type: Backup + attributes: + # You can assign initial values to attributes + # Though it's expected that they may change + max_size: 10 gib + + backup2: + type: Backup + attributes: + # There is also a long notation that lets you override the description + max_size: + description: Current max size + value: 10 gib diff --git a/examples/2.0/copy.yaml b/examples/2.0/copy.yaml new file mode 100644 index 00000000..8eba4a49 --- /dev/null +++ b/examples/2.0/copy.yaml @@ -0,0 +1,52 @@ +tosca_definitions_version: tosca_2_0 + +# "copy" is a convience feature that works like a YAML copy-and-merge +# It is available for both node templates and relationship templates +# The YAML is copied from the source to the target *before* applying the changes +# Note that during the merge of values lists are replaced, not appended to +# This can happen recursively, +# though Puccini does make sure to report a problem if you are copying in a loop + +metadata: + + template_name: Copy Example + template_author: Puccini + +node_types: + + Machine: + properties: + cpu: + type: CPU + +data_types: + + CPU: + properties: + architecture: + type: string + cores: + type: integer + +service_template: + + node_templates: + + server1: + type: Machine + properties: + cpu: + architecture: x86 + cores: 4 + + server2: + copy: server1 + properties: + cpu: + cores: 8 + + client: + copy: server2 + properties: + cpu: + architecture: ARM diff --git a/examples/2.0/data-types.yaml b/examples/2.0/data-types.yaml new file mode 100644 index 00000000..e04b8d62 --- /dev/null +++ b/examples/2.0/data-types.yaml @@ -0,0 +1,294 @@ +tosca_definitions_version: tosca_2_0 + +# To apply the constraints use "--coerce": +# puccini-tosca compile --coerce examples/2.0/data-types.yaml + +metadata: + + template_name: Data Types Example + template_author: Puccini + +node_types: + + DataNode: + properties: + + # Primitive types + string: + type: string + integer: + type: integer + float: + type: float + default: -0.1 + boolean: + type: boolean + required: false + # Note: We must wrap "null" in quotes so that the YAML parser won't treat it as null + 'null': + type: 'null' + + # List and map types *must* specify "entry_schema" for entry types + integer_list: + type: list + entry_schema: integer + string_map: + type: map + entry_schema: string + + # Complex types are defined in "data_types" + complex: + type: Complex + + # The "entry_schema" can be a complex type + complex_list: + type: list + entry_schema: Complex + + # The following are "special" types + # Puccini will insert an object that has a rich API, accessible in JavaScript + scalar_unit_size: + type: scalar-unit.size + scalar_unit_time: + type: scalar-unit.time + scalar_unit_frequency: + type: scalar-unit.frequency + scalar_unit_bitrate: + type: scalar-unit.bitrate + timestamp: + type: timestamp + version: + type: version + range: + type: range + + # These can also be considered to be "special" types + # Though they are currently part of the Simple Profile + json: + type: tosca.datatypes.json + xml: + type: tosca.datatypes.xml + + # Properties can have constraints + # Note that constraints *must* use literal values (no function calls) + # (*All* constraints must be satisfied by values; it's a logical "and") + constrained_string: + type: string + constraints: + - min_length: 2 + - max_length: 5 + + # This property is also constrained, but not here: see the data type + # (You can also add *additional* constraints here if needed; it's logical "and") + lowercase: + type: LowerCase + + # We can constrain map keys via the "key_schema" + # The key_schema must be string (the default) or a derivative + lowercase_string_map: + type: map + key_schema: LowerCase + entry_schema: string + + # Using a longer notation you can also set constraints for the entry schema + # (Remember: logical "and") + constrained_float_list: + type: list + entry_schema: + type: float + constraints: + - in_range: [ -1.0, 1.0 ] + + # Constraints are type-aware, such that comparisons of special type values + # will be done semantically, e.g. a "scalar-unit": + constrained_time: + type: scalar-unit.time + constraints: + - in_range: [ 1m, 1h ] + + # Another example showing semantic "version" comparison + constrained_version: + type: version + constraints: + - in_range: [ 1.2.3.beta-3, 1.2.3.beta-5 ] + + # Custom map + time_map: + type: TimeMap + + # In Puccini you can also create your own custom constraints + # See: examples/javascript/constraints.yaml + +data_types: + + Complex: + # (Poorly named: these are really "fields" of our complex type, rather than "properties") + properties: + string: + type: string + # Individual "properties" can have default values + default: Default Value + integer: + type: integer + float: + type: float + # "Properties" are required by default + required: false + # Complex types can be nested + nested: + type: Nested + + Nested: + properties: + nested_float: + type: float + constraints: + - greater_or_equal: 0.0 + nested_string: + type: string + required: false + + # Puccini lets you derive from primitive types; useful for adding constraints + # Note that if you derive from a primitive you *cannot* also define properties + LowerCase: + derived_from: string + description: Lowercase string + constraints: + - pattern: '[a-z]*' + + TimeMap: + derived_from: map + # You can only use entry_schema if you derive from map or list + # And you can only use key_schema if you derive from map + entry_schema: scalar-unit.time + +service_template: + + inputs: + + number: + type: integer + default: 4 + + node_templates: + + data: + type: DataNode + properties: + + string: Hello, Puccini + integer: 123 + float: 12.3 + boolean: true + # The "null" type can have only the null value + 'null': null + + integer_list: [ 1, 2, 3, { get_input: number } ] + + string_map: + Greeting: Hello + # Note that values as well map keys could be function calls + Message: { concat: [ Good, ' ', Day ] } + { concat: [ Recip, ient ] }: Puccini + + lowercase_string_map: + greeting: Hello + { concat: [ recip, ient ] }: Puccini + + complex: + string: Hello, Puccini + integer: 123 + nested: + nested_float: 12.3 + + complex_list: + - integer: 123 + nested: + nested_float: 45.6 + - integer: 789 + nested: + nested_float: 1.0 + + # Size is normalized to number of bytes (unsigned integer) + # GiB, MiB, etc. are also supported for multiples of 1024 + # For most scalars the case of the unit doesn't matter ("gB" = "Gb") + scalar_unit_size: 1.23 gb + + # Time is normalized to seconds (float) + # Also, you don't need a space between the scalar and the unit + scalar_unit_time: 1.23ms + + # Frequency is normalized to Hz (float) + scalar_unit_frequency: 123e3 kHz + + # Bitrate is normalized to bits-per-second (float) + # This is the only scalar in which the case *does* matter: + # Use "b" for bits and "B" for bytes + # Gibps, Mibps, etc. are also supported for multiples of 1024 + scalar_unit_bitrate: 1.23 KiBps + + # "timestamp" is a string formatted according to ISO 8601: + timestamp: '1975-09-15 12:34:56.7 +2' + + # Note that some YAML environments may support a !!timestamp type: + # http://yaml.org/type/timestamp.html + # Normally Puccini will not allow it, but it could be enabled via a quirk: + # puccini-tosca compile --quirk=data_types.timestamp.permissive + # (In this case the YAML parser parses the timestamp, not Puccini's TOSCA parser) + #timestamp: !!timestamp 1975-09-15t12:34:56.7+02:00 + + # The version structure in TOSCA is very specific and might not fit your needs + # This example has all fields: major.minor.fix.qualifier-build + # (You need *at least* major.minor) + # With "--quirk=data_types.string.permissive" enabled Puccini will also accept + # literal integers such as "5" and literal floats such as "5.2" + version: 1.2.3.beta-4 + + # Range is actually quite limited in use: + # * Unsigned integers only + # * Upper must be >= than lower + # You can also use "UNBOUNDED" string for the upper bound, which will be converted to + # the maximum uint value + range: [ 1, UNBOUNDED ] + + # These are validated, but otherwise the text will be left as is + json: |- + { + "key1": "value", + "key2": [ 1, 2, 3 ] + } + xml: + # Constraints are applied *after* functions are called + concat: + - | + value + + 1 + 2 + 3 + - |- + + + # Constraints: min length = 2 and max length = 5 + # (The length-related constraints work on both strings and lists) + constrained_string: ABCDE + + # Constraints: lowercase letters only + lowercase: helloworld + + # Constraints: -1.0 <= x <= 1.0 + constrained_float_list: + - -0.999 + - 0.0 + - 1.0 + + # Constraints: 1m <= x <= 1h + constrained_time: 10.5m + + # Constraints: 1.2.3.beta-3 <= x <= 1.2.3.beta-5 + constrained_version: 1.2.3.beta-4 + + # Custom map + time_map: + first: 100 s + second: 200 s diff --git a/examples/2.0/descriptions.yaml b/examples/2.0/descriptions.yaml new file mode 100644 index 00000000..1f770968 --- /dev/null +++ b/examples/2.0/descriptions.yaml @@ -0,0 +1,70 @@ +tosca_definitions_version: tosca_2_0 + +# You can add a human-readable "description" almost anywhere in TOSCA +# Descriptions are compiled into Clout + +metadata: + + template_name: Descriptions Example + template_author: Puccini + +description: >- + My service + +node_types: + + Server: + derived_from: tosca:Compute + # It's good practice to use YAML's ">-" for multiline strings + # (It will collapse paragraphs into lines and remove the final trailing newline) + description: >- + A really good server for our application. + + On a scale of 1 to 10, this is an "11" server. That's how good it is. + properties: + cost: + type: float + # Even properties can have descriptions + description: Cost in US dollars + + SuperServer: + derived_from: Server + properties: + memory_configurations: + description: Tiers of memory + type: map + entry_schema: + type: RAMSize + # Using the long notation for "entry_schema" you can specify a description for it + # (Which will override the type's description) + description: Soldered RAM size + default: + low: 1 gib + mid: 4 gib + hi: 16 gib + +data_types: + + RAMSize: + derived_from: scalar-unit.size + description: RAM size + +service_template: + + description: >- + My service template. + + Note that when compiled this description will be appended to the service level description. + + node_templates: + + main: + type: Server + description: The main server + properties: + cost: 1200.0 + + super: + type: SuperServer + properties: + cost: 2200.0 diff --git a/examples/2.0/dsl-definitions.yaml b/examples/2.0/dsl-definitions.yaml new file mode 100644 index 00000000..a043252f --- /dev/null +++ b/examples/2.0/dsl-definitions.yaml @@ -0,0 +1,33 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: DSL Definitions Example + template_author: Puccini + +dsl_definitions: + + # This area is allowed but otherwise ignored by TOSCA + # Its intended use is as a scratch space for YAML anchors + # See: http://yaml.org/spec/1.2/spec.html#id2785586 + + # (Note that the key name doesn't matter here + # It's just a placeholder) + port: &PORT + properties: + protocol: udp + port: 9100 + +service_template: + + node_templates: + + web: + type: tosca:WebServer + capabilities: + # Here we'll use the anchor + data_endpoint: *PORT + admin_endpoint: *PORT + + host: + type: tosca:Compute diff --git a/examples/2.0/functions.yaml b/examples/2.0/functions.yaml new file mode 100644 index 00000000..46c6021a --- /dev/null +++ b/examples/2.0/functions.yaml @@ -0,0 +1,104 @@ +tosca_definitions_version: tosca_2_0 + +# To evaluate the functions use "--coerce": +# puccini-tosca compile --coerce functions.yaml + +# Puccini also lets you create your own custom functions +# See: examples/javascript/functions.yaml + +metadata: + + template_name: Functions Example + template_author: Puccini + +node_types: + + Ports: + properties: + user_port: + type: tosca:PortInfo + required: false + admin_port: + type: tosca:PortInfo + required: false + management_port: + type: tosca:PortInfo + required: false + capabilities: + ingress: Ingress + requirements: + - egress: + capability: Ingress + relationship: Connection + +capability_types: + + Ingress: + properties: + ingress_port: + type: tosca:PortInfo + required: false + +relationship_types: + + Connection: + properties: + connection_port: + type: tosca:PortInfo + required: false + +service_template: + + node_templates: + + ports1: + type: Ports + properties: + user_port: + addresses: + # You can call functions in property, attribute, input, or output assignments + # (and *only* there) + - { concat: [ local, host ] } + - { token: [ ip=10.0.0.2, =, 1 ] } + - { join: [ [ 192, 168, 1, 1 ], . ] } + # Function calls can be nested + - { concat: [ 127, ., 0, ., { concat: [ 0, ., 1 ] } ] } + # Also note that YAML allows this multiline notation for function calls: + - concat: + - '::' + - 1 + admin_port: + addresses: + - ::1 + # Some functions support special "modelable entity names", such as "SELF": + management_port: { get_property: [ SELF, admin_port ] } + # (Also see: examples/2.0/source-and-target.yaml) + capabilities: + ingress: + properties: + ingress_port: + addresses: + - 192.168.1.2 + + ports2: + type: Ports + properties: + user_port: + # This function returns a list + addresses: { get_nodes_of_type: Ports } + management_port: + addresses: + # "get_property" can extract nested values, even from lists: + - { get_property: [ ports1, management_port, addresses, 0 ] } + # The second argument for "get_property" can be a cabability name: + - { get_property: [ ports1, ingress, ingress_port, addresses, 0 ] } + # Or a requirement name (in which case the properties would be that of the relationship): + - { get_property: [ SELF, egress, 0, connection_port, addresses, 0 ] } + requirements: + - egress: + node: ports1 + relationship: + properties: + connection_port: + addresses: + - 192.168.1.3 diff --git a/examples/tosca/future/tosca_2_0.yaml b/examples/2.0/future/_tosca_2_0.yaml similarity index 100% rename from examples/tosca/future/tosca_2_0.yaml rename to examples/2.0/future/_tosca_2_0.yaml diff --git a/examples/2.0/imports/cloud.yaml b/examples/2.0/imports/cloud.yaml new file mode 100644 index 00000000..13930dd8 --- /dev/null +++ b/examples/2.0/imports/cloud.yaml @@ -0,0 +1,6 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: Cloud Profile Example + template_author: Puccini diff --git a/examples/2.0/imports/mongodb.yaml b/examples/2.0/imports/mongodb.yaml new file mode 100644 index 00000000..3ef48845 --- /dev/null +++ b/examples/2.0/imports/mongodb.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: MongoDB Example + template_author: Puccini + +namespace: mongodb + +node_types: + + MongoDB: + derived_from: tosca:DBMS diff --git a/examples/2.0/imports/nginx.yaml b/examples/2.0/imports/nginx.yaml new file mode 100644 index 00000000..2e75e050 --- /dev/null +++ b/examples/2.0/imports/nginx.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: NGINX Example + template_author: Puccini + +namespace: nginx + +node_types: + + NginX: + derived_from: tosca:WebServer diff --git a/examples/2.0/imports/super-load-balancer.yaml b/examples/2.0/imports/super-load-balancer.yaml new file mode 100644 index 00000000..c2a24133 --- /dev/null +++ b/examples/2.0/imports/super-load-balancer.yaml @@ -0,0 +1,31 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: Super Load Balancer Example + template_author: Puccini + +node_types: + + # We're going to allow this single node to be substituted by an entire service + SuperLoadBalancer: + derived_from: tosca:LoadBalancer + properties: + redundancy: + type: integer + required: false + attributes: + admin_state: + type: string + db_state: + type: string + requirements: + # We require hosts for our internal components + - admin_host: + capability: tosca:Compute + node: tosca:Compute + relationship: tosca:HostedOn + - db_host: + capability: tosca:Compute + node: tosca:Compute + relationship: tosca:HostedOn diff --git a/examples/2.0/inputs-and-outputs.yaml b/examples/2.0/inputs-and-outputs.yaml new file mode 100644 index 00000000..7360a5bd --- /dev/null +++ b/examples/2.0/inputs-and-outputs.yaml @@ -0,0 +1,51 @@ +tosca_definitions_version: tosca_2_0 + +# To see the constraints and outputs in action run: +# puccini-tosca compile --coerce --input ram=1gib inputs-and-outputs.yaml + +metadata: + + template_name: Inputs and Outputs Example + template_author: Puccini + +service_template: + + inputs: + # Like properties and attributes, inputs are required by default + # (But you can set "required" to false) + # If any required inputs do not have a value then the parser will fail with a problem report + cores: + type: integer + # You can also assign the "value" field here, but it really works identically to "default" + default: 4 + # Inputs can have constraints + constraints: + - less_than: 8 + ram: + type: scalar-unit.size + # This property is required and doesn't have "default" (or "value"), + # So you *must* specify it in the CLI: + # puccini-tosca --input ram=1gib ... + # (The inputs are in JSON format, which you'll need if you're using a complex data type) + + node_templates: + + server: + type: tosca:Compute + capabilities: + host: + properties: + num_cpus: { get_input: cores } + mem_size: { get_input: ram } + attributes: + # Let's give the attribute an initial value (see: attributes.yaml) + # But the idea is that it would be updated by the deployment + # (That's outside the scope of puccini-tosca) + public_address: + + # Outputs are commonly used for the "get_attribute" function + outputs: + url: + type: string + # You can also assign the "default" field here, but it really works identically to "value" + value: { concat: [ 'http://', { get_attribute: [ server, public_address ] }, ':8080' ] } diff --git a/examples/2.0/interfaces.yaml b/examples/2.0/interfaces.yaml new file mode 100644 index 00000000..47dbe3cd --- /dev/null +++ b/examples/2.0/interfaces.yaml @@ -0,0 +1,175 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: Interfaces Example + template_author: Puccini + +node_types: + + # (You can also define interfaces in group and relationship types) + + Server: + derived_from: tosca:Compute + interfaces: + Maintenance: + type: Maintenance + + # All normative node types (derived from Root) have the "Standard" lifecycle interface + Standard: + # (You can override the type here, but only if it's a derived type) + # You can define operations both at the interface type and at the node type + operations: + create: + # You *must* define inputs in order to assign them at the template + inputs: + retries: + type: integer + attributes: + progress: + type: string + last-turned-off: + type: timestamp + requirements: + - dhcp: + capability: DHCP + relationship: AllocateAddress + + BetterServer: + derived_from: Server + interfaces: + Standard: + operations: + create: + inputs: + # Inputs are inherited (both from interface type and node type) + retries: + # You can override the type, but only if it's a derived type + type: Retries + + DHCPServer: + derived_from: tosca:Compute + capabilities: + dhcp: + type: DHCP + +data_types: + + Retries: + derived_from: integer + constraints: + - greater_or_equal: 0 + +capability_types: + + DHCP: + derived_from: tosca:Endpoint + attributes: + ip-pool: + type: list + entry_schema: + type: string + +interface_types: + + Maintenance: + # You can define inputs for the interface as a whole as well as for individual operations + inputs: + mode: + type: string + constraints: + - valid_values: [ staging, production ] + operations: + maintenance-on: + description: Turn maintenance mode on + maintenance-off: + description: Turn maintenance mode off + inputs: + priority: + type: float + outputs: + # Outputs map to *attributes* + # The attribute must be declared at the type + timestamp: [ SELF, last-turned-off ] + notifications: + progress: + description: Progress on maintenance mode + outputs: + percentage: [ SELF, progress ] + +relationship_types: + + AllocateAddress: + derived_from: tosca:ConnectsTo + interfaces: + Configure: + operations: + pre_configure_source: + inputs: + ip-pool: + value: { get_attribute: [ TARGET, dhcp, ip-pool ] } + outputs: + # Inside a relationship, output mappings can target + # SOURCE and TARGET entities + ip: [ SOURCE, public_address ] + + # We cannot validate the TARGET attributes, because + # the target node type is not known until the target node template is + # resolved. We at best know the base type only. + # + # To evaluate the target use "--coerce": + # puccini-tosca compile --coerce interfaces.yaml + updated-ip-pool: [ TARGET, dhcp, ip-pool ] + +service_template: + + node_templates: + + dhcp-server: + type: DHCPServer + + server: + type: Server + requirements: + - dhcp: + node: dhcp-server + relationship: + interfaces: + Configure: + operations: + pre_configure_source: + implementation: scripts/get_ip.sh + interfaces: + Standard: + operations: + # Shortest notation has just the implementation + start: scripts/start.sh + stop: scripts/start.sh + + # Longer notation with inputs + create: + implementation: scripts/create.sh + inputs: + retries: 3 + + # Longest notation also allows adding dependencies and other params to the implementation + configure: + implementation: + primary: scripts/configure.sh + dependencies: + - scripts/utils.sh + - scripts/config.yaml + timeout: 3 + operation_host: SELF + + Maintenance: + inputs: + mode: production + operations: + maintenance-on: scripts/maintenance-on.sh + maintenance-off: + implementation: scripts/maintenance-off.sh + inputs: + priority: .75 + notifications: + progress: scripts/progress.sh diff --git a/examples/2.0/metadata.yaml b/examples/2.0/metadata.yaml new file mode 100644 index 00000000..16e19d3e --- /dev/null +++ b/examples/2.0/metadata.yaml @@ -0,0 +1,56 @@ +tosca_definitions_version: tosca_2_0 + +# Metadata does not have any specified use +# But, because it's compiled to Clout, it's a great way to add hints for your Clout processor +# or orchestrator + +# For example, Puccini uses metadata to define custom functions +# See: examples/javascript/ + +# The service template can have optional metadata +metadata: + + # The following fields are "normative" and expected in TOSCA + template_name: Metadata Example + template_author: Puccini + template_version: '1.0' # (must be a string so we add quotes to avoid being read as a float) + # And you can add your custom metadata + # (The "." has no special general meaning for metadata names) + galactic.planet: Mercury + +node_types: + + Server: + derived_from: tosca:Compute + # You can also add metadata to any type + # Note that it is not normally inherited: every distinct type has its own metadata + # However, every node template in Clout will get a map of its entire type hierarchy with the + # metadata for each one, so you can decide to interpret any metadata as inheritable + metadata: + galactic.planet: Jupiter + # Types can also have a semantic version + version: 1.0.0 + properties: + planet: + type: Planet + required: false + # Properties can have metadata, too + metadata: + galaxy: Andromeda + +service_template: + + node_templates: + + server: + type: Server + # The metadata for the node template is distinct from that of the node type + metadata: + galactic.planet: Venus + # You can also assign a list of string directives to node templates + # The only "normative" directive mentioned in the TOSCA spec is "substitutable" + # (See: substitution-mapping-client.yaml) + directives: + - proxy + - mock + - disposable diff --git a/examples/2.0/namespaces.yaml b/examples/2.0/namespaces.yaml new file mode 100644 index 00000000..d735cd82 --- /dev/null +++ b/examples/2.0/namespaces.yaml @@ -0,0 +1,49 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: Namespaces Example + template_author: Puccini + +imports: + +# The short notation of import merges the names into this namespace +- imports/nginx.yaml + +# Use the long notation of import to specify "namespace_prefix" +- namespace_prefix: mongodb + file: imports/mongodb.yaml + +# The optional "namespace" keyword specifies the canonical namespace for the types declared here +# (In Puccini it appears only in the compiled Clout output with a "::" separator) +# It is typically used when designing type profiles +# In this file it does nothing, because we do not declare types here +# But see its use in "imports/nginx.yaml" and "imports/mongodb.yaml" +namespace: example + +service_template: + + node_templates: + + web: + # Imported + type: NginX + + db: + # With the namespace prefix we specified in the import + type: mongodb:MongoDB + + server1: + # Normative types have the "tosca" namespace prefix by default + # This is the recommended way to refer to them + type: tosca:Compute + + server2: + # Normative types can also be reffered to without the namespace prefix + # Unfortunately, this means that you can't use these names for your own types + # (This feature can be disabled in Puccini via the "namespace.normative.shortcuts.disable" quirk) + type: Compute + + server3: + # Normative types also have a "fully qualified name" + type: tosca.nodes.Compute diff --git a/examples/2.0/policies-and-groups.yaml b/examples/2.0/policies-and-groups.yaml new file mode 100644 index 00000000..b716be61 --- /dev/null +++ b/examples/2.0/policies-and-groups.yaml @@ -0,0 +1,139 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: Policies and Groups Example + template_author: Puccini + +policy_types: + + Backup: + targets: + # Can include both node types and group types + - tosca:Compute + - RedundantResources # This group type is declared below + # If "targets" is not specified then any node template or group can be a target + + ContinuousBackup: + derived_from: Backup + # Properties are how you configure the policy + properties: + frequency: + type: + scalar-unit.time + # Targets are inherited + + ContinuousBlockStorageBackup: + derived_from: ContinuousBackup + targets: + # When inheriting we are allowed to remove target types that were specified in the parent + # But any types we *do* specify must be equal to or derived from any of those in the parent + - tosca:Compute + - RedundantBlockStorages + # So this would not work: + #- Redundants + +group_types: + + Redundants: + # Groups can have properties + properties: + priority: + type: + float + # "members" is not specified here, so any node template can be a member + + RedundantResources: + derived_from: Redundants + members: + # Can only be node types (nested groups are not supported) + - tosca:Compute + - tosca:Abstract.Storage + + RedundantBlockStorages: + derived_from: RedundantResources + members: + # When inheriting we are allowed to remove member types that were specified in the parent + # But any types we *do* specify must be equal to or derived from any of those in the parent + - tosca:Storage.BlockStorage + # So this would not work: + #- tosca:LoadBalancer + +interface_types: + + Backup: + operations: + start_backup: {} + +node_types: + + SuperCompute: + derived_from: tosca:Compute + interfaces: + backup: + type: Backup + +service_template: + + node_templates: + + server1: + type: tosca:Compute + + server2: + type: tosca:Compute + + server3: + type: tosca:Compute + + server4: + type: SuperCompute + + storage: + type: tosca:Storage.ObjectStorage + properties: + name: My Storage + + groups: + + redundants: + type: RedundantResources + properties: + priority: 0.8 + members: + # Member node templates must match our definition at the group type + # (Can include derived types) + - server3 + - server4 + - storage + + policies: + + # Policies are represented as a sequenced list (potentially indicating order of priority) + # However, note that Puccini does require them to have unique names + + - backup: + type: ContinuousBackup + properties: + frequency: .5 d + triggers: + # Triggers are optional + backup: + event: power-failure + condition: + period: 1 m + constraint: + or: + - private_address: [ { pattern: '^192\.168\.1\..+' } ] + - private_address: [ { pattern: '^192\.168\.2\..+' } ] + action: + - call_operation: Backup.start_backup + # Scheduling a trigger is optional + schedule: + start_time: '2020-01-01T10:00:00Z' + end_time: '2020-01-01T11:00:00Z' + targets: + # Target node templates and groups must match our definition at the policy type + # (Can include derived types) + - server2 + - redundants diff --git a/examples/2.0/requirements-and-capabilities.yaml b/examples/2.0/requirements-and-capabilities.yaml new file mode 100644 index 00000000..3edbbb9b --- /dev/null +++ b/examples/2.0/requirements-and-capabilities.yaml @@ -0,0 +1,256 @@ +tosca_definitions_version: tosca_2_0 + +# This is by far the most elaborate aspect of TOSCA +# There are many ways to define and assign requirements and relationships + +# Note that by default "puccini-tosca compile" will attempt to resolve the topoloy +# (meaning: satisfy all requirements) +# But it's possible to disable it: +# puccini-tosca compile --resolve=false examples/2.0/requirements-and-capabilities.yaml + +metadata: + + template_name: Requirements and Capabilities Example + template_author: Puccini + +node_types: + + # Though requirements are a sequenced list, you cannot specify the same name more than once at the node type + # (Even though you can do so at the node template) + LightBulb: + requirements: + # The short notation is used to just specify a target capability type + - socket: Socket + + # The long notation for requirements lets us further specify a target node type + # And also (optionally) a default relationship type + Fan: + requirements: + - socket: + capability: SuperSocket + node: PowerPanel + relationship: SmartPlug + # You can also control the number of times the requirement *must* be assigned per node template + # The implied default is the range of [ 1, 1 ] + # Note that if you don't specify "occurrences" then a requirement will be automatically assigned + # (That is the situation with the short notation we used in "LightBulb", above) + occurrences: [ 2, UNBOUNDED ] + + PowerPanel: + properties: + age: + type: scalar-unit.time + capabilities: + main: Socket + aux: Socket + emergency: + type: SuperSocket + # The long notation for capabilities lets us specify "occurrences", + # which is how many times the capability *must* be required + # This functionality applies to the requirements resolution phase + # and does *not* have a grammatical (parsing) effect + # (It's thus *very* different from the meaning of the "occurrences" keyword in requirements) + # The default if not specified is [ 0, UNBOUNDED ] + occurrences: [ 2, 4 ] + +capability_types: + + Socket: + properties: + standard: + type: string + voltage: + type: float + frequency: + type: scalar-unit.frequency + + SuperSocket: + derived_from: Socket + properties: + failsafe: + type: boolean + +relationship_types: + + SmartPlug: + properties: + vendor: + type: string + required: false + attributes: + ip_address: + type: string + + SuperSmartPlug: + derived_from: SmartPlug + properties: + failsafe: + type: boolean + +service_template: + + inputs: + age: + type: scalar-unit.time + default: 5 d + + node_templates: + + # By default Puccini will automatically create requirement assignments to ensure that + # the lower bound of the requirement "occurrences" is met, with the default being [ 1, 1 ] + # That requirement has 3 matching capabilities in this topology, + # So Puccini will arbitrarily satisfy it with one of them + light1: + type: LightBulb + + # You can also specify it and require a specific node template + # (It must have a capability of the right type, or a derived type) + light2: + type: LightBulb + requirements: + - socket: main_panel + + # Or specify a node type, which will match with node templates of that type (or a derived type) + # (Again, it must have a matching capability) + light3: + type: LightBulb + requirements: + - socket: PowerPanel + + # With the long notation you can also specify the *name* of the capability at the target node + # (Again, it must be a matching capability) + light4: + type: LightBulb + requirements: + - socket: + node: main_panel + capability: emergency + + # Or you can specify a capability type + # (Which must be derived from the capability type specified at the node type requirement) + light5: + type: LightBulb + requirements: + - socket: + capability: SuperSocket + + # You can use "node_filter" to further require property values at the target node + light6: + type: LightBulb + requirements: + - socket: + capability: Socket + node_filter: + properties: + - age: + # Note that special data types are not supported here + less_than: 8640000 # 100 d -> seconds + + # You can also put "node_filter" at the node itself, in which case the filter will + # apply to *all* requirements + light7: + type: LightBulb + node_filter: + properties: + - age: + less_than: 8640000 # 100 d -> seconds + requirements: + - socket: + capability: Socket + + # "node_filter" can also work on capability properties + light8: + type: LightBulb + requirements: + - socket: + capability: Socket + node_filter: + capabilities: + - emergency: + properties: + - frequency: + greater_than: 100 # 100 hz + + # You can add a relationship type to the requirement + # (If you don't, Puccini creates an empty relationship with no properties) + light9: + type: LightBulb + requirements: + - socket: + relationship: SmartPlug + + # The long notation lets you assign values to the relationship + light10: + type: LightBulb + requirements: + - socket: + relationship: + type: SmartPlug + properties: + vendor: Smart Appliances Industries + + # Yet another option is to use a relationship template (see below) instead of a type + light11: + type: LightBulb + requirements: + - socket: + relationship: smart_plug + + # If the lower bound of occurences is > 1 then you can specify the same requirement more than once, + # which will lead to multiple relationships + # Here it is [ 2, UNBOUNDED ] + fan1: + type: Fan + requirements: + - socket: + relationship: + properties: + vendor: PowerEmperor + - socket: + relationship: + # The relationship type was already specified in the "Fan" node type + # Still, we can change that type as long as it's of a derived type + # (The same rule would apply if we use a relationship template instead) + type: SuperSmartPlug + properties: + vendor: PowerEmperor + failsafe: false + + main_panel: + type: PowerPanel + properties: + age: { get_input: age } + capabilities: + main: + properties: + standard: People's Republic of China + voltage: 220.0 + frequency: 50 hz + aux: + properties: + standard: United States of America + voltage: 110.0 + frequency: 60 hz + emergency: + properties: + standard: High Frequency + voltage: 110.0 + frequency: 120 hz + failsafe: true + + relationship_templates: + + # Relationship templates are not like node templates! + # They do *not* model the topology + # Instead, they are used as a set of "pre-filled" values for relationship assignments + # (See usage in node template "light12" above) + # You can achieve a similar result by deriving a relationship type and providing + # "default" values to properties, attributes, and interface inputs/outputs + smart_plug: + type: SuperSmartPlug + # The metadata for the relationship template is distinct from that of the relationship type + metadata: + galaxy.planet: Jupiter + properties: + vendor: Electric Stuff International + failsafe: false diff --git a/examples/2.0/simple-for-nfv.yaml b/examples/2.0/simple-for-nfv.yaml new file mode 100644 index 00000000..0dc77e63 --- /dev/null +++ b/examples/2.0/simple-for-nfv.yaml @@ -0,0 +1,48 @@ +# To enable the NFV profile use this reserved "tosca_definitions_version" +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0 + +# The Simple Profile for NFV is a work in progress +# It aims to allow ETSI MANO descriptors to be compatible with TOSCA +# It builds on the Simple Profile but actually subverts aspects of it + +metadata: + + template_name: Simple Profile for NFV Example + template_author: Puccini + +topology_template: + + node_templates: + + cpd: + type: tosca:VduCpd + requirements: + - virtual_binding: firewall + + firewall: + type: tosca:VDU.Compute + properties: + name: vfirewall + description: Virtual Firewall + configurable_properties: {} + capabilities: + virtual_compute: + properties: + virtual_cpu: + num_virtual_cpu: 4 + virtual_memory: + virtual_mem_size: 8 GB + + router: + type: tosca:VDU.Compute + properties: + name: vrouter + description: Virtual Router + configurable_properties: {} + capabilities: + virtual_compute: + properties: + virtual_cpu: + num_virtual_cpu: 2 + virtual_memory: + virtual_mem_size: 4 GB diff --git a/examples/2.0/source-and-target.yaml b/examples/2.0/source-and-target.yaml new file mode 100644 index 00000000..1c72083e --- /dev/null +++ b/examples/2.0/source-and-target.yaml @@ -0,0 +1,49 @@ +tosca_definitions_version: tosca_2_0 + +metadata: + + template_name: Source and Target Example + template_author: Puccini + +node_types: + + Application: + derived_from: tosca:WebServer + properties: + url: + type: string + +service_template: + + node_templates: + + server: + type: tosca:Compute + attributes: + public_address: myapp.com + requirements: + - local_storage: + node: storage + relationship: + properties: + # Within relationships you can use "SOURCE" and "TARGET" keywords + # For both the "get_property" and "get_attribute" functions + location: { concat: [ /mnt/, { get_property: [ TARGET, volume_id ] } ] } + device: /dev/hda1 + + app: + type: Application + properties: + # Another special kind of target is "HOST", which can be used in nodes and their capabilities + # It refers to the target of any "HostedOn" relationship from the node + url: { get_attribute: [ HOST, public_address ] } + requirements: + - host: + relationship: tosca:HostedOn + + storage: + type: tosca:Storage.BlockStorage + properties: + name: storage + volume_id: bucket + size: 20 gib diff --git a/examples/2.0/substitution-mapping-client.yaml b/examples/2.0/substitution-mapping-client.yaml new file mode 100644 index 00000000..7d484975 --- /dev/null +++ b/examples/2.0/substitution-mapping-client.yaml @@ -0,0 +1,52 @@ +tosca_definitions_version: tosca_2_0 + +# Also see: substitution-mapping.yaml + +metadata: + + template_name: Substitution Mapping Client Example + template_author: Puccini + +imports: + +# (Make sure to take a look at the import) +- imports/super-load-balancer.yaml + +service_template: + + node_templates: + + # This is actually not a very interesting service template + # (We're just using an imported node type) + loadbalancer: + type: SuperLoadBalancer + directives: + - substitutable + + # This single Compute will satisfy *both* "admin_host" and "db_hosts" requirements in loadbalancer + # (It's allowed because the "occurrences" for our "host" capability is the default [0, UNBOUNDED]) + server: + type: tosca:Compute + +# So, you might be wondering how our loadbalancer node will be "substituted" +# by the complete service modeled in substitution-mapping.yaml + +# That's beyond the scope of TOSCA, which only provides the design +# Another way to think of it is that TOSCA is all about "service templates" and "node templates" +# While actual "services" and "nodes" are implementation details beyond its scope + +# All we can do here is specify the "substitutable" directive (see: metadata.yaml) +# Which tells the orchestrator that it's an abstract node +# It's stil up to the orchestrator to compose the services together + +# Service composition can in fact be a very complex orchestration implementation detail +# (It's not just a "copy-and-paste" of templates) + +# It would likely involve looking up possible substitutions in a catalog of services +# And even provisioning/deploying a new service if one is not available + +# And then these deployed services would need to talk to each other +# Which might involve quite a bit of network configuration (ingress, routing, TLS, SDN, etc.) +# And/or setting up a proxy/gateway between them + +# Exciting stuff to be sure, but TOSCA can only model it, not implement it diff --git a/examples/2.0/substitution-mapping.yaml b/examples/2.0/substitution-mapping.yaml new file mode 100644 index 00000000..03786d8d --- /dev/null +++ b/examples/2.0/substitution-mapping.yaml @@ -0,0 +1,66 @@ +tosca_definitions_version: tosca_2_0 + +# Also see: substitution-mapping-client.yaml + +metadata: + + template_name: Substitution Mapping Example + template_author: Puccini + +imports: + +# (Make sure to take a look at the import) +- imports/super-load-balancer.yaml + +service_template: + + inputs: + + # This input is mapped to a property in "substitution_mappings" + # Thus, we do not have to give it a default value + # (even though it is a required input) + scale: + type: integer + + node_templates: + + loadbalancer: + type: tosca:LoadBalancer + + # Both the WebServer and DBMS types derive from SoftwareComponent, meaning that they require a host + # So normally this service template would fail to parse due to unsatisfied requirements + # However, because we are mapping these in "substitution_mappings", Puccini will allow it + # (They are expected to be satisfied by a client service template) + + admin: + type: tosca:WebServer + properties: + component_version: '1.0' + + db: + type: tosca:DBMS + + # Allow this entire service to be used as a single node + substitution_mappings: + node_type: SuperLoadBalancer + capabilities: + # Expose the internal loadbalancer node's capability + # The capability types must be compatible + client: [ loadbalancer, client ] + requirements: + # Expose the requirements of our software components + # Any requirement can be mapped + admin_host: [ admin, host ] + db_host: [ db, host ] + properties: + # Properties are mapped to inputs + # (You can also map properties to node template properties, though this use is deprecated in TOSCA 1.3) + # The data types must be compatible + redundancy: [ scale ] + attributes: + # The data types must be compatible + admin_state: [ admin, state ] + db_state: [ db, state ] + interfaces: + # The interface types must be compatible + Standard: [ admin, Standard ] diff --git a/examples/2.0/unicode.yaml b/examples/2.0/unicode.yaml new file mode 100644 index 00000000..8734e929 --- /dev/null +++ b/examples/2.0/unicode.yaml @@ -0,0 +1,66 @@ +tosca_definitions_version: tosca_2_0 + +# Puccini supports Unicode everywhere + +metadata: + + template_name: Unicode Example + template_author: Puccini + +node_types: + + 燈泡: + requirements: + - 插座: 插座 + + 電源面板: + properties: + 年齡: + type: scalar-unit.time + capabilities: + 主要: 插座 + +capability_types: + + 插座: + properties: + 標準: + type: string + 電壓: + type: float + 電頻: + type: scalar-unit.frequency + +relationship_types: + + 插頭: + properties: + 供應商: + type: string + attributes: + IP地址: + type: string + +service_template: + + node_templates: + + 燈: + type: 燈泡 + requirements: + - 插座: + relationship: + type: 插頭 + properties: + 供應商: 智能家電行業 + + 主面板: + type: 電源面板 + properties: + 年齡: 5 d + capabilities: + 主要: + properties: + 標準: 高頻 + 電壓: 110.0 + 電頻: 120 hz diff --git a/examples/2.0/workflows.yaml b/examples/2.0/workflows.yaml new file mode 100644 index 00000000..4d5bebc3 --- /dev/null +++ b/examples/2.0/workflows.yaml @@ -0,0 +1,90 @@ +tosca_definitions_version: tosca_2_0 + +# TODO: not fully supported + +# See: interfaces.yaml + +metadata: + + template_name: Workflows Example + template_author: Puccini + +interface_types: + + Backup: + operations: + start_backup: + inputs: + async: + type: boolean + default: false + +node_types: + + MyDB: + derived_from: tosca:DBMS + interfaces: + Backup: + type: Backup + +service_template: + + node_templates: + + web: + type: tosca:WebServer + + db: + type: MyDB + + server: + type: tosca:Compute + + workflows: + + backup: + # Workflows are made of steps + # The order of execution is a graph with sequential and parallel branches + steps: + notify_users: + # Each step targets a node template (or a relationship of that node template) + target: web + activities: [] + # Here we'll launch 2 steps in parallel + on_success: + - shutdown + - backup + filter: + - or: + - foo: [ { equal: true } ] + - bar: [ { greater_than: 2 }, { less_than: 20 } ] + shutdown: + target: web + # You can specify 0 or more activities for the step + activities: + - set_state: down + on_success: + - restart + backup: + target: db + activities: + - set_state: down + # We can call an operation on an interface on the target node + # (Note that it *cannot* accept inputs) + - call_operation: + operation: Backup.start_backup + inputs: + async: true + on_failure: + - notify_admins + on_success: + - restart + # Because two other steps launch this step + # *Both* of them have to conclude successfully before this one starts + restart: + target: db + activities: + - set_state: up + notify_admins: + target: web + activities: [] diff --git a/examples/java/README.md b/examples/java/README.md index 47ec4b6f..5a0a2d53 100644 --- a/examples/java/README.md +++ b/examples/java/README.md @@ -10,4 +10,4 @@ To build this example using [Maven](https://maven.apache.org/): To run this example using Maven we need to make sure that the JVM process can load the shared libraries: - LD_LIBRARY_PATH=$LD_LIBRARY_PATH:dist mvn --quiet --file examples/java exec:java --define exec.args=examples/tosca/data-types.yaml + LD_LIBRARY_PATH=$LD_LIBRARY_PATH:dist mvn --quiet --file examples/java exec:java --define exec.args=examples/1.3/data-types.yaml diff --git a/examples/javascript/artifacts.yaml b/examples/javascript/artifacts.yaml index 3c7d8421..814630fc 100644 --- a/examples/javascript/artifacts.yaml +++ b/examples/javascript/artifacts.yaml @@ -3,7 +3,7 @@ tosca_definitions_version: tosca_simple_yaml_1_3 # To execute the scriptlet and extract artifacts to a specific directory: # puccini-tosca compile examples/javascript/artifacts.yaml --exec=extract --output=work -# See also: examples/tosca/artifacts.yaml +# See also: examples/1.3/artifacts.yaml metadata: diff --git a/examples/javascript/functions.yaml b/examples/javascript/functions.yaml index bf847b8d..65857d74 100644 --- a/examples/javascript/functions.yaml +++ b/examples/javascript/functions.yaml @@ -3,7 +3,7 @@ tosca_definitions_version: tosca_simple_yaml_1_3 # To evaluate the functions run: # puccini-tosca compile --coerce examples/javascript/functions.yaml -# Also see: define.yaml, examples/tosca/functions.yaml, examples/tosca/metadata.yaml +# Also see: define.yaml, examples/1.3/functions.yaml, examples/1.3/metadata.yaml metadata: diff --git a/examples/tosca/legacy/tosca_1_0.yaml b/examples/legacy/tosca_1_0.yaml similarity index 100% rename from examples/tosca/legacy/tosca_1_0.yaml rename to examples/legacy/tosca_1_0.yaml diff --git a/examples/tosca/legacy/tosca_1_1.yaml b/examples/legacy/tosca_1_1.yaml similarity index 100% rename from examples/tosca/legacy/tosca_1_1.yaml rename to examples/legacy/tosca_1_1.yaml diff --git a/examples/tosca/legacy/tosca_1_2.yaml b/examples/legacy/tosca_1_2.yaml similarity index 100% rename from examples/tosca/legacy/tosca_1_2.yaml rename to examples/legacy/tosca_1_2.yaml diff --git a/examples/python/README.md b/examples/python/README.md index 5eb4fb96..1229ca29 100644 --- a/examples/python/README.md +++ b/examples/python/README.md @@ -5,4 +5,4 @@ This relies on the [Python wrapper](../../wrappers/python/), so make sure to ins You can now run the example: - examples/python/compile.py examples/tosca/data-types.yaml + examples/python/compile.py examples/1.3/data-types.yaml diff --git a/examples/ruby/README.md b/examples/ruby/README.md index 82bc2c20..00991666 100644 --- a/examples/ruby/README.md +++ b/examples/ruby/README.md @@ -5,4 +5,4 @@ This relies on the [Ruby wrapper](../../wrappers/ruby/), so make sure to install You can now run the example: - examples/ruby/compile.rb examples/tosca/data-types.yaml + examples/ruby/compile.rb examples/1.3/data-types.yaml diff --git a/executables/puccini-clout/default.pgo b/executables/puccini-clout/default.pgo index af34e5c90c6f340defda418f148ea48e2d9b0879..85fc7b568412d88ddd4ddce189bc89f54fc0968e 100644 GIT binary patch literal 2406 zcmV-s37PgEiwFP!00004|FlK$4-2&eUp@=rL-Yw zX&F#f(9nihcXM;=y4d%6_g=g0Ukjp@fJvpO6ef@mi~@y1c~qKsO)9KZn#BGb;pZW0L?cpE^KutJEY9V;_ zO;5abd*H|N^G|1=crVC+1n|LE4%V;`3Ba!d5Qs-e074j|b^J(x0ja?QhY!@S5UGKu z>p{RZP>=PL@JH$ykXn5FclQW(E!^55*|pGs4V3UV1RTUOMh#of+Pe<2*krA1QCqTMn1%%qz?c3*ck!V!IT8+U>Po>%lRaWl6pM$=otal z!$t|#LlmQQIlqKO3Be=xoE0D`fdl}7Ht`KCN*eIw$FB&m0mdY=0h+OyHt{Y7B#ejO zJrQCd5{9?^Y{SrkEwq*YvyK6Y;FljsI0A1InN9>&;0oHx?<1^@G~#o2ovmXb(g=4D z79`6+l}3%whHbQ!A13iISqAOcPLV4tN|xap@5n%xL!*pkIdotL?c`wwWI5jU-XT%i zC>*YlI#KAtF1nH*2{gAu07L`B%L6sF!BAa2X$VIemn~;NqWI#G`vec*W5Ej(fK|AP zuI4=q2;jXZj|#L2p7q<^1l`z8DSs-!fHdLjf4fB#pc#(UN~g`R2G>x=@2h1%n(@GE z5^jO_g?5CrKo9m%#?RC+AT9XjBNA?f$Ax&9v_dcTQpRltq!r(MsD%D10K(e}Ja$s9 ztbo(PK0;PNANEnkUl4E`-g;WXZE&matquCIpE5pM!`ewZzW%U;+u?-(3z1eh=8Lq$ z01i;bpBEyCr=FEo2>f~n zZ!72cu)nerk3Cwlxl^n}$twK)(OW_+NID@S``QU{j8n#c!ho#CcRsvbl(-8%_dRyO zAP&+Y{%L?kNjIK&{Q<#U36qk$5)zo83U6URD1LC_0l{4bcMEQqtO6BPn&dxcQL+YK zJR(PXHMo+x8d8{|8ehkNF#Pi~Cq(1B;gz85Y&Q(!FdgAHiO%-mCwEGi!Uuk>DU9MM z9pUeb&i3MeKRP5vdkvh8O7b#y&H-pPOr;AgMhCE#8->$7{|V!W8H=T8YX$Bz!)E#N+QxlXeC zU;}QT>-h^}Q^xS{8R@$p9`i@GA1=X5=r})E%i2jCkG?A50eHTag$Re2eX9Z3h#ToR zf37wjAsja0COXbv615n_C!aem9LC^FzZNl=zzI6ezYw(;!av@Ahk)boX|s$c4wvGk z^dkOAGXs*qTfUIl48jRN+(DScNxGgtAi`Dfz#Wo31P`@H_7F_rl&GZWu!_GpB;f>n z;)^F>Gj66A@sEXg5)Zw2TKHDvti>Zlfi1X&Ud9iK;Ys0tPRRpRg}rhDRM?7J>1Etv zKs3Df=9dIF2~UgRiI600!)>&YKPI@t_?z;Px(Nc!ljRd;T@;#{TUuANwSVaQ5A^b^P+NKxZqdf!X_?eCS`F zb>r;2@;Co}XD6u@cAx)G{0rdh{pFAR3hjGZy{qT)S<}@*hF!2ct=7mFw1}l!wrd); zHREdN6f7^3GZh}s8M?9Cj46(}E0fJ?L+X^7w>@DjDp2qh>h`Aca-Ybvi;=3aYxk7;|D;a_PB|(y+>EBGWTw_iUP=)mZx2#?zVHLYUZZ1W-hNg`i!ZjZ8d*m zTFu!rYID(al1;fZ#8P&+z1y9}MDm=dVJSnDJW$wM)tys}U z)hSu!s~uY;=Bn3jzh-h`j?PzIkAHpFJItRIGLETDEKD``nMT3Wr?aM8jv(P@B8sb9 zGp@3EpJ`}277x0*jOrRrChuiUFCmOYF)#a8VP&k0r|c?NhNi_TgxvhD)UayU(~hq2 z_@tc^NyHT4v*4N9mL*R`h0vyAN*Pm9<&uclCW#eERnT{i7pV6Xq3FQwHv;x5Q@3Q0^sptE~YpIOXCZKc+TQlXa6?KGMz;VJgvLt zb0ViIr=f4(+N1)}I`#jmqEA5#=*3`Byd8SIQunRQB zwi90t3}0AGkya7&e3T2qC_T&9R_9cFZ-||H&JWBV{B*`DAE^ElUaPylIOEzkXyNON Y?ta(Mv)LQ|9{>RV|786xdh8Sc0M_!d*#H0l literal 2937 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 diff --git a/executables/puccini-csar/default.pgo b/executables/puccini-csar/default.pgo index 6015fb0ae47576dbf4ab8a08a32bc2576f6e841b..6df92314c2f4d12b89f64892487684c88f3e800a 100644 GIT binary patch literal 690 zcmV;j0!{rNiwFP!00000|BRDOXxv5^hCM53HLF>#KdX5Kl51i}Vu&Gx+!7~9 zWNj02@bP{0&hvdE7)!?p8kUYV(7PSWKn+bd0Kw?sR-KzBZdsQyx%7PjFoMx&)S#o? zeZw_Yky8;w|N8BlhGSp^*A^YX4M22nrzQ>9TW|ntfat&f)kK5sB?qt$h@RZ6i4I@b z4qyWiy??k<5d;3z9KcOL^mO~HiZtP8;s7=Q(T88x#Du?F&OF9|=#%fitO$l1*fDSm zcB^U&5WRO)>n!+OcK};}=>E5LmB1Ep<}m?8&wj0!Xv0sd^$q@6^aw`Kq)pp&|ENL( zFvYg%9=_@ktU-&mY|}k^%_CR`i(0nn9xr(W8$c+r+wOtp5!{4HI%#*@JC;YV2~%{+ z?zm5}M=%DUV0YaAtI&dJI&F8|E#eVu!3>?T+wSd3Kwy^6+FkdTO3;QmI%k{ikE?8g znK_TsNaoBCNvR5^iL_)yah2p!Br3?+>;7gEOJBzQNX9A8cp&{j;`c-4r=<{~3RgtV zGd7)-st9A*%L~b)50h-jJbz85N#Vbhrco$(5hg0H&gPl$pSS%qOGIywu-WnPjZg(2 zluGe_BpIAb#ik6(NV3kDq&yq0$82((W5J_{^{z0I=kYp^gE!yk<*a)#fUBhci4+A} zxq>4eh?r-?YV)bFVj$Ks9xCR%0N&%-u=*b|Ta!U0lmT13=)66+DD*Z;B^X=2+6LA1 znez*LmKQS43oeH2m6zMu!kD{W##NBS@2E0f?kV|c@$Td6$0y$%oj#g>|L%hyen%hG YZ~Eivp{5hh0ssL2|6iwptmgv&03R4u<^TWy literal 2308 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 puccini/go-source/go.work # KUTIL=$(readlink --canonicalize "$ROOT/../kutil") diff --git a/scripts/test b/scripts/test index 9576eeb1..6e354657 100755 --- a/scripts/test +++ b/scripts/test @@ -15,5 +15,6 @@ cd "$ROOT" PUCCINI_TEST_ROOT=$ROOT \ KUTIL_LOCK_DEFAULT=debug \ +KUTIL_LOCK_DEBUG_ORDER_DETECTION=true \ GORACE=history_size=7 \ go test -count=1 -timeout=30s . "$@" diff --git a/scripts/test-formats b/scripts/test-formats index f4840770..e3e82dd9 100755 --- a/scripts/test-formats +++ b/scripts/test-formats @@ -8,7 +8,7 @@ HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") function t () { m "testing format: $1..." - puccini-tosca compile --format="$1" "$ROOT/examples/tosca/data-types.yaml" | + puccini-tosca compile --format="$1" "$ROOT/examples/1.3/data-types.yaml" | puccini-clout --input-format="$1" --format="$1" scriptlet exec tosca.coerce > /dev/null } diff --git a/scripts/test-git-url b/scripts/test-git-url index b625f37c..ec1aa96d 100755 --- a/scripts/test-git-url +++ b/scripts/test-git-url @@ -7,4 +7,4 @@ HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") "$HERE/build" puccini-tosca compile \ -'git:https://github.com/tliron/puccini.git#main!examples/tosca/data-types.yaml' "$@" +'git:https://github.com/tliron/puccini.git#main!examples/1.3/data-types.yaml' "$@" diff --git a/scripts/test-https-url b/scripts/test-https-url index ee4aac22..1d5bd5ce 100755 --- a/scripts/test-https-url +++ b/scripts/test-https-url @@ -7,4 +7,4 @@ HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") "$HERE/build" puccini-tosca compile \ -https://raw.githubusercontent.com/tliron/puccini/main/examples/tosca/data-types.yaml "$@" +https://raw.githubusercontent.com/tliron/puccini/main/examples/1.3/data-types.yaml "$@" diff --git a/scripts/test-java b/scripts/test-java index 6fe376d2..8ab5378d 100755 --- a/scripts/test-java +++ b/scripts/test-java @@ -14,4 +14,4 @@ mvn --file "$ROOT/examples/java" --define puccini.version=${VERSION:1} # Run LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROOT/dist \ mvn --quiet --file "$ROOT/examples/java" \ - exec:java --define exec.args="$ROOT/examples/tosca/inputs-and-outputs.yaml --input=ram=1gib --input=cores=6" --errors + exec:java --define exec.args="$ROOT/examples/1.3/inputs-and-outputs.yaml --input=ram=1gib --input=cores=6" --errors diff --git a/scripts/test-js b/scripts/test-js index 49b4be3f..64abd400 100755 --- a/scripts/test-js +++ b/scripts/test-js @@ -6,5 +6,5 @@ HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") "$HERE/build" -puccini-tosca compile "$ROOT/examples/tosca/requirements-and-capabilities.yaml" "$@" | \ +puccini-tosca compile "$ROOT/examples/1.3/requirements-and-capabilities.yaml" "$@" | \ puccini-clout scriptlet exec tosca.resolve diff --git a/scripts/test-parse b/scripts/test-parse index 0da81eed..3b4820c3 100755 --- a/scripts/test-parse +++ b/scripts/test-parse @@ -6,4 +6,4 @@ HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") "$HERE/build" -puccini-tosca parse "$ROOT/examples/tosca/data-types.yaml" "$@" +puccini-tosca parse "$ROOT/examples/1.3/data-types.yaml" "$@" diff --git a/scripts/test-python b/scripts/test-python index dbd6c5b0..c185f6f4 100755 --- a/scripts/test-python +++ b/scripts/test-python @@ -10,4 +10,4 @@ FLAG=${1:--s} SUFFIX=$SUFFIX "$HERE/build-wrapper-python" "$FLAG" . "$ROOT/dist/python-env/bin/activate" -"$ROOT/examples/python/compile.py" "$ROOT/examples/tosca/inputs-and-outputs.yaml" --input=ram=1gib --input=cores=6 +"$ROOT/examples/python/compile.py" "$ROOT/examples/1.3/inputs-and-outputs.yaml" --input=ram=1gib --input=cores=6 diff --git a/scripts/test-ruby b/scripts/test-ruby index 219728c3..31101528 100755 --- a/scripts/test-ruby +++ b/scripts/test-ruby @@ -8,4 +8,4 @@ HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") gem install "$ROOT/dist/puccini.gem" -"$ROOT/examples/ruby/compile.rb" "$ROOT/examples/tosca/inputs-and-outputs.yaml" --input=ram=1gib --input=cores=6 "$@" +"$ROOT/examples/ruby/compile.rb" "$ROOT/examples/1.3/inputs-and-outputs.yaml" --input=ram=1gib --input=cores=6 "$@" diff --git a/scripts/test-visualize b/scripts/test-visualize index cbf5e123..091dd472 100755 --- a/scripts/test-visualize +++ b/scripts/test-visualize @@ -6,6 +6,6 @@ HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") "$HERE/build" -puccini-tosca compile "$ROOT/examples/tosca/requirements-and-capabilities.yaml" \ +puccini-tosca compile "$ROOT/examples/1.3/requirements-and-capabilities.yaml" \ --exec="$ROOT/assets/profiles/common/1.0/js/visualize.js" > /tmp/puccini.html && \ xdg-open /tmp/puccini.html diff --git a/scripts/test-wasi b/scripts/test-wasi index 8fb87e99..9d0cee66 100755 --- a/scripts/test-wasi +++ b/scripts/test-wasi @@ -19,10 +19,10 @@ function run () { } run puccini-tosca compile \ -"$ROOT/examples/tosca/data-types.yaml" "$@" +"$ROOT/examples/1.3/data-types.yaml" "$@" run puccini-tosca compile \ "$ROOT/dist/cloud.csar" "$@" #run puccini-tosca compile \ -#https://raw.githubusercontent.com/tliron/puccini/main/examples/tosca/data-types.yaml "$@" +#https://raw.githubusercontent.com/tliron/puccini/main/examples/1.3/data-types.yaml "$@" diff --git a/scripts/test-wasm b/scripts/test-wasm index f43409f5..8fad1cbf 100755 --- a/scripts/test-wasm +++ b/scripts/test-wasm @@ -19,7 +19,7 @@ function run () { } run puccini-tosca compile \ -"$ROOT/examples/tosca/data-types.yaml" "$@" +"$ROOT/examples/1.3/data-types.yaml" "$@" run puccini-tosca compile \ "$ROOT/dist/cloud.csar" "$@" diff --git a/wrappers/ansible/ansible_collections/puccini/tosca/plugins/modules/compile.py b/wrappers/ansible/ansible_collections/puccini/tosca/plugins/modules/compile.py index 37326932..5d6444f0 100644 --- a/wrappers/ansible/ansible_collections/puccini/tosca/plugins/modules/compile.py +++ b/wrappers/ansible/ansible_collections/puccini/tosca/plugins/modules/compile.py @@ -30,7 +30,7 @@ EXAMPLES = r''' - name: Compile TOSCA service template puccini.tosca.compile: - service_template: ../../examples/tosca/requirements-and-capabilities.yaml + service_template: ../../examples/1.3/requirements-and-capabilities.yaml inputs: {} register: service ''' diff --git a/wrappers/python/description.md b/wrappers/python/description.md index cbf4bebe..314939f3 100644 --- a/wrappers/python/description.md +++ b/wrappers/python/description.md @@ -31,12 +31,14 @@ Usage Example: - import sys, puccini.tosca, ard - - try: - clout = puccini.tosca.compile('/path/to/my-tosca-service.csar') # can also be a URL - ard.write(clout, sys.stdout) - except puccini.tosca.Problems as e: - print('Problems:', file=sys.stderr) - for problem in e.problems: - ard.write(problem, sys.stderr) +```python +import sys, puccini.tosca, ard + +try: + clout = puccini.tosca.compile('/path/to/my-tosca-service.csar') # can also be a URL + ard.write(clout, sys.stdout) +except puccini.tosca.Problems as e: + print('Problems:', file=sys.stderr) + for problem in e.problems: + ard.write(problem, sys.stderr) +``` diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index 1efcdba8..ab28c00b 100755 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -16,7 +16,7 @@ with open(root / 'description.md') as f: description = f.read() -go_version = os.environ.get('PUCCINI_GO_VERSION', '1.22.6') +go_version = os.environ.get('PUCCINI_GO_VERSION', '1.23.0') root = str(root).replace('"', '\\"') script = '''\