Developer HowTo for RO Module: Difference between revisions
Line 134: | Line 134: | ||
Or can be run inside a screen (the prefered method for developpers). The script to easily launch/remove is '''./scripts/service-openmano.sh'''. Execute with -h to see options | Or can be run inside a screen (the prefered method for developpers). The script to easily launch/remove is '''./scripts/service-openmano.sh'''. Execute with -h to see options | ||
Note that the general OSM install script, installs openmano inside a container and code run at folder /opt/openmano (instead of $HOME/openmano) | |||
===Tests=== | ===Tests=== |
Revision as of 12:27, 22 March 2017
Getting Started
RO Module is implemented by openmano. The rcomended Linux distribution for developping is Ubuntu Sever LTS 16.04. Pycharm is a nice and easy to use tool for developping
The step Release_1_Installation install all OSM modules on a container. However for development a virtual machine may be more suitable. To install openmano module you can run a script that installs the required packages, clone the project from git clones https://osm.etsi.org/gerrit/osm/RO and configures openmano client and other utility scripts at path
wget -O install-openmano.sh "https://osm.etsi.org/gitweb/?p=osm/RO.git;a=blob_plain;f=scripts/install-openmano.sh" chmod +x install-openmano.sh sudo ./install-openmano.sh -q --develop #-h for help
See also and follow Workflow_with_OSM_tools#Clone_your_project
New code features must be incorporated to master:
git checkout master
Generate a ".gitignore", you can use the .gitignore-common example that skip pycharm and eclipse files
cp RO/.gitignore-common RO/.gitignore #edit to include your local files to ignore
Prepare your git environment to push with a proper user/email, push to gerrit. See and configure:
Workflow_with_OSM_tools#Configure_your_Git_environment
Workflow_with_OSM_tools#Commit_changes_to_your_local_project
Workflow_with_OSM_tools#Push_your_contribution_to_Gerrit
Programming Language
The RO module uses Python2. However Python3 conventions for a possible future migration should be used as far as possible. For example:
BAD Python2 | OK Python2 compatible with python3 |
---|---|
"format test string %s number %d" % (st, num) | "format test string {} number {}".format(st, num) |
print a, b, c | print(a,b,c) |
except Exception, e | except Exception as e |
if type(x) == X: | if isinstance(x,X): |
Descriptors can be YAML (prefered because more readable and allow comments) or JSON
Code Style
Please follow PEP8 style guide for all the Python code.
Logging
Use the appropriate logging levels when logging the messages. An example is shown below:
self.logger.debug("Changing state to %s", next_state)
Logging levels (general and per module) are specified at openmanod.cfg
Try to use few useful logs, not verbose, that brings useful information. For example, in case of fail getting a server, the complete URL should be provided.
Avoid several logs together
WRONG: self.looger.debug("Entering in method A") self.logger.debug("Contacting server"
RIGHT: self.logger.debug("method A, contacting server %s", url)
When the traceback is needed(call stack that generate the exception) , use the "exc_info=True" parameter
self.logger.error("Exception %s when ...", exception, exc_info=True)
Exceptions
Code must be wrote in a way that functions and methods raise an exception when something goes wrong, instead of returning a negative or false value.
Example
WRONG def get_ip_address(): ... if fail: return False, "Fail because xxx" return True, ip ... result, ip = get_ip_address() if not result: return False, "Cannot get ip address..."
RIGHT def get_ip_address(): ... if fail: raise customException("Fail because ...") return ip ... try: ip = get_ip_address() ... except customException as e: raise customException2(str(e))
Directory Organization
The code organized into the following high level directories:
- / contains the openmano code
- /test contains scripts and code for testing
- /database_utils contains scripts for database creation, dumping and migration
- /scripts general scripts, as installation, execution, reporting
- /scenarios examples and templates of network scnario descriptors
- /vnfs examples and templates of VNF descriptors
RO Architecture
The RO module contains the following modules
- openmanod.py is the main program. It reads the configuration file (openmanod.cfg) and execute the httpserver and wait for the end
- nfvo.py is the main engine, implementing all the methods for the creation, deletion and management of vnfs, scenarios and instances
- httpserver.py is a thread that implements the northbound API interface, uses python bottle module
- nfvo_db.py is the module in charge of database operations. Uses MySQLdb python module
- openmano_schemas.py is a dictionary schemas used to validate API request and response content using jsonschema library
- vimconn.py is the base class for the VIM connector modules. The inherited vimconn_openstack.py and vimconn_openvim.py implements the connection to these two VIMs. Openstack ones uses the client-python libraris, meanwhile the Openvim ones uses direct http requests
- console_proxy_thread.py is a thread that implements a TCP/IP proxy for the console access to a VIM
Other modules not part of the server are:
- openmnao is a CLI client
- openmanoclient.py is a client python library for managing openmano server
Northbound Interface
The RO uses a REST API with YAML/JSON content. The primitives are explained here
Running Unit Tests
Launching RO
Openmano can run as systemd service. (Can be installed with ./scripts/install-openmano-service.sh -f RO)
Or can be run inside a screen (the prefered method for developpers). The script to easily launch/remove is ./scripts/service-openmano.sh. Execute with -h to see options
Note that the general OSM install script, installs openmano inside a container and code run at folder /opt/openmano (instead of $HOME/openmano)
Tests
Many of openmano operations rely on an external VIM. Without external infraestructure it is recomended to use openvim in "test" (fake) mode. Install it in the same machine where openmano is located with OpenVIM_installation_(Release_One)#Installation
Run ./test/basictest for a initial test. Type -h to see options. For testing using openvim just run
. ./test/basictest.sh --force --screen --init-openvim
Creating a new VIM plugin
Choose a name, eg. XXX
Create a new python module vimconn_XXX.py derived from vimconn.py class. Implement the relevant functions. You have two already connector created to be used as example, for openstack and openvim. Openstack connector uses the python openstack client libraries, meanwhile openvim connector uses direct http requests.
DO NOT change the method names, parameters or parameter content. Openmano use the same methods for all the VIMs and the cannot be changed to accomodate VIM specifics. The VIM specific must be solved inside the connector
The new module can need specific configuration for the VIM that it is passed as a dictionary in the config variable at constructor. For example in the case of openstack it is specify the activation or not of the port_security_enable, the name of the physical network uses for dataplane, regions, etc. Here you can specify those needed parameters not provided by openmano at the methods that form part of the VIM configuration.
Integration with the main project is automatic, just create a new datacenter of type XXX and this module will be automatically loaded. No other module of the main program need to be updated.
openmano datacenter-create <name> <access-URL> --type=XXX --config <specific config> #example of <specific config> text: "{dataplane_physical_net: physnet_sriov, port_security_enabled: False}" openmano datacenter-attach <name> --vim-tenant-name=<tenant-to-use-by-openmano> --user=<tenant-user> --password=<tenant-password>
You can test it using:
#The openmano client : (you will need admin rights to create tenant, flavors,...) ./test_openmanoclient.py -h ./test_openmanoclient.py -t <working tenant> --datacenter <name> --image=<path/url of an testing image> #The vinconnector tester: ./test/test_vimconn.sh -h