aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/odl_cluster
diff options
context:
space:
mode:
authorYifei Xue <xueyifei@huawei.com>2017-06-19 19:22:11 +0800
committerYifei Xue <xueyifei@huawei.com>2017-07-10 10:42:20 +0000
commita7fed3be428eddf64f626c52ef35cf691c68e431 (patch)
tree4fe6b4cf635cd3ebf3450dd97fa0e947d47ae92c /plugins/odl_cluster
parent4db2df5989e16b2ad1152b7851136ff4dc637252 (diff)
Upgrade ODL from boron to carbon
JIRA: - Change-Id: I031444d1094af646ae39a9c0c3fbfc30548e6ee4 Signed-off-by: Yifei Xue <xueyifei@huawei.com>
Diffstat (limited to 'plugins/odl_cluster')
-rw-r--r--plugins/odl_cluster/files/opendaylight.service20
-rwxr-xr-xplugins/odl_cluster/handlers/main.yml11
-rw-r--r--plugins/odl_cluster/plugins.desc58
-rw-r--r--plugins/odl_cluster/tasks/control-agents-1.yml39
-rw-r--r--plugins/odl_cluster/tasks/control-agents-2.yml87
-rw-r--r--plugins/odl_cluster/tasks/control-agents-3.yml37
-rw-r--r--plugins/odl_cluster/tasks/control-db-1.yml8
-rw-r--r--plugins/odl_cluster/tasks/control-hosts-1.yml98
-rw-r--r--plugins/odl_cluster/tasks/control-hosts-2.yml23
-rw-r--r--plugins/odl_cluster/tasks/control-repos-1.yml17
-rw-r--r--plugins/odl_cluster/tasks/control-servers-1.yml15
-rw-r--r--plugins/odl_cluster/tasks/control-servers-2.yml34
-rw-r--r--plugins/odl_cluster/tasks/control-servers-3.yml19
-rw-r--r--plugins/odl_cluster/tasks/main.yml39
-rw-r--r--plugins/odl_cluster/tasks/odl-post.yml32
-rwxr-xr-xplugins/odl_cluster/templates/acl_conf.sh12
-rwxr-xr-xplugins/odl_cluster/templates/custom.properties105
-rwxr-xr-xplugins/odl_cluster/templates/ml2_conf.sh14
-rwxr-xr-xplugins/odl_cluster/templates/org.apache.karaf.features.cfg54
-rwxr-xr-xplugins/odl_cluster/vars/Debian.yml21
-rwxr-xr-xplugins/odl_cluster/vars/RedHat.yml19
-rwxr-xr-xplugins/odl_cluster/vars/main.yml60
22 files changed, 822 insertions, 0 deletions
diff --git a/plugins/odl_cluster/files/opendaylight.service b/plugins/odl_cluster/files/opendaylight.service
new file mode 100644
index 00000000..f4801a36
--- /dev/null
+++ b/plugins/odl_cluster/files/opendaylight.service
@@ -0,0 +1,20 @@
+[Unit]
+Description=OpenDaylight
+After=
+
+
+[Service]
+User=root
+Group=root
+Type=simple
+WorkingDirectory=/opt/opendaylight
+PermissionsStartOnly=true
+ExecStartPre=
+ExecStart=/usr/lib/jvm/java-8-oracle/bin/java -Djava.security.properties=/opt/opendaylight/etc/odl.java.security -server -Xms128M -Xmx2048m -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass -XX:+HeapDumpOnOutOfMemoryError -Dcom.sun.management.jmxremote -Djava.security.egd=file:/dev/./urandom -Djava.endorsed.dirs=/usr/lib/jvm/java-8-oracle/jre/lib/endorsed:/usr/lib/jvm/java-8-oracle/lib/endorsed:/opt/opendaylight/lib/endorsed -Djava.ext.dirs=/usr/lib/jvm/java-8-oracle/jre/lib/ext:/usr/lib/jvm/java-8-oracle/lib/ext:/opt/opendaylight/lib/ext -Dkaraf.instances=/opt/opendaylight/instances -Dkaraf.home=/opt/opendaylight -Dkaraf.base=/opt/opendaylight -Dkaraf.data=/opt/opendaylight/data -Dkaraf.etc=/opt/opendaylight/etc -Djava.io.tmpdir=/opt/opendaylight/data/tmp -Djava.util.logging.config.file=/opt/opendaylight/etc/java.util.logging.properties -Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true -classpath /opt/opendaylight/lib/karaf.branding-1.8.1-SNAPSHOT.jar:/opt/opendaylight/lib/karaf-jaas-boot.jar:/opt/opendaylight/lib/karaf.jar:/opt/opendaylight/lib/karaf-org.osgi.core.jar org.apache.karaf.main.Main
+Restart=on-failure
+LimitNOFILE=65535
+TimeoutStopSec=15
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/plugins/odl_cluster/handlers/main.yml b/plugins/odl_cluster/handlers/main.yml
new file mode 100755
index 00000000..2650d072
--- /dev/null
+++ b/plugins/odl_cluster/handlers/main.yml
@@ -0,0 +1,11 @@
+##############################################################################
+# Copyright (c) 2016 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+- name: restart odl service
+ service: name=opendaylight state=restarted
diff --git a/plugins/odl_cluster/plugins.desc b/plugins/odl_cluster/plugins.desc
new file mode 100644
index 00000000..04e78f99
--- /dev/null
+++ b/plugins/odl_cluster/plugins.desc
@@ -0,0 +1,58 @@
+# ##############################################################
+# This is an example for add a plugin into Compass4nfv
+# It illustrates how feature components can be integrated into Compass4nfv
+# together with scenarios.
+#
+#
+# More details can be found in the development document.
+# ##############################################################
+---
+plugin:
+ # plugin name,it is also as the switch to enable/disable plugin in scenario
+ # files
+ name: opendaylight
+
+ description: plugin introduce and description
+ maintainers:
+ - xueyifei@huawei.com
+
+ # true: this plugin is deployed separately on a new node
+ # false: this plugin is deployed on controller or compute node
+ independent_hosts: false
+
+ # artifact: packege download url for this plugin
+ artifacts:
+ url:
+
+ # global_vars:
+ # define the parameters required by the plugin
+ # and its value will be defined and passed by compass4nfv
+ global_vars:
+ - xxx: yyy
+ - ntp_server: "pool.ntp.org"
+
+ # orchestration
+ # A plugin can have mutiple components, each component may need to be
+ # installed on different inventory or have its own configuration.
+ # due to Compass4nfv currently only supports ansible, so each component
+ # of the installation and configuration script need to be use ansible.
+ # cm : congfiguration management tool : only ansible support
+ # role: each component corresponds to ansible script that locates in the same
+ # directory as plugin.desc.
+ # phrase: pre_openstack -- the component is installed after the OS
+ # provisioning, before the OpenStack deployment.
+ # phrase: post_openstack -- the component is installed before the OpenStack
+ # deployment.
+ # inventory: if the phrase is pre_openstack, inventory can be controller and
+ # compute. if the phrase is post_openstack, inventory can be get from the file
+ # openstack-ansible.inventory
+ orchestration:
+ cm: ansible
+ roles:
+ - role: opendaylight
+ phrase: post_openstack
+ inventory:
+ - neutron_all
+ - galera_container
+ - network_hosts
+ - repo_container
diff --git a/plugins/odl_cluster/tasks/control-agents-1.yml b/plugins/odl_cluster/tasks/control-agents-1.yml
new file mode 100644
index 00000000..dc071cc7
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-agents-1.yml
@@ -0,0 +1,39 @@
+---
+
+- name: install crudini
+ package:
+ name: crudini
+ state: latest
+
+- name: install networking-odl
+ pip:
+ name: networking-odl
+ version: "{{ networking_odl_version }}"
+ virtualenv: /openstack/venvs/neutron-15.1.4
+
+- name: configure vsctl for dhcp agent
+ shell: |
+ crudini --set /etc/neutron/dhcp_agent.ini OVS \
+ ovsdb_interface vsctl;
+ when:
+ - inventory_hostname not in groups['nova_compute']
+
+- name: configure vsctl for l3 agent
+ shell: |
+ crudini --set /etc/neutron/l3_agent.ini OVS \
+ ovsdb_interface vsctl;
+ when: odl_l3_agent == "Disable" and inventory_hostname not in groups['nova_compute']
+
+- name: stop neutron l3 agent
+ service: name=neutron-l3-agent state=stopped enabled=no
+ when: odl_l3_agent == "Enable" and inventory_hostname not in groups['nova_compute']
+
+- name: shut down and disable Neutron's openvswitch agent services
+ service: name={{ service_ovs_agent_name }} state=stopped enabled=no
+
+- name: Stop the Open vSwitch service and clear existing OVSDB
+ shell: >
+ service {{ service_ovs_name }} stop ;
+ rm -rf /var/log/openvswitch/* ;
+ rm -rf /etc/openvswitch/conf.db ;
+ service {{ service_ovs_name }} start ;
diff --git a/plugins/odl_cluster/tasks/control-agents-2.yml b/plugins/odl_cluster/tasks/control-agents-2.yml
new file mode 100644
index 00000000..b138dc38
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-agents-2.yml
@@ -0,0 +1,87 @@
+---
+
+- name: set opendaylight as the manager
+ command: |
+ su -s /bin/sh -c "ovs-vsctl set-manager tcp:{{ internal_lb_vip_address }}:6640;"
+
+- name: check br-int
+ shell: |
+ ovs-vsctl list-br | grep br-int; while [ $? -ne 0 ]; do sleep 10; \
+ ovs-vsctl list-br | grep br-int; done
+
+# yamllint disable rule:line-length
+- name: set local ip in openvswitch
+ shell: |
+ ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) \
+ other_config={'local_ip'=' {{ hostvars[inventory_hostname]['container_networks']['tunnel_address']['address'] }} '};
+ when: inventory_hostname not in groups['nova_compute']
+
+- name: set local ip in openvswitch
+ shell: |
+ ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) \
+ other_config={'local_ip'=' {{ hostvars[inventory_hostname]['ansible_br_vxlan']['ipv4']['address'] }} '};
+ when: inventory_hostname in groups['nova_compute']
+# yamllint enable rule:line-length
+
+- name: Setup br-provider
+ openvswitch_bridge:
+ bridge: br-provider
+ state: present
+ when:
+ - inventory_hostname not in groups['nova_compute']
+ - odl_l3_agent == "Disable"
+
+- name: add ovs uplink
+ openvswitch_port:
+ bridge: br-provider
+ port: "eth12"
+ state: present
+ when:
+ - inventory_hostname not in groups['nova_compute']
+ - odl_l3_agent == "Disable"
+
+- name: set external nic in openvswitch
+ shell: |
+ ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) \
+ other_config:provider_mappings=physnet1:br-provider
+ when:
+ - odl_l3_agent == "Disable"
+ - inventory_hostname not in groups['nova_compute']
+
+- name: set external nic in openvswitch
+ shell: |
+ ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) \
+ other_config:provider_mappings=physnet1:eth12
+ when:
+ - odl_l3_agent == "Enable"
+
+- name: Set host OVS configurations
+ command: |
+ /openstack/venvs/neutron-15.1.4/bin/neutron-odl-ovs-hostconfig \
+ --datapath_type=system --bridge_mappings=physnet1:br-provider
+ when:
+ - inventory_hostname not in groups['nova_compute']
+ - odl_l3_agent == "Disable"
+
+- name: Set host OVS configurations
+ command: |
+ /openstack/venvs/neutron-15.1.4/bin/neutron-odl-ovs-hostconfig
+ --datapath_type=system --bridge_mappings=physnet1:eth12
+ when:
+ - inventory_hostname not in groups['nova_compute']
+ - odl_l3_agent == "Enable"
+
+- name: Set host OVS configurations
+ command: |
+ /openstack/venvs/neutron-15.1.4/bin/neutron-odl-ovs-hostconfig --datapath_type=system
+ when:
+ - inventory_hostname in groups['nova_compute']
+ - odl_l3_agent == "Disable"
+
+- name: Set host OVS configurations
+ command: |
+ /openstack/venvs/neutron-15.1.4/bin/neutron-odl-ovs-hostconfig
+ --datapath_type=system --bridge_mappings=physnet1:eth12
+ when:
+ - inventory_hostname in groups['nova_compute']
+ - odl_l3_agent == "Enable"
diff --git a/plugins/odl_cluster/tasks/control-agents-3.yml b/plugins/odl_cluster/tasks/control-agents-3.yml
new file mode 100644
index 00000000..66a0873f
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-agents-3.yml
@@ -0,0 +1,37 @@
+---
+
+- name: configure opendaylight -> ml2
+ shell: >
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 mechanism_drivers opendaylight_v2;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types vxlan;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovs enable_tunneling "True";
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 extension_drivers port_security;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovs bridge_mappings physnet1:br-provider;
+
+- name: configure bridge_mappings for L3
+ shell: |
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovs bridge_mappings physnet1:eth12;
+ when: odl_l3_agent == "Enable"
+
+- name: configure opendaylight in ml2
+ shell: |
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_odl username admin;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_odl password admin;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_odl url \
+ http://{{ internal_lb_vip_address }}:8080/controller/nb/v2/neutron;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_odl port_binding_controller \
+ pseudo-agentdb-binding;
+
+- name: configure metadata for l3 configuration
+ shell: |
+ crudini --set /etc/neutron/dhcp_agent.ini DEFAULT \
+ enable_isolated_metadata "True";
+ when:
+ - inventory_hostname not in groups['nova_compute']
+
+- name: force metadata for l3 configuration
+ shell: |
+ crudini --set /etc/neutron/dhcp_agent.ini DEFAULT \
+ force_metadata "True";
+ when:
+ - inventory_hostname not in groups['nova_compute']
diff --git a/plugins/odl_cluster/tasks/control-db-1.yml b/plugins/odl_cluster/tasks/control-db-1.yml
new file mode 100644
index 00000000..3cef9792
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-db-1.yml
@@ -0,0 +1,8 @@
+---
+
+- name: drop and recreate neutron database
+ shell: |
+ mysql -e "drop database if exists neutron;";
+ mysql -e "create database neutron character set utf8;";
+ mysql -e "grant all on neutron.* to 'neutron'@'%' identified by \
+ '{{ neutron_container_mysql_password }}';";
diff --git a/plugins/odl_cluster/tasks/control-hosts-1.yml b/plugins/odl_cluster/tasks/control-hosts-1.yml
new file mode 100644
index 00000000..133d98a7
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-hosts-1.yml
@@ -0,0 +1,98 @@
+---
+
+- name: check sdn_package cache
+ stat:
+ path=/opt/sdn_package.tar.gz
+ register: sdn_cache # Todo: remove hard code and add md5 check
+
+- name: debug
+ debug: msg="{{ sdn_cache }}"
+
+- name: get sdn_package
+ get_url:
+ url: "{{ sdn_package }}"
+ dest: /opt/
+ when: sdn_cache.stat.exists != 'true'
+
+- name: create odl group
+ group: name=odl system=yes state=present
+
+- name: create odl user
+ user:
+ name: odl
+ group: odl
+ home: "{{ odl_home }}"
+ createhome: "yes"
+ system: "yes"
+ shell: "/bin/false"
+
+- name: clear sdn_package
+ command: su -s /bin/sh -c "rm -rf /opt/sdn_package"
+
+- name: clear jdk8 package
+ command: su -s /bin/sh -c "rm -rf /opt/install_jdk8"
+
+- name: unarchive sdn_package
+ command: su -s /bin/sh -c "tar xzf /opt/sdn_package.tar.gz -C /opt/"
+
+- name: copy java package
+ command: su -s /bin/sh -c "cp /opt/sdn_package/java/jdk-8u51-linux-x64.tar.gz /opt/"
+
+- name: unarchive java_install package
+ command: su -s /bin/sh -c "tar xvf /opt/sdn_package/java/install_jdk8.tar -C /opt/"
+
+- name: install java
+ command: su -s /bin/sh -c "/opt/install_jdk8/install_jdk8.sh"
+
+- name: clear odl package
+ command: su -s /bin/sh -c "rm -rf {{ odl_home }}*"
+
+- name: extract odl package
+ command: |
+ su -s /bin/sh -c "tar xzf /opt/sdn_package/odl/{{ odl_pkg_name }} -C {{ odl_home }} \
+ --strip-components 1" odl
+
+- name: opendaylight system file
+ copy:
+ src: "{{ service_file.src }}"
+ dest: "{{ service_file.dst }}"
+ mode: 0755
+
+- name: set l3 fwd enable in custom.properties
+ template:
+ src: custom.properties
+ dest: "{{ odl_home }}/etc/custom.properties"
+ owner: odl
+ group: odl
+ mode: 0775
+ when: odl_l3_agent == "Enable"
+
+- name: create karaf config
+ template:
+ src: org.apache.karaf.features.cfg
+ dest: "{{ odl_home }}/etc/org.apache.karaf.features.cfg"
+ owner: odl
+ group: odl
+ mode: 0775
+
+- name: copy acl configuration script
+ template:
+ src: acl_conf.sh
+ dest: "/opt/acl_conf.sh"
+ mode: 0777
+
+- name: execute acl configuration script
+ command: su -s /bin/sh -c "/opt/acl_conf.sh;" odl
+
+- name: create jetty config
+ shell: >
+ sed -i 's/default="8181"/default="8081"/'
+ {{ odl_home }}etc/jetty.xml
+
+- name: create tomcat config
+ shell: >
+ sed -i 's/port="8282"/port="8081"/'
+ {{ odl_home }}configuration/tomcat-server.xml
+
+- name: remove karaf data directory
+ shell: rm -rf {{ odl_home }}/data/*;
diff --git a/plugins/odl_cluster/tasks/control-hosts-2.yml b/plugins/odl_cluster/tasks/control-hosts-2.yml
new file mode 100644
index 00000000..b8d9403a
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-hosts-2.yml
@@ -0,0 +1,23 @@
+---
+
+- name: chown opendaylight directory and files
+ shell: >
+ chown -R odl:odl "{{ odl_home }}";
+ chown odl:odl "{{ service_file.dst }}";
+
+- name: start opendaylight
+ service: name=opendaylight state=started
+ when: ansible_os_family == "Debian"
+
+- name: set opendaylight autostart
+ shell: chkconfig opendaylight on
+ when: ansible_os_family == "RedHat"
+
+- name: start opendaylight
+ shell: service opendaylight start
+ when: ansible_os_family == "RedHat"
+
+- name: check if opendaylight running
+ shell: |
+ netstat -lpen --tcp | grep java | grep 6653;
+ while [ $? -ne 0 ]; do sleep 10; netstat -lpen --tcp | grep java | grep 6653; done
diff --git a/plugins/odl_cluster/tasks/control-repos-1.yml b/plugins/odl_cluster/tasks/control-repos-1.yml
new file mode 100644
index 00000000..8427e4f0
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-repos-1.yml
@@ -0,0 +1,17 @@
+---
+
+- name: download networking-odl
+ get_url:
+ url: "{{ odl_pip }}"
+ dest: /var/www/repo/os-releases/15.1.4/ubuntu-16.04-x86_64
+
+- name: patch networking-odl to fix a bug
+ shell: |
+ cd /var/www/repo/os-releases/15.1.4/ubuntu-16.04-x86_64/
+ tar -zxf networking-odl-4.0.0.tar.gz # hard code, need to modify
+ rm -rf networking-odl-4.0.0.tar.gz
+ sed -i 's/^Babel.*/Babel!=2.4.0,>=2.3.4/' networking-odl-4.0.0/requirements.txt
+ tar -zcf networking-odl-4.0.0.tar.gz networking-odl-4.0.0/
+ rm -rf networking-odl-4.0.0/
+ pip install networking-odl-4.0.0.tar.gz -d ./
+ cd -
diff --git a/plugins/odl_cluster/tasks/control-servers-1.yml b/plugins/odl_cluster/tasks/control-servers-1.yml
new file mode 100644
index 00000000..459c734a
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-servers-1.yml
@@ -0,0 +1,15 @@
+---
+
+- name: install crudini
+ package:
+ name: crudini
+ state: latest
+
+- name: install networking-odl
+ pip:
+ name: networking-odl
+ version: "{{ networking_odl_version }}"
+ virtualenv: /openstack/venvs/neutron-15.1.4 # Todo: hardcode, need to modify
+
+- name: turn off neutron-server on control node
+ service: name=neutron-server state=stopped
diff --git a/plugins/odl_cluster/tasks/control-servers-2.yml b/plugins/odl_cluster/tasks/control-servers-2.yml
new file mode 100644
index 00000000..d19d2db1
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-servers-2.yml
@@ -0,0 +1,34 @@
+---
+
+- name: configure odl l3 driver
+ shell: |
+ crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins \
+ odl-router,metering;
+ when: odl_l3_agent == "Enable"
+
+- name: configure opendaylight -> ml2
+ shell: >
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 mechanism_drivers opendaylight_v2;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types vxlan;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovs enable_tunneling "True";
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 extension_drivers port_security;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovs bridge_mappings physnet1:br-provider;
+
+- name: configure bridge_mappings for L3
+ shell: |
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ovs bridge_mappings physnet1:eth12;
+ when: odl_l3_agent == "Enable"
+
+- name: configure external bridge name for L2
+ shell: |
+ crudini --set /etc/neutron/l3_agent.ini DEFAULT external_network_bridge br-provider;
+ when: odl_l3_agent == "Disable"
+
+- name: configure opendaylight in ml2
+ shell: |
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_odl username admin;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_odl password admin;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_odl url \
+ http://{{ internal_lb_vip_address }}:8080/controller/nb/v2/neutron;
+ crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_odl port_binding_controller \
+ pseudo-agentdb-binding;
diff --git a/plugins/odl_cluster/tasks/control-servers-3.yml b/plugins/odl_cluster/tasks/control-servers-3.yml
new file mode 100644
index 00000000..3d5c307b
--- /dev/null
+++ b/plugins/odl_cluster/tasks/control-servers-3.yml
@@ -0,0 +1,19 @@
+---
+
+- name: Perform a Neutron DB online upgrade
+ command: |
+ /openstack/venvs/neutron-15.1.4/bin/neutron-db-manage
+ --config-file /etc/neutron/neutron.conf
+ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini
+ upgrade --expand
+ become: "yes"
+ become_user: "neutron"
+
+- name: Perform a Neutron DB offline upgrade
+ command: |
+ /openstack/venvs/neutron-15.1.4/bin/neutron-db-manage
+ --config-file /etc/neutron/neutron.conf
+ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini
+ upgrade --contract
+ become: "yes"
+ become_user: "neutron"
diff --git a/plugins/odl_cluster/tasks/main.yml b/plugins/odl_cluster/tasks/main.yml
new file mode 100644
index 00000000..44359056
--- /dev/null
+++ b/plugins/odl_cluster/tasks/main.yml
@@ -0,0 +1,39 @@
+---
+
+- include_vars: "{{ ansible_os_family }}.yml"
+
+- include: control-hosts-1.yml
+ when: inventory_hostname in groups['network_hosts'] # Todo: modify to odl_hosts
+
+- include: control-repos-1.yml
+ vars:
+ odl_pip: "{{ networking_odl_url }}"
+ when: inventory_hostname in groups['repo_container']
+
+- include: control-servers-1.yml
+ when: inventory_hostname in groups['neutron_server']
+
+- include: control-agents-1.yml
+ when: inventory_hostname in groups['neutron_openvswitch_agent']
+
+- include: control-hosts-2.yml
+ when: inventory_hostname in groups['network_hosts'] # Todo: modify to odl_hosts
+
+- include: control-agents-2.yml
+ when: inventory_hostname in groups['neutron_openvswitch_agent']
+
+- include: control-servers-2.yml
+ when: inventory_hostname in groups['neutron_server']
+
+- include: control-agents-3.yml
+ when: inventory_hostname in groups['neutron_openvswitch_agent']
+
+- include: control-db-1.yml
+ when: inventory_hostname == groups['galera_container'][0]
+
+- include: control-servers-3.yml
+ when:
+ - inventory_hostname in groups['neutron_server'][0]
+ - inventory_hostname not in groups['network_hosts']
+
+- include: odl-post.yml
diff --git a/plugins/odl_cluster/tasks/odl-post.yml b/plugins/odl_cluster/tasks/odl-post.yml
new file mode 100644
index 00000000..8794ff0c
--- /dev/null
+++ b/plugins/odl_cluster/tasks/odl-post.yml
@@ -0,0 +1,32 @@
+---
+
+- name: restart neutron-server
+ service: name=neutron-server state=restarted enabled=yes
+ when: inventory_hostname in groups['neutron_server']
+
+- name: restart neutron-l3-agent server
+ service: name=neutron-l3-agent state=restarted
+ when:
+ - odl_l3_agent == "Disable"
+ - inventory_hostname in groups['neutron_openvswitch_agent']
+ - inventory_hostname not in groups['nova_compute']
+
+- name: restart neutron-dhcp-agent server
+ service: name=neutron-dhcp-agent state=restarted
+ when:
+ - inventory_hostname in groups['neutron_openvswitch_agent']
+ - inventory_hostname not in groups['nova_compute']
+
+- name: restart neutron-metadata-agent server
+ service: name=neutron-metadata-agent state=restarted
+ when:
+ - inventory_hostname in groups['neutron_openvswitch_agent']
+ - inventory_hostname not in groups['nova_compute']
+
+- name: clear karaf data
+ shell: rm -rf {{ odl_home }}/data/*;
+ when: inventory_hostname in groups['network_hosts']
+
+- name: restart opendaylight
+ shell: sleep 60; service opendaylight restart; sleep 60;
+ when: inventory_hostname in groups['network_hosts']
diff --git a/plugins/odl_cluster/templates/acl_conf.sh b/plugins/odl_cluster/templates/acl_conf.sh
new file mode 100755
index 00000000..4962a17c
--- /dev/null
+++ b/plugins/odl_cluster/templates/acl_conf.sh
@@ -0,0 +1,12 @@
+##############################################################################
+# Copyright (c) 2017 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+mkdir -p {{ odl_home }}etc/opendaylight/datastore/initial/config/
+CONFFILE=$(find {{ odl_home }} -name "*aclservice*config.xml")
+cp $CONFFILE {{ odl_home }}etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml
+sed -i s/stateful/transparent/ {{ odl_home }}etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml
diff --git a/plugins/odl_cluster/templates/custom.properties b/plugins/odl_cluster/templates/custom.properties
new file mode 100755
index 00000000..f103c1b8
--- /dev/null
+++ b/plugins/odl_cluster/templates/custom.properties
@@ -0,0 +1,105 @@
+# Extra packages to import from the boot class loader
+org.osgi.framework.system.packages.extra=org.apache.karaf.branding,sun.reflect,sun.reflect.misc,sun.misc,sun.nio.ch,com.sun.media.sound
+
+# https://bugs.eclipse.org/bugs/show_bug.cgi?id=325578
+# Extend the framework to avoid the resources to be presented with
+# a URL of type bundleresource: but to be presented as file:
+osgi.hook.configurators.include=org.eclipse.virgo.kernel.equinox.extensions.hooks.ExtensionsHookConfigurator
+
+# Embedded Tomcat configuration File
+org.eclipse.gemini.web.tomcat.config.path=configuration/tomcat-server.xml
+org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
+
+# Use Equinox as default OSGi Framework Implementation
+karaf.framework=equinox
+
+# Show a progress bar on startup and start the console when all bundles are up and running.
+# (If you are in a hurry you can still type enter to start the shell faster.)
+karaf.delay.console=true
+
+# Set security provider to BouncyCastle
+org.apache.karaf.security.providers = org.bouncycastle.jce.provider.BouncyCastleProvider
+
+# We set this to false to disable the Aries BlueprintExtender from doing its orderly container
+# shutdown so we can do it after the CSS has shut down all its modules. Otherwise Aries will
+# shutdown blueprint containers when the karaf framework starts shutdown (ie when bundle 0 is
+# stopped) which can cause failures on CSS module shutdown due to the core blueprint containers
+# and services already being shut down. This setting can be removed when/if CSS is removed
+# completely from ODL.
+org.apache.aries.blueprint.preemptiveShutdown=false
+
+netconf.config.persister.active=1
+
+netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter
+netconf.config.persister.1.properties.fileStorage=etc/opendaylight/current/controller.currentconfig.xml
+netconf.config.persister.1.properties.numberOfBackups=1
+
+# logback configuration
+logback.configurationFile=configuration/logback.xml
+
+# Container configuration
+container.profile = Container
+
+# Connection manager configuration
+connection.scheme = ANY_CONTROLLER_ONE_MASTER
+
+# OVSDB configuration
+# ovsdb plugin supports both active and passive connections. It listens on port 6640 by default for Active connections.
+ovsdb.listenPort=6640
+
+# ovsdb creates Openflow nodes/bridges. This configuration configures the bridge's Openflow version.
+# default Openflow version = 1.0, we also support 1.3.
+# ovsdb.of.version=1.3
+
+# ovsdb can be configured with ml2 to perform l3 forwarding. The config below enables that functionality, which is
+# disabled by default.
+ovsdb.l3.fwd.enabled=yes
+
+# ovsdb can be configured with ml2 to perform arp responder, enabled by default.
+ovsdb.l3.arp.responder.disabled=no
+
+# ovsdb can be configured with ml2 to perform l3 forwarding. When used in that scenario, the mac address of the default
+# gateway --on the external subnet-- is expected to be resolved from its inet address. The config below overrides that
+# specific arp/neighDiscovery lookup.
+# ovsdb.l3gateway.mac=00:00:5E:00:02:01
+
+# TLS configuration
+# To enable TLS, set secureChannelEnabled=true and specify the location of controller Java KeyStore and TrustStore files.
+# The Java KeyStore contains controller's private key and certificate. The Java TrustStore contains the trusted certificate
+# entries, including switches' Certification Authority (CA) certificates. For example,
+# secureChannelEnabled=true
+# controllerKeyStore=./configuration/ctlKeyStore
+# controllerKeyStorePassword=xxxxxxxx (this password should match the password used for KeyStore generation and at least 6 characters)
+# controllerTrustStore=./configuration/ctlTrustStore
+# controllerTrustStorePassword=xxxxxxxx (this password should match the password used for TrustStore generation and at least 6 characters)
+
+secureChannelEnabled=false
+controllerKeyStore=
+controllerKeyStorePassword=
+controllerTrustStore=
+controllerTrustStorePassword=
+
+# User Manager configurations
+enableStrongPasswordCheck = false
+
+#Jolokia configurations
+#org.jolokia.listenForHttpService=false
+
+# Logging configuration for Tomcat-JUL logging
+java.util.logging.config.file=configuration/tomcat-logging.properties
+
+#Hosttracker hostsdb key scheme setting
+hosttracker.keyscheme=IP
+
+# LISP Flow Mapping configuration
+# Enable merging RLOC sets received from different xTR-IDs for the same EID (default: false)
+lisp.mappingMerge = false
+# Enable the Solicit-Map-Request (SMR) mechanism (default: true)
+lisp.smr = true
+# Choose policy for Explicit Locator Path (ELP) handling
+# There are three options:
+# default: don't add or remove locator records, return mapping as-is
+# both: keep the ELP, but add the next hop as a standalone non-LCAF locator with a lower priority
+# replace: remove the ELP, add the next hop as a standalone non-LCAF locator
+lisp.elpPolicy = default
+
diff --git a/plugins/odl_cluster/templates/ml2_conf.sh b/plugins/odl_cluster/templates/ml2_conf.sh
new file mode 100755
index 00000000..0d42e48b
--- /dev/null
+++ b/plugins/odl_cluster/templates/ml2_conf.sh
@@ -0,0 +1,14 @@
+##############################################################################
+# Copyright (c) 2016 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+cat <<EOT>> /etc/neutron/plugins/ml2/ml2_conf.ini
+[ml2_odl]
+password = admin
+username = admin
+url = http://{{ internal_vip.ip }}:8080/controller/nb/v2/neutron
+EOT
diff --git a/plugins/odl_cluster/templates/org.apache.karaf.features.cfg b/plugins/odl_cluster/templates/org.apache.karaf.features.cfg
new file mode 100755
index 00000000..bc625cda
--- /dev/null
+++ b/plugins/odl_cluster/templates/org.apache.karaf.features.cfg
@@ -0,0 +1,54 @@
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+#
+# Defines if the startlvl should be respected during feature startup. The default value is true. The default
+# behavior for 2.x is false (!) for this property
+#
+# Be aware that this property is deprecated and will be removed in Karaf 4.0. So, if you need to
+# set this to false, please use this only as a temporary solution!
+#
+#respectStartLvlDuringFeatureStartup=true
+
+
+#
+# Defines if the startlvl should be respected during feature uninstall. The default value is true.
+# If true, means stop bundles respecting the descend order of start level in a certain feature.
+#
+#respectStartLvlDuringFeatureUninstall=true
+
+#
+# Comma separated list of features repositories to register by default
+#
+featuresRepositories = mvn:org.apache.karaf.features/standard/3.0.8/xml/features,mvn:org.apache.karaf.features/enterprise/3.0.8/xml/features,mvn:org.ops4j.pax.web/pax-web-features/3.2.9/xml/features,mvn:org.apache.karaf.features/spring/3.0.8/xml/features,mvn:org.opendaylight.integration/features-integration-index/0.6.1-SNAPSHOT/xml/features
+
+#
+# Comma separated list of features to install at startup
+#
+featuresBoot=config,standard,region,package,kar,ssh,management,odl-restconf-all,odl-aaa-authn,odl-dlux-all,odl-netvirt-openstack,odl-mdsal-apidocs,odl-dlux-core,odl-dluxapps-nodes,odl-dluxapps-topology,odl-dluxapps-yangui,odl-dluxapps-yangvisualizer,odl-l2switch-switch,odl-l2switch-switch-ui,odl-ovsdb-hwvtepsouthbound-ui,odl-ovsdb-southbound-impl-ui,odl-netvirt-ui,odl-openflowplugin-flow-services-ui,odl-neutron-logger
+
+#
+# Defines if the boot features are started in asynchronous mode (in a dedicated thread)
+#
+featuresBootAsynchronous=false
+
+#
+# Store cfg file for config element in feature
+#
+#configCfgStore=true
diff --git a/plugins/odl_cluster/vars/Debian.yml b/plugins/odl_cluster/vars/Debian.yml
new file mode 100755
index 00000000..c78c5221
--- /dev/null
+++ b/plugins/odl_cluster/vars/Debian.yml
@@ -0,0 +1,21 @@
+##############################################################################
+# Copyright (c) 2016 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+
+common_packages:
+ - crudini
+
+service_ovs_name: openvswitch-switch
+service_ovs_agent_name: neutron-openvswitch-agent
+
+service_file:
+ src: opendaylight.service
+ dst: /lib/systemd/system/opendaylight.service
+
+# networking_odl_pkg_name: networking-odl-3.2.0.tar.gz
diff --git a/plugins/odl_cluster/vars/RedHat.yml b/plugins/odl_cluster/vars/RedHat.yml
new file mode 100755
index 00000000..a2e6d01d
--- /dev/null
+++ b/plugins/odl_cluster/vars/RedHat.yml
@@ -0,0 +1,19 @@
+##############################################################################
+# Copyright (c) 2016 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+
+common_packages:
+ - crudini
+
+service_ovs_name: openvswitch
+service_ovs_agent_name: neutron-openvswitch-agent
+
+service_file:
+ src: opendaylight.service
+ dst: /lib/systemd/system/opendaylight.service
diff --git a/plugins/odl_cluster/vars/main.yml b/plugins/odl_cluster/vars/main.yml
new file mode 100755
index 00000000..42e1acb1
--- /dev/null
+++ b/plugins/odl_cluster/vars/main.yml
@@ -0,0 +1,60 @@
+##############################################################################
+# Copyright (c) 2016 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+odl_username: admin
+odl_password: admin
+odl_api_port: 8181
+
+odl_pkg_url: distribution-karaf-0.6.1-Carbon.tar.gz
+odl_pkg_name: distribution-karaf-0.6.1-Carbon.tar.gz
+odl_home: "/opt/opendaylight/"
+odl_base_features:
+ - config
+ - standard
+ - region
+ - package
+ - kar
+ - ssh
+ - management
+ - odl-restconf
+ - odl-l2switch-switch
+ - odl-openflowplugin-all
+ - odl-mdsal-apidocs
+ - odl-dlux-all
+ - odl-adsal-northbound
+ - odl-nsf-all
+ - odl-ovsdb-openstack
+ - odl-ovsdb-northbound
+ - odl-dlux-core
+
+odl_extra_features:
+ - odl-restconf-all
+ - odl-mdsal-clustering
+ - odl-openflowplugin-flow-services
+ - http
+ - jolokia-osgi
+
+odl_features: "{{ odl_base_features + odl_extra_features }}"
+
+sdn_package: http://artifacts.opnfv.org/compass4nfv/packages/master/sdn_package.tar.gz
+
+# yamllint disable rule:line-length
+networking_odl_url: https://launchpad.net/networking-odl/4.0-ocata/4.0.0/+download/networking-odl-4.0.0.tar.gz
+# yamllint enable rule:line-length
+
+jdk8_pkg_name: jdk-8u51-linux-x64.tar.gz
+jdk8_script_name: install_jdk8.tar
+
+common_packages_noarch: []
+
+odl_pip: networking-odl-3.2.0
+
+networking_odl_version: 4.0.0
+
+networking_odl_pkg_name: networking-odl-3.2.0.tar.gz