tliron / puccini

Cloud topology management and deployment tools based on TOSCA
https://puccini.cloud
Apache License 2.0
91 stars 20 forks source link

Not able to resolve inputs/properties in puccini-js #25

Closed edwardchoh closed 5 years ago

edwardchoh commented 5 years ago

How do I resolve the values for get_input and get_property in interface inputs?

Given

tosca_definitions_version: tosca_simple_profile_for_nfv_1_0

metadata:
    template_name: sample

node_types:
  VDU1:
    derived_from: tosca.nodes.nfv.VDU.Compute
    interfaces:
      Standard:
        configure:
          inputs:
            username:
              type: string
            version:
              type: string

topology_template:
  inputs:
    username:
      type: string
      description: username
      default: user1

  node_templates:
    vdu1:
      type: VDU1
      properties:
        name: vdu1
        description: vdu1
        configurable_properties:
          additional_vnfc_configurable_properties: {}
      capabilities:
        virtual_compute:
          properties:
            virtual_cpu:
              num_virtual_cpu: 1
            virtual_memory:
                virtual_mem_size: 1 GB
      interfaces:
        Standard:
          configure:
            implementation: /tmp/configure.sh
            inputs:
              vnf_name: { get_property: [ SELF, name ]}
              username: { get_input: username }
              version: "1.0"

The generated clout vertex looks like, so how I resolve the inputs for username?:

      interfaces:
        Standard:
          description: This lifecycle interface defines the essential, normative operations
            that TOSCA nodes may support.
          inputs: {}
          operations:
            configure:
              dependencies: []
              description: Standard lifecycle configure operation.
              host: ""
              implementation: /tmp/configure.sh
              inputs:
                username:
                  constraints: []
                  description: ""
                  function:
                    arguments:
                    - constraints: []
                      description: ""
                      value: username
                    name: get_input
                    path: topology_template.node_templates["vdu1"].interfaces["Standard"].configure.inputs["username"]
                version:
                  constraints: []
                  description: ""
                  value: "1.0"
tliron commented 5 years ago

Simply compile with the --coerce flag to call all functions, e.g.:

puccini-tosca compile mytemplate.yaml --coerce

This is intentional behavior, as by default we may not want all functions to be called. For example, attributes might need to be changed according to live deployment data, at which case calling the get_attribute function would return a different value from when the template was first compiled.

Please let me know if this works for you, and if so we can close this issue.

edwardchoh commented 5 years ago

Calling --coerce fixes part of the it. So how do I call get_input/get_properties from puccini-js to resolve the values for each operation? I tried calling get_input or cloud.get_input given the username value, but neither is defined.

Thanks.

tliron commented 5 years ago

Hm, I'm not clear on what you're trying to do. It sounds to me like you're trying to write your own special JavaScript that will coerce specific values on demand, manually?

I that's the case, the functions that will help you are coercible = clout.newCoercible(data), which converts things like {function: {name: ..., arguments: ...}, constraints: ...} to an internal object that can then be executed via clout.coerce(coercible). You can see an example of their use in the default --coerce source code.

The nice thing about these wrappers is that they take care of nested function calls for you (function arguments can themselves be function calls, etc.), so a single call will handle all the recursion.

edwardchoh commented 5 years ago

Let me try to explain, I wrote a Javascript generator that writes Terraform based on the Clout output. Things work great until I try to convert the interfaces section. I'm trying to figure out how do I get the actual values for vnf_name and username, so I can write them into Terraform.

An example:

      interfaces:
        Standard:
          configure:
            implementation: /tmp/configure.sh
            inputs:
              vnf_name: { get_property: [ SELF, name ]}
              username: { get_input: username }
              version: "1.0"

get translated into Clout as:

          operations:
            configure:
              dependencies: []
              description: Standard lifecycle configure operation.
              host: ""
              implementation: /tmp/configure.sh
              inputs:
                username:
                  constraints: []
                  description: ""
                  function:
                    arguments:
                    - constraints: []
                      description: ""
                      value: username
                    name: get_input
                    path: topology_template.node_templates["vdu1"].interfaces["Standard"].configure.inputs["username"]

To get the value, I should call something like get_input('username') which will get the right value from the inputs section in Clout. In the generated Clout output, I see Javascript functions like get_input and get_parameters defined, but I can't figure out how to call them.

tliron commented 5 years ago

Are you calling tosca.coerce(); at the top of your script? That should coerce all the values via the method I explained above. Of course, there might be a bug! When I look at this line I see that it refers to Inputs in uppercase, which might be a mistake. Are you able to try to test a fix for this? Are you building Puccini from source?

edwardchoh commented 5 years ago

I am calling tosca.coerce() at the top. I tried changing the line to tosca.traverseObjectValues(traverser, interface_.operations[operationName].inputs, site, source, target);, and I ran embed.sh && build.sh. But the output remains the same, the operation inputs didn't get coerced/evaluated.

tliron commented 5 years ago

OK, definitely looks like a bug. I am looking into it now also, thank you!

tliron commented 5 years ago

There were actually two issues in that code. :) I committed a fix, please let me know if it works for you!

edwardchoh commented 5 years ago

Awesome, that worked. Both the get_input and get_property inputs were coerced correctly. Thanks!