class oci::network(
  $region_name              = 'RegionOne',
  $openstack_release        = undef,
  $cluster_name             = undef,
  $machine_hostname         = undef,
  $machine_ip               = undef,
  $bridge_mapping_list      = undef,
  $external_network_list    = undef,
  $first_master             = undef,
  $first_master_ip          = undef,
  $cluster_domain           = undef,
  $vmnet_ip                 = undef,

  $messaging_nodes_for_notifs = false,
  $all_rabbits                = [],
  $all_rabbits_ips            = [],

  $neutron_global_physnet_mtu = 1500,
  $neutron_path_mtu         = 1500,

  $all_masters              = undef,
  $all_masters_ip           = undef,
  $vip_hostname             = undef,
  $vip_ipaddr               = undef,
  $vip_netmask              = undef,
  $self_signed_api_cert     = true,
  $sql_vip_ip               = undef,
  $network_ipaddr           = undef,
  $network_cidr             = undef,
  $use_ssl                  = true,
  $pass_nova_authtoken      = undef,
  $pass_neutron_authtoken   = undef,
  $pass_neutron_messaging   = undef,
  $pass_neutron_vrrpauth    = undef,
  $pass_metadata_proxy_shared_secret = undef,
  $pass_keystone_adminuser  = undef,

  $pass_haproxy_stats       = undef,

  $disable_notifications    = false,

  $bgp_to_the_host             = false,
  $dhcp_domain                 = '',
  $has_subrole_designate       = false,
  $neutron_dns_domain          = 'example.com.',
  $admin_email_address         = 'admin@example.com',
  $neutron_dnsmasq_dns_servers = '',

  $use_dynamic_routing      = false,

  $neutron_install_dragent  = false,

  $neutron_use_dvr          = true,
  # This one is unused, because we use the agregate of
  # netowrk + bridge instead. However, it's transmitted
  # by the ENC because it is a machine variable, so this
  # variable must be present.
  $neutron_external_network_name = undef,

  $kernel_from_backports    = false,
  $install_designate        = false,
  $brex_macaddr             = undef,

  $neutron_vxlan_vni_min     = '1000',
  $neutron_vxlan_vni_max     = '9999',

  $designate_zone_admin_email = 'hostmaster@example.com',

  $external_keystone_activate              = false,
  $external_keystone_url                   = 'https://api.example.com/identity',
  $external_keystone_admin_password        = undef,
  $external_keystone_region_prefixed_users = false,

  # Neutron AZ
  $neutron_use_az  = false,
  $neutron_az_list = 'az1,az2,az3',
  $neutron_az_name = 'az1',

  $configure_dkms = false,

  $haproxy_use_sni = false,

  $designate_sni_name  = "dns",
  $keystone_sni_name   = "identity",

  $rabbitmq_enable_quorum_queues = false,
  $rabbitmq_message_timeout      = 120,

  $use_json_log = false,

  $neutron_debug_log = false,
  $logrotate_hourly  = true,
){

  if $logrotate_hourly {
    $logrotate_period = 'hour'
  }else{
    $logrotate_period = 'day'
  }

  $logging_context_format_string = '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(global_request_id)s %(request_id)s %(user_identity)s] %(instance)s%(message)s'
  $logging_default_format_string = '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s'

  # With a lot of VMs and a lot of traffic
  # the Kernel default is far from enough on network nodes.
  sysctl::value { 'net.core.netdev_max_backlog':
    value  => '24000',
    target => '/etc/sysctl.d/60-ipv4-netdev-backlog.conf',
  }
  sysctl::value { 'net.core.netdev_budget':
    value  => '600',
    target => '/etc/sysctl.d/60-ipv4-netdev-budget.conf',
  }

  $rabbitmq_transient_queue_expire = $rabbitmq_message_timeout + 60

  if $rabbitmq_enable_quorum_queues {
    $rabbit_ha_queues              = false
    $rabbit_quorum_queue           = true
    $rabbit_transient_quorum_queue = true
    $amqp_durable_queues           = true
    $use_queue_manager             = true
    $rabbit_stream_fanout          = true
    $rabbit_qos_prefetch_count     = 20
  }else{
    $rabbit_ha_queues              = true
    $rabbit_quorum_queue           = false
    $rabbit_transient_quorum_queue = false
    $amqp_durable_queues           = false
    $use_queue_manager             = false
    $rabbit_stream_fanout          = false
    $rabbit_qos_prefetch_count     = $facts['os_service_default']
  }

  if $configure_dkms { class { '::oci::dkms': } }

  # Tweak performances for network host
  class { '::oci::tuned': profile => 'network-throughput' }

  if $neutron_use_az {
    $availability_zone = $neutron_az_name
  }else{
    $availability_zone = $facts['os_service_default']
  }

  if $messaging_nodes_for_notifs {
    $notif_rabbit_servers = $all_rabbits
  }else{
    $notif_rabbit_servers = $all_masters
  }

  if $use_ssl {
    $proto = 'https'
    $messaging_default_port = '5671'
    $messaging_notify_port = '5671'
    $api_port = 443
  } else {
    $proto = 'http'
    $messaging_default_port = '5672'
    $messaging_notify_port = '5672'
    $api_port = 80
  }
  $messaging_default_proto = 'rabbit'
  $messaging_notify_proto = 'rabbit'


  $base_url = "${proto}://${vip_hostname}"

  $base_url_designate = $haproxy_use_sni ? { true => "${designate_sni_name}.${vip_hostname}", false => "${base_url}/dns"}
  $base_url_keystone  = $haproxy_use_sni ? { true => "${keystone_sni_name}.${vip_hostname}", false => "${base_url}/identity"}

  $keystone_auth_uri  = $external_keystone_activate ? { true => "${external_keystone_url}", false => "${base_url_keystone}"}
  $keystone_admin_uri = $external_keystone_activate ? { true => "${external_keystone_url}", false => "${base_url_keystone}"}

  $region_suffix = $external_keystone_region_prefixed_users ? {
    true  => "-${region_name}",
    false => ''
  }

  $nova_user    = "nova${region_suffix}"
  $neutron_user = "neutron${region_suffix}"

  if $self_signed_api_cert {
    $api_endpoint_ca_file = '/etc/ssl/certs/oci-pki-oci-ca-chain.pem'
  }else{
    $api_endpoint_ca_file = ''
  }
  $oci_pki_root_ca_file = '/etc/ssl/certs/oci-pki-oci-ca-chain.pem'

  class { '::oci::puppet_oci_ca_cert':
    self_signed_api_cert => $self_signed_api_cert,
  }

  if $disable_notifications {
    $notification_driver = 'noop'
  }else{
    $notification_driver = 'messagingv2'
  }

  ###############
  ### Neutron ###
  ###############
  if $disable_notifications {
    $neutron_notif_transport_url = undef
  } else {
    $neutron_notif_transport_url = os_transport_url({
                                    'transport' => $messaging_notify_proto,
                                    'hosts'     => fqdn_rotate($notif_rabbit_servers),
                                    'port'      => $messaging_notify_port,
                                    'username'  => 'neutron',
                                    'password'  => $pass_neutron_messaging,
                                  })
  }

  if $neutron_use_dvr {
    $router_distributed         = true
    $enable_distributed_routing = true
    $l3_agent_mode              = 'dvr_snat'
  }else{
    $router_distributed         = false
    $enable_distributed_routing = false
    $l3_agent_mode              = 'legacy'
  }


  if $install_designate {
    $notif_topics_neutron = ['notifications','notifications_designate']
  } else {
    $notif_topics_neutron = ['notifications']
  }

  if $openstack_release == 'rocky'{
    class { '::neutron':
      debug                      => true,
      default_transport_url      => os_transport_url({
        'transport' => $messaging_default_proto,
        'hosts'     => fqdn_rotate($all_masters),
        'port'      => $messaging_default_port,
        'username'  => 'neutron',
        'password'  => $pass_neutron_messaging,
      }),
      notification_transport_url  => $neutron_notif_transport_url,
      dns_domain                  => $neutron_dns_domain,
      rabbit_use_ssl              => $use_ssl,
      rpc_response_timeout        => $rabbitmq_message_timeout,
      amqp_durable_queues         => $amqp_durable_queues,
      amqp_auto_delete            => false,
      rabbit_ha_queues            => true,
      kombu_ssl_ca_certs          => $oci_pki_root_ca_file,
      allow_overlapping_ips       => true,
      core_plugin                 => 'ml2',
      service_plugins             => ['router', 'metering', 'qos', 'trunk'],
      bind_host                   => $machine_ip,
      notification_driver         => $notification_driver,
      global_physnet_mtu          => $neutron_global_physnet_mtu,
      notification_topics         => $notif_topics_neutron,
      rabbit_transient_queues_ttl => $rabbitmq_transient_queue_expire,
    }
  }else{
    if $openstack_release == 'stein' or $openstack_release == 'train' or $openstack_release == 'ussuri' or $openstack_release == 'victoria' or $openstack_release == 'wallaby' or $openstack_release == 'xena' or $openstack_release == 'yoga'{
      class { '::neutron':
        default_transport_url      => os_transport_url({
          'transport' => $messaging_default_proto,
          'hosts'     => fqdn_rotate($all_masters),
          'port'      => $messaging_default_port,
          'username'  => 'neutron',
          'password'  => $pass_neutron_messaging,
        }),
        notification_transport_url  => $neutron_notif_transport_url,
        dns_domain                  => $neutron_dns_domain,
        rabbit_use_ssl              => $use_ssl,
        rpc_response_timeout        => $rabbitmq_message_timeout,
        amqp_durable_queues         => $amqp_durable_queues,
        amqp_auto_delete            => false,
        rabbit_ha_queues            => true,
        kombu_ssl_ca_certs          => $oci_pki_root_ca_file,
        allow_overlapping_ips       => true,
        core_plugin                 => 'ml2',
        service_plugins             => ['router', 'metering', 'qos', 'trunk'],
        bind_host                   => $machine_ip,
        notification_driver         => $notification_driver,
        global_physnet_mtu          => $neutron_global_physnet_mtu,
        notification_topics         => $notif_topics_neutron,
        rabbit_transient_queues_ttl => $rabbitmq_transient_queue_expire,
      }
    # No allow_overlapping_ips in Zed and up
    }else{
      if($openstack_release == 'zed' or $openstack_release == 'antelope'){
        class { '::neutron':
          default_transport_url      => os_transport_url({
            'transport' => $messaging_default_proto,
            'hosts'     => fqdn_rotate($all_masters),
            'port'      => $messaging_default_port,
            'username'  => 'neutron',
            'password'  => $pass_neutron_messaging,
          }),
          notification_transport_url  => $neutron_notif_transport_url,
          dns_domain                  => $neutron_dns_domain,
          rabbit_use_ssl              => $use_ssl,
          rpc_response_timeout        => $rabbitmq_message_timeout,
          amqp_durable_queues         => $amqp_durable_queues,
          amqp_auto_delete            => false,
          rabbit_ha_queues            => true,
          kombu_ssl_ca_certs          => $oci_pki_root_ca_file,
          core_plugin                 => 'ml2',
          service_plugins             => ['router', 'metering', 'qos', 'trunk'],
          bind_host                   => $machine_ip,
          notification_driver         => $notification_driver,
          global_physnet_mtu          => $neutron_global_physnet_mtu,
          notification_topics         => $notif_topics_neutron,
          rabbit_transient_queues_ttl => $rabbitmq_transient_queue_expire,
        }
      }elsif($openstack_release == 'bobcat'){
        class { '::neutron':
          default_transport_url      => os_transport_url({
            'transport' => $messaging_default_proto,
            'hosts'     => fqdn_rotate($all_masters),
            'port'      => $messaging_default_port,
            'username'  => 'neutron',
            'password'  => $pass_neutron_messaging,
          }),
          notification_transport_url  => $neutron_notif_transport_url,
          dns_domain                  => $neutron_dns_domain,
          rabbit_use_ssl              => $use_ssl,
          rpc_response_timeout        => $rabbitmq_message_timeout,
          amqp_durable_queues         => $amqp_durable_queues,
          amqp_auto_delete            => false,
          rabbit_ha_queues            => $rabbit_ha_queues,
          rabbit_quorum_queue         => $rabbit_quorum_queue,
          kombu_ssl_ca_certs          => $oci_pki_root_ca_file,
          core_plugin                 => 'ml2',
          service_plugins             => ['router', 'metering', 'qos', 'trunk'],
          bind_host                   => $machine_ip,
          notification_driver         => $notification_driver,
          global_physnet_mtu          => $neutron_global_physnet_mtu,
          notification_topics         => $notif_topics_neutron,
          rabbit_transient_queues_ttl => $rabbitmq_transient_queue_expire,
        }
      # Caracal and up.
      }else{
        class { '::neutron':
          default_transport_url         => os_transport_url({
            'transport' => $messaging_default_proto,
            'hosts'     => fqdn_rotate($all_masters),
            'port'      => $messaging_default_port,
            'username'  => 'neutron',
            'password'  => $pass_neutron_messaging,
          }),
          notification_transport_url    => $neutron_notif_transport_url,
          dns_domain                    => $neutron_dns_domain,
          rabbit_use_ssl                => $use_ssl,
          rpc_response_timeout          => $rabbitmq_message_timeout,
          amqp_durable_queues           => $amqp_durable_queues,
          amqp_auto_delete              => false,
          rabbit_ha_queues              => $rabbit_ha_queues,
          rabbit_quorum_queue           => $rabbit_quorum_queue,
          rabbit_transient_quorum_queue => $rabbit_transient_quorum_queue,
          rabbit_use_queue_manager      => $use_queue_manager,
          rabbit_stream_fanout          => $rabbit_stream_fanout,
          rabbit_qos_prefetch_count     => $rabbit_qos_prefetch_count,
          kombu_ssl_ca_certs            => $oci_pki_root_ca_file,
          core_plugin                   => 'ml2',
          service_plugins               => ['router', 'metering', 'qos', 'trunk'],
          bind_host                     => $machine_ip,
          notification_driver           => $notification_driver,
          global_physnet_mtu            => $neutron_global_physnet_mtu,
          notification_topics           => $notif_topics_neutron,
          rabbit_transient_queues_ttl   => $rabbitmq_transient_queue_expire,
        }
      }
    }
    class { '::neutron::logging':
      debug                         => $neutron_debug_log,
      use_json                      => $use_json_log,
      logging_context_format_string => $logging_context_format_string,
      logging_default_format_string => $logging_default_format_string,
    }
  }
  neutron_config {
    'nova/cafile':         value => $api_endpoint_ca_file;
    'database/connection': value => $facts['os_service_default'];
  }

  if $openstack_release == 'rocky' or $openstack_release == 'stein' or $openstack_release == 'train' or $openstack_release == 'ussuri'{
    class { '::neutron::server::notifications':
      auth_url    => $keystone_admin_uri,
      username    => $nova_user,
      password    => $pass_nova_authtoken,
      region_name => $region_name,
    }
  # Victoria and up
  }else{
    class { 'neutron::server::notifications::nova':
      auth_url    => $keystone_admin_uri,
      username => $nova_user,
      password    => $pass_nova_authtoken,
      region_name => $region_name,
    }
  }

  if($openstack_release == 'rocky' or $openstack_release == 'stein' or $openstack_release == 'train' or $openstack_release == 'ussuri' or $openstack_release == 'victoria' or $openstack_release == 'wallaby' or $openstack_release == 'xena' or $openstack_release == 'yoga' or $openstack_release == 'zed' or $openstack_release == 'antelope'){
    class { '::neutron::client': }
  }
  class { '::neutron::keystone::authtoken':
    username             => $neutron_user,
    password             => $pass_neutron_authtoken,
    auth_url             => $keystone_admin_uri,
    www_authenticate_uri => $keystone_auth_uri,
    cafile               => $api_endpoint_ca_file,
  }
  if($openstack_release == 'rocky' or $openstack_release == 'stein' or $openstack_release == 'train' or $openstack_release == 'ussuri' or $openstack_release == 'victoria' or $openstack_release == 'wallaby' or $openstack_release == 'xena' or $openstack_release == 'yoga' or $openstack_release == 'zed' or $openstack_release == 'antelope' or $openstack_release == 'bobcat'){
    class { '::neutron::agents::ml2::ovs':
      local_ip                   => $vmnet_ip,
      tunnel_types               => ['vxlan'],
      bridge_uplinks             => ['eth0'],
      bridge_mappings            => $bridge_mapping_list,
      extensions                 => 'qos',
      l2_population              => true,
      arp_responder              => true,
      firewall_driver            => 'iptables_hybrid',
      drop_flows_on_start        => false,
      enable_distributed_routing => $enable_distributed_routing,
      manage_vswitch             => false,
    }
  # Caracal and up
  } else {
    class { '::neutron::agents::ml2::ovs':
      local_ip                   => $vmnet_ip,
      tunnel_types               => ['vxlan'],
      bridge_uplinks             => ['eth0'],
      bridge_mappings            => $bridge_mapping_list,
      extensions                 => 'qos',
      l2_population              => true,
      arp_responder              => true,
      firewall_driver            => 'openvswitch',
      drop_flows_on_start        => false,
      enable_distributed_routing => $enable_distributed_routing,
      manage_vswitch             => false,
    }
  }
  if($openstack_release == 'rocky' or $openstack_release == 'stein' or $openstack_release == 'train' or $openstack_release == 'ussuri' or $openstack_release == 'victoria' or $openstack_release == 'wallaby' or $openstack_release == 'xena' or $openstack_release == 'yoga' or $openstack_release == 'zed' or $openstack_release == 'antelope' or $openstack_release == 'bobcat' or $openstack_release == 'caracal'){
    class { '::neutron::agents::l3':
      interface_driver      => 'openvswitch',
      debug                 => true,
      agent_mode            => $l3_agent_mode,
      ha_enabled            => false,
      extensions            => 'port_forwarding,fip_qos,gateway_ip_qos',
      ha_vrrp_auth_type     => 'PASS',
      ha_vrrp_auth_password => $pass_neutron_vrrpauth,
      ha_vrrp_advert_int    => '3',
      manage_service        => false,
      availability_zone     => $availability_zone,
    }
    ~>systemd::unit_file { 'keepalived.service':
      enable => 'mask',
      active => false,
    }
  # At Dalmatian, ha_enabled is deprecated, and for Flamingo and up, it's removed.
  }else{
    class { '::neutron::agents::l3':
      interface_driver      => 'openvswitch',
      debug                 => true,
      agent_mode            => $l3_agent_mode,
      extensions            => 'port_forwarding,fip_qos,gateway_ip_qos',
      ha_vrrp_auth_type     => 'PASS',
      ha_vrrp_auth_password => $pass_neutron_vrrpauth,
      ha_vrrp_advert_int    => '3',
      manage_service        => false,
      availability_zone     => $availability_zone,
    }
    ~>systemd::unit_file { 'keepalived.service':
      enable => 'mask',
      active => false,
    }
  }
  neutron_l3_agent_config {
    'DEFAULT/external_network_bridge': value => '';
  }

  if $has_subrole_designate {
    $extension_drivers = 'port_security,qos,dns,dns_domain_ports'
  }else{
    $extension_drivers = 'port_security,qos'
  }

  if($openstack_release == 'rocky' or $openstack_release == 'stein' or $openstack_release == 'train' or $openstack_release == 'ussuri'){
    class { '::neutron::plugins::ml2':
      type_drivers         => ['flat', 'vxlan', 'vlan', ],
      tenant_network_types => ['flat', 'vxlan', 'vlan', ],
      extension_drivers    => $extension_drivers,
      mechanism_drivers    => 'openvswitch,l2population',
      firewall_driver      => 'iptables_v2',
      flat_networks        => $external_network_list,
      network_vlan_ranges  => $external_network_list,
      vni_ranges           => "${neutron_vxlan_vni_min}:${neutron_vxlan_vni_max}",
      path_mtu             => $neutron_path_mtu,
    }
  }else{
    class { '::neutron::plugins::ml2':
      type_drivers         => ['flat', 'vxlan', 'vlan', ],
      tenant_network_types => ['flat', 'vxlan', 'vlan', ],
      extension_drivers    => $extension_drivers,
      mechanism_drivers    => 'openvswitch,l2population',
      flat_networks        => $external_network_list,
      network_vlan_ranges  => $external_network_list,
      vni_ranges           => "${neutron_vxlan_vni_min}:${neutron_vxlan_vni_max}",
      path_mtu             => $neutron_path_mtu,
    }
  }
  class { '::neutron::agents::dhcp':
    interface_driver         => 'openvswitch',
    debug                    => true,
    enable_isolated_metadata => true,
    enable_metadata_network  => true,
    availability_zone        => $availability_zone,
    dnsmasq_dns_servers      => split($neutron_dnsmasq_dns_servers, ';'),
  }
#  class { '::neutron::agents::metering':
#    interface_driver => 'openvswitch',
#    debug            => true,
#  }
  package { 'l2gw networking':
    name => 'python3-networking-l2gw',
    ensure => installed,
  }

  class { '::neutron::agents::metadata':
    debug             => true,
    shared_secret     => $pass_metadata_proxy_shared_secret,
    metadata_workers  => 2,
    metadata_protocol => 'http',
    metadata_host     => 'localhost',
  }

  class { 'haproxy':
    restart_command => 'systemctl reload haproxy',
    global_options   => {
      'log'      => '/dev/log local0',
      'maxconn'  => '256',
      'user'     => 'haproxy',
      'group'    => 'haproxy',
      'stats'   => [
        'socket /var/lib/haproxy/stats',
        'socket /var/lib/haproxy/admin.sock mode 600 level admin',
        'timeout 30s'
      ],
      'daemon'   => '',
      'nbthread' => '8',
    },
    defaults_options => {
      'mode'    => 'http',
      'option'    => [
        'httplog',
      ],
    },
    merge_options => true,
  }->
  haproxy::listen { 'hapstats':
    section_name => 'statshttp',
    bind         => { "${machine_ip}:8088" => 'user root'},
    mode         => 'http',
    options      => {
        'stats' => [ 'uri /', "auth admin:${pass_haproxy_stats}", 'refresh 15', 'admin if TRUE', 'realm Haproxy Statistics', ],
      },
  }

  $haproxy_options_for_metadata_proxy = [
    { 'use_backend' => 'metadatabe' },
  ]
  haproxy::frontend { 'openstackfe':
    mode      => 'http',
    bind      => { "127.0.0.1:8775" => [] },
    options   => $haproxy_options_for_metadata_proxy,
  }
  haproxy::backend { 'metadatabe':
    options => [
      { 'option' => 'forwardfor' },
      { 'option' => 'httpchk GET /healthcheck' },
      { 'mode' => 'http' },
      { 'balance' => 'roundrobin' },
    ],
  }
  if $openstack_release == 'rocky'{
    $metadatabm_options = 'check'
  }else{
    $metadatabm_options = 'check check-ssl ssl verify required ca-file /etc/ssl/certs/oci-pki-oci-ca-chain.pem'
  }
  haproxy::balancermember { 'metadatabm':
    listening_service => 'metadatabe',
    ipaddresses       => $all_masters_ip,
    server_names      => $all_masters,
    ports             => 8775,
    options           => $metadatabm_options
  }

  if $has_subrole_designate {
    class { '::neutron::designate':
      url                 => "${base_url_designate}/",
      username            => 'admin',
      project_domain_name => 'admin',
      password            => $pass_keystone_adminuser,
      auth_url            => "${base_url_keystone}/v3/",
      ptr_zone_email      => $designate_zone_admin_email,
    }
  }

  if $neutron_install_dragent {
    class { '::neutron::agents::bgp_dragent':
      bgp_router_id => $machine_ip,
    }
  }else{
    package { 'neutron dynamic routing':
      name   => 'neutron-bgp-dragent',
      ensure => purged,
    }
    if $use_dynamic_routing {
      package { 'neutron-dynamic-routing-common':
        name   => 'neutron-dynamic-routing-common',
        ensure => present,
      }
    }else{
      package { 'python3-neutron-dynamic-routing':
        name   => 'python3-neutron-dynamic-routing',
        ensure => purged,
      }
    }
  }

  logrotate::rule { 'conntrackd':
    path          => '/var/log/conntrackd-stats.log',
    rotate        => '2',
    rotate_every  => 'day',
    missingok     => true,
    copytruncate  => true,
    require       => Class['::neutron'],
  }

  logrotate::rule { 'neutron-common':
    path          => '/var/log/neutron/*.log',
    rotate_every  => $logrotate_period,
    missingok     => true,
    compress      => true,
    delaycompress => true,
    ifempty       => false,
    copytruncate  => true,
    rotate        => '4',
  }

  ############################
  ### OpenVSwitch defaults ###
  ############################
  file { '/etc/default/openvswitch-switch':
    content => '# Managed by Puppet
OVS_CTL_OPTS="--delete-bridges"',
  }

  file { '/etc/rsyslog.d/30-neutron-l3-keepalived.conf':
    ensure  => present,
    source  => "puppet:///modules/oci/rsyslog/30-neutron-l3-keepalived.conf",
    require => [Package['rsyslog']],
    notify  => Service['rsyslog'],
  }
}
