MidoNet heat templates
authorJaume Devesa <devvesa@gmail.com>
Sat, 17 Oct 2015 16:30:36 +0000 (16:30 +0000)
committerJaume Devesa <devvesa@gmail.com>
Mon, 21 Dec 2015 11:15:32 +0000 (12:15 +0100)
Deploy a TripleO overcloud with networking midonet. MidoNet is a
monolithic plugin and quite changes on the puppet manifest must be done.

Depends-On: I72f21036fda795b54312a7d39f04c30bbf16c41b
Depends-On: I6f1ac659297b8cf6671e11ad23284f8f543568b0
Depends-On: Icea9bd96e4c80a26b9e813d383f84099c736d7bf
Change-Id: I9692e2ef566ea37e0235a6059b1ae1ceeb9725ba

environments/neutron-midonet.yaml [new file with mode: 0644]
puppet/compute.yaml
puppet/controller.yaml
puppet/extraconfig/all_nodes/neutron-midonet-all-nodes.yaml [new file with mode: 0644]
puppet/manifests/overcloud_compute.pp
puppet/manifests/overcloud_controller.pp
puppet/manifests/overcloud_controller_pacemaker.pp

diff --git a/environments/neutron-midonet.yaml b/environments/neutron-midonet.yaml
new file mode 100644 (file)
index 0000000..726852a
--- /dev/null
@@ -0,0 +1,20 @@
+# A Heat environment that can be used to deploy MidoNet Services
+resource_registry:
+  OS::TripleO::AllNodesExtraConfig: ../puppet/extraconfig/all_nodes/neutron-midonet-all-nodes.yaml
+  OS::TripleO::Controller::Net::SoftwareConfig: ../net-config-linux-bridge.yaml # We have to avoid any ovs bridge. MidoNet is incompatible with its datapath
+
+parameter_defaults:
+  EnableZookeeperOnController: true
+  EnableCassandraOnController: true
+  NeutronCorePlugin: 'midonet.neutron.plugin_v1.MidonetPluginV2' # Overriding default core_plugin in Neutron. Don't touch it
+  NeutronEnableIsolatedMetadata: true  # MidoNet 1.9 needs this one to work. Don't change it
+  NeutronEnableL3Agent: false
+  NeutronEnableOVSAgent: false
+
+  # Other available options for MidoNet Services
+  # TunnelZoneName: 'tunnelname'
+  # TunnelZoneType: 'gre'
+  # CassandraStoragePort: 7000
+  # CassandraSslStoragePort: 7009
+  # CassandraClientPort: 9042
+  # CassandraClientPortThrift: 9160
index 43ef582..e9f7876 100644 (file)
@@ -404,6 +404,7 @@ resources:
             - common
             - cisco_n1kv_data  # Optionally provided by ComputeExtraConfigPre
             - nova_nuage_data  # Optionally provided by ComputeExtraConfigPre
+            - midonet_data # Optionally provided by AllNodesExtraConfig
           datafiles:
             compute_extraconfig:
               mapped_data: {get_param: NovaComputeExtraConfig}
index 7089f60..87233b6 100644 (file)
@@ -1119,6 +1119,7 @@ resources:
             - neutron_cisco_data # Optionally provided by ControllerExtraConfigPre
             - cisco_n1kv_data # Optionally provided by ControllerExtraConfigPre
             - neutron_nuage_data # Optionally provided by ControllerExtraConfigPre
+            - midonet_data #Optionally provided by AllNodesExtraConfig
           datafiles:
             controller_extraconfig:
               mapped_data: {get_param: ControllerExtraConfig}
