From 57496c4147e648eb7432a8b06f47666b4e3c86ff Mon Sep 17 00:00:00 2001 From: Marcus G K Williams Date: Wed, 4 Jan 2017 16:58:48 -0800 Subject: [PATCH] Add OpenDaylight role Adds role for OpenDaylight deploy. Change-Id: I1e697ea4d3f33aab4b0f55863a377b39eda8f609 Co-Authored-By: Mauricio Lima Co-Authored-By: Jiri Prokes Co-Authored-By: Eduardo Gonzalez Partially-Implements: blueprint opendaylight-support --- ansible/group_vars/all.yml | 32 +++- ansible/inventory/all-in-one | 3 + ansible/inventory/multinode | 3 + .../roles/haproxy/templates/haproxy.cfg.j2 | 27 +++ ansible/roles/neutron/defaults/main.yml | 22 ++- .../roles/neutron/templates/dhcp_agent.ini.j2 | 4 + .../roles/neutron/templates/ml2_conf.ini.j2 | 14 +- .../neutron/templates/neutron-server.json.j2 | 2 +- .../roles/neutron/templates/neutron.conf.j2 | 7 +- ansible/roles/opendaylight/defaults/main.yml | 24 +++ ansible/roles/opendaylight/handlers/main.yml | 31 +++ ansible/roles/opendaylight/meta/main.yml | 3 + ansible/roles/opendaylight/tasks/check.yml | 1 + ansible/roles/opendaylight/tasks/config.yml | 178 ++++++++++++++++++ ansible/roles/opendaylight/tasks/deploy.yml | 5 + ansible/roles/opendaylight/tasks/main.yml | 2 + ansible/roles/opendaylight/tasks/precheck.yml | 111 +++++++++++ ansible/roles/opendaylight/tasks/pull.yml | 10 + .../roles/opendaylight/tasks/reconfigure.yml | 2 + ansible/roles/opendaylight/tasks/upgrade.yml | 5 + .../roles/opendaylight/templates/akka.conf.j2 | 33 ++++ .../templates/custom.properties.j2 | 47 +++++ .../roles/opendaylight/templates/jetty.xml.j2 | 90 +++++++++ .../templates/module-shards.conf.j2 | 59 ++++++ .../opendaylight/templates/modules.conf.j2 | 20 ++ .../netvirt-aclservice-config.xml.j2 | 4 + ...irt-impl-config_netvirt-impl-config.xml.j2 | 7 + .../templates/opendaylight.json.j2 | 90 +++++++++ .../org.apache.karaf.features.cfg.j2 | 24 +++ .../org.opendaylight.ovsdb.library.cfg.j2 | 7 + .../templates/org.ops4j.pax.logging.cfg.j2 | 52 +++++ .../templates/org.ops4j.pax.url.mvn.cfg.j2 | 34 ++++ .../roles/opendaylight/templates/setenv.j2 | 24 +++ .../roles/opendaylight/templates/start-odl.j2 | 3 + .../templates/tomcat-server.xml.j2 | 46 +++++ ansible/roles/openvswitch/handlers/main.yml | 3 + ansible/roles/openvswitch/tasks/config.yml | 26 +++ .../templates/openvswitch-db-server.json.j2 | 9 +- .../templates/openvswitch-vswitchd.json.j2 | 11 +- .../roles/openvswitch/templates/start-ovs.j2 | 10 + .../templates/start-ovsdb-server.j2 | 33 ++++ ansible/site.yml | 8 + etc/kolla/globals.yml | 9 +- etc/kolla/passwords.yml | 5 + .../opendaylight-role-b1787bc458da5bc4.yaml | 3 + 45 files changed, 1128 insertions(+), 15 deletions(-) create mode 100644 ansible/roles/opendaylight/defaults/main.yml create mode 100644 ansible/roles/opendaylight/handlers/main.yml create mode 100644 ansible/roles/opendaylight/meta/main.yml create mode 100644 ansible/roles/opendaylight/tasks/check.yml create mode 100644 ansible/roles/opendaylight/tasks/config.yml create mode 100644 ansible/roles/opendaylight/tasks/deploy.yml create mode 100644 ansible/roles/opendaylight/tasks/main.yml create mode 100644 ansible/roles/opendaylight/tasks/precheck.yml create mode 100644 ansible/roles/opendaylight/tasks/pull.yml create mode 100644 ansible/roles/opendaylight/tasks/reconfigure.yml create mode 100644 ansible/roles/opendaylight/tasks/upgrade.yml create mode 100644 ansible/roles/opendaylight/templates/akka.conf.j2 create mode 100644 ansible/roles/opendaylight/templates/custom.properties.j2 create mode 100644 ansible/roles/opendaylight/templates/jetty.xml.j2 create mode 100644 ansible/roles/opendaylight/templates/module-shards.conf.j2 create mode 100644 ansible/roles/opendaylight/templates/modules.conf.j2 create mode 100644 ansible/roles/opendaylight/templates/netvirt-aclservice-config.xml.j2 create mode 100644 ansible/roles/opendaylight/templates/netvirt-impl-config_netvirt-impl-config.xml.j2 create mode 100644 ansible/roles/opendaylight/templates/opendaylight.json.j2 create mode 100644 ansible/roles/opendaylight/templates/org.apache.karaf.features.cfg.j2 create mode 100644 ansible/roles/opendaylight/templates/org.opendaylight.ovsdb.library.cfg.j2 create mode 100644 ansible/roles/opendaylight/templates/org.ops4j.pax.logging.cfg.j2 create mode 100644 ansible/roles/opendaylight/templates/org.ops4j.pax.url.mvn.cfg.j2 create mode 100644 ansible/roles/opendaylight/templates/setenv.j2 create mode 100644 ansible/roles/opendaylight/templates/start-odl.j2 create mode 100644 ansible/roles/opendaylight/templates/tomcat-server.xml.j2 create mode 100644 ansible/roles/openvswitch/templates/start-ovs.j2 create mode 100644 ansible/roles/openvswitch/templates/start-ovsdb-server.j2 create mode 100644 releasenotes/notes/opendaylight-role-b1787bc458da5bc4.yaml diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index ef6ccc7d6b..992eb4b2d9 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -122,7 +122,7 @@ bifrost_network_interface: "{{ network_interface }}" dns_interface: "{{ network_interface }}" tunnel_interface_address: "{{ hostvars[inventory_hostname]['ansible_' + tunnel_interface]['ipv4']['address'] }}" -# Valid options are [ openvswitch, linuxbridge, vmware_nsxv, vmware_dvs ] +# Valid options are [ openvswitch, linuxbridge, vmware_nsxv, vmware_dvs, opendaylight ] neutron_plugin_agent: "openvswitch" # The default ports used by each service. @@ -260,6 +260,19 @@ watcher_api_port: "9322" zun_api_port: "9517" +opendaylight_clustering_port: "2550" +opendaylight_restconf_port: "8087" +opendaylight_restconf_port_backup: "8182" +opendaylight_haproxy_restconf_port: "8088" +opendaylight_haproxy_restconf_port_backup: "8183" +opendaylight_jetty_conf_port: "8543" +opendaylight_jetty_conf2_port: "8443" +opendaylight_tomcat_port: "8282" +opendaylight_tomcat_redirect_port: "8663" +opendaylight_karaf_ssh_port: "8101" +opendaylight_openflow_port: "6653" +opendaylight_ovsdb_port: "6641" +opendaylight_haproxy_ovsdb_port: "6642" public_protocol: "{{ 'https' if kolla_enable_tls_external | bool else 'http' }}" internal_protocol: "http" @@ -375,6 +388,7 @@ enable_neutron_provider_networks: "no" enable_neutron_sfc: "no" enable_nova_serialconsole_proxy: "no" enable_octavia: "no" +enable_opendaylight: "no" enable_openvswitch: "{{ neutron_plugin_agent != 'linuxbridge' | bool }}" enable_osprofiler: "no" enable_panko: "no" @@ -530,7 +544,7 @@ neutron_type_drivers: "flat,vlan,vxlan" # NOTE: for ironic this list should also contain 'flat' neutron_tenant_network_types: "vxlan" -computes_need_external_bridge: "{{ enable_neutron_dvr | bool or enable_neutron_provider_networks | bool and neutron_plugin_agent != 'vmware_dvs' }}" +computes_need_external_bridge: "{{ enable_neutron_dvr | bool or enable_neutron_provider_networks | bool or enable_opendaylight | bool and neutron_plugin_agent != 'vmware_dvs' }}" ####################### # Nova options @@ -612,3 +626,17 @@ vmware_vcenter_host_ip: vmware_vcenter_host_username: vmware_vcenter_host_password: vmware_vcenter_cluster_name: + +###################### +# OpenDaylight +###################### +opendaylight_release: "0.6.1-Carbon" +opendaylight_mechanism_driver: "opendaylight_v2" +opendaylight_l3_service_plugin: "odl-router_v2" +opendaylight_acl_impl: "learn" +enable_opendaylight_qos: "no" +enable_opendaylight_l3: "{{ enable_opendaylight }}" +enable_opendaylight_legacy_netvirt_conntrack: "no" +opendaylight_port_binding_type: "pseudo-agentdb-binding" +opendaylight_features: "odl-mdsal-apidocs,odl-netvirt-openstack" +opendaylight_allowed_network_types: '"flat", "vlan", "vxlan"' diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one index 154abf5e6f..f9c6de918b 100644 --- a/ansible/inventory/all-in-one +++ b/ansible/inventory/all-in-one @@ -103,6 +103,9 @@ network compute manila-share +[opendaylight:children] +network + [cinder:children] control diff --git a/ansible/inventory/multinode b/ansible/inventory/multinode index 8b57b3d4d1..c319219ce3 100644 --- a/ansible/inventory/multinode +++ b/ansible/inventory/multinode @@ -124,6 +124,9 @@ network compute manila-share +[opendaylight:children] +network + [cinder:children] control diff --git a/ansible/roles/haproxy/templates/haproxy.cfg.j2 b/ansible/roles/haproxy/templates/haproxy.cfg.j2 index 49c7e029d4..bdde3f92da 100644 --- a/ansible/roles/haproxy/templates/haproxy.cfg.j2 +++ b/ansible/roles/haproxy/templates/haproxy.cfg.j2 @@ -873,3 +873,30 @@ listen mariadb {% endfor %} {% endif %} +{% if enable_opendaylight | bool %} +listen opendaylight_api + bind {{ kolla_internal_vip_address }}:{{ opendaylight_haproxy_restconf_port }} + balance source +{% for host in groups['opendaylight'] %} + server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_restconf_port }} check fall 5 inter 2000 rise 2 +{% endfor %} + +listen opendaylight_api_backup + bind {{ kolla_internal_vip_address }}:{{ opendaylight_haproxy_restconf_port_backup }} + balance source +{% for host in groups['opendaylight'] %} + server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_restconf_port_backup }} check fall 5 inter 2000 rise 2 +{% endfor %} + +listen opendaylight_ovsdb + mode tcp + timeout client 3600s + timeout server 3600s + option tcplog + option tcpka + bind {{ kolla_internal_vip_address }}:{{ opendaylight_haproxy_ovsdb_port }} +{% for host in groups['opendaylight'] %} + server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_ovsdb_port }} check inter 2000 rise 2 fall 5 {% if not loop.first %}backup{% endif %} + +{% endfor %} +{% endif %} diff --git a/ansible/roles/neutron/defaults/main.yml b/ansible/roles/neutron/defaults/main.yml index f24ab2b4aa..e52d60a692 100644 --- a/ansible/roles/neutron/defaults/main.yml +++ b/ansible/roles/neutron/defaults/main.yml @@ -81,7 +81,7 @@ neutron_services: container_name: "neutron_l3_agent" image: "{{ neutron_l3_agent_image_full }}" privileged: True - enabled: "{{ not enable_neutron_vpnaas | bool and neutron_plugin_agent not in ['vmware_nsxv', 'vmware_dvs'] }}" + enabled: "{{ not enable_neutron_vpnaas | bool and neutron_plugin_agent not in ['vmware_nsxv', 'vmware_dvs'] and not enable_opendaylight_l3 | bool }}" host_in_groups: >- {{ inventory_hostname in groups['neutron-l3-agent'] @@ -90,6 +90,7 @@ neutron_services: volumes: - "{{ node_config_directory }}/neutron-l3-agent/:{{ container_config_directory }}/:ro" - "/etc/localtime:/etc/localtime:ro" + - "/lib/modules:/lib/modules:ro" - "/run:/run:shared" - "neutron_metadata_socket:/var/lib/neutron/kolla/" - "kolla_logs:/var/log/kolla/" @@ -186,7 +187,7 @@ neutron_openvswitch_agent_image: "{{ docker_registry ~ '/' if docker_registry el neutron_openvswitch_agent_tag: "{{ neutron_tag }}" neutron_openvswitch_agent_image_full: "{{ neutron_openvswitch_agent_image }}:{{ neutron_openvswitch_agent_tag }}" -neutron_server_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ neutron_install_type }}-neutron-server" +neutron_server_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ neutron_install_type }}-neutron-server{{ '-opendaylight' if enable_opendaylight | bool else '' }}" neutron_server_tag: "{{ neutron_tag }}" neutron_server_image_full: "{{ neutron_server_image }}:{{ neutron_server_tag }}" @@ -218,7 +219,7 @@ openstack_neutron_auth: "{{ openstack_auth }}" #################### extension_drivers: - name: "qos" - enabled: "{{ enable_neutron_qos | bool }}" + enabled: "{{ enable_neutron_qos | bool or enable_opendaylight_qos | bool }}" - name: "port_security" enabled: true - name: "dns" @@ -241,13 +242,15 @@ service_plugins: - name: "vpnaas" enabled: "{{ enable_neutron_vpnaas | bool }}" - name: "qos" - enabled: "{{ enable_neutron_qos | bool }}" + enabled: "{{ enable_neutron_qos | bool or enable_opendaylight_qos | bool}}" - name: "router" - enabled: true + enabled: "{{ not enable_opendaylight_l3 | bool }}" - name: "sfc" enabled: "{{ enable_neutron_sfc | bool }}" - name: "neutron_dynamic_routing.services.bgp.bgp_plugin.BgpPlugin" enabled: "{{ enable_neutron_bgp_dragent | bool }}" + - name: "{{ opendaylight_l3_service_plugin }}" + enabled: "{{ enable_opendaylight_l3 | bool and enable_opendaylight | bool }}" neutron_service_plugins: "{{ service_plugins|selectattr('enabled', 'equalto', true)|list }}" @@ -302,3 +305,12 @@ vmware_dvs_host_password: "password" vmware_dvs_insecure: "True" vmware_dvs_dvs_name: "VDS-1" vmware_dvs_dhcp_override_mac: "" + +###################### +# Notification Drivers +###################### +notification_drivers: + - name: "odl-qos-v2" + enabled: "{{ enable_opendaylight_qos | bool }}" + +neutron_notification_drivers: "{{ notification_drivers|selectattr('enabled', 'equalto', true)|list }}" diff --git a/ansible/roles/neutron/templates/dhcp_agent.ini.j2 b/ansible/roles/neutron/templates/dhcp_agent.ini.j2 index 71c40967cc..240482db44 100644 --- a/ansible/roles/neutron/templates/dhcp_agent.ini.j2 +++ b/ansible/roles/neutron/templates/dhcp_agent.ini.j2 @@ -16,6 +16,10 @@ dhcp_override_mac = {{ vmware_dvs_dhcp_override_mac }} {% endif %} {% endif %} +{% if enable_opendaylight | bool %} +interface_driver = openvswitch +{% endif %} + [ovs] ovsdb_interface = native ovsdb_connection = tcp:{{ api_interface_address }}:6640 diff --git a/ansible/roles/neutron/templates/ml2_conf.ini.j2 b/ansible/roles/neutron/templates/ml2_conf.ini.j2 index 054b8faa43..279423ba3a 100644 --- a/ansible/roles/neutron/templates/ml2_conf.ini.j2 +++ b/ansible/roles/neutron/templates/ml2_conf.ini.j2 @@ -12,6 +12,8 @@ mechanism_drivers = openvswitch,l2population {% endif %} {% elif neutron_plugin_agent == "linuxbridge" %} mechanism_drivers = linuxbridge,l2population +{% elif neutron_plugin_agent == "opendaylight" %} +mechanism_drivers = {{ opendaylight_mechanism_driver }} {% endif %} {% if neutron_extension_drivers %} @@ -20,6 +22,14 @@ extension_drivers = {{ neutron_extension_drivers|map(attribute='name')|join(',') extension_drivers = port_security {% endif %} +{% if enable_opendaylight | bool %} +[ml2_odl] +url = {{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ opendaylight_haproxy_restconf_port }}/controller/nb/v2/neutron +username = admin +password = {{ opendaylight_password }} +port_binding_controller = {{ opendaylight_port_binding_type }} +{% endif %} + [ml2_type_vlan] {% if enable_ironic | bool %} network_vlan_ranges = physnet1 @@ -41,13 +51,13 @@ vxlan_group = 239.1.1.1 {% endif %} [securitygroup] -{% if neutron_plugin_agent == "openvswitch" %} +{% if neutron_plugin_agent == "openvswitch" or neutron_plugin_agent == "opendaylight" %} firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver {% elif neutron_plugin_agent == "linuxbridge" %} firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver {% endif %} -{% if neutron_plugin_agent == "openvswitch" %} +{% if neutron_plugin_agent == "openvswitch" or neutron_plugin_agent == "opendaylight" %} {% if not enable_hyperv | bool %} [agent] tunnel_types = vxlan diff --git a/ansible/roles/neutron/templates/neutron-server.json.j2 b/ansible/roles/neutron/templates/neutron-server.json.j2 index 076e9a5eae..9f83c71f9d 100644 --- a/ansible/roles/neutron/templates/neutron-server.json.j2 +++ b/ansible/roles/neutron/templates/neutron-server.json.j2 @@ -1,5 +1,5 @@ { - "command": "neutron-server --config-file /etc/neutron/neutron.conf {% if neutron_plugin_agent in ['openvswitch', 'linuxbridge'] %} --config-file /etc/neutron/plugins/ml2/ml2_conf.ini --config-file /etc/neutron/neutron_lbaas.conf --config-file /etc/neutron/neutron_vpnaas.conf {% elif neutron_plugin_agent in ['vmware_nsx', 'vmware_dvs'] %} --config-file /etc/neutron/plugins/vmware/nsx.ini {% endif %} --config-file /etc/neutron/fwaas_driver.ini", + "command": "neutron-server --config-file /etc/neutron/neutron.conf {% if neutron_plugin_agent in ['openvswitch', 'linuxbridge', 'opendaylight'] %} --config-file /etc/neutron/plugins/ml2/ml2_conf.ini --config-file /etc/neutron/neutron_lbaas.conf --config-file /etc/neutron/neutron_vpnaas.conf {% elif neutron_plugin_agent in ['vmware_nsx', 'vmware_dvs'] %} --config-file /etc/neutron/plugins/vmware/nsx.ini {% endif %} --config-file /etc/neutron/fwaas_driver.ini", "config_files": [ { "source": "{{ container_config_directory }}/neutron.conf", diff --git a/ansible/roles/neutron/templates/neutron.conf.j2 b/ansible/roles/neutron/templates/neutron.conf.j2 index 919c7422c6..d1aa1d8681 100644 --- a/ansible/roles/neutron/templates/neutron.conf.j2 +++ b/ansible/roles/neutron/templates/neutron.conf.j2 @@ -24,7 +24,7 @@ rpc_state_report_workers = {{ openstack_service_rpc_workers }} # in it is because we are sharing this socket in a volume which is it's own dir metadata_proxy_socket = /var/lib/neutron/kolla/metadata_proxy -{% if neutron_plugin_agent == "openvswitch" %} +{% if neutron_plugin_agent == "openvswitch" or neutron_plugin_agent == "opendaylight" %} interface_driver = openvswitch {% elif neutron_plugin_agent == "linuxbridge" %} interface_driver = linuxbridge @@ -145,3 +145,8 @@ hmac_keys = {{ osprofiler_secret }} connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }} {% endif %} {% endif %} + +{% if enable_opendaylight_qos | bool %} +[qos] +notification_drivers = {{ neutron_notification_drivers|map(attribute='name')|join(',') }} +{% endif %} diff --git a/ansible/roles/opendaylight/defaults/main.yml b/ansible/roles/opendaylight/defaults/main.yml new file mode 100644 index 0000000000..f2d35bda47 --- /dev/null +++ b/ansible/roles/opendaylight/defaults/main.yml @@ -0,0 +1,24 @@ +--- +project_name: "opendaylight" + +opendaylight_services: + opendaylight: + container_name: "opendaylight" + image: "{{ opendaylight_image_full }}" + enabled: True + privileged: True + group: "opendaylight" + host_in_groups: "{{ inventory_hostname in groups['opendaylight'] }}" + volumes: + - "{{ node_config_directory }}/opendaylight/:{{ container_config_directory }}/:ro" + - "/etc/localtime:/etc/localtime:ro" + - "kolla_logs:/var/log/kolla/" + +#################### +# Docker +#################### + +opendaylight_install_type: "{{ kolla_install_type }}" +opendaylight_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ opendaylight_install_type }}-opendaylight" +opendaylight_tag: "{{ openstack_release }}" +opendaylight_image_full: "{{ opendaylight_image }}:{{ opendaylight_tag }}" diff --git a/ansible/roles/opendaylight/handlers/main.yml b/ansible/roles/opendaylight/handlers/main.yml new file mode 100644 index 0000000000..0a5f9eec70 --- /dev/null +++ b/ansible/roles/opendaylight/handlers/main.yml @@ -0,0 +1,31 @@ +--- +- name: Restart opendaylight container + vars: + service_name: "opendaylight" + service: "{{ opendaylight_services[service_name] }}" + kolla_docker: + action: "recreate_or_restart_container" + common_options: "{{ docker_common_options }}" + name: "{{ service.container_name }}" + image: "{{ service.image }}" + volumes: "{{ service.volumes }}" + privileged: "{{ service.privileged | default(False) }}" + when: + - action != "config" + - service.enabled | bool + - service.host_in_groups | bool + - opendaylight_config_json | changed + or opendaylight_config_start_odl | changed + or opendaylight_config_custom_props | changed + or opendaylight_config_jetty | changed + or opendaylight_config_features | changed + or opendaylight_config_ovsdb | changed + or opendaylight_config_tomcat | changed + or opendaylight_config_logging | changed + or opendaylight_config_netvirt | changed + or opendaylight_config_netvirt_acl | changed + or opendaylight_config_env | changed + or opendaylight_config_akka | changed + or opendaylight_config_modules | changed + or opendaylight_config_module_shards | changed + or check_opendaylight_containers | changed diff --git a/ansible/roles/opendaylight/meta/main.yml b/ansible/roles/opendaylight/meta/main.yml new file mode 100644 index 0000000000..6b4fff8fef --- /dev/null +++ b/ansible/roles/opendaylight/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - { role: common } diff --git a/ansible/roles/opendaylight/tasks/check.yml b/ansible/roles/opendaylight/tasks/check.yml new file mode 100644 index 0000000000..ed97d539c0 --- /dev/null +++ b/ansible/roles/opendaylight/tasks/check.yml @@ -0,0 +1 @@ +--- diff --git a/ansible/roles/opendaylight/tasks/config.yml b/ansible/roles/opendaylight/tasks/config.yml new file mode 100644 index 0000000000..06e4957337 --- /dev/null +++ b/ansible/roles/opendaylight/tasks/config.yml @@ -0,0 +1,178 @@ +--- +- name: Setting sysctl values + sysctl: name={{ item.name }} value={{ item.value }} sysctl_set=yes + with_items: + - { name: "net.bridge.bridge-nf-call-iptables", value: 1} + - { name: "net.bridge.bridge-nf-call-ip6tables", value: 1} + - { name: "net.ipv4.conf.all.rp_filter", value: 0} + - { name: "net.ipv4.conf.default.rp_filter", value: 0} + when: + - set_sysctl | bool + - inventory_hostname in groups['opendaylight'] + +- name: Ensuring config directories exist + file: + path: "{{ node_config_directory }}/{{ item }}" + state: "directory" + recurse: yes + with_items: + - "opendaylight" + +- name: Copying over config.json files for services + register: opendaylight_config_json + template: + src: "{{ item }}.json.j2" + dest: "{{ node_config_directory }}/{{ item }}/config.json" + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over custom.properties + register: opendaylight_config_custom_props + template: + src: "{{ role_path }}/templates/custom.properties.j2" + dest: "{{ node_config_directory }}/opendaylight/custom.properties" + notify: + - Restart opendaylight container + +- name: Copying over start-odl + register: opendaylight_config_start_odl + template: + src: "{{ role_path }}/templates/start-odl.j2" + dest: "{{ node_config_directory }}/opendaylight/start-odl" + notify: + - Restart opendaylight container + +- name: Copying over jetty.xml + register: opendaylight_config_jetty + template: + src: "{{ role_path }}/templates/jetty.xml.j2" + dest: "{{ node_config_directory }}/{{ item }}/jetty.xml" + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over org.apache.karaf.features.cfg + register: opendaylight_config_features + template: + src: "{{ role_path }}/templates/org.apache.karaf.features.cfg.j2" + dest: "{{ node_config_directory }}/{{ item }}/org.apache.karaf.features.cfg" + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over org.opendaylight.ovsdb.library.cfg + register: opendaylight_config_ovsdb + template: + src: "{{ role_path }}/templates/org.opendaylight.ovsdb.library.cfg.j2" + dest: "{{ node_config_directory }}/{{ item }}/org.opendaylight.ovsdb.library.cfg" + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over tomcat-server.xml + template: + src: "{{ role_path }}/templates/tomcat-server.xml.j2" + dest: "{{ node_config_directory }}/{{ item }}/tomcat-server.xml" + register: opendaylight_config_tomcat + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over org.ops4j.pax.logging.cfg.j2 + template: + src: "{{ role_path }}/templates/org.ops4j.pax.logging.cfg.j2" + dest: "{{ node_config_directory }}/{{ item }}/org.ops4j.pax.logging.cfg" + register: opendaylight_config_logging + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over netvirt-impl-config_netvirt-impl-config.xml + template: + src: "{{ role_path }}/templates/netvirt-impl-config_netvirt-impl-config.xml.j2" + dest: "{{ node_config_directory }}/{{ item }}/netvirt-impl-config_netvirt-impl-config.xml" + register: opendaylight_config_netvirt + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over netvirt-aclservice-config.xml + template: + src: "{{ role_path }}/templates/netvirt-aclservice-config.xml.j2" + dest: "{{ node_config_directory }}/{{ item }}/netvirt-aclservice-config.xml" + register: opendaylight_config_netvirt_acl + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over setenv + template: + src: "{{ role_path }}/templates/setenv.j2" + dest: "{{ node_config_directory }}/{{ item }}/setenv" + register: opendaylight_config_env + with_items: + - "opendaylight" + notify: + - Restart opendaylight container + +- name: Copying over akka.conf + template: + src: "{{ role_path }}/templates/akka.conf.j2" + dest: "{{ node_config_directory }}/opendaylight/akka.conf" + with_first_found: + - "{{ node_custom_config }}/opendaylight/{{ inventory_hostname }}/akka.conf" + - "{{ node_custom_config }}/opendaylight/akka.conf" + - "akka.conf.j2" + register: opendaylight_config_akka + notify: + - Restart opendaylight container + +- name: Copying over modules.conf + template: + src: "{{ role_path }}/templates/modules.conf.j2" + dest: "{{ node_config_directory }}/opendaylight/modules.conf" + with_first_found: + - "{{ node_custom_config }}/opendaylight/{{ inventory_hostname }}/modules.conf" + - "{{ node_custom_config }}/opendaylight/modules.conf" + - "modules.conf.j2" + register: opendaylight_config_modules + notify: + - Restart opendaylight container + +- name: Copying over module-shards.conf + template: + src: "{{ role_path }}/templates/module-shards.conf.j2" + dest: "{{ node_config_directory }}/opendaylight/module-shards.conf" + with_first_found: + - "{{ node_custom_config }}/opendaylight/{{ inventory_hostname }}/module-shards.conf" + - "{{ node_custom_config }}/opendaylight/module-shards.conf" + - "module-shards.conf.j2" + register: opendaylight_config_module_shards + notify: + - Restart opendaylight container + +- name: Check opendaylight containers + kolla_docker: + action: "compare_container" + common_options: "{{ docker_common_options }}" + name: "{{ item.value.container_name }}" + image: "{{ item.value.image }}" + privileged: "{{ item.value.privileged | default(False) }}" + volumes: "{{ item.value.volumes }}" + register: check_opendaylight_containers + when: + - action != "config" + - item.value.enabled | bool + - item.value.host_in_groups | bool + with_dict: "{{ opendaylight_services }}" + notify: + - "Restart {{ item.key }} container" diff --git a/ansible/roles/opendaylight/tasks/deploy.yml b/ansible/roles/opendaylight/tasks/deploy.yml new file mode 100644 index 0000000000..5aac9f5a7f --- /dev/null +++ b/ansible/roles/opendaylight/tasks/deploy.yml @@ -0,0 +1,5 @@ +--- +- include: config.yml + +- name: Flush Handlers + meta: flush_handlers diff --git a/ansible/roles/opendaylight/tasks/main.yml b/ansible/roles/opendaylight/tasks/main.yml new file mode 100644 index 0000000000..b017e8b4ad --- /dev/null +++ b/ansible/roles/opendaylight/tasks/main.yml @@ -0,0 +1,2 @@ +--- +- include: "{{ action }}.yml" diff --git a/ansible/roles/opendaylight/tasks/precheck.yml b/ansible/roles/opendaylight/tasks/precheck.yml new file mode 100644 index 0000000000..260e774f4e --- /dev/null +++ b/ansible/roles/opendaylight/tasks/precheck.yml @@ -0,0 +1,111 @@ +--- +- name: Get container facts + kolla_container_facts: + name: + - opendaylight + register: container_facts + +- name: Checking free port for opendaylight_clustering + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_clustering_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_restconf + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_restconf_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_restconf_backup + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_restconf_port_backup }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_karaf_ssh + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_karaf_ssh_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_openflow + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_openflow_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_ovsdb + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_ovsdb_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_jetty_conf_port + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_jetty_conf_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_jetty_conf2_port + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_jetty_conf2_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_tomcat_port + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_tomcat_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking free port for opendaylight_tomcat_redirect_port + wait_for: + host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" + port: "{{ opendaylight_tomcat_redirect_port }}" + connect_timeout: 1 + state: stopped + when: + - inventory_hostname in groups['opendaylight'] + - container_facts['opendaylight'] is not defined + +- name: Checking available opendaylight nodes in inventory + fail: + msg: "Either 1 or 3 nodes required in inventory for OpenDaylight clustering" + when: groups['opendaylight'] | length == 2 diff --git a/ansible/roles/opendaylight/tasks/pull.yml b/ansible/roles/opendaylight/tasks/pull.yml new file mode 100644 index 0000000000..76a1bd6b6a --- /dev/null +++ b/ansible/roles/opendaylight/tasks/pull.yml @@ -0,0 +1,10 @@ +--- +- name: Pulling opendaylight image + kolla_docker: + action: "pull_image" + common_options: "{{ docker_common_options }}" + image: "{{ item.value.image }}" + when: + - item.value.enabled | bool + - item.value.host_in_groups | bool + with_dict: "{{ opendaylight_services }}" diff --git a/ansible/roles/opendaylight/tasks/reconfigure.yml b/ansible/roles/opendaylight/tasks/reconfigure.yml new file mode 100644 index 0000000000..e078ef1318 --- /dev/null +++ b/ansible/roles/opendaylight/tasks/reconfigure.yml @@ -0,0 +1,2 @@ +--- +- include: deploy.yml diff --git a/ansible/roles/opendaylight/tasks/upgrade.yml b/ansible/roles/opendaylight/tasks/upgrade.yml new file mode 100644 index 0000000000..5aac9f5a7f --- /dev/null +++ b/ansible/roles/opendaylight/tasks/upgrade.yml @@ -0,0 +1,5 @@ +--- +- include: config.yml + +- name: Flush Handlers + meta: flush_handlers diff --git a/ansible/roles/opendaylight/templates/akka.conf.j2 b/ansible/roles/opendaylight/templates/akka.conf.j2 new file mode 100644 index 0000000000..22d63e566f --- /dev/null +++ b/ansible/roles/opendaylight/templates/akka.conf.j2 @@ -0,0 +1,33 @@ + +odl-cluster-data { + akka { + remote { + artery { + enabled = off + canonical.hostname = "{{ hostvars[inventory_hostname]['ansible_' + hostvars[inventory_hostname]['api_interface']]['ipv4']['address'] }}" + canonical.port = {{ opendaylight_clustering_port }} + } + netty.tcp { + hostname = "{{ hostvars[inventory_hostname]['ansible_' + hostvars[inventory_hostname]['api_interface']]['ipv4']['address'] }}" + port = {{ opendaylight_clustering_port }} + } + } + + cluster { + seed-nodes = [{% for host in groups['opendaylight'] %}"akka.tcp://opendaylight-cluster-data@{{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_clustering_port }}"{% if not loop.last %},{% endif %}{% endfor %}] + + roles = [ + "{{ hostvars[inventory_hostname]['ansible_hostname'] }}" + ] + + } + + persistence { + + journal { + leveldb { + } + } + } + } +} diff --git a/ansible/roles/opendaylight/templates/custom.properties.j2 b/ansible/roles/opendaylight/templates/custom.properties.j2 new file mode 100644 index 0000000000..5f8c90cfea --- /dev/null +++ b/ansible/roles/opendaylight/templates/custom.properties.j2 @@ -0,0 +1,47 @@ +org.osgi.framework.system.packages.extra=org.apache.karaf.branding,sun.reflect,sun.reflect.misc,sun.misc,sun.nio.ch,com.sun.media.sound + +osgi.hook.configurators.include=org.eclipse.virgo.kernel.equinox.extensions.hooks.ExtensionsHookConfigurator + + +org.eclipse.gemini.web.tomcat.config.path=configuration/tomcat-server.xml +org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true + +karaf.framework=equinox + +karaf.delay.console=true + +org.apache.karaf.security.providers = org.bouncycastle.jce.provider.BouncyCastleProvider + +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.configurationFile=configuration/logback.xml + +container.profile = Container + +connection.scheme = ANY_CONTROLLER_ONE_MASTER + +ovsdb.l3.arp.responder.disabled=no + +secureChannelEnabled=false +controllerKeyStore= +controllerKeyStorePassword= +controllerTrustStore= +controllerTrustStorePassword= + +enableStrongPasswordCheck = false + +java.util.logging.config.file=configuration/tomcat-logging.properties + +hosttracker.keyscheme=IP + +lisp.mappingMerge = false + +lisp.smr = true + +lisp.elpPolicy = default diff --git a/ansible/roles/opendaylight/templates/jetty.xml.j2 b/ansible/roles/opendaylight/templates/jetty.xml.j2 new file mode 100644 index 0000000000..4e4cf897ca --- /dev/null +++ b/ansible/roles/opendaylight/templates/jetty.xml.j2 @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + 300000 + 2 + false + {{ opendaylight_jetty_conf_port }} + 20000 + 5000 + + + + + + + + + + + + + 300000 + 2 + false + {{ opendaylight_jetty_conf2_port }} + 20000 + 5000 + + + + + + + + karaf + karaf + + + org.apache.karaf.jaas.boot.principal.RolePrincipal + + + + + + + + + + default + karaf + + + org.apache.karaf.jaas.boot.principal.RolePrincipal + + + + + + + + diff --git a/ansible/roles/opendaylight/templates/module-shards.conf.j2 b/ansible/roles/opendaylight/templates/module-shards.conf.j2 new file mode 100644 index 0000000000..4fe1f999ff --- /dev/null +++ b/ansible/roles/opendaylight/templates/module-shards.conf.j2 @@ -0,0 +1,59 @@ +module-shards = [ + { + name = "default" + shards = [ + { + name="default" + replicas = [ + {% for host in groups['opendaylight'] %} + "{{ hostvars[host]['ansible_hostname'] }}"{% if not loop.last %}, + {% endif %} + {% endfor %} + ] + } + ] + }, + { + name = "topology" + shards = [ + { + name="topology" + replicas = [ + {% for host in groups['opendaylight'] %} + "{{ hostvars[host]['ansible_hostname'] }}"{% if not loop.last %}, + {% endif %} + {% endfor %} + ] + } + ] + }, + { + name = "inventory" + shards = [ + { + name="inventory" + replicas = [ + {% for host in groups['opendaylight'] %} + "{{ hostvars[host]['ansible_hostname'] }}"{% if not loop.last %}, + {% endif %} + {% endfor %} + ] + } + ] + }, + { + name = "toaster" + shards = [ + { + name="toaster" + replicas = [ + {% for host in groups['opendaylight'] %} + "{{ hostvars[host]['ansible_hostname'] }}"{% if not loop.last %}, + {% endif %} + {% endfor %} + ] + } + ] + } + +] diff --git a/ansible/roles/opendaylight/templates/modules.conf.j2 b/ansible/roles/opendaylight/templates/modules.conf.j2 new file mode 100644 index 0000000000..5b0711ea50 --- /dev/null +++ b/ansible/roles/opendaylight/templates/modules.conf.j2 @@ -0,0 +1,20 @@ +modules = [ + { + name = "inventory" + namespace = "urn:opendaylight:inventory" + shard-strategy = "module" + }, + + { + name = "topology" + namespace = "urn:TBD:params:xml:ns:yang:network-topology" + shard-strategy = "module" + }, + + { + name = "toaster" + namespace = "http://netconfcentral.org/ns/toaster" + shard-strategy = "module" + } + +] diff --git a/ansible/roles/opendaylight/templates/netvirt-aclservice-config.xml.j2 b/ansible/roles/opendaylight/templates/netvirt-aclservice-config.xml.j2 new file mode 100644 index 0000000000..398719570b --- /dev/null +++ b/ansible/roles/opendaylight/templates/netvirt-aclservice-config.xml.j2 @@ -0,0 +1,4 @@ + + {{ opendaylight_acl_impl }} + deny + diff --git a/ansible/roles/opendaylight/templates/netvirt-impl-config_netvirt-impl-config.xml.j2 b/ansible/roles/opendaylight/templates/netvirt-impl-config_netvirt-impl-config.xml.j2 new file mode 100644 index 0000000000..9e22e427a3 --- /dev/null +++ b/ansible/roles/opendaylight/templates/netvirt-impl-config_netvirt-impl-config.xml.j2 @@ -0,0 +1,7 @@ +{% if enable_opendaylight_legacy_netvirt_conntrack | bool %} + + + true + + +{% endif %} diff --git a/ansible/roles/opendaylight/templates/opendaylight.json.j2 b/ansible/roles/opendaylight/templates/opendaylight.json.j2 new file mode 100644 index 0000000000..e475b9cb15 --- /dev/null +++ b/ansible/roles/opendaylight/templates/opendaylight.json.j2 @@ -0,0 +1,90 @@ +{ + "command": "start-odl", + "config_files": [ + { + "source": "{{ container_config_directory }}/start-odl", + "dest": "/usr/local/bin/start-odl", + "owner": "odl", + "perm": "0655" + }, + { + "source": "{{ container_config_directory }}/org.apache.karaf.features.cfg", + "dest": "/opt/opendaylight/etc/org.apache.karaf.features.cfg", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/org.opendaylight.ovsdb.library.cfg", + "dest": "/opt/opendaylight/etc/org.opendaylight.ovsdb.library.cfg", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/tomcat-server.xml", + "dest": "/opt/opendaylight/configuration/tomcat-server.xml", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/jetty.xml", + "dest": "/opt/opendaylight/etc/jetty.xml", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/org.ops4j.pax.logging.cfg", + "dest": "/opt/opendaylight/etc/org.ops4j.pax.logging.cfg", + "owner": "odl", + "perm": "0600" + }, + { + "source": "/var/lib/kolla/config_files/custom.properties", + "dest": "/opt/opendaylight/etc/custom.properties", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/netvirt-impl-config_netvirt-impl-config.xml", + "dest": "/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-impl-config_netvirt-impl-config.xml", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/netvirt-aclservice-config.xml", + "dest": "/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-aclservice-config.xml", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/setenv", + "dest": "/opt/opendaylight/bin/setenv", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/akka.conf", + "dest": "/opt/opendaylight/configuration/initial/akka.conf", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/modules.conf", + "dest": "/opt/opendaylight/configuration/initial/modules.conf", + "owner": "odl", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/module-shards.conf", + "dest": "/opt/opendaylight/configuration/initial/module-shards.conf", + "owner": "odl", + "perm": "0600" + } + ], + "permissions": [ + { + "path": "/var/log/kolla/opendaylight", + "owner": "odl:odl", + "recurse": true + } + ] +} diff --git a/ansible/roles/opendaylight/templates/org.apache.karaf.features.cfg.j2 b/ansible/roles/opendaylight/templates/org.apache.karaf.features.cfg.j2 new file mode 100644 index 0000000000..ba2dfcd513 --- /dev/null +++ b/ansible/roles/opendaylight/templates/org.apache.karaf.features.cfg.j2 @@ -0,0 +1,24 @@ +################################################################################ +# +# 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. +# +################################################################################ + +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/{{ opendaylight_release }}/xml/features + +featuresBoot=config,standard,region,package,kar,ssh,management{% if not opendaylight_features == '' %},{% endif %}{{ opendaylight_features }} + +featuresBootAsynchronous=false diff --git a/ansible/roles/opendaylight/templates/org.opendaylight.ovsdb.library.cfg.j2 b/ansible/roles/opendaylight/templates/org.opendaylight.ovsdb.library.cfg.j2 new file mode 100644 index 0000000000..d5cae1b52f --- /dev/null +++ b/ansible/roles/opendaylight/templates/org.opendaylight.ovsdb.library.cfg.j2 @@ -0,0 +1,7 @@ +ovsdb-listener-port = {{ opendaylight_ovsdb_port }} + +use-ssl = false + +json-rpc-decoder-max-frame-length = 100000 + +ovsdb-rpc-task-timeout = 1000 diff --git a/ansible/roles/opendaylight/templates/org.ops4j.pax.logging.cfg.j2 b/ansible/roles/opendaylight/templates/org.ops4j.pax.logging.cfg.j2 new file mode 100644 index 0000000000..d2aa291f4b --- /dev/null +++ b/ansible/roles/opendaylight/templates/org.ops4j.pax.logging.cfg.j2 @@ -0,0 +1,52 @@ +################################################################################ +# +# 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. +# +################################################################################ + +log4j.rootLogger=INFO, async, osgi:* +log4j.throwableRenderer=org.apache.log4j.OsgiThrowableRenderer + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n + +log4j.appender.async=org.apache.log4j.AsyncAppender +log4j.appender.async.appenders=out + +log4j.appender.out=org.apache.log4j.RollingFileAppender +log4j.appender.out.layout=org.apache.log4j.PatternLayout +log4j.appender.out.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n +log4j.appender.out.file=/var/log/kolla/opendaylight/karaf.log +log4j.appender.out.append=true +log4j.appender.out.maxFileSize=1MB +log4j.appender.out.maxBackupIndex=10 + +log4j.appender.sift=org.apache.log4j.sift.MDCSiftingAppender +log4j.appender.sift.key=bundle.name +log4j.appender.sift.default=karaf +log4j.appender.sift.appender=org.apache.log4j.FileAppender +log4j.appender.sift.appender.layout=org.apache.log4j.PatternLayout +log4j.appender.sift.appender.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %m%n +log4j.appender.sift.appender.file=/var/log/kolla/opendaylight/$\\{bundle.name\\}.log +log4j.appender.sift.appender.append=true + +log4j.appender.syslog=org.apache.log4j.net.SyslogAppender +log4j.appender.syslog.layout=org.apache.log4j.PatternLayout +log4j.appender.syslog.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n +log4j.appender.syslog.syslogHost=127.0.0.1 +log4J.appender.syslog.facility=KARAF +log4j.appender.syslog.facilityPrinting=false diff --git a/ansible/roles/opendaylight/templates/org.ops4j.pax.url.mvn.cfg.j2 b/ansible/roles/opendaylight/templates/org.ops4j.pax.url.mvn.cfg.j2 new file mode 100644 index 0000000000..37e9e24206 --- /dev/null +++ b/ansible/roles/opendaylight/templates/org.ops4j.pax.url.mvn.cfg.j2 @@ -0,0 +1,34 @@ +################################################################################ +# +# 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. +# +################################################################################ + +org.ops4j.pax.url.mvn.settings=/var/lib/odl/.m2/settings.xml + +org.ops4j.pax.url.mvn.localRepository=${karaf.home}/${karaf.default.repository} + +org.ops4j.pax.url.mvn.useFallbackRepositories=false + +org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=false + +org.ops4j.pax.url.mvn.repositories= \ +file:${karaf.home}/${karaf.default.repository}@id=system.repository, \ +file:${karaf.data}/kar@id=kar.repository@multi, \ +http://repo1.maven.org/maven2@id=central, \ +http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, \ +http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external, \ +http://zodiac.springsource.com/maven/bundles/release@id=gemini diff --git a/ansible/roles/opendaylight/templates/setenv.j2 b/ansible/roles/opendaylight/templates/setenv.j2 new file mode 100644 index 0000000000..7376186e18 --- /dev/null +++ b/ansible/roles/opendaylight/templates/setenv.j2 @@ -0,0 +1,24 @@ +#!/bin/sh +# +# 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. +# + +if [ "x$JAVA_MAX_PERM_MEM" = "x" ]; then + export JAVA_MAX_PERM_MEM="512m" +fi +if [ "x$JAVA_MAX_MEM" = "x" ]; then + export JAVA_MAX_MEM="8g" +fi diff --git a/ansible/roles/opendaylight/templates/start-odl.j2 b/ansible/roles/opendaylight/templates/start-odl.j2 new file mode 100644 index 0000000000..e039b1c655 --- /dev/null +++ b/ansible/roles/opendaylight/templates/start-odl.j2 @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +java -jar /opt/opendaylight/bin/aaa-cli-jar.jar --dbd /opt/opendaylight/ --nu admin -p {{ opendaylight_password }} +/opt/opendaylight/bin/karaf diff --git a/ansible/roles/opendaylight/templates/tomcat-server.xml.j2 b/ansible/roles/opendaylight/templates/tomcat-server.xml.j2 new file mode 100644 index 0000000000..1d199d591e --- /dev/null +++ b/ansible/roles/opendaylight/templates/tomcat-server.xml.j2 @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ansible/roles/openvswitch/handlers/main.yml b/ansible/roles/openvswitch/handlers/main.yml index 155536d836..d631076ea1 100644 --- a/ansible/roles/openvswitch/handlers/main.yml +++ b/ansible/roles/openvswitch/handlers/main.yml @@ -17,6 +17,8 @@ - service.host_in_groups | bool - config_json | changed or openvswitch_db_container | changed + or openvswitch_start_ovsdb_server | changed + notify: - Waiting for openvswitch_db service to be ready - Ensuring OVS bridge is properly setup @@ -60,3 +62,4 @@ - service.host_in_groups | bool - config_json | changed or openvswitch_vswitchd_container | changed + or openvswitch_start_ovs | changed diff --git a/ansible/roles/openvswitch/tasks/config.yml b/ansible/roles/openvswitch/tasks/config.yml index 0a24c63f4f..fb5dff2381 100644 --- a/ansible/roles/openvswitch/tasks/config.yml +++ b/ansible/roles/openvswitch/tasks/config.yml @@ -21,6 +21,32 @@ notify: - "Restart {{ item.key }} container" +- name: Copying over start-ovs file for openvswitch-vswitchd + vars: + service: "{{ openvswitch_services['openvswitch-vswitchd'] }}" + template: + src: "{{ role_path }}/templates/start-ovs.j2" + dest: "{{ node_config_directory }}/openvswitch-vswitchd/start-ovs" + register: openvswitch_start_ovs + when: + - inventory_hostname in groups[service.group] + - service.enabled | bool + notify: + - "Restart openvswitch-vswitchd container" + +- name: Copying over start-ovsdb-server files for openvswitch-db-server + vars: + service: "{{ openvswitch_services['openvswitch-db-server'] }}" + template: + src: "{{ role_path }}/templates/start-ovsdb-server.j2" + dest: "{{ node_config_directory }}/openvswitch-db-server/start-ovsdb-server" + register: openvswitch_start_ovsdb_server + when: + - inventory_hostname in groups[service.group] + - service.enabled | bool + notify: + - "Restart openvswitch-db-server container" + - name: Check openvswitch containers kolla_docker: action: "compare_container" diff --git a/ansible/roles/openvswitch/templates/openvswitch-db-server.json.j2 b/ansible/roles/openvswitch/templates/openvswitch-db-server.json.j2 index fdeea72ecb..955131cf81 100644 --- a/ansible/roles/openvswitch/templates/openvswitch-db-server.json.j2 +++ b/ansible/roles/openvswitch/templates/openvswitch-db-server.json.j2 @@ -1,4 +1,11 @@ { "command": "start-ovsdb-server {{ api_interface_address }}", - "config_files": [] + "config_files": [ + { + "source": "{{ container_config_directory }}/start-ovsdb-server", + "dest": "/usr/local/bin/start-ovsdb-server", + "owner": "root", + "perm": "0655" + } + ] } diff --git a/ansible/roles/openvswitch/templates/openvswitch-vswitchd.json.j2 b/ansible/roles/openvswitch/templates/openvswitch-vswitchd.json.j2 index 97308d886b..0c75c355f6 100644 --- a/ansible/roles/openvswitch/templates/openvswitch-vswitchd.json.j2 +++ b/ansible/roles/openvswitch/templates/openvswitch-vswitchd.json.j2 @@ -1,4 +1,11 @@ { - "command": "/usr/sbin/ovs-vswitchd unix:/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --log-file=/var/log/kolla/openvswitch/ovs-vswitchd.log", - "config_files": [] + "command": "start-ovs", + "config_files": [ + { + "source": "{{ container_config_directory }}/start-ovs", + "dest": "/usr/local/bin/start-ovs", + "owner": "root", + "perm": "0655" + } + ] } diff --git a/ansible/roles/openvswitch/templates/start-ovs.j2 b/ansible/roles/openvswitch/templates/start-ovs.j2 new file mode 100644 index 0000000000..d6dd723b68 --- /dev/null +++ b/ansible/roles/openvswitch/templates/start-ovs.j2 @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +{% if enable_opendaylight | bool %} +/usr/bin/ovs-vsctl --no-wait -- set-manager ptcp:{{ ovsdb_port }}:{{ hostvars[inventory_hostname]['ansible_' + hostvars[inventory_hostname]['api_interface']]['ipv4']['address'] }} tcp:{{ kolla_internal_vip_address }}:{{ opendaylight_haproxy_ovsdb_port }} +/usr/bin/ovs-vsctl --no-wait -- set Open_vSwitch . other_config:local_ip={{ hostvars[inventory_hostname]['ansible_' + hostvars[inventory_hostname]['tunnel_interface']]['ipv4']['address'] }} +/usr/bin/ovs-vsctl --no-wait -- set Open_vSwitch . other_config:provider_mappings=physnet1:{{ neutron_bridge_name }} +/usr/bin/ovs-vsctl --no-wait -- set Open_vSwitch . external_ids:system-id=`cat /proc/sys/kernel/random/uuid` +/usr/bin/ovs-vsctl --no-wait -- set Open_vSwitch . external_ids:odl_os_hostconfig_config_odl_l2='{"supported_vnic_types": [{"vnic_type": "normal", "vif_type": "ovs", "vif_details": {} }], "allowed_network_types": [{{ opendaylight_allowed_network_types }}], "datapath_types": ["netdev", "system"], "bridge_mappings": {"physnet1":"{{ neutron_bridge_name }}"} }' +/usr/bin/ovs-vsctl --no-wait -- set Open_vSwitch . external_ids:odl_os_hostconfig_hostid="{{ hostvars[inventory_hostname]['ansible_hostname'] }}" +{% endif %} +/usr/sbin/ovs-vswitchd unix:/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --log-file=/var/log/kolla/openvswitch/ovs-vswitchd.log diff --git a/ansible/roles/openvswitch/templates/start-ovsdb-server.j2 b/ansible/roles/openvswitch/templates/start-ovsdb-server.j2 new file mode 100644 index 0000000000..803e85660e --- /dev/null +++ b/ansible/roles/openvswitch/templates/start-ovsdb-server.j2 @@ -0,0 +1,33 @@ +#!/bin/bash + +# NOTE: (sbezverk) ovs_bridge and ovs_ext_intf variables get initialized only when +# this script is executed for kubernetes deployment. With Ansible deployment, only +# ovsdb-server gets launched and then the following workflow step will create +# an external bridge and plug an external interface. With Kubernetes we want to +# leverage its dynamic nature of automatic scaling up and down. It means all +# activities related to creating initial bridge, plugging external interface +# must be done by DaemonSet launched container. + +ovsdb_ip=$1 +ovs_bridge=$2 +ovs_ext_intf=$3 + +printf "Argument p_out is %s\n" "$p_out" +printf "Argument arg_1 is %s\n" "$arg_1" + +# NOTE: (sbezverk) The reason for introducing this script is to be able +# to launch ovsdb-server and to create the initial external bridge in one step. +# It is required in order to be able to use DaemonSet. + +if [ ! -e $ovs_bridge ] && [ ! -e $ovs_ext_intf ]; then +# NOTE: (sbezverk) This part is executed only by kubernetes deployment. +# Creating external bridge + /usr/sbin/ovsdb-server /var/lib/openvswitch/conf.db --remote=punix:/var/run/openvswitch/db.sock --run="ovs-vsctl --no-wait --db=unix:/var/run/openvswitch/db.sock add-br $ovs_bridge" +# Plug the external interface into the external bridge. + /usr/sbin/ovsdb-server /var/lib/openvswitch/conf.db --remote=punix:/var/run/openvswitch/db.sock --run="ovs-vsctl --no-wait --db=unix:/var/run/openvswitch/db.sock add-port $ovs_bridge $ovs_ext_intf" +# Run ovsdb server process + /usr/sbin/ovsdb-server /var/lib/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/var/run/openvswitch/db.sock --remote=ptcp:6640 --log-file=/var/log/kolla/openvswitch/ovsdb-server.log +else +# NOTE: (sbezverk) This part is executed only by kolla-ansible deployment. + /usr/sbin/ovsdb-server /var/lib/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/run/openvswitch/db.sock --remote=ptcp:{{ ovsdb_port }}:$ovsdb_ip --remote=db:Open_vSwitch,Open_vSwitch,manager_options --log-file=/var/log/kolla/openvswitch/ovsdb-server.log +fi diff --git a/ansible/site.yml b/ansible/site.yml index 0ed2edc28c..50cbce1fa0 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -308,6 +308,14 @@ tags: nova, when: enable_nova | bool } +- name: Apply role opendaylight + gather_facts: false + hosts: opendaylight + roles: + - { role: opendaylight, + tags: opendaylight, + when: enable_opendaylight | bool } + - name: Apply role openvswitch hosts: - openvswitch diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml index 5227f9da79..f0a4b65963 100644 --- a/etc/kolla/globals.yml +++ b/etc/kolla/globals.yml @@ -86,7 +86,7 @@ kolla_internal_vip_address: "10.10.10.254" # addresses for that reason. #neutron_external_interface: "eth1" -# Valid options are [ openvswitch, linuxbridge, vmware_nsxv, vmware_dvs ] +# Valid options are [ openvswitch, linuxbridge, vmware_nsxv, vmware_dvs, opendaylight ] #neutron_plugin_agent: "openvswitch" @@ -107,6 +107,12 @@ kolla_internal_vip_address: "10.10.10.254" #kolla_external_fqdn_cert: "{{ node_config_directory }}/certificates/haproxy.pem" +############################### +# OpenDaylight +############################### +#enable_opendaylight_qos: "no" +#enable_opendaylight_l3: "yes" + #################### # OpenStack options #################### @@ -184,6 +190,7 @@ kolla_internal_vip_address: "10.10.10.254" #enable_neutron_sfc: "no" #enable_nova_serialconsole_proxy: "no" #enable_octavia: "no" +#enable_opendaylight: "no" #enable_openvswitch: "{{ neutron_plugin_agent != 'linuxbridge' }}" #enable_osprofiler: "no" #enable_panko: "no" diff --git a/etc/kolla/passwords.yml b/etc/kolla/passwords.yml index 822c32e642..b126c5a131 100644 --- a/etc/kolla/passwords.yml +++ b/etc/kolla/passwords.yml @@ -22,6 +22,11 @@ database_password: # This should only be set if you require a password for your Docker registry docker_registry_password: +###################### +# OpenDaylight options +###################### +opendaylight_password: + #################### # OpenStack options #################### diff --git a/releasenotes/notes/opendaylight-role-b1787bc458da5bc4.yaml b/releasenotes/notes/opendaylight-role-b1787bc458da5bc4.yaml new file mode 100644 index 0000000000..b7c0ae0f89 --- /dev/null +++ b/releasenotes/notes/opendaylight-role-b1787bc458da5bc4.yaml @@ -0,0 +1,3 @@ +--- +features: + - Add OpenDaylight role \ No newline at end of file