Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Handle inputs for optional properties in interface definitions #129

Open
v-yussupov opened this issue Nov 16, 2020 · 2 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@v-yussupov
Copy link

Description

It could be helpful to enhance handling of inputs in interface definitions for optional properties. In this case, Ansible tasks relying on such optional values will not fail, not breaking the deployment.

Consider the following example (based on AwsLambdaFunction Node Type from RADON Particles repository):
AwsLambdaFunction Node Type allows configuring concurrency using an optional concurrency property, which is later accessed in the lambda_concurrency input definition using TOSCA's get_property intrinsic function as shown in Snippet 1.

[Snippet 1] Excerpt of AwsLambdaFunction Node Type

node_types:
  radon.nodes.aws.AwsLambdaFunction:
    derived_from: radon.nodes.abstract.Function    
    properties:
      ...      
      concurrency:
        type: integer
        description: Function concurrency
        required: false
        constraints:
          - in_range: [ 0, UNBOUNDED ]
    interfaces:
      Standard:
        type: tosca.interfaces.node.lifecycle.Standard
        inputs:          
          lambda_concurrency:
            type: integer
            required: true
            default: { get_property: [ SELF, concurrency ] }
...

Since AWS allows optional configuration of concurrency for functions, the Ansible playbook responsible for deploying AwsLambdaFunction Node Templates has a dedicated part to configure the concurrency, which is intended to be triggered only if the lambda_concurrency input is defined as shown in Snippet 2.

[Snippet 2] Excerpt of an Ansible Playbook responsible for deployment of AwsLambdaFunction Node Templates

---
- hosts: localhost
  tasks:
    ...
    - name: "Put concurrency of Lambda function on AWS : {{ function_name }}"
      command: >-
        aws lambda put-function-concurrency
          --function-name {{ function_name }}
          --reserved-concurrent-executions {{ lambda_concurrency }}
          --region {{ aws_region }}
      when: lambda_concurrency is defined
...

To summarize, the concurrency property is optional, whereas the lambda_concurrency input is required because the corresponding Ansible variable is checked in one of the Ansible tasks.

Current Behavior

In cases when the concurrency value was not set in AwsLambdaFunction Node Templates, xopera throws an exception because it tries to access a property which does not exist although the concurrency property is designed to be optional.
As a workaround, on the type level we set a default value for concurrency to be 0 (not a valid value for AWS) and added checks in the Ansible task not to run if the value is 0. However, this basically results in enforcing the concurrency property to be set even if it's not needed.

Desired Behavior

It would be helpful if xopera is able to set required inputs (with required=true) for optional properties that are not defined instead of raising exceptions. In the aforementioned example, it would be sufficient to have an Ansible variable lambda_concurrency which is declared, but not set.

@cankarm
Copy link
Contributor

cankarm commented Nov 16, 2020

@v-yussupov thank you very much for a detailed explanation of the issue! We will investigate the options and present our prefered solution to this.

@anzoman
Copy link
Contributor

anzoman commented Dec 7, 2020

@v-yussupov thanks for submitting your feature request. I see it as an important update to the current version of the Ansible executor within opera.

As of now it is true that opera raises an exception if you try to use optional (required: false) interface inputs. This is the result:

Error processing node test_0: Cannot use an unset value: lambda_concurrency
Traceback (most recent call last):
  File "/home/anzoman/Desktop/xopera-opera/.venv/bin/opera", line 33, in <module>
    sys.exit(load_entry_point('opera', 'console_scripts', 'opera')())
  File "/home/anzoman/Desktop/xopera-opera/src/opera/cli.py", line 41, in main
    return args.func(args)
  File "/home/anzoman/Desktop/xopera-opera/src/opera/commands/deploy.py", line 116, in _parser_callback
    deploy(service_template, inputs, storage, args.verbose, args.workers,
  File "/home/anzoman/Desktop/xopera-opera/src/opera/commands/deploy.py", line 157, in deploy
    topology.deploy(verbose_mode, workdir, num_workers)
  File "/home/anzoman/Desktop/xopera-opera/src/opera/instance/topology.py", line 36, in deploy
    do_deploy = executor.wait_results()
  File "/home/anzoman/Desktop/xopera-opera/src/opera/threading/node_executor.py", line 52, in wait_results
    raise OperationError("Failed")
opera.error.OperationError: Failed

Even if you don't use TOSCA functions like get_input, get_attribute or get_property, the result is the same. This is because opera does not yet handle these optional input values. And for the future versions we could avoid throwing errors like that by passing those interface inputs to the playbooks (without the value) even if they have not been set in the TOSCA. I believe that this could resolve a lot of problems and would lead to the better connection of Ansible and TOSCA within opera.

@anzoman anzoman added enhancement New feature or request good first issue Good for newcomers labels Dec 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants