Giter Site home page Giter Site logo

ignition's Introduction

License Build Status PyPI version

Ignition

What is it?

The Resource Manager provided with the Stratoss™ Lifecycle Manager, known as Brent, requires Resource drivers to integrate with virtual infrastructure and to complete transitions and operations with different scripting mechanims.

Ignition is a framework which aims to ease the process of building those driver applications with Python.

Docs

Install from source

Clone the source code and install it from the root directory:

pip3 install .

ignition's People

Contributors

1jenkins avatar akshata-desai-ibm avatar chowarth123 avatar davetobin avatar deepansh1092 avatar dependabot[bot] avatar dvaccarosenna avatar eflamini avatar haynesdavis avatar lokanalla avatar manojn94 avatar manojn97 avatar monam-bharti avatar owen-lynch-ibm avatar sglover avatar swatij-ibm avatar tonyob avatar tushar123sharma avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ignition's Issues

Add support for a Request Queue

Currently all driver requests are handled by calling a REST API. This enhancement will provide a request queue that will automatically queue REST API requests (this will be configurable on a per driver type basis), which can then be consumed in whichever way the driver sees fit (an API will be provided to get the request queue, the request queue will have APIs to consume requests). The request queue will be based on a partitioned Kafka topic (the usage of Kafka is driven by the fact that it is present in the Accanto LM stack)

KeyError: 'value' when iterating PropValueMap including an entry with no value

The following code results in a KeyError:

values = PropValueMap({
            'prop1': {
                'type': 'string'
            }
        })
        for k, v in values.items():
            self.assertEqual(k, 'prop1')
            self.assertEqual(v, None)

Error:

Traceback (most recent call last):
  File "/home/dvs/src/accanto-github/ignition/tests/unit/utils/test_propvalueandtype.py", line 262, in test_iter_without_value
    for k, v in values.items():
  File "/home/dvs/src/accanto-github/ignition/env/lib/python3.6/_collections_abc.py", line 744, in __iter__
    yield (key, self._mapping[key])
  File "/home/dvs/src/accanto-github/ignition/ignition/utils/propvaluemap.py", line 29, in __getitem__
    return value_and_type['value']
KeyError: 'value'

The PropValueMap should cater for entries with no value entry (as some Rest API requests will not send the 'value' key if the value is null/none)

Add health endpoint

So drivers have an endpoint to use for health checks in their pod deployments.

This endpoint should return a 200 OK if the driver is up.

Add CLI with command to generate the necessary files to create a driver

Would be useful to create a command line application, which based on some inputs could generate:

  • full python project with module containing necessary code to configure Ignition to run the driver
  • Dockerfile for building a docker image
  • Helm chart sources for deployment to Kubernetes with recommended settings
  • Example test and release process

This would essentially automate the process of creating a driver, rather than document every line of code required.

The user guide should then be updated to explain how the new command should be used.

Auto-create Kafka topics for Job queue

The Job Queue service provided by Ignition makes use of a Kafka topic to queue tasks for execution. The name of this topic is generated using the applications name appended with the string _job_queue.

The topic is auto-created when the KafkaProducer/KafkaConsumer starts with the Kafka defaults for a new topic. Also, at times, the producer/consumer are still not able to connect to the topic even though it should have been created (almost like the topic is not quite ready).

Ignition should be enhanced with the ability to pre-create Kafka topics on startup,. This feature should then be used by the JobQueue service to ensure the job topic is available.

Find API should not return 400 when nothing is found

Version: 0.2.0dev0

The find API previously (0.1.0) returned 404 when no infrastructure matching the request could be found. The API now returns a 400, as 404 is reserved for "URI not found".

400 is still wrong, as the request is not bad, it just has no results. As this API is search based, it may be best if it returns a 200 with an empty result.

Validate app name

Background:
The "app_name" configuration is used when creating kafka topics and kafka topics have limitations on which characters can be used in topic names.

Desired functionality:
The app name is validated to only allow alphanumeric characters.

Templating services to support key properties

Currently key properties can only be referenced by name {{ my_key_property }}, which will result in the privateKey value being returned.

We should expand key properties into dictionary with 3 items:

<the name of the key property>:
  private: <the private key>
  public: <the public key>
  name: <the name of the key>

In this way, we can reference the private, public or name part of the key in a template:

{{ my_key_property.private }}
{{ my_key_property.public }}
{{ my_key_property.name }}

Job Queue thread aborts on error

If a handler on a Job Queue throws an error, then the thread managing the queue dies. This means no more jobs can be handled.

Update infrastructure API to include systemProperties on create requests

