diff --git a/02-developer-how-to.md b/02-developer-how-to.md index 2325ba5bb74bdd0a670a882270cf39cd18ec458c..fead85aff41ed21d093839d315c46717506c2dae 100644 --- a/02-developer-how-to.md +++ b/02-developer-how-to.md @@ -48,7 +48,7 @@ This picture shows the modules with the port that they export, their relationshi _______ _______ _______ _________ | | | | | | | | | mon | | pm | | kafka |KAFKA_ZOOKEEPER_CONNECT |zookeeper| - | :8662 | | | | :9092 |-------------------------> | :2181 | + | :8662 | | | | :9092 |-------------------------> | :2181 | |_______| |_______| |_______| |_________| ``` @@ -75,12 +75,14 @@ git clone https://osm.etsi.org/gerrit/osm/LCM Inside the folder where the module is cloned type the following command: ```bash -pip3 install -e . # try with --user if get permission errors +python3 -m pip install -e +# use option '--user' if get permission errors. +# Use option '-U' (upgrade) if you have already installed it using a different folder ``` **Note**: `pip3` can be installed with `sudo apt-get install python3-pip` -**Note**: it is recommended `pip3` version 9.0.3. Check version with `pip3 --version` and fix it if needed with `pip3 install pip==9.0.3` +**Note**: it is recommended to upgrade `pip3` with `python3 -m pip install -U pip` ### 4 Setup the IDE @@ -96,21 +98,21 @@ Next we will configure a new debug environment. For that we will go to the "Run" You need to feed the IP addresses of the modules it is going to communicate to. For that, you can use your "/etc/hosts" file. -In case the module under development is running in the same server where the rest of the modules are located, use "127.0.0.1" (localhost) as the IP address of those modules. For instance, in the following example we have added mongo, ro and kafka to the line containing "127.0.0.1": +In case the module under development is running in the same server where the rest of the modules are located, use "127.0.0.1" (localhost) as the IP address of those modules. For instance, in the following example we have added mongo, mysql, ro and kafka to the line containing "127.0.0.1": ```text -127.0.0.1 localhost mongo ro kafka nbi ro-db +127.0.0.1 localhost mongo keystone ro kafka nbi mysql ``` In case the module under development is running in a different server from the rest of modules, you will need to provide the IP address of that server. For instance, in the following example we have added a new line with the name resolution for mongo ro and kafka to IP address "a.b.c.d": ```text -a.b.c.d mongo ro kafka nbi ro-db +a.b.c.d mongo keystone ro kafka nbi mysql ``` ### 6 Install needed packages -Is it possible that you will need to install some additional packages in your server. If needed use the commands `pip3 install` or `apt-get install` for that. +Is it possible that you will need to install some additional packages in your server. If needed use the commands `python3 -m pip install` or `apt-get install` for that. Some modules imports another modules from OSM. The modules needed are: @@ -121,18 +123,18 @@ Some modules imports another modules from OSM. The modules needed are: Install them with: ```bash -pip3 install -e common --user # needed for LCM, NBI -pip3 install -e N2VC --user # needed for LCM -pip3 install -e IM --user # needed for NBI +python3 -m pip install -e common --user # needed for LCM, NBI +python3 -m pip install -e N2VC --user # needed for LCM +python3 -m pip install -e IM --user # needed for NBI ``` ### 7 Expose needed ports of docker services -To expose **mongo** database (service `osm_mongo`), needed for NBI, LCM, MON: +To expose **mongo** database and **kafka** (services `osm_mongo`, `osm_kafka`), needed for NBI, LCM, MON: ```bash docker service update osm_mongo --publish-add 27017:27017 -#NOTE: Not sure if this is persistent upon reboot +docker service update osm_kafka --publish-add 9092:9092 # check exposed ports by: docker service list ``` @@ -144,71 +146,53 @@ sudo vi /etc/osm/docker/docker-compose.yaml # add/uncomment at section mongo: # ports: # - "27017:27017" +# same for kafka +# ports: +# - "9092:9092" docker stack rm osm && sleep 60 docker stack deploy -c /etc/osm/docker/docker-compose.yaml osm # make again the service scale to 0 of step 1 in this section ``` -Similarly, **ro-db** (service `osm_ro-db`) needed for RO, uses ports "3306:3306" +Similarly, **mysql** (service `osm_mysql`) needed for RO, uses ports "3306:3306" ... and, **kafka** (service `osm_kafka`) needed for LCM, NBI uses ports "9092:9092". Note: for kafka sometimes this is not enough and other modules has errors connecting to kafka controller. If this is the case modify docker-compose adding kafka bus and relaunch service ## NBI -Install needed OSM packages IM, common: - -```bash -# osm_im: -# Install Information Model vnfd.py and nsd.py files for pyangbind validation at e.g. parent folder where NBI is cloned -pip3 install pyang -git clone https://github.com/robshakir/pyangbind -pip3 install -e pyangbind -git clone https://osm.etsi.org/gerrit/osm/IM -mkdir IM/osm_im -cd IM/models/yang -wget -q https://raw.githubusercontent.com/YangModels/yang/master/standard/ietf/RFC/ietf-yang-types%402013-07-15.yang -O ./ietf-yang-types.yang -wget -q https://raw.githubusercontent.com/YangModels/yang/master/standard/ietf/RFC/ietf-inet-types%402013-07-15.yang -O ./ietf-inet-types.yang -pyang --plugindir ../../../pyangbind/pyangbind/plugin -f pybind -o ../../osm_im/vnfd.py vnfd.yang -pyang --plugindir ../../../pyangbind/pyangbind/plugin -f pybind -o ../../osm_im/nsd.py nsd.yang -pyang --plugindir ../../../pyangbind/pyangbind/plugin -f pybind -o ../../osm_im/nst.py nst.yang -cd ../../.. -pip3 install -e IM -# osm_common: -git clone https://osm.etsi.org/gerrit/osm/common -pip3 install -e common # try with --user if get permission errors -# pip3 install aiokafka==0.4.* pymongo==3.7.* pycrypto pyyaml==3.* -``` - Change docker service **mongo** and **kafka** to expose ports. See [Developer_HowTo - Expose needed ports of docker services](02-developer-how-to.md#7-expose-needed-ports-of-docker-services) Additionally you may want that docker `light-ui` uses your local copy of NBI by one of: -- Edit again file `/etc/osm/docker/docker-compose.yaml`, and set at `light-ui` section the required IP address from docker to the VM: +- Update light-ui docker service: -```text -OSM_SERVER: <172.17.0.1> # nbi +```bash +docker service update osm_light-ui --force --env-add "OSM_SERVER=172.17.0.1" # Get the needed address at your setup by 'ip a | grep docker0' ``` -- ... Or update light-ui docker service (not persistent on reboot): +- ... Or edit file `/etc/osm/docker/docker-compose.yaml`, and set at `light-ui` section the required IP address from docker to the VM: -```bash -docker service update osm_light-ui --force --env-add "OSM_SERVER=172.17.0.1" +```text +OSM_SERVER: <172.17.0.1> # nbi # Get the needed address at your setup by 'ip a | grep docker0' ``` -Clone and install needed NBI packages +Clone and install needed IM and NBI packages. Scale to 0 osm_nbi service ```bash -docker service scale osm_nbi=0 +# Install Information Model IM +git clone https://osm.etsi.org/gerrit/osm/IM +python3 -m pip install -e IM --user + git clone https://osm.etsi.org/gerrit/osm/NBI # configure gerrit commit-msg hook curl -Lo NBI/.git/hooks/commit-msg http://osm.etsi.org/gerrit/tools/hooks/commit-msg chmod u+x NBI/.git/hooks/commit-msg cp NBI/.gitignore-common NBI/.gitignore -pip3 install -e NBI # try with --user if get permission errors -# sudo apt-get install python3-keystoneclient -# pip3 install cherrypy==18.0.0 pyyaml==3.* keystoneauth1 +python3 -m pip install -e NBI # try with --user if get permission errors + +docker service scale osm_nbi=0 ``` Python interpreter: Python3 Script: `$INSTALLATION_FOLDER/NBI/osm_nbi/nbi.py` @@ -229,11 +213,11 @@ Install needed OSM packages if not done: ```bash # N2VC: git clone https://osm.etsi.org/gerrit/osm/N2VC -pip3 install -e N2VC # try with --user if get permission errors +python3 -m pip install -e N2VC # try with --user if get permission errors # osm_common: git clone https://osm.etsi.org/gerrit/osm/common -pip3 install -e common # try with --user if get permission errors +python3 -m pip install -e common # try with --user if get permission errors ``` Change docker service **mongo** and **kafka** to expose ports. See [Developer_HowTo#7 Expose needed ports of docker services](02-developer-how-to.md#7-expose-needed-ports-of-docker-services) @@ -247,7 +231,7 @@ git clone https://osm.etsi.org/gerrit/osm/LCM curl -Lo LCM/.git/hooks/commit-msg http://osm.etsi.org/gerrit/tools/hooks/commit-msg chmod u+x LCM/.git/hooks/commit-msg cp LCM/.gitignore-common LCM/.gitignore -pip3 install -e LCM # try with --user if get permission errors +python3 -m pip install -e LCM # try with --user if get permission errors ``` Python interpreter: Python3 Script: `$INSTALLATION_FOLDER/LCM/osm_lcm/lcm.py` @@ -280,21 +264,39 @@ Values are stored at `/etc/osm/docker/lcm.env` but here it is explained how to o ## RO -It is needed to edit the docker service in order to expose the database port for the `mysql` container. Edit file `/etc/osm/docker/docker-compose.yaml` (recommended to make a backup copy), and uncomment at `mysql` section the following two lines: +It is needed to expose the database port of the `mysql` container by one of: + +- Modify docker service + + ```bash + docker service update osm_mysql --publish-add 3306:3306 + ``` + +- Edit file `/etc/osm/docker/docker-compose.yaml` (recommended to make a backup copy), and uncomment at `mysql` section the following two lines. (Restart stack afterwards): ```yaml - ports: - - "3306:3306" + ports: + - "3306:3306" ``` -Additionally you may want that docker `lcm` uses your local copy of RO. Edit again file `/etc/osm/docker/docker-compose.yaml`, and set at `lcm` section the required IP address from docker to the VM: +Additionally you may want that docker `lcm` uses your local copy of RO. Similarly it can be done by one of: + +- Modify docker service + +```bash + docker service update osm_lcm --env-add OSMLCM_RO_HOST=172.17.0.1 + # check the right IP address to use in your system with: + ip a | grep docker0 +``` + +- Edit file `/etc/osm/docker/docker-compose.yaml`, and set at `lcm` section the required IP address from docker to the VM (Restart stack afterwards): ```yaml - OSMLCM_RO_HOST: <172.17.0.1> # ro + OSMLCM_RO_HOST: 172.17.0.1 # ro # Get the needed address at your setup by 'ip a | grep docker0' ``` -Then, relaunch service: +**Note**: to restart stack, run: ```bash docker stack rm osm @@ -312,15 +314,46 @@ chmod u+x RO/.git/hooks/commit-msg cp RO/.gitignore-common RO/.gitignore ``` -Install needed packages using its own installation script. Though it is not recomended, you can skip the `--no-db` option for installing a local database alternatively to use the database at `ro-db` container: +Install needed packages and install RO with python3-pip: + +```bash +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install libssl-dev libmysqlclient-dev mysql-client +python3 -m pip install --user -e ./RO/RO +# client +python3 -m pip install --user -e ./RO/RO-client +``` + +Install other additional plugins for VIM and SDN ```bash -sudo ./RO/scripts/install-openmano.sh --no-db --noclone --develop +# VMware VIM +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install genisoimage +python3 -m pip install --user -U progressbar pyvmomi pyvcloud==19.1.1 +python3 -m pip install --user -e ./RO/RO-VIM-vmware + +# openstack VIM +python3 -m pip install -U --user networking-l2gw +python3 -m pip install --user -e ./RO/RO-VIM-openstack + +# other VIMs +python3 -m pip install --user -e ./RO/RO-VIM-openvim +python3 -m pip install --user -e ./RO/RO-VIM-aws +python3 -m pip install --user -e ./RO/RO-VIM-azure +python3 -m pip install --user -e ./RO/RO-VIM-fos + +# SDN plugins +python3 -m pip install --user -e ./RO/RO-SDN-dynpac +python3 -m pip install --user -e ./RO/RO-SDN-tapi +python3 -m pip install --user -e ./RO/RO-SDN-onos_vpls +python3 -m pip install --user -e ./RO/RO-SDN-onos_openflow +python3 -m pip install --user -e ./RO/RO-SDN-floodlight_openflow +python3 -m pip install --user -e ./RO/RO-SDN-arista + ``` -Python interpreter: Python2 Script: `$INSTALLATION_FOLDER/RO/openmanod` +Python interpreter: Python3 Script: `$INSTALLATION_FOLDER/RO/RO/openmanod.py` Environment variables: -- `RO_DB_HOST`, `RO_DB_OVIM_HOST`: `localhost` or `` depending if running on the same server or not. Not needed if alternatively you use a local database copy. +- `RO_DB_HOST`, `RO_DB_OVIM_HOST`: `mysql` or `` depending if running on the same server or not. - `RO_LOG_LEVEL`: `DEBUG` diff --git a/03-developer-how-to-for-modules.md b/03-developer-how-to-for-modules.md index c260f417a23af484fca13662825c6eec476a83ce..73d12a3a04ab8efbb4c5b3996966553cb64526a5 100644 --- a/03-developer-how-to-for-modules.md +++ b/03-developer-how-to-for-modules.md @@ -4,9 +4,9 @@ ### Getting Started -The RO Module of OSM is implemented by openmano. The recommended Linux distribution for development is Ubuntu 16.04 LTS Server. PyCharm is a nice and easy to use tool for development and debugging. +The recommended Linux distribution for RO module is Ubuntu 18.04 LTS Server. PyCharm is a nice and easy to use tool for development and debugging. -The community installer installs all OSM modules as containers. However, for development, a virtual machine may be more suitable. To install the openmano module you can run a script that installs the required packages, clone the project from `git clone https://osm.etsi.org/gerrit/osm/RO` and configures openmano client and other utility scripts at path: +The community installer installs all OSM modules as containers. However, for development, a virtual machine may be more suitable. To install the RO module follow [Developer on RO](02-developer-how-to.md#RO). There are an installation script useful for installing RO as separate component including the needed mysql datatabase: ```bash wget -O install-openmano.sh "https://osm.etsi.org/gitweb/?p=osm/RO.git;a=blob_plain;f=scripts/install-openmano.sh" @@ -14,13 +14,15 @@ 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](01-workflow-osm-tools.md#clone-your-project) +Prepare your git environment to push with a proper user/email, push to gerrit, etc. See and configure: -New code features must be incorporated to master: +[Workflow_with_OSM_tools#Clone_your_project](01-workflow-osm-tools.md#clone-your-project) -```bash -git checkout master -``` +[Workflow_with_OSM_tools#Configure_your_Git_environment](01-workflow-osm-tools.md#configure-your-git-environment) + +[Workflow_with_OSM_tools#Commit_changes_to_your_local_project](01-workflow-osm-tools.md#commit-changes-to-your-local-project) + +[Workflow_with_OSM_tools#Push_your_contribution_to_Gerrit](01-workflow-osm-tools.md#push-your-contribution-to-gerrit) Generate a `.gitignore`, you can use the `.gitignore-common` example that skips PyCharm and Eclipse files: @@ -29,30 +31,11 @@ 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](01-workflow-osm-tools.md#configure-your-git-environment) - -[Workflow_with_OSM_tools#Commit_changes_to_your_local_project](01-workflow-osm-tools.md#commit-changes-to-your-local-project) - -[Workflow_with_OSM_tools#Push_your_contribution_to_Gerrit](01-workflow-osm-tools.md#push-your-contribution-to-gerrit) - ### Programming Language -The RO module is in the transition to Python3, so Python3 conventions must 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):` | - -In addition, **DO NOT USE libraries not compatible with python3** +The RO module uses Python3. Descriptors can be YAML (preferred, as it is more readable and allows comments) or JSON. -### Descriptors can be YAML (preferred, as it is more readable and allows comments) or JSON. - -### Code Style +#### Code Style Please follow PEP8 style guide for all the Python code. Lines up to 120 length @@ -131,13 +114,16 @@ RIGHT: The code organized into the following high level directories: -- **`/`** contains the entry server file `openmanod` and client `openmano` code -- **`/osm_ro`** contains the RO server code files -- **`/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 scenario descriptors -- **`/vnfs`** examples and templates of VNF descriptors +- **RO/** main RO server engine + - **`RO/osm_ro/`** contains the RO server code files + - **`RO/test/`** contains scripts and code for testing + - **`RO/database_utils/`** contains scripts for database creation, dumping and migration + - **`RO/scripts/`** general scripts, as installation, execution, reporting + - **`RO/scenarios/`** examples and templates of network scenario descriptors + - **`RO/vnfs/`** examples and templates of VNF descriptors +- **RO-client/** contains the own RO client CLI +- **RO-SDN-*/** contains the SDN plugins +- **RO-VIM-*/** contains the VIM plugins ### RO Architecture @@ -147,21 +133,19 @@ The code organized into the following high level directories: The RO module contains the following modules -- **`openmanod`** is the main program. It reads the configuration file (`openmanod.cfg`) and execute `httpserver` and wait for the end +- **`openmanod.py`** is the main program. It reads the configuration file (`openmanod.cfg`) and execute `httpserver` and wait for the end - **`httpserver.py`** is a thread that implements the northbound API interface, uses python bottle module. Calls main engine methods to perform the tasks - **`nfvo.py`** is the main engine, implementing all the methods for the creation, deletion and management of vnfs, scenarios and instances. Operations against a VIM are asynchornous. ACTIONs to be done are stored at database before returning ok to the client - **`nfvo_db.py`** is the module in charge of database operations. Uses base **`db_base.py`**. Database is managed with MySQLdb python library - **`openmano_schemas.py`** is a dictionary schemas used to validate API request and response content using jsonschema library - **`vim_thread.py`** There is a thread per VIM and credentials. It performs basic tasks of creating/deleting VM, networks, flavors, etc. In addition it refreshes the VM and network status. It calls vimconn.py methods -- **`vimconn.py`** is the base class for the VIM plugin. It contains the definition of the methods to be implemented. The inherited **`vimconn_openstack.py`**, **`vimconn_openvim.py`**, **`vimconn_vmware`** and **`vimconn_aws`** implements the operations against the concrete VIM type. OpenStack plugin uses the `python-*client` libraries, meanwhile Openvim plugin uses direct http requests. -- **`console_proxy_thread.py`** is a thread that implements a TCP/IP proxy for the console access to ## a VIM. +- **`vimconn.py`** is the base class for the VIM plugin. It contains the definition of the methods to be implemented. The inherited - **`console_proxy_thread.py`** is a thread that implements a TCP/IP proxy for the console access to ## a VIM. #### RO Client modules Other modules not part of the server are: -- **`openmano`** is a CLI client -- **`openmanoclient.py`** is a client python library for managing openmano server +- **`roclient.py`** is a CLI client #### ACTIONS and TASKS @@ -175,13 +159,13 @@ TODO: add details on DB content Database schema can be changed if needed. It is recommended to use a graphical tool (e.g. Heidy) to change database and change it back and copy the SQL commands. Make these steps: -1. `openmanod`: increment `__version__`, `version_date` and `database_version` -2. `database_utils/migrate_mano_db.sh`. See the three "TODO" +1. `RO/osm_ro/openmanod.py`: increment `__version__`, `version_date` and `database_version` +2. `RO/osm_ro/database_utils/migrate_mano_db.sh`. See the three "TODO" - 2a. Increment `LAST_DB_VERSION` - 2b. Annotate a comment to have a track of versions: `[ $OPENMANO_VER_NUM -ge 50XX ] && DB_VERSION=XX #0.5.XX => XX` - 2c. Generate new methods; `function upgrade_to_XX()` and `function downgrade_from_XX()`. Insert here the sql commands. Last sql command over schema_version is quite important to detect the database version. -## Test several upgrades/downgrades to version 20 with `migrate_mano_db.sh` and `migrate_mano_db.sh 20` +Test several upgrades/downgrades to version 20 with `migrate_mano_db.sh` and `migrate_mano_db.sh 20` ### Package dependency osm-im @@ -198,40 +182,12 @@ The OSM binary installation install this package. In case of needed you can inst ```bash apt-get update apt-get install make git python python-pip tox debhelper python-bitarray python-lxml -pip install --upgrade pip +python3 -m pip install --upgrade pip # If not inside a container. Use "sudo -HE" to get root privileges for pip installation -pip install pyangbind stdeb git clone https://osm.etsi.org/gerrit/osm/IM -make -C IM clean all -dpkg -i IM/deb_dist/python-pyang_*.deb -dpkg -i IM/deb_dist/python-pyangbind_*.deb -dpkg -i IM/deb_dist/python-osm-im_*.deb +python3 -m install -e IM # Use this line to check if it is installed and where -python -c 'import osm_im; print osm_im.__path__[0]' -``` - -### Package dependency `lib-osm-openvim` - -It is under openvim repository. RO uses a library for the SDN assist that is in charge of performing the underlay dataplane connectivity using an openflow controller. `osm-openvim` and `lib-osm-openvim` are different, though they share same pieces of code. `lib-osm-openvim` uses a different database name (`mano_vim_db`) so that openvim can be installed in the same virtual machine or container (openvim uses `vim_db` database name) - -TODO: complete where RO uses it. - -#### Installation - -The OSM binary installation install this package. In case of needed you can install/update it manually by: - -```bash -apt-get update -apt-get install make git python tox libmysqlclient-dev -git clone https://osm.etsi.org/gerrit/osm/openvim -git -C openvim checkout 005a9dc # this is temporal, because last version contains error at Makefile -make -C openvim lite -# Use this line to check if it is installed and where -python -c 'import lib_osm_openvim; print lib_osm_openvim.__path__[0]' -# Install database of ovim library -OSMLIBOVIM_PATH=`python -c 'import lib_osm_openvim; print lib_osm_openvim.__path__[0]'` -# -U and -P are the admin database user/password. Normally "-U root" without password "executed as root" -${OSMLIBOVIM_PATH}/database_utils/install-db-server.sh -U root [-P passwd] -u mano -p manopw -d mano_vim_db --updatedb +python3 -c 'import osm_im; print osm_im.__path__[0]' ``` ### CLI client @@ -246,7 +202,7 @@ The RO uses a REST API with YAML/JSON content. The primitives are explained [her #### Launching RO -Openmano can run as `systemd` service. (Can be installed with `./scripts/install-openmano-service.sh -f RO`). +RO can run as `systemd` service. (Can be installed with `./scripts/install-openmano-service.sh -f RO`). Or can be run inside a screen (the preferred method for developers). The script to easily launch/remove is `./scripts/service-openmano.sh`. Execute with `-h` to see options. @@ -254,7 +210,7 @@ Note that the general OSM install script, installs openmano inside a container a #### Tests -Many of openmano operations rely on an external VIM. Without external infrastructure it is recommended to use openvim in "test" (fake) mode. Install it in the same machine where openmano is located with [OpenVIM_installation_(Release_One)#Installation](10-00-openvim-install.md#installation) +Many of RO operations rely on an external VIM. Without external infrastructure it is recommended to use openvim in "test" (fake) mode. Install it in the same machine where openmano is located with [OpenVIM_installation_(Release_One)#Installation](10-00-openvim-install.md#installation) Run; @@ -266,14 +222,12 @@ Run; Choose a name, eg. XXX -Create a new python module vimconn_XXX.py derived from vimconn.py class. Implement the relevant functions. You have several connectors already created to be used as example as openstack and openvim. Openstack connector uses the python openstack client libraries, meanwhile openvim connector uses direct http requests. +Create a new plugin folder RO-VIM-XXX. Copy one of the existing, there are several connectors already created to be used as example as openstack and openvim. Openstack connector uses the python openstack client libraries, meanwhile openvim connector uses direct http requests. Create a class derived from vimconn.py. Implement the relevant functions. DO NOT change the method names, parameters or parameter content. RO uses the same methods for all the VIMs and they cannot be changed to accommodate VIM specifics. VIM specifics 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, `config` variable is used for: enabling/disabling port_security_enable, specifying the name of the physical network used for dataplane, regions, etc. The `config` variable is the right place to specify those needed parameters not provided by RO at the methods that form part of the VIM configuration. See [Openstack configuration#Add openstack to OSM](05-02-openstack-configuration.md#add-openstack-to-osm) and [Configuring AWS for OSM Release TWO#Add AWS to OSM](12-aws-configuration.md#add-aws-to-osm) for examples. -For integration with the main project, it is needed to add the new vim type to dictionary `vim_module` at file `osm_ro/vim_thread.py`. - ```bash openmano tenant-create osm # if not already done export OPENMANO_TENANT=osm