From 187401f1be6b4a85c032d66d3d436683fbd2514c Mon Sep 17 00:00:00 2001 From: Dan Radez <dradez@redhat.com> Date: Sun, 13 Dec 2015 21:20:40 -0500 Subject: [PATCH] Adds OpenDaylight support To enable OpenDaylight on controllers use environments/opendaylight.yaml To enable OpenDaylight on external node use environments/opendaylight-external.yaml --- environments/opendaylight-external.yaml | 21 +++ environments/opendaylight.yaml | 18 ++ overcloud-resource-registry-puppet.yaml | 3 + overcloud-without-mergepy.yaml | 62 ++++++ puppet/all-nodes-config.yaml | 6 + puppet/compute.yaml | 19 ++ puppet/controller.yaml | 27 +++ puppet/manifests/overcloud_compute.pp | 27 ++- puppet/manifests/overcloud_controller.pp | 47 ++++- puppet/manifests/overcloud_controller_pacemaker.pp | 184 +++++++++++------- puppet/manifests/overcloud_opendaylight.pp | 26 +++ puppet/opendaylight-puppet.yaml | 209 +++++++++++++++++++++ 12 files changed, 569 insertions(+), 80 deletions(-) create mode 100644 environments/opendaylight-external.yaml create mode 100644 environments/opendaylight.yaml create mode 100644 puppet/manifests/overcloud_opendaylight.pp create mode 100644 puppet/opendaylight-puppet.yaml diff --git a/environments/opendaylight-external.yaml b/environments/opendaylight-external.yaml new file mode 100644 index 0000000..bbc78db --- /dev/null +++ b/environments/opendaylight-external.yaml @@ -0,0 +1,21 @@ +# Environment file used to enable OpenDaylight +# Currently uses overcloud image that is assumed +# to be virt-customized with ODL RPM already on it + +# These parameters customize the OpenDaylight Node +# The user name and password are for the ODL service +# Defaults are included here for reference +#parameter_defaults: +# OpenDaylightFlavor: baremetal +# OpenDaylightHostname: opendaylight-server +# OpenDaylightImage: overcloud-full +# OpenDaylightUsername: admin +# OpenDaylightPassword: admin + +parameters: + # increase this if you need more ODL nodes + # OpenDaylightCount: 1 + NeutronL3HA: false + ExtraConfig: + neutron_mechanism_drivers: ['opendaylight'] + neutron_tenant_network_type: vxlan diff --git a/environments/opendaylight.yaml b/environments/opendaylight.yaml new file mode 100644 index 0000000..b9ffeb9 --- /dev/null +++ b/environments/opendaylight.yaml @@ -0,0 +1,18 @@ +# Environment file used to enable OpenDaylight +# Currently uses overcloud image that is assumed +# to be virt-customized with ODL RPM already on it + +# These parameters customize the OpenDaylight Service +# Defaults are included here for reference +#parameter_defaults: +# OpenDaylightUsername: admin +# OpenDaylightPassword: admin + +parameters: + # instructs there not to be any ODL only nodes + OpenDaylightCount: 0 + NeutronL3HA: false + ExtraConfig: + neutron_mechanism_drivers: ['opendaylight'] + neutron_tenant_network_type: vxlan + opendaylight_install: true diff --git a/overcloud-resource-registry-puppet.yaml b/overcloud-resource-registry-puppet.yaml index 4cfed6b..adecc79 100644 --- a/overcloud-resource-registry-puppet.yaml +++ b/overcloud-resource-registry-puppet.yaml @@ -27,6 +27,9 @@ resource_registry: # To disable, replace with firstboot/userdata_default.yaml OS::TripleO::NodeAdminUserData: firstboot/userdata_heat_admin.yaml + # This configures OpenDaylight to drive the network + OS::TripleO::OpenDaylightNode: puppet/opendaylight-puppet.yaml + # Hooks for operator extra config # NodeUserData == Cloud-init additional user-data, e.g cloud-config # ControllerExtraConfigPre == Controller configuration pre service deployment diff --git a/overcloud-without-mergepy.yaml b/overcloud-without-mergepy.yaml index a532c2f..733eb7f 100644 --- a/overcloud-without-mergepy.yaml +++ b/overcloud-without-mergepy.yaml @@ -227,6 +227,23 @@ parameters: default: false description: Should MongoDb journaling be disabled type: boolean + OpenDaylightPort: + default: 8081 + description: Set opendaylight service port + type: number + OpenDaylightInstall: + default: false + description: Whether to install OpenDaylight on the control nodes. + type: boolean + OpenDaylightUsername: + default: 'admin' + description: The username for the opendaylight server. + type: string + OpenDaylightPassword: + default: 'admin' + type: string + description: The password for the opendaylight server. + hidden: true PublicVirtualFixedIPs: default: [] description: > @@ -664,6 +681,18 @@ parameters: structure as ExtraConfig. type: json +# OpenDaylight specific parameters + OpenDaylightCount: + type: number + default: 1 + OpenDaylightImage: + default: overcloud-full + type: string + OpenDaylightFlavor: + default: baremetal + description: Flavor for OpenDaylight node + type: string + # Hostname format for each role # Note %index% is translated into the index of the node, e.g 0/1/2 etc # and %stackname% is replaced with OS::stack_name in the template below. @@ -688,6 +717,10 @@ parameters: type: string description: Format for CephStorage node hostnames default: '%stackname%-cephstorage-%index%' + OpenDaylightHostnameFormat: + type: string + description: Format for OpenDaylight node hostnames + default: '%stackname%-opendaylight-%index%' # Identifiers to trigger tasks on nodes UpdateIdentifier: @@ -770,6 +803,27 @@ resources: SwiftProxyVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, SwiftProxyNetwork]}]} PublicVirtualIP: {get_attr: [VipMap, net_ip_map, external]} + OpenDaylightNode: + type: OS::Heat::ResourceGroup + depends_on: Networks + properties: + count: {get_param: OpenDaylightCount} + removal_policies: {get_param: ComputeRemovalPolicies} + resource_def: + type: OS::TripleO::OpenDaylightNode + properties: + UpdateIdentifier: {get_param: UpdateIdentifier} + OpenDaylightFlavor: {get_param: OpenDaylightFlavor} + OpenDaylightImage: {get_param: OpenDaylightImage} + OpenDaylightPort: {get_param: OpenDaylightPort} + OpenDaylightUsername: {get_param: OpenDaylightUsername} + OpenDaylightPassword: {get_param: OpenDaylightPassword} + OpenDaylightHostname: + str_replace: + template: {get_param: OpenDaylightHostnameFormat} + params: + '%stackname%': {get_param: 'OS::stack_name'} + Controller: type: OS::Heat::ResourceGroup depends_on: Networks @@ -853,6 +907,10 @@ resources: NovaPassword: {get_param: NovaPassword} NtpServer: {get_param: NtpServer} MongoDbNoJournal: {get_param: MongoDbNoJournal} + OpenDaylightPort: {get_param: OpenDaylightPort} + OpenDaylightInstall: {get_param: OpenDaylightInstall} + OpenDaylightUsername: {get_param: OpenDaylightUsername} + OpenDaylightPassword: {get_param: OpenDaylightPassword} PcsdPassword: {get_resource: PcsdPassword} PublicVirtualInterface: {get_param: PublicVirtualInterface} RabbitPassword: {get_param: RabbitPassword} @@ -948,6 +1006,9 @@ resources: NovaPublicIP: {get_attr: [PublicVirtualIP, ip_address]} NovaPassword: {get_param: NovaPassword} NtpServer: {get_param: NtpServer} + OpenDaylightPort: {get_param: OpenDaylightPort} + OpenDaylightUsername: {get_param: OpenDaylightUsername} + OpenDaylightPassword: {get_param: OpenDaylightPassword} RabbitHost: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, RabbitMqNetwork]}]} RabbitPassword: {get_param: RabbitPassword} RabbitUserName: {get_param: RabbitUserName} @@ -1068,6 +1129,7 @@ resources: compute_hosts: {get_attr: [Compute, hosts_entry]} controller_hosts: {get_attr: [Controller, hosts_entry]} controller_ips: {get_attr: [Controller, ip_address]} + opendaylight_ip: {get_attr: [OpenDaylightNode, ip_address]} block_storage_hosts: {get_attr: [BlockStorage, hosts_entry]} object_storage_hosts: {get_attr: [ObjectStorage, hosts_entry]} ceph_storage_hosts: {get_attr: [CephStorage, hosts_entry]} diff --git a/puppet/all-nodes-config.yaml b/puppet/all-nodes-config.yaml index 2bc519b..98283c2 100644 --- a/puppet/all-nodes-config.yaml +++ b/puppet/all-nodes-config.yaml @@ -8,6 +8,8 @@ parameters: type: comma_delimited_list controller_ips: type: comma_delimited_list + opendaylight_ip: + type: comma_delimited_list block_storage_hosts: type: comma_delimited_list object_storage_hosts: @@ -82,6 +84,10 @@ resources: raw_data: {get_file: hieradata/RedHat.yaml} all_nodes: mapped_data: + opendaylight_controller_ip: + list_join: + - ',' + - {get_param: opendaylight_ip} controller_node_ips: list_join: - ',' diff --git a/puppet/compute.yaml b/puppet/compute.yaml index 70c7403..df6c16f 100644 --- a/puppet/compute.yaml +++ b/puppet/compute.yaml @@ -213,6 +213,19 @@ parameters: NtpServer: type: string default: '' + OpenDaylightPort: + default: 8081 + description: Set opendaylight service port + type: number + OpenDaylightUsername: + default: 'admin' + description: The username for the opendaylight server. + type: string + OpenDaylightPassword: + default: 'admin' + type: string + description: The password for the opendaylight server. + hidden: true RabbitHost: type: string default: '' # Has to be here because of the ignored empty value bug @@ -406,6 +419,9 @@ resources: neutron::rabbit_user: {get_input: rabbit_user} neutron::rabbit_use_ssl: {get_input: rabbit_client_use_ssl} neutron::rabbit_port: {get_input: rabbit_client_port} + opendaylight_port: {get_input: opendaylight_port} + opendaylight_username: {get_input: opendaylight_username} + opendaylight_password: {get_input: opendaylight_password} neutron_flat_networks: {get_input: neutron_flat_networks} neutron_host: {get_input: neutron_host} neutron::agents::ml2::ovs::local_ip: {get_input: neutron_local_ip} @@ -459,6 +475,9 @@ resources: snmpd_readonly_user_name: {get_param: SnmpdReadonlyUserName} snmpd_readonly_user_password: {get_param: SnmpdReadonlyUserPassword} glance_api_servers: {get_param: [EndpointMap, GlanceInternal, uri]} + opendaylight_port: {get_param: OpenDaylightPort} + opendaylight_username: {get_param: OpenDaylightUsername} + opendaylight_password: {get_param: OpenDaylightPassword} neutron_flat_networks: {get_param: NeutronFlatNetworks} neutron_host: {get_param: NeutronHost} neutron_local_ip: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NeutronTenantNetwork]}]} diff --git a/puppet/controller.yaml b/puppet/controller.yaml index ea0b3af..a339eb2 100644 --- a/puppet/controller.yaml +++ b/puppet/controller.yaml @@ -443,6 +443,23 @@ parameters: NtpServer: type: string default: '' + OpenDaylightPort: + default: 8081 + description: Set opendaylight service port + type: number + OpenDaylightInstall: + default: false + description: Whether to install OpenDaylight on the control nodes. + type: boolean + OpenDaylightUsername: + default: 'admin' + description: The username for the opendaylight server. + type: string + OpenDaylightPassword: + default: 'admin' + type: string + description: The password for the opendaylight server. + hidden: true PcsdPassword: type: string description: The password for the 'pcsd' user. @@ -805,6 +822,10 @@ resources: template: tripleo-CLUSTER params: CLUSTER: {get_param: MysqlClusterUniquePart} + opendaylight_port: {get_param: OpenDaylightPort} + opendaylight_install: {get_param: OpenDaylightInstall} + opendaylight_username: {get_param: OpenDaylightUsername} + opendaylight_password: {get_param: OpenDaylightPassword} neutron_flat_networks: {get_param: NeutronFlatNetworks} neutron_metadata_proxy_shared_secret: {get_param: NeutronMetadataProxySharedSecret} neutron_agent_mode: {get_param: NeutronAgentMode} @@ -1136,6 +1157,12 @@ resources: mysql_bind_host: {get_input: mysql_network} mysql_virtual_ip: {get_input: mysql_virtual_ip} + # OpenDaylight + opendaylight_port: {get_input: opendaylight_port} + opendaylight_install: {get_input: opendaylight_install} + opendaylight_username: {get_input: opendaylight_username} + opendaylight_password: {get_input: opendaylight_password} + # Neutron neutron::bind_host: {get_input: neutron_api_network} neutron::rabbit_password: {get_input: rabbit_password} diff --git a/puppet/manifests/overcloud_compute.pp b/puppet/manifests/overcloud_compute.pp index cd41cc7..a81f88d 100644 --- a/puppet/manifests/overcloud_compute.pp +++ b/puppet/manifests/overcloud_compute.pp @@ -75,9 +75,30 @@ class { '::neutron::plugins::ml2': tenant_network_types => [hiera('neutron_tenant_network_type')], } -class { '::neutron::agents::ml2::ovs': - bridge_mappings => split(hiera('neutron_bridge_mappings'), ','), - tunnel_types => split(hiera('neutron_tunnel_types'), ','), +if 'opendaylight' in hiera('neutron_mechanism_drivers') { + + if str2bool(hiera('opendaylight_install', 'false')) { + $controller_ips = split(hiera('controller_node_ips'), ',') + $opendaylight_controller_ip = $controller_ips[0] + } else { + $opendaylight_controller_ip = hiera('opendaylight_controller_ip') + } + + if str2bool(hiera('opendaylight_install', 'false')) { + class { 'neutron::plugins::ovs::opendaylight': + odl_controller_ip => $opendaylight_controller_ip, + tunnel_ip => hiera('neutron::agents::ml2::ovs::local_ip'), + odl_port => hiera('opendaylight_port'), + odl_username => hiera('opendaylight_username'), + odl_password => hiera('opendaylight_password'), + } + } + +} else { + class { 'neutron::agents::ml2::ovs': + bridge_mappings => split(hiera('neutron_bridge_mappings'), ','), + tunnel_types => split(hiera('neutron_tunnel_types'), ','), + } } if 'cisco_n1kv' in hiera('neutron_mechanism_drivers') { diff --git a/puppet/manifests/overcloud_controller.pp b/puppet/manifests/overcloud_controller.pp index 1f6c2be..75bbee7 100644 --- a/puppet/manifests/overcloud_controller.pp +++ b/puppet/manifests/overcloud_controller.pp @@ -30,6 +30,13 @@ if hiera('step') >= 1 { if hiera('step') >= 2 { + if str2bool(hiera('opendaylight_install', 'false')) { + class {"opendaylight": + extra_features => ['odl-ovsdb-openstack'], + odl_rest_port => hiera('opendaylight_port'), + } + } + if count(hiera('ntp::servers')) > 0 { include ::ntp } @@ -242,10 +249,43 @@ if hiera('step') >= 3 { tenant_network_types => [hiera('neutron_tenant_network_type')], mechanism_drivers => [hiera('neutron_mechanism_drivers')], } - class { '::neutron::agents::ml2::ovs': - bridge_mappings => split(hiera('neutron_bridge_mappings'), ','), - tunnel_types => split(hiera('neutron_tunnel_types'), ','), + + if 'opendaylight' in hiera('neutron_mechanism_drivers') { + + if str2bool(hiera('opendaylight_install', 'false')) { + $controller_ips = split(hiera('controller_node_ips'), ',') + $opendaylight_controller_ip = $controller_ips[0] + } else { + $opendaylight_controller_ip = hiera('opendaylight_controller_ip') + } + + class { 'neutron::plugins::ml2::opendaylight': + odl_controller_ip => $opendaylight_controller_ip, + odl_username => hiera('opendaylight_username'), + odl_password => hiera('opendaylight_password'), + odl_port => hiera('opendaylight_port'), + } + + if str2bool(hiera('opendaylight_install', 'false')) { + class { 'neutron::plugins::ovs::opendaylight': + odl_controller_ip => $opendaylight_controller_ip, + tunnel_ip => hiera('neutron::agents::ml2::ovs::local_ip'), + odl_port => hiera('opendaylight_port'), + odl_username => hiera('opendaylight_username'), + odl_password => hiera('opendaylight_password'), + } + } + + } else { + + class { 'neutron::agents::ml2::ovs': + bridge_mappings => split(hiera('neutron_bridge_mappings'), ','), + tunnel_types => split(hiera('neutron_tunnel_types'), ','), + } + + Service['neutron-server'] -> Service['neutron-ovs-agent-service'] } + if 'cisco_n1kv' in hiera('neutron_mechanism_drivers') { include ::neutron::plugins::ml2::cisco::nexus1000v @@ -281,7 +321,6 @@ if hiera('step') >= 3 { Service['neutron-server'] -> Service['neutron-dhcp-service'] Service['neutron-server'] -> Service['neutron-l3'] - Service['neutron-server'] -> Service['neutron-ovs-agent-service'] Service['neutron-server'] -> Service['neutron-metadata'] include ::cinder diff --git a/puppet/manifests/overcloud_controller_pacemaker.pp b/puppet/manifests/overcloud_controller_pacemaker.pp index 3fb92f3..31c5332 100644 --- a/puppet/manifests/overcloud_controller_pacemaker.pp +++ b/puppet/manifests/overcloud_controller_pacemaker.pp @@ -380,6 +380,13 @@ if hiera('step') >= 2 { } + if str2bool(hiera('opendaylight_install', 'false')) { + class {"opendaylight": + extra_features => ['odl-ovsdb-openstack'], + odl_rest_port => hiera('opendaylight_port'), + } + } + exec { 'galera-ready' : command => '/usr/bin/clustercheck >/dev/null', timeout => 30, @@ -614,13 +621,43 @@ if hiera('step') >= 3 { tenant_network_types => [hiera('neutron_tenant_network_type')], mechanism_drivers => [hiera('neutron_mechanism_drivers')], } - class { '::neutron::agents::ml2::ovs': - manage_service => false, - enabled => false, - bridge_mappings => split(hiera('neutron_bridge_mappings'), ','), - tunnel_types => split(hiera('neutron_tunnel_types'), ','), - } + if 'opendaylight' in hiera('neutron_mechanism_drivers') { + if str2bool(hiera('opendaylight_install', 'false')) { + $controller_ips = split(hiera('controller_node_ips'), ',') + $opendaylight_controller_ip = $controller_ips[0] + } else { + $opendaylight_controller_ip = hiera('opendaylight_controller_ip') + } + + $opendaylight_port = hiera('opendaylight_port') + $private_ip = hiera('neutron::agents::ml2::ovs::local_ip') + + class { 'neutron::plugins::ml2::opendaylight': + odl_controller_ip => $opendaylight_controller_ip, + odl_username => hiera('opendaylight_username'), + odl_password => hiera('opendaylight_password'), + odl_port => hiera('opendaylight_port'), + } + + if str2bool(hiera('opendaylight_install', 'false')) { + class { 'neutron::plugins::ovs::opendaylight': + odl_controller_ip => $opendaylight_controller_ip, + tunnel_ip => hiera('neutron::agents::ml2::ovs::local_ip'), + odl_port => hiera('opendaylight_port'), + odl_username => hiera('opendaylight_username'), + odl_password => hiera('opendaylight_password'), + } + } + + } else { + class { 'neutron::agents::ml2::ovs': + manage_service => false, + enabled => false, + bridge_mappings => split(hiera('neutron_bridge_mappings'), ','), + tunnel_types => split(hiera('neutron_tunnel_types'), ','), + } + } if 'cisco_ucsm' in hiera('neutron_mechanism_drivers') { include ::neutron::plugins::ml2::cisco::ucsm } @@ -1061,56 +1098,13 @@ if hiera('step') >= 4 { pacemaker::resource::service { $::neutron::params::dhcp_agent_service: clone_params => 'interleave=true', } - pacemaker::resource::service { $::neutron::params::ovs_agent_service: - clone_params => 'interleave=true', - } pacemaker::resource::service { $::neutron::params::metadata_agent_service: clone_params => 'interleave=true', } - pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service: - ocf_agent_name => 'neutron:OVSCleanup', - clone_params => 'interleave=true', - } pacemaker::resource::ocf { 'neutron-netns-cleanup': ocf_agent_name => 'neutron:NetnsCleanup', clone_params => 'interleave=true', } - - # neutron - one chain ovs-cleanup-->netns-cleanup-->ovs-agent - pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint': - constraint_type => 'order', - first_resource => "${::neutron::params::ovs_cleanup_service}-clone", - second_resource => 'neutron-netns-cleanup-clone', - first_action => 'start', - second_action => 'start', - require => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service], - Pacemaker::Resource::Ocf['neutron-netns-cleanup']], - } - pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation': - source => 'neutron-netns-cleanup-clone', - target => "${::neutron::params::ovs_cleanup_service}-clone", - score => 'INFINITY', - require => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service], - Pacemaker::Resource::Ocf['neutron-netns-cleanup']], - } - pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint': - constraint_type => 'order', - first_resource => 'neutron-netns-cleanup-clone', - second_resource => "${::neutron::params::ovs_agent_service}-clone", - first_action => 'start', - second_action => 'start', - require => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'], - Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]], - } - pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation': - source => "${::neutron::params::ovs_agent_service}-clone", - target => 'neutron-netns-cleanup-clone', - score => 'INFINITY', - require => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'], - Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]], - } - - #another chain keystone-->neutron-server-->ovs-agent-->dhcp-->l3 pacemaker::constraint::base { 'keystone-to-neutron-server-constraint': constraint_type => 'order', first_resource => "${::keystone::params::service_name}-clone", @@ -1120,31 +1114,75 @@ if hiera('step') >= 4 { require => [Pacemaker::Resource::Service[$::keystone::params::service_name], Pacemaker::Resource::Service[$::neutron::params::server_service]], } - pacemaker::constraint::base { 'neutron-server-to-openvswitch-agent-constraint': - constraint_type => 'order', - first_resource => "${::neutron::params::server_service}-clone", - second_resource => "${::neutron::params::ovs_agent_service}-clone", - first_action => 'start', - second_action => 'start', - require => [Pacemaker::Resource::Service[$::neutron::params::server_service], - Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]], - } - pacemaker::constraint::base { 'neutron-openvswitch-agent-to-dhcp-agent-constraint': - constraint_type => 'order', - first_resource => "${::neutron::params::ovs_agent_service}-clone", - second_resource => "${::neutron::params::dhcp_agent_service}-clone", - first_action => 'start', - second_action => 'start', - require => [Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service], - Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]], + if 'openvswitch' in hiera('neutron_mechanism_drivers') { + pacemaker::resource::service { $::neutron::params::ovs_agent_service: + clone_params => "interleave=true", + } + pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service: + ocf_agent_name => "neutron:OVSCleanup", + clone_params => "interleave=true", + } + # neutron - one chain ovs-cleanup-->netns-cleanup-->ovs-agent + pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint': + constraint_type => "order", + first_resource => "${::neutron::params::ovs_cleanup_service}-clone", + second_resource => "neutron-netns-cleanup-clone", + first_action => "start", + second_action => "start", + require => [Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"], + Pacemaker::Resource::Ocf['neutron-netns-cleanup']], + } + pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation': + source => "neutron-netns-cleanup-clone", + target => "${::neutron::params::ovs_cleanup_service}-clone", + score => "INFINITY", + require => [Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"], + Pacemaker::Resource::Ocf['neutron-netns-cleanup']], + } + pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint': + constraint_type => "order", + first_resource => "neutron-netns-cleanup-clone", + second_resource => "${::neutron::params::ovs_agent_service}-clone", + first_action => "start", + second_action => "start", + require => [Pacemaker::Resource::Ocf["neutron-netns-cleanup"], + Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"]], + } + pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation': + source => "${::neutron::params::ovs_agent_service}-clone", + target => "neutron-netns-cleanup-clone", + score => "INFINITY", + require => [Pacemaker::Resource::Ocf["neutron-netns-cleanup"], + Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"]], + } - } - pacemaker::constraint::colocation { 'neutron-openvswitch-agent-to-dhcp-agent-colocation': - source => "${::neutron::params::dhcp_agent_service}-clone", - target => "${::neutron::params::ovs_agent_service}-clone", - score => 'INFINITY', - require => [Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service], - Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]], + #another chain keystone-->neutron-server-->ovs-agent-->dhcp-->l3 + pacemaker::constraint::base { 'neutron-server-to-openvswitch-agent-constraint': + constraint_type => "order", + first_resource => "${::neutron::params::server_service}-clone", + second_resource => "${::neutron::params::ovs_agent_service}-clone", + first_action => "start", + second_action => "start", + require => [Pacemaker::Resource::Service[$::neutron::params::server_service], + Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]], + } + pacemaker::constraint::base { 'neutron-openvswitch-agent-to-dhcp-agent-constraint': + constraint_type => "order", + first_resource => "${::neutron::params::ovs_agent_service}-clone", + second_resource => "${::neutron::params::dhcp_agent_service}-clone", + first_action => "start", + second_action => "start", + require => [Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"], + Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"]], + + } + pacemaker::constraint::colocation { 'neutron-openvswitch-agent-to-dhcp-agent-colocation': + source => "${::neutron::params::dhcp_agent_service}-clone", + target => "${::neutron::params::ovs_agent_service}-clone", + score => "INFINITY", + require => [Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"], + Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"]], + } } pacemaker::constraint::base { 'neutron-dhcp-agent-to-l3-agent-constraint': constraint_type => 'order', diff --git a/puppet/manifests/overcloud_opendaylight.pp b/puppet/manifests/overcloud_opendaylight.pp new file mode 100644 index 0000000..aea6568 --- /dev/null +++ b/puppet/manifests/overcloud_opendaylight.pp @@ -0,0 +1,26 @@ +# Copyright 2015 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed 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. + +include ::tripleo::packages + +if count(hiera('ntp::servers')) > 0 { + include ::ntp +} + +class {"opendaylight": + extra_features => ['odl-ovsdb-openstack'], + odl_rest_port => hiera('opendaylight_port'), +} + diff --git a/puppet/opendaylight-puppet.yaml b/puppet/opendaylight-puppet.yaml new file mode 100644 index 0000000..70f2543 --- /dev/null +++ b/puppet/opendaylight-puppet.yaml @@ -0,0 +1,209 @@ +heat_template_version: 2015-04-30 + +description: > + OpenDaylight node configured by Puppet. + +parameters: + OpenDaylightFlavor: + default: baremetal + description: The flavor to use for the OpenDaylight node + type: string + OpenDaylightImage: + default: overcloud-full + description: The image to use for the OpenDaylight node + type: string + OpenDaylightHostname: + default: opendaylight-server + description: The hostname to use for the OpenDaylight node + type: string + OpenDaylightUsername: + default: admin + description: The admin user for the OpenDaylight node + type: string + OpenDaylightPassword: + default: '' + description: The admin password for the OpenDaylight node + type: string + hidden: true + OpenDaylightPort: + default: 8081 + description: Set OpenDaylight service port + type: number + KeyName: + description: The keypair to use for SSH access to the node (via heat-admin user) + type: string + default: default + constraints: + - custom_constraint: nova.keypair + ImageUpdatePolicy: + default: 'REBUILD_PRESERVE_EPHEMERAL' + description: What policy to use when reconstructing instances. REBUILD for rebuilds, REBUILD_PRESERVE_EPHEMERAL to preserve /mnt. + type: string + UpdateIdentifier: + default: '' + type: string + description: > + Setting to a previously unused value during stack-update will trigger + package update on all nodes + NtpServer: + type: string + default: '' + PublicInterface: + default: nic1 + description: What interface to bridge onto br-ex for network nodes. + type: string + +resources: + OpenDaylightNode: + type: OS::Nova::Server + properties: + image: {get_param: OpenDaylightImage} + image_update_policy: {get_param: ImageUpdatePolicy} + flavor: {get_param: OpenDaylightFlavor} + key_name: {get_param: KeyName} + networks: + - network: ctlplane + user_data_format: SOFTWARE_CONFIG + user_data: {get_resource: NodeUserData} + name: {get_param: OpenDaylightHostname} + + NodeUserData: + type: OS::TripleO::NodeUserData + + ExternalPort: + type: OS::TripleO::Controller::Ports::ExternalPort + properties: + ControlPlaneIP: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]} + + InternalApiPort: + type: OS::TripleO::Controller::Ports::InternalApiPort + properties: + ControlPlaneIP: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]} + + NetIpMap: + type: OS::TripleO::Network::Ports::NetIpMap + properties: + ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]} + ExternalIp: {get_attr: [ExternalPort, ip_address]} + InternalApiIp: {get_attr: [InternalApiPort, ip_address]} + + NetIpSubnetMap: + type: OS::TripleO::Network::Ports::NetIpSubnetMap + properties: + ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]} + ExternalIpSubnet: {get_attr: [ExternalPort, ip_subnet]} + InternalApiIpSubnet: {get_attr: [InternalApiPort, ip_subnet]} + + NetworkConfig: + type: OS::TripleO::Controller::Net::SoftwareConfig + properties: + ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]} + ExternalIpSubnet: {get_attr: [ExternalPort, ip_subnet]} + InternalApiIpSubnet: {get_attr: [InternalApiPort, ip_subnet]} + + NetworkDeployment: + type: OS::TripleO::SoftwareDeployment + properties: + config: {get_resource: NetworkConfig} + server: {get_resource: OpenDaylightNode} + input_values: + bridge_name: br-ex + interface_name: {get_param: PublicInterface} + + OpenDaylightDeployment: + type: OS::TripleO::SoftwareDeployment + depends_on: NetworkDeployment + properties: + config: {get_resource: OpenDaylightConfig} + server: {get_resource: OpenDaylightNode} + input_values: + ntp_servers: + str_replace: + template: '["server"]' + params: + server: {get_param: NtpServer} + opendaylight_port: {get_param: OpenDaylightPort} + + OpenDaylightConfig: + type: OS::Heat::StructuredConfig + properties: + group: os-apply-config + config: + hiera: + hierarchy: + - '"%{::uuid}"' + - heat_config_%{::deploy_config_name} + - extraconfig + - bootstrap_node # provided by BootstrapNodeConfig + - all_nodes # provided by allNodesConfig + - vip_data # provided by vip-config + - RedHat # Workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1236143 + - common + datafiles: + common: + raw_data: {get_file: hieradata/common.yaml} + mapped_data: + ntp::servers: {get_input: ntp_servers} + opendaylight::admin_username: {get_param: OpenDaylightUsername} + opendaylight::admin_password: {get_param: OpenDaylightPassword} + opendaylight_port: {get_input: opendaylight_port} + ceph: + raw_data: {get_file: hieradata/ceph.yaml} + + UpdateConfig: + type: OS::TripleO::Tasks::PackageUpdate + + UpdateDeployment: + type: OS::Heat::SoftwareDeployment + properties: + config: {get_resource: UpdateConfig} + server: {get_resource: OpenDaylightNode} + input_values: + update_identifier: + get_param: UpdateIdentifier + + OpenDaylightHostsConfig: + type: OS::Heat::SoftwareConfig + properties: + group: script + config: | + #!/usr/bin/env bash + echo -e "$(facter ipaddress)\t\t$(hostname -f)\t$(hostname -s)" >> /etc/hosts + + OpenDaylightHostsDeployment: + type: OS::Heat::StructuredDeployment + depends_on: OpenDaylightDeployment + properties: + server: {get_resource: OpenDaylightNode} + config: {get_resource: OpenDaylightHostsConfig} + + OpenDaylightPuppetConfig: + type: OS::Heat::SoftwareConfig + properties: + group: puppet + config: + get_file: manifests/overcloud_opendaylight.pp + + OpenDaylightPuppetDeployment: + depends_on: OpenDaylightHostsDeployment + type: OS::Heat::StructuredDeployment + properties: + server: {get_resource: OpenDaylightNode} + config: {get_resource: OpenDaylightPuppetConfig} + input_values: + update_identifier: {get_param: UpdateIdentifier} + +outputs: + ip_address: + description: IP address of the server in the ctlplane network + value: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]} + opendaylight_controller_ip: + description: IP address of the server on the internal network + value: {get_attr: [InternalApiPort, ip_address]} + config_identifier: + description: identifier which changes if the node configuration may need re-applying + value: + list_join: + - ',' + - - {get_attr: [OpenDaylightDeployment, deploy_stdout]} + - {get_param: UpdateIdentifier} -- 2.5.0