diff --git a/puppet/extraconfig/all_nodes/neutron-midonet-all-nodes.yaml b/puppet/extraconfig/all_nodes/neutron-midonet-all-nodes.yaml
new file mode 100644 (file)
index 0000000..26ce713
--- /dev/null
@@ -0,0 +1,119 @@
+heat_template_version: 2015-10-15
+
+description: Configure hieradata for all MidoNet nodes
+
+parameters:
+  # Parameters passed from the parent template
+  controller_servers:
+    type: json
+  compute_servers:
+    type: json
+  blockstorage_servers:
+    type: json
+  objectstorage_servers:
+    type: json
+  cephstorage_servers:
+    type: json
+
+  EnableZookeeperOnController:
+    label: Enable Zookeeper On Controller
+    description: 'Whether enable Zookeeper cluster on Controller'
+    type: boolean
+    default: false
+  EnableCassandraOnController:
+    label: Enable Cassandra On Controller
+    description: 'Whether enable Cassandra cluster on Controller'
+    type: boolean
+    default: false
+  CassandraStoragePort:
+    label: Cassandra Storage Port
+    description: 'The Cassandra port for inter-node communication'
+    type: string
+    default: '7000'
+  CassandraSslStoragePort:
+    label: Cassandra SSL Storage Port
+    description: 'The SSL port for encrypted communication. Unused unless enabled in encryption_options'
+    type: string
+    default: '7001'
+  CassandraClientPort:
+    label: Cassandra Client Port
+    description: 'Native Transport Port'
+    type: string
+    default: '9042'
+  CassandraClientPortThrift:
+    label: Cassandra Client Thrift Port
+    description: 'The port for the Thrift RPC service, which is used for client connections'
+    type: string
+    default: '9160'
+  TunnelZoneName:
+    label: Name of the Tunnelzone
+    description: 'Name of the tunnel zone used to tunnel packages'
+    type: string
+    default: 'tunnelzone_tripleo'
+  TunnelZoneType:
+    label: Type of the Tunnel
+    description: 'Type of the tunnels on the overlay. Choose between `gre` and `vxlan`'
+    type: string
+    default: 'vxlan'
+
+resources:
+
+  NetworkMidoNetConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config:
+        hiera:
+          datafiles:
+            midonet_data:
+              mapped_data:
+                enable_zookeeper_on_controller: {get_param: EnableZookeeperOnController}
+                enable_cassandra_on_controller: {get_param: EnableCassandraOnController}
+                midonet_tunnelzone_name: {get_param: TunnelZoneName}
+                midonet_tunnelzone_type: {get_param: TunnelZoneType}
+                midonet_libvirt_qemu_data: |
+                    user = "root"
+                    group = "root"
+                    cgroup_device_acl = [
+                        "/dev/null", "/dev/full", "/dev/zero",
+                        "/dev/random", "/dev/urandom",
+                        "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
+                        "/dev/rtc","/dev/hpet", "/dev/vfio/vfio",
+                        "/dev/net/tun"
+                    ]
+                tripleo::cluster::cassandra::storage_port: {get_param: CassandraStoragePort}
+                tripleo::cluster::cassandra::ssl_storage_port: {get_param: CassandraSslStoragePort}
+                tripleo::cluster::cassandra::client_port: {get_param: CassandraClientPort}
+                tripleo::cluster::cassandra::client_port_thrift: {get_param: CassandraClientPortThrift}
+                tripleo::loadbalancer::midonet_api: true
+                # Missed Neutron Puppet data
+                neutron::agents::dhcp::interface_driver: 'neutron.agent.linux.interface.MidonetInterfaceDriver'
+                neutron::agents::dhcp::dhcp_driver: 'midonet.neutron.agent.midonet_driver.DhcpNoOpDriver'
+                neutron::plugins::midonet::midonet_api_port: 8081
+                neutron::params::midonet_server_package: 'python-networking-midonet'
+
+                # Make sure the l3 agent does not run
+                l3_agent_service: false
+                neutron::agents::l3::manage_service: false
+                neutron::agents::l3::enabled: false
+
+
+  NetworkMidonetDeploymentControllers:
+    type: OS::Heat::StructuredDeploymentGroup
+    properties:
+      config: {get_resource: NetworkMidoNetConfig}
+      servers: {get_param: controller_servers}
+
+  NetworkMidonetDeploymentComputes:
+    type: OS::Heat::StructuredDeploymentGroup
+    properties:
+      config: {get_resource: NetworkMidoNetConfig}
+      servers: {get_param: compute_servers}
+
+outputs:
+  config_identifier:
+    value:
+      list_join:
+        - ' '
+        - - {get_attr: [NetworkMidonetDeploymentControllers, deploy_stdouts]}
+          - {get_attr: [NetworkMidonetDeploymentComputes, deploy_stdouts]}
index e0566ac..79a6abb 100644 (file)
@@ -68,11 +68,19 @@ if hiera('cinder_enable_nfs_backend', false) {
 }
 
 include ::nova::compute::libvirt
