[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: RE: [tosca] Operation implementations
Thanks Tal, these examples are extremely helpful. Most of the examples in the Version 1.3 specification show the use of bash scripts to provide implementations for interface operations. Your
gRPC and SSH examples, together with Adamâs Ansible examples, will help guide us towards a general-purpose approach for specifying operation implementations. You email touches on most of the issues that need clarification. Iâll try to organize my comments by topic: The proposed grammar is actually very simple. Instead of "implementation" having that weird structure of a "primary" string and a string-list of "dependencies", which
semantically were never very clear, I suggest that it be given a data type using a "type" keyword for both the operation definition and assignment (a refinement of the definition). I believe there are actually two separate issues here:
Iâll offer my perspectives on each of these separately:
Implementation Operation Types This data type provides syntactical validation for "implementation", but more importantly it represents the processor's mechanism for reacting to the operation event. I donât think there is any disagreement about whether operation implementations should be typed. TOSCA uses types for (almost) everything, and operation implementations should be no exception. As you correctly point out, the type of the
operation implementation serves two purposes:
The question then is not whether operation implementations should be typed, but rather which type to use. TOSCA v1.3 uses Artifact Types for this purpose, and youâre proposing to use data types
instead. Iâll use your ssh example to compare the two.
Implementations Operations use Data Types You state that: The ssh implementation is actually quite similar, but it does have optional support for artifacts. The idea is that the artifacts would be copied over (scp) before
executing the ssh command. Here we can extract TOSCA artifacts from the CSAR using the "get_artifact" function or just use any file from a URL.
Iâm showing your topology template code snippet here (without the gRPC part):
Implementation Operations use Artifact Types Using existing Version 1.3 grammar, your example would be written as follows:
topology_template:
node_templates:
server:
type: Server
interfaces:
Maintenance:
operations:
maintenance-off:
implementation:
type: SSH # artifact type, not data type
file: off.sh
properties:
immediate: true In this example, the âprocessorâ for the SSH artifact type would copy the âoff.shâ script to the remote server (using the provided credentials) and execute it there. A couple of notes about this snippet:
I believe the existing Artifact Types approach has a lot of advantages over using data types:
I believe this is not good practice. An interface type definition should be just that: a definition of the set of operations that can be called within the context of that interface. Interface types should not have
an opinion about how they should be implemented. Specifically, they should not restrict the type of their implementations.
The âaddressâ property has a default value that references SELF. However, data type definitions do not have a SELF context. That context is only available inside node types or relationship types. In my opinion (and
in my implementation) this is invalid TOSCA. This type definition is only valid when it happens to be used inside a node or relationship that happens to have an address attribute of type string and inside a service template that has a credential input of type
Credential. We donât know if thatâs the case until an attribute or property of that type is defined inside a node or relationship somewhere. If weâre going to have a typed language, we should be able to validate those types at design time without having to
wait until âuse timeâ to see if things will work.
Primary and Dependent Artifacts As I mentioned earlier, my SSH Artifact type doesnât handle the extra files that need to be deployed on the remote server first. While it would be trivial to extend the SSH Artifact type do handle this, the Version 1.3 spec actually anticipates
this use case by supporting âdependentâ artifacts in addition to a âprimaryâ artifact. My understanding of the spec is that the list of dependent artifacts are processed first (in the order in which they are defined) and then the primary artifact is processed.
In my implementation, I define a Deployment artifact type for âdeployingâ files onto remote servers. Using this Deployment artifact type, the example above would be supported as follows:
This results in the âutilsâshâ being deployed into the /home/tosca directory on the remote server, where it can then be used by the âoff.shâ script. This approach is perhaps slightly more verbose, but it has the advantage that the operation implementation types (i.e., the artifact types) can be designed to be a collection of primitive, re-usable types that can be combined as necessary
to provide a full implementation. On the flip side, what I donât like about this grammar is the artificial distinction between a primary operation implementation and dependent operation implementations. I would much rather see us eliminate the âprimaryâ and âdependenciesâ
keywords, and just support lists of operation implementations in the âimplementationâ keyword. As an optimization, we could also support a single operation implementation definition (instead of a list) if only one single operation implementation is required.
Operation Implementations that are not Artifacts Hopefully the discussion so far has shown that the existing operation implementation grammar supports most of the functionality in your examples. This brings us to the one feature that is not
easily supported: how do we specify operation implementations that are not artifacts (i.e., where there is no file that contains the code that needs to be executed or the commands that need to be processed).
The gRPC call has nothing to do with artifacts per se. However, it is expected that there is a gRPC client somewhere that can handle these calls, perhaps statically
compiled from a ".proto" file, which perhaps can be included in the CSAR. But that ".proto" file defines the entire membrane, not individual calls. It's also possible to imagine a ".proto"-to-TOSCA translator that would create derived data types and for each
supported call and one big interface type. Your gRPC example illustrates this use case. By the way, I believe your example shows grammar that is slightly different from what you intended. If my understanding is correct, the following
snippet is grammatically more correct (i.e., the type is specified inside the âimplementationâ block, not the other way around, and the âpropertiesâ keyword is required):
Calin and I suggested during last weekâs language ad-hoc that this use case can be supported if current artifact definition grammar were extended with an âinlineâ keyword. If the âinlineâ keyword
is present, then the âcommandâ or the âexecutableâ or the âscriptâ (or whatever you want to call it) is specified directly inside the TOSCA grammar rather than being retrieved from a file. If the âfileâ keyword is specified, then the contents of that file
are used as the command or executable or script. The resulting grammar could look as follows:
In this example, the âStartMaintenanceWithModeâ is the gRPC command that needs to be executed, the âmodeâ is an input to that command, and the âtimeoutâ is a value that is provided to the gRPC
client. While I believe this approach will work just fine for all use cases, I understand the problem related to terminology. It is absolutely confusing to use the word âartifactâ to describe an operation implementation that are not artifacts.
To avoid this confusion, I would support using a different type of types (different from artifact types) for operation implementations. We could use the term Implementation Type for this purpose.
Summary As you pointed out, there are more issues that need to be resolved, but hopefully we can come to agreement on some of the basics. Here is my recommendation:
I believe this proposal preserves most of the Version 1.3 grammar while addressing the objections to this grammar that have been raised to date. Chris From: tosca@lists.oasis-open.org <tosca@lists.oasis-open.org>
On Behalf Of Tal Liron Sorry it took me a while to write this up, but finally here is a draft of what I mean by "typed implementations". The proposed grammar is actually very simple. Instead of "implementation" having that weird structure of a "primary" string and a string-list of "dependencies", which semantically were never very clear, I suggest that it be given a data
type using a "type" keyword for both the operation definition and assignment (a refinement of the definition). This data type provides syntactical validation for "implementation", but more importantly it represents the processor's mechanism for reacting to the operation event. In the example below I'm showing a node with two operations. One of them is a gRPC call and the other is remote execution using ssh. Both of them are "remote", and the default for the Remote data type from which they both derive assumes
that the node has an "address" attribute. However, this default address can be overridden and given a different value if necessary, for example if the node is not a server itself, or if another component (an orchestrator) is handling execution. The gRPC call has nothing to do with artifacts per se. However, it is expected that there is a gRPC client somewhere that can handle these calls, perhaps statically compiled from a ".proto" file, which perhaps can be included in the CSAR.
But that ".proto" file defines the entire membrane, not individual calls. It's also possible to imagine a ".proto"-to-TOSCA translator that would create derived data types and for each supported call and one big interface type. The ssh implementation is actually quite similar, but it does have optional support for artifacts. The idea is that the artifacts would be copied over (scp) before executing the ssh command. Here we can extract TOSCA artifacts from the
CSAR using the "get_artifact" function or just use any file from a URL. One issue is what to do with inputs: setting environment variables may be impossible (PermitUserEnvironment is set to false for most sshd deployments). So, what I am suggesting here is
that the processor would know how to pack the inputs into a command-line-compatible string. The result is something which I think is most similar to the spirit of the existing "primary + dependencies" structure of "implementation", but I did want to present
some of the complexities regarding where the command runs and how to construct it. Also note a simple use of metadata in order to configure specific aspects of execution for specific orchestrators. This approach raises a more general issue regarding interfaces in TOSCA. In much of our thinking and examples until now we've treated interfaces as a design element coming from TOSCA. In the Simple Profile specifically they represent the
lifecycle as defined by TOSCA. So, our job in that case is to then map that paradigm onto whatever exists in the real world. This mapping needs to be done not just in TOSCA but likely also with some kind of adapter layer. In Ubicity this layer is a collection
of executable scripts. But I want to suggest that there's another approach in which we actually start from the real world and find ways to expose it to TOSCA. For example above I mention that an existing ".proto" file (or a Swagger schema) can be translated
into TOSCA. In this approach the designer actually has no freedom to create arbitrary interfaces, because they are defined by the environment, and there's no adapter layer: it is a direct membrane to the environment. TOSCA's job, then, is to map data from
the topology into that given interface. And that's where better topology traversal functions (get_property/get_attribute) would be really useful. There are a lot of issues I'm not addressing here, but I want to start the discussion simply! The example: interface_types: |
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]