To enhance the Infrastructure API (and align it with the Lifecycle API), the following changes should be made to the /create API:

  • rename inputs to properties (as they are the properties of the Resource, they don't have to be used as inputs in any work the driver completes)
  • add systemProperties which will include data generated by LM for the Resource

Drivers sometimes "hang" on bootstrap

The driver appears to have bootstrapped successfully, but no REST API requests can be made (the driver does not respond). This has been seen with all drivers that are using Ignition.

Logging Errors

Errors like this are appearing in the logs:

--- Logging error ---
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/logging/__init__.py", line 1025, in emit
    msg = self.format(record)
  File "/usr/local/lib/python3.7/logging/__init__.py", line 869, in format
    return fmt.format(record)
  File "/usr/local/lib/python3.7/site-packages/ignition/service/logging.py", line 136, in format
    return self.serialize(message)
  File "/usr/local/lib/python3.7/site-packages/ignition/service/logging.py", line 110, in serialize
    return json.dumps(message)
  File "/usr/local/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/local/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/local/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/local/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type type is not JSON serializable
Call stack:
  File "/usr/local/lib/python3.7/site-packages/kopdriver/__init__.py", line 12, in create_wsgi_app
    ignition_app = create_app()
  File "/usr/local/lib/python3.7/site-packages/kopdriver/app.py", line 39, in create_app
    return app_builder.configure()
  File "/usr/local/lib/python3.7/site-packages/ignition/boot/api.py", line 127, in configure
    return BootstrapRunner(configuration).init_app()
  File "/usr/local/lib/python3.7/site-packages/ignition/boot/app.py", line 149, in init_app
    connexion_app.add_api(connexion_api['api_spec'], **connexion_api['kwargs'])
  File "/usr/local/lib/python3.7/site-packages/connexion/apps/flask_app.py", line 54, in add_api
    api = super(FlaskApp, self).add_api(specification, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/connexion/apps/abstract.py", line 155, in add_api
    options=api_options.as_dict())
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 109, in __init__
    self.add_paths()
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 207, in add_paths
    self.add_operation(path, method)
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 173, in add_operation
    self._add_operation_internal(method, path, operation)
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/flask_api.py", line 106, in _add_operation_internal
    function = operation.function
  File "/usr/local/lib/python3.7/site-packages/connexion/operations/abstract.py", line 370, in function
    security_decorator = self.security_decorator
  File "/usr/local/lib/python3.7/site-packages/connexion/operations/secure.py", line 75, in security_decorator
    logger.debug('... Security: %s', self.security, extra=vars(self))

Documentation should include details of how the framework should be used, preferaby with examples

The documentation for Ignition explains very well how to create a driver, but it does not explain how to actually go about building one.

The documentation needs to be more detailed in explaining what someone must do to create a driver. It seems that the documentation at the moment is good at explaining some of the concepts used to create the framework, but does not illustrate to driver creator, what they must do to successfully create a driver.

Things that should be in the documentation are:
How is a driver to be called - a simple message diagram of the interaction of Brent to the driver would help - or reference the Brent documentation.
The model of messages that should be used to return values to Brent.
There is no information or examples around the differences between the lifecycle and infrastructure drivers.

Not found response to return 400 code instead of 404

As the requests for infrastructure include the ID as part of the body, rather the URL, it has been suggested that we return a 400 response code if the infrastructure is not found.

404 implies the URL is not found.

Document exception handling

Documentation should explain exception handling in service implementations. In particular:

  • how to handle specific exceptions (such as infrastructure already exists) and convert them to FailureDetails objects and in what circumstances this isn't appropriate (if any)?
  • how Ignition converts (custom) exceptions in to API responses (including which status codes are applied) and whether this is ever appropriate i.e. should all exceptions be caught by the driver and converted in to FailureDetails objects in the response?

Common Kubernetes deployment location

Multiple drivers make use of a Kubernetes based deployment location (Kube driver and Ansible driver). Creating a common set of classes to capture the requirements of this location would allow a single location to be used in both drivers.

Add HTTPS Support

Add support for generating drivers that can run with https. In particular, update the new driver generation feature to include changes to the Helm chart and UWSGI configuration to support SSL drivers.

Jobs not sent to Kafka queue when running in uwsgi

It has been noticed that when running applications on uWSGI the KafkaProducer used by the Job queue service is not sending messages, even though other uses of the same producer work.

This is not the case when using gunicorn. The difference being that gunicorn creates the full application for each server process, whilst uWSGI creates a single process which is then forked X times for each process. This forking causes issues with the use of the KafkaProducer as it cannot be shared by multiple processes.

Creating a new producer for each message would solve the problem but would be expensive. Lazy loading the producer, so it's not created in the first process, but in each forked-process when needed for the first time, should be enough to prevent this happening.

ValueError('File does not include valid YAML: {0}') when using YmlFileSource

Describe the bug
YmlFileSource throws this error when the file content is invalid YAML, the error message features {0} instead of an actual value (of the file path)

To Reproduce

  1. Create an invalid YAML config file
  2. Attempt to load this file with the YmlFileSource class

Expected behavior
An error is thrown with the file path included

**Environment: **

  • Version [e.g. 1.0.0]

LM request context is missing from logs for request queue requests

Drivers that use the request queue (such as the Ansible Driver) are missing LM request context (e.g. transaction id) because it is not included in the request queue payload (and therefore, cannot be applied to log entries resulting from processing these requests)

Allow log levels to be configured using a REST API

Currently, changing the log level on a per-module basis is not possible (for example, increase logging level to DEBUG only on a specific module such as the Kafka module). It would be useful to be able to change the log level for a module using a REST API, much like the functionality that Spring Boot offers (https://docs.spring.io/spring-boot/docs/2.2.1.RELEASE/actuator-api/html/#loggers-setting-level) for example.

This would require adding a REST API to change the log level, and removing the log level configuration in the Helm chart.

Infrastructure and Lifecycle monitors should send message to Brent when an error is raised which will not re-queue the job

The monitors catch specific errors and in some cases will not re-queue the job if an error occurs. For all other errors, the Job Queue service default handling is used, which will also not re-queue the job.

We should consider, for all error cases which will lead to the discarding of the job, sending a standard FAILED result for the Infrastructure or Lifecycle task, so Brent knows it has finished in error. Otherwise, Brent will continue to wait for a response, and will only update the transition as failed when a timeout occurs, with no knowledge of the error.

Raising this as a bug, rather than a new feature request, as it seems to be a mistake in the implementation of the monitors.

Add templateType to infrastructure API

A new templateType field is to be added to the infrastructure create/find APIs. This field will indicate the type of template in use (on the template field). Currently the assumption is the template is TOSCA, this change allows the VIM drivers to support additional types.

Name used in setup.py of generated driver application should be the module name

The setup.py generated from a ignition create command is using the application name as the name field, which leads to whl file names that differ to the module - this is generally considered bad practice.

For example if you create a driver with:
ignition create "Test Driver" --module-name tdriver

Then the whl built using setuptools will be called: Test_Driver-0.0.1-py3-none.whl
If would be better if this file was: tdriver-0.0.1-py3-none.whl

Input properties should include property type

In order to allow key properties to have custom handling, and to control/obfuscate the logging of secure key properties, API requests that contain properties should extend the request to include property types. Specifically, VIM driver CreateInfrastructureRequest "inputs" properties, and lifecycle driver ExecutionRequest "properties" and "systemProperties".

LifecycleScripts workspace should be auto-created

The LifecycleScriptFileManagerService manages writing Lifecycle scripts to a location for the drivers to access the files but it does not auto-create the root directory. As a result, each driver has to ensure this directory exists either in their own code or with the Dockerfile.

Common templating tools

Is your feature request related to a problem? Please describe.
Many of the drivers support the use of template syntax to inject resource property, system property and deployment location property values into infrastructure templates/lifecycle scripts.

The template requirements are often the same but the solutions differ slightly in each driver (e.g. reference names such as dl_properties in one driver, deploymentLocation in another)

Describe the solution you'd like
To encourage consistent syntax Ignition could provide:

  • Common library for rendering templates
  • Common library for building the collection of properties which may be referenced in a template (render props)

Kafka consumer created without group id

The KafkaConsumer created for the inbox service does not set a group id. Kafka prints a warning to say: group id is None. Disabling autocommit.

This means the offset is never committed, so if a driver restarts it may start consuming from the very beginning of the topic rather than the last message.

We should add a group id to the consumer.

Docker image build instructions missing docker context path in command

Describe the bug
The steps for building a docker image provided as part of driver templates is missing the "." on the end of the build command, to provide docker with build context.

Results in error:

"docker build" requires exactly 1 argument.
See 'docker build --help'.

Usage:  docker build [OPTIONS] PATH | URL | -

To Reproduce

  1. Generate a new driver project
  2. Follow the docker build instructions provided at devdocs/docker-image.md

Environment: (please complete the following information where applicable):

  • Ignition 1.0.0

OpenAPI specification files are broken in release 0.5.0

The infrastructure and lifecycle OpenAPI specifications are causing errors when bootstrapping a driver e.g.

connexion.exceptions.InvalidSpecification: {'description': 'Request accepted (async examples shown for information but they will never be returned via this API, they are returned by Kafka instead)', 'content': {'application/json': {'schema': {'$ref': '#/components/schemas/ExecutionAcceptedResponse', 'x-scope': ['']}, 'response': {'example': {'$ref': '#/components/examples/ExampleExecutionAcceptedResponse'}, 'async-response': {'$ref': '#/components/examples/ExampleExecutionAsyncResponse'}, 'failed-async-reponse': {'$ref': '#/components/examples/ExampleFailedExecutionAsyncResponse'}}}}} is not valid under any of the given schemas

Failed validating 'oneOf' in schema['properties']['paths']['patternProperties']['^/']['properties']['post']['properties']['responses']['patternProperties']['^([0-9X]{3})$']:
    {'oneOf': [{'$ref': '#/definitions/response'},
               {'$ref': '#/definitions/reference'}]}

On instance['paths']['/execute']['post']['responses']['202']:
    {'content': {'application/json': {'response': {'async-response': {'$ref': '#/components/examples/ExampleExecutionAsyncResponse'},
                                                   'example': {'$ref': '#/components/examples/ExampleExecutionAcceptedResponse'},
                                                   'failed-async-reponse': {'$ref': '#/components/examples/ExampleFailedExecutionAsyncResponse'}},
                                      'schema': {'$ref': '#/components/schemas/ExecutionAcceptedResponse',
                                                 'x-scope': ['']}}},
     'description': 'Request accepted (async examples shown for '
                    'information but they will never be returned via this '
                    'API, they are returned by Kafka instead)'}

Logs missing traceCtx

Error logs thrown when attempting to unzip the lifecycle scripts directory do not include the traceCtx information:

Example log entry:

{"@timestamp": "2020-02-05T10:12:42.684Z", "@version": "1", "message": "API error occured: Bad magic number for central directory", "host": "ansible-lifecycle-driver-6d947cbfbd-d754x", "path": "/home/ald/.local/lib/python3.7/site-packages/ignition/api/exceptions.py", "tags": [], "type": "logstash", "thread_name": "MainThread", "level": "ERROR", "logger_name": "ignition.api.exceptions", "stack_trace": "Traceback (most recent call last):\n  File \"/home/ald/.local/lib/python3.7/site-packages/flask/app.py\", line 1949, in full_dispatch_request\n    rv = self.dispatch_request()\n  File \"/home/ald/.local/lib/python3.7/site-packages/flask/app.py\", line 1935, in dispatch_request\n    return self.view_functions[rule.endpoint](**req.view_args)\n  File \"/home/ald/.local/lib/python3.7/site-packages/connexion/decorators/decorator.py\", line 48, in wrapper\n    response = function(request)\n  File \"/home/ald/.local/lib/python3.7/site-packages/connexion/decorators/uri_parsing.py\", line 144, in wrapper\n    response = function(request)\n  File \"/home/ald/.local/lib/python3.7/site-packages/connexion/decorators/validation.py\", line 184, in wrapper\n    response = function(request)\n  File \"/home/ald/.local/lib/python3.7/site-packages/connexion/decorators/parameter.py\", line 121, in wrapper\n    return function(**kwargs)\n  File \"/home/ald/.local/lib/python3.7/site-packages/ignition/service/lifecycle.py\", line 146, in execute\n    execute_response = self.service.execute_lifecycle(lifecycle_name, lifecycle_scripts, system_properties, properties, deployment_location)\n  File \"/home/ald/.local/lib/python3.7/site-packages/ignition/service/lifecycle.py\", line 175, in execute_lifecycle\n    lifecycle_scripts_tree = self.script_file_manager.build_tree(file_name, lifecycle_scripts)\n  File \"/home/ald/.local/lib/python3.7/site-packages/ignition/service/lifecycle.py\", line 276, in build_tree\n    extracted_path = self.__extract_scripts(tree_name, package_path)\n  File \"/home/ald/.local/lib/python3.7/site-packages/ignition/service/lifecycle.py\", line 306, in __extract_scripts\n    with zipfile.ZipFile(package_path, 'r') as package_zip:\n  File \"/usr/local/lib/python3.7/zipfile.py\", line 1225, in __init__\n    self._RealGetContents()\n  File \"/usr/local/lib/python3.7/zipfile.py\", line 1320, in _RealGetContents\n    raise BadZipFile(\"Bad magic number for central directory\")\nzipfile.BadZipFile: Bad magic number for central directory\n", "lineno": 38, "process": 10}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.