+if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
+  file {'/etc/libvirt/qemu.conf':
+    ensure  => present,
+    content => hiera('midonet_libvirt_qemu_data')
+  }
+}
 include ::nova::network::neutron
 include ::neutron
 
 # If the value of core plugin is set to 'nuage',
 # include nuage agent,
+# If the value of core plugin is set to 'midonet',
+# include midonet agent,
 # else use the default value of 'ml2'
 if hiera('neutron::core_plugin') == 'neutron.plugins.nuage.plugin.NuagePlugin' {
   include ::nuage::vrs
@@ -84,7 +92,20 @@ if hiera('neutron::core_plugin') == 'neutron.plugins.nuage.plugin.NuagePlugin' {
     nova_metadata_ip    => hiera('nova_metadata_node_ips'),
     nova_auth_ip        => hiera('keystone_public_api_virtual_ip'),
   }
-} else {
+}
+elsif hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
+
+  # TODO(devvesa) provide non-controller ips for these services
+  $zookeeper_node_ips = hiera('neutron_api_node_ips')
+  $cassandra_node_ips = hiera('neutron_api_node_ips')
+
+  class {'::tripleo::network::midonet::agent':
+    zookeeper_servers => $zookeeper_node_ips,
+    cassandra_seeds   => $cassandra_node_ips
+  }
+}
+else {
+
   include ::neutron::plugins::ml2
   include ::neutron::agents::ml2::ovs
 
index 7d3012e..a84a534 100644 (file)
@@ -230,13 +230,61 @@ if hiera('step') >= 3 {
   include ::nova::scheduler
   include ::nova::scheduler::filter
 
-  include ::neutron
+  if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
+
+    # TODO(devvesa) provide non-controller ips for these services
+    $zookeeper_node_ips = hiera('neutron_api_node_ips')
+    $cassandra_node_ips = hiera('neutron_api_node_ips')
+
+    # Run zookeeper in the controller if configured
+    if hiera('enable_zookeeper_on_controller') {
+      class {'::tripleo::cluster::zookeeper':
+        zookeeper_server_ips => $zookeeper_node_ips,
+        zookeeper_client_ip  => $ipaddress,
+        zookeeper_hostnames  => hiera('controller_node_names')
+      }
+    }
+
+    # Run cassandra in the controller if configured
+    if hiera('enable_cassandra_on_controller') {
+      class {'::tripleo::cluster::cassandra':
+        cassandra_servers => $cassandra_node_ips,
+        cassandra_ip      => $ipaddress
+      }
+    }
+
+    class {'::tripleo::network::midonet::agent':
+      zookeeper_servers => $zookeeper_node_ips,
+      cassandra_seeds   => $cassandra_node_ips
+    }
+
+    class {'::tripleo::network::midonet::api':
+      zookeeper_servers    => $zookeeper_node_ips,
+      vip                  => $ipaddress,
+      keystone_ip          => $ipaddress,
+      keystone_admin_token => hiera('keystone::admin_token'),
+      bind_address         => $ipaddress,
+      admin_password       => hiera('admin_password')
+    }
+
+    # TODO: find a way to get an empty list from hiera
+    class {'::neutron':
+      service_plugins => []
+    }
+
+  }
+  else {
+
+    # ML2 plugin
+    include ::neutron
+  }
+
   include ::neutron::server
   include ::neutron::server::notifications
 
   # If the value of core plugin is set to 'nuage',
-  # include nuage core plugin,
-  # else use the default value of 'ml2'
+  # include nuage core plugin, and it does not
+  # need the l3, dhcp and metadata agents
   if hiera('neutron::core_plugin') == 'neutron.plugins.nuage.plugin.NuagePlugin' {
     include ::neutron::plugins::nuage
   } else {
@@ -252,45 +300,57 @@ if hiera('step') >= 3 {
       require => Package['neutron'],
     }
 
-    include ::neutron::plugins::ml2
-    include ::neutron::agents::ml2::ovs
-
-    if 'cisco_n1kv' in hiera('neutron::plugins::ml2::mechanism_drivers') {
-      include ::neutron::plugins::ml2::cisco::nexus1000v
+    # If the value of core plugin is set to 'midonet',
+    # skip all the ML2 configuration
+    if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
 
-      class { '::neutron::agents::n1kv_vem':
-        n1kv_source  => hiera('n1kv_vem_source', undef),
-        n1kv_version => hiera('n1kv_vem_version', undef),
+      class {'::neutron::plugins::midonet':
+        midonet_api_ip    => $ipaddress,
+        keystone_tenant   => hiera('neutron::server::auth_tenant'),
+        keystone_password => hiera('neutron::server::auth_password')
       }
+    } else {
+
+      include ::neutron::plugins::ml2
+      include ::neutron::agents::ml2::ovs
+
+      if 'cisco_n1kv' in hiera('neutron::plugins::ml2::mechanism_drivers') {
+        include ::neutron::plugins::ml2::cisco::nexus1000v
 
-      class { '::n1k_vsm':
-        n1kv_source       => hiera('n1kv_vsm_source', undef),
-        n1kv_version      => hiera('n1kv_vsm_version', undef),
-        pacemaker_control => false,
+        class { '::neutron::agents::n1kv_vem':
+          n1kv_source  => hiera('n1kv_vem_source', undef),
+          n1kv_version => hiera('n1kv_vem_version', undef),
+        }
+
+        class { '::n1k_vsm':
+          n1kv_source       => hiera('n1kv_vsm_source', undef),
+          n1kv_version      => hiera('n1kv_vsm_version', undef),
+          pacemaker_control => false,
+        }
       }
-    }
 
-    if 'cisco_ucsm' in hiera('neutron::plugins::ml2::mechanism_drivers') {
-      include ::neutron::plugins::ml2::cisco::ucsm
-    }
-    if 'cisco_nexus' in hiera('neutron::plugins::ml2::mechanism_drivers') {
-      include ::neutron::plugins::ml2::cisco::nexus
-      include ::neutron::plugins::ml2::cisco::type_nexus_vxlan
-    }
+      if 'cisco_ucsm' in hiera('neutron::plugins::ml2::mechanism_drivers') {
+        include ::neutron::plugins::ml2::cisco::ucsm
+      }
+      if 'cisco_nexus' in hiera('neutron::plugins::ml2::mechanism_drivers') {
+        include ::neutron::plugins::ml2::cisco::nexus
+        include ::neutron::plugins::ml2::cisco::type_nexus_vxlan
+      }
 
-    if hiera('neutron_enable_bigswitch_ml2', false) {
-      include ::neutron::plugins::ml2::bigswitch::restproxy
-    }
-    neutron_l3_agent_config {
-      'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
-    }
-    neutron_dhcp_agent_config {
-      'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
+      if hiera('neutron_enable_bigswitch_ml2', false) {
+        include ::neutron::plugins::ml2::bigswitch::restproxy
+      }
+      neutron_l3_agent_config {
+        'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
+      }
+      neutron_dhcp_agent_config {
+        'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
+      }
+      Service['neutron-server'] -> Service['neutron-ovs-agent-service']
     }
 
     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']
   }
 
index ad356e3..d0d46e2 100644 (file)
@@ -592,8 +592,54 @@ if hiera('step') >= 3 {
   }
   include ::nova::network::neutron
 
-  # Neutron class definitions
-  include ::neutron
+  if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
+
+    # TODO(devvesa) provide non-controller ips for these services
+    $zookeeper_node_ips = hiera('neutron_api_node_ips')
+    $cassandra_node_ips = hiera('neutron_api_node_ips')
+
+    # Run zookeeper in the controller if configured
+    if hiera('enable_zookeeper_on_controller') {
+      class {'::tripleo::cluster::zookeeper':
+        zookeeper_server_ips => $zookeeper_node_ips,
+        zookeeper_client_ip  => $ipaddress,
+        zookeeper_hostnames  => hiera('controller_node_names')
+      }
+    }
+
+    # Run cassandra in the controller if configured
+    if hiera('enable_cassandra_on_controller') {
+      class {'::tripleo::cluster::cassandra':
+        cassandra_servers => $cassandra_node_ips,
+        cassandra_ip      => $ipaddress
+      }
+    }
+
+    class {'::tripleo::network::midonet::agent':
+      zookeeper_servers => $zookeeper_node_ips,
+      cassandra_seeds   => $cassandra_node_ips
+    }
+
+    class {'::tripleo::network::midonet::api':
+      zookeeper_servers    => hiera('neutron_api_node_ips'),
+      vip                  => $public_vip,
+      keystone_ip          => $public_vip,
+      keystone_admin_token => hiera('keystone::admin_token'),
+      bind_address         => $ipaddress,
+      admin_password       => hiera('admin_password')
+    }
+
+    # Configure Neutron
+    class {'::neutron':
+      service_plugins => []
+    }
+
+  }
+  else {
+    # Neutron class definitions
+    include ::neutron
+  }
+
   class { '::neutron::server' :
     sync_db        => $sync_db,
     manage_service => false,
@@ -603,6 +649,13 @@ if hiera('step') >= 3 {
   if  hiera('neutron::core_plugin') == 'neutron.plugins.nuage.plugin.NuagePlugin' {
     include ::neutron::plugins::nuage
   }
+  if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
+    class {'::neutron::plugins::midonet':
+      midonet_api_ip    => $public_vip,
+      keystone_tenant   => hiera('neutron::server::auth_tenant'),
+      keystone_password => hiera('neutron::server::auth_password')
+    }
+  }
   if hiera('neutron::enable_dhcp_agent',true) {
     class { '::neutron::agents::dhcp' :
       manage_service => false,
@@ -1095,6 +1148,11 @@ if hiera('step') >= 4 {
         clone_params => 'interleave=true',
       }
     }
+    if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
+      pacemaker::resource::service {'tomcat':
+        clone_params => 'interleave=true',
+      }
+    }
     if hiera('neutron::enable_metadata_agent', true) {
       pacemaker::resource::service { $::neutron::params::metadata_agent_service:
         clone_params => 'interleave=true',
@@ -1145,7 +1203,6 @@ if hiera('step') >= 4 {
       }
     }
 
-    #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",
@@ -1221,6 +1278,43 @@ if hiera('step') >= 4 {
                     Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]]
       }
     }
+    if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
+      #midonet-chain chain keystone-->neutron-server-->dhcp-->metadata->tomcat
+      pacemaker::constraint::base { 'neutron-server-to-dhcp-agent-constraint':
+        constraint_type => 'order',
+        first_resource  => "${::neutron::params::server_service}-clone",
+        second_resource => "${::neutron::params::dhcp_agent_service}-clone",
+        first_action    => 'start',
+        second_action   => 'start',
+        require         => [Pacemaker::Resource::Service[$::neutron::params::server_service],
+                            Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
+      }
+      pacemaker::constraint::base { 'neutron-dhcp-agent-to-metadata-agent-constraint':
+        constraint_type => 'order',
+        first_resource  => "${::neutron::params::dhcp_agent_service}-clone",
+        second_resource => "${::neutron::params::metadata_agent_service}-clone",
+        first_action    => 'start',
+        second_action   => 'start',
+        require         => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
+                            Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
+      }
+      pacemaker::constraint::base { 'neutron-metadata-agent-to-tomcat-constraint':
+        constraint_type => 'order',
+        first_resource  => "${::neutron::params::metadata_agent_service}-clone",
+        second_resource => 'tomcat-clone',
+        first_action    => 'start',
+        second_action   => 'start',
+        require         => [Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service],
+                            Pacemaker::Resource::Service['tomcat']],
+      }
+      pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-metadata-agent-colocation':
+        source  => "${::neutron::params::metadata_agent_service}-clone",
+        target  => "${::neutron::params::dhcp_agent_service}-clone",
+        score   => 'INFINITY',
+        require => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
+                    Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
+      }
+    }
 
     # Nova
     pacemaker::resource::service { $::nova::params::api_service_name :