From 97e758182bf69a616db216a43636d96f2c776770 Mon Sep 17 00:00:00 2001 From: Tim Rozet Date: Sun, 22 Mar 2015 11:39:03 -0400 Subject: [PATCH] JIRA: BGS-23 - Adds the new base for common puppet modules for target OPNFV installation. Intent of this commit is to be a common place where we can contain a common set of puppet modules that installers should leverage when installing/configuring OPNFV target system. Change-Id: I3a694b05a35a6e6025489b74c7bb38256dd84f12 Signed-off-by: Tim Rozet --- common/puppet-opnfv/manifests/compute.pp | 103 ++++++++++++++ common/puppet-opnfv/manifests/controller.pp | 135 +++++++++++++++++++ .../puppet-opnfv/manifests/controller_networker.pp | 150 +++++++++++++++++++++ common/puppet-opnfv/manifests/init.pp | 30 +++++ common/puppet-opnfv/manifests/network.pp | 77 +++++++++++ common/puppet-opnfv/manifests/repo.pp | 36 +++++ common/puppet-opnfv/manifests/tempest.pp | 27 ++++ 7 files changed, 558 insertions(+) create mode 100644 common/puppet-opnfv/manifests/compute.pp create mode 100644 common/puppet-opnfv/manifests/controller.pp create mode 100644 common/puppet-opnfv/manifests/controller_networker.pp create mode 100644 common/puppet-opnfv/manifests/init.pp create mode 100644 common/puppet-opnfv/manifests/network.pp create mode 100644 common/puppet-opnfv/manifests/repo.pp create mode 100644 common/puppet-opnfv/manifests/tempest.pp diff --git a/common/puppet-opnfv/manifests/compute.pp b/common/puppet-opnfv/manifests/compute.pp new file mode 100644 index 0000000..fdef9c7 --- /dev/null +++ b/common/puppet-opnfv/manifests/compute.pp @@ -0,0 +1,103 @@ +#Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# +# 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. + +class opnfv::compute { + if ($odl_flag != '') and str2bool($odl_flag) { + $ml2_mech_drivers = ['opendaylight'] + $this_agent = 'opendaylight' + } + else { + $ml2_mech_drivers = ['openvswitch','l2population'] + $this_agent = 'ovs' + } + + if $ovs_tunnel_if == '' { fail('ovs_tunnel_if is empty') } + if $private_ip == '' { fail('private_ip is empty') } + if $odl_control_ip == '' { $odl_control_ip = $private_ip } + + if $mysql_ip == '' { fail('mysql_ip is empty') } + if $amqp_ip == '' { fail('mysql_ip is empty') } + + if $admin_password == '' { fail('admin_password is empty') } + + if $nova_user_password == '' { fail('nova_user_password is empty') } + if $nova_db_password == '' { fail('nova_db_password is empty') } + + if $neutron_user_password == '' { fail('nova_user_password is empty') } + if $neutron_db_password == '' { fail('nova_db_password is empty') } + + if $ceilometer_user_password == '' { fail('ceilometer_user_password is empty') } + if $ceilometer_metering_secret == '' { fail('ceilometer_user_password is empty') } + + class { "quickstack::neutron::compute": + auth_host => $private_ip, + glance_host => $private_ip, + libvirt_images_rbd_pool => 'volumes', + libvirt_images_rbd_ceph_conf => '/etc/ceph/ceph.conf', + libvirt_inject_password => 'false', + libvirt_inject_key => 'false', + libvirt_images_type => 'rbd', + nova_host => $private_ip, + nova_db_password => $nova_db_password, + nova_user_password => $nova_user_password, + private_network => '', + private_iface => '', + private_ip => '', + rbd_user => 'volumes', + rbd_secret_uuid => '', + network_device_mtu => $quickstack::params::network_device_mtu, + + admin_password => $admin_password, + ssl => false, + + mysql_host => $mysql_ip, + mysql_ca => $quickstack::params::mysql_ca, + amqp_host => $amqp_ip, + amqp_username => 'guest', + amqp_password => 'guest', + #amqp_nssdb_password => $quickstack::params::amqp_nssdb_password, + + ceilometer => 'true', + ceilometer_metering_secret => $ceilometer_metering_secret, + ceilometer_user_password => $ceilometer_user_password, + + cinder_backend_gluster => $quickstack::params::cinder_backend_gluster, + + agent_type => $this_agent, + enable_tunneling => true, + + ml2_mechanism_drivers => $ml2_mech_drivers, + odl_controller_ip => $odl_control_ip, + + neutron_db_password => $neutron_db_password, + neutron_user_password => $neutron_user_password, + neutron_host => $private_ip, + + #ovs_bridge_mappings = $quickstack::params::ovs_bridge_mappings, + #ovs_bridge_uplinks = $quickstack::params::ovs_bridge_uplinks, + #ovs_vlan_ranges = $quickstack::params::ovs_vlan_ranges, + ovs_tunnel_iface => $ovs_tunnel_if, + ovs_tunnel_network => '', + ovs_l2_population => 'True', + + tenant_network_type => 'vxlan', + tunnel_id_ranges => '1:1000', + #ovs_vxlan_udp_port = $quickstack::params::ovs_vxlan_udp_port, + ovs_tunnel_types => ['vxlan'], + + verbose => $quickstack::params::verbose, + security_group_api => 'neutron', + + } +} diff --git a/common/puppet-opnfv/manifests/controller.pp b/common/puppet-opnfv/manifests/controller.pp new file mode 100644 index 0000000..97b0181 --- /dev/null +++ b/common/puppet-opnfv/manifests/controller.pp @@ -0,0 +1,135 @@ +#Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# +# 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. + + +class opnfv::controller { + ###use 8081 as a default work around swift service + if $odl_rest_port == '' {$odl_rest_port = '8081'} + + if ($odl_flag != '') and str2bool($odl_flag) { + $ml2_mech_drivers = ['opendaylight'] + } + else { + $ml2_mech_drivers = ['openvswitch','l2population'] + } + + + if $admin_email == '' { fail('admin_email is empty') } + if $admin_password == '' { fail('admin_password is empty') } + + if $public_ip == '' { fail('public_ip is empty') } + if $private_ip == '' { fail('private_ip is empty') } + + if $odl_control_ip == '' { fail('odl_controL_ip is empty, should be the IP of your network node private interface') } + + if $mysql_ip == '' { fail('mysql_ip is empty') } + if $mysql_root_password == '' { fail('mysql_root_password is empty') } + if $amqp_ip == '' { fail('amqp_ip is empty') } + + if $memcache_ip == '' { fail('memcache_ip is empty') } + if $neutron_ip == '' { fail('neutron_ip is empty') } + + if $keystone_admin_token == '' { fail('keystone_admin_token is empty') } + if $keystone_db_password == '' { fail('keystone_db_password is empty') } + + if $horizon_secret_key == '' { fail('horizon_secret_key is empty') } + #if $trystack_db_password == '' { fail('trystack_db_password is empty') } + + if $nova_user_password == '' { fail('nova_user_password is empty') } + if $nova_db_password == '' { fail('nova_db_password is empty') } + + if $cinder_user_password == '' { fail('cinder_user_password is empty') } + if $cinder_db_password == '' { fail('cinder_db_password is empty') } + + if $glance_user_password == '' { fail('glance_user_password is empty') } + if $glance_db_password == '' { fail('glance_db_password is empty') } + + if $neutron_user_password == '' { fail('neutron_user_password is empty') } + if $neutron_db_password == '' { fail('neutron_db_password is empty') } + if $neutron_metadata_shared_secret == '' { fail('neutron_metadata_shared_secret is empty') } + + if $ceilometer_user_password == '' { fail('ceilometer_user_password is empty') } + if $ceilometer_metering_secret == '' { fail('ceilometer_user_password is empty') } + + if $heat_user_password == '' { fail('heat_user_password is empty') } + if $heat_db_password == '' { fail('heat_db_password is empty') } + if $heat_auth_encrypt_key == '' { fail('heat_auth_encrypt_key is empty') } + + if $swift_user_password == '' { fail('swift_user_password is empty') } + if $swift_shared_secret == '' { fail('swift_shared_secret is empty') } + if $swift_admin_password == '' { fail('swift_admin_password is empty') } + + class { "quickstack::neutron::controller": + admin_email => $admin_email, + admin_password => $admin_password, + controller_admin_host => $private_ip, + controller_priv_host => $private_ip, + controller_pub_host => $public_ip, + ssl => false, + #support_profile => $quickstack::params::support_profile, + #freeipa => $quickstack::params::freeipa, + + mysql_host => $mysql_ip, + mysql_root_password => $mysql_root_password, + #amqp_provider => $amqp_provider, + amqp_host => $amqp_ip, + amqp_username => 'guest', + amqp_password => 'guest', + #amqp_nssdb_password => $quickstack::params::amqp_nssdb_password, + + keystone_admin_token => $keystone_admin_token, + keystone_db_password => $keystone_db_password, + + ceilometer_metering_secret => $ceilometer_metering_secret, + ceilometer_user_password => $ceilometer_user_password, + + cinder_backend_gluster => $quickstack::params::cinder_backend_gluster, + cinder_backend_gluster_name => $quickstack::params::cinder_backend_gluster_name, + cinder_gluster_shares => $quickstack::params::cinder_gluster_shares, + cinder_user_password => $cinder_user_password, + cinder_db_password => $cinder_db_password, + + glance_db_password => $glance_db_password, + glance_user_password => $glance_user_password, + + heat_cfn => true, + heat_cloudwatch => true, + heat_db_password => $heat_db_password, + heat_user_password => $heat_user_password, + heat_auth_encrypt_key => $heat_auth_encrypt_key, + + horizon_secret_key => $horizon_secret_key, + horizon_ca => $quickstack::params::horizon_ca, + horizon_cert => $quickstack::params::horizon_cert, + horizon_key => $quickstack::params::horizon_key, + + ml2_mechanism_drivers => $ml2_mech_drivers, + #neutron => true, + neutron_metadata_proxy_secret => $neutron_metadata_shared_secret, + neutron_db_password => $neutron_db_password, + neutron_user_password => $neutron_user_password, + + nova_db_password => $nova_db_password, + nova_user_password => $nova_user_password, + odl_controller_ip => $odl_control_ip, + odl_controller_port => $odl_rest_port, + + swift_shared_secret => $swift_shared_secret, + swift_admin_password => $swift_admin_password, + swift_ringserver_ip => '192.168.203.1', + swift_storage_ips => ["192.168.203.2","192.168.203.3","192.168.203.4"], + swift_storage_device => 'device1', + } + +} diff --git a/common/puppet-opnfv/manifests/controller_networker.pp b/common/puppet-opnfv/manifests/controller_networker.pp new file mode 100644 index 0000000..1c65779 --- /dev/null +++ b/common/puppet-opnfv/manifests/controller_networker.pp @@ -0,0 +1,150 @@ +#Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# +# 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. + + +class opnfv::controller_networker { + ###use 8081 as a default work around swift service + if $odl_rest_port == '' {$odl_rest_port = '8081'} + + if ($odl_flag != '') and str2bool($odl_flag) { + $ml2_mech_drivers = ['opendaylight'] + $this_agent = 'opendaylight' + class {"opendaylight": + odl_rest_port => $odl_rest_port, + extra_features => ['odl-base-all', 'odl-aaa-authn', 'odl-restconf', 'odl-nsf-all', 'odl-adsal-northbound', 'odl-mdsal-apidocs', 'odl-ovsdb-openstack', 'odl-ovsdb-northbound', 'odl-dlux-core'], + } + } + else { + $ml2_mech_drivers = ['openvswitch','l2population'] + $this_agent = 'ovs' + } + if $ovs_tunnel_if == '' { fail('ovs_tunnel_if is empty') } + if $admin_email == '' { fail('admin_email is empty') } + if $admin_password == '' { fail('admin_password is empty') } + + if $public_ip == '' { fail('public_ip is empty') } + if $private_ip == '' { fail('private_ip is empty') } + + if $odl_control_ip == '' { $odl_control_ip = $private_ip } + + if $mysql_ip == '' { fail('mysql_ip is empty') } + if $mysql_root_password == '' { fail('mysql_root_password is empty') } + if $amqp_ip == '' { fail('amqp_ip is empty') } + + if $memcache_ip == '' { fail('memcache_ip is empty') } + if $neutron_ip == '' { fail('neutron_ip is empty') } + + if $keystone_admin_token == '' { fail('keystone_admin_token is empty') } + if $keystone_db_password == '' { fail('keystone_db_password is empty') } + + if $horizon_secret_key == '' { fail('horizon_secret_key is empty') } + #if $trystack_db_password == '' { fail('trystack_db_password is empty') } + + if $nova_user_password == '' { fail('nova_user_password is empty') } + if $nova_db_password == '' { fail('nova_db_password is empty') } + + if $cinder_user_password == '' { fail('cinder_user_password is empty') } + if $cinder_db_password == '' { fail('cinder_db_password is empty') } + + if $glance_user_password == '' { fail('glance_user_password is empty') } + if $glance_db_password == '' { fail('glance_db_password is empty') } + + if $neutron_user_password == '' { fail('neutron_user_password is empty') } + if $neutron_db_password == '' { fail('neutron_db_password is empty') } + if $neutron_metadata_shared_secret == '' { fail('neutron_metadata_shared_secret is empty') } + + if $ceilometer_user_password == '' { fail('ceilometer_user_password is empty') } + if $ceilometer_metering_secret == '' { fail('ceilometer_user_password is empty') } + + if $heat_user_password == '' { fail('heat_user_password is empty') } + if $heat_db_password == '' { fail('heat_db_password is empty') } + if $heat_auth_encrypt_key == '' { fail('heat_auth_encrypt_key is empty') } + + if $swift_user_password == '' { fail('swift_user_password is empty') } + if $swift_shared_secret == '' { fail('swift_shared_secret is empty') } + if $swift_admin_password == '' { fail('swift_admin_password is empty') } + + class { "quickstack::neutron::controller_networker": + admin_email => $admin_email, + admin_password => $admin_password, + agent_type => $this_agent, + enable_tunneling => true, + ovs_tunnel_iface => $ovs_tunnel_if, + ovs_tunnel_network => '', + ovs_tunnel_types => ['vxlan'], + ovs_l2_population => 'True', + external_network_bridge => 'br-ex', + tenant_network_type => 'vxlan', + tunnel_id_ranges => '1:1000', + controller_admin_host => $private_ip, + controller_priv_host => $private_ip, + controller_pub_host => $public_ip, + ssl => false, + #support_profile => $quickstack::params::support_profile, + #freeipa => $quickstack::params::freeipa, + + mysql_host => $mysql_ip, + mysql_root_password => $mysql_root_password, + #amqp_provider => $amqp_provider, + amqp_host => $amqp_ip, + amqp_username => 'guest', + amqp_password => 'guest', + #amqp_nssdb_password => $quickstack::params::amqp_nssdb_password, + + keystone_admin_token => $keystone_admin_token, + keystone_db_password => $keystone_db_password, + + ceilometer_metering_secret => $ceilometer_metering_secret, + ceilometer_user_password => $ceilometer_user_password, + + cinder_backend_gluster => $quickstack::params::cinder_backend_gluster, + cinder_backend_gluster_name => $quickstack::params::cinder_backend_gluster_name, + cinder_gluster_shares => $quickstack::params::cinder_gluster_shares, + cinder_user_password => $cinder_user_password, + cinder_db_password => $cinder_db_password, + + glance_db_password => $glance_db_password, + glance_user_password => $glance_user_password, + + heat_cfn => true, + heat_cloudwatch => true, + heat_db_password => $heat_db_password, + heat_user_password => $heat_user_password, + heat_auth_encrypt_key => $heat_auth_encrypt_key, + + horizon_secret_key => $horizon_secret_key, + horizon_ca => $quickstack::params::horizon_ca, + horizon_cert => $quickstack::params::horizon_cert, + horizon_key => $quickstack::params::horizon_key, + + ml2_mechanism_drivers => $ml2_mech_drivers, + + #neutron => true, + neutron_metadata_proxy_secret => $neutron_metadata_shared_secret, + neutron_db_password => $neutron_db_password, + neutron_user_password => $neutron_user_password, + + nova_db_password => $nova_db_password, + nova_user_password => $nova_user_password, + + odl_controller_ip => $odl_control_ip, + odl_controller_port => $odl_rest_port, + swift_shared_secret => $swift_shared_secret, + swift_admin_password => $swift_admin_password, + swift_ringserver_ip => '192.168.203.1', + swift_storage_ips => ["192.168.203.2","192.168.203.3","192.168.203.4"], + swift_storage_device => 'device1', + } + +} diff --git a/common/puppet-opnfv/manifests/init.pp b/common/puppet-opnfv/manifests/init.pp new file mode 100644 index 0000000..f1b4576 --- /dev/null +++ b/common/puppet-opnfv/manifests/init.pp @@ -0,0 +1,30 @@ +#Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# +# 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. + + +class opnfv { + exec {'disable selinux': + command => '/usr/sbin/setenforce 0', + unless => '/usr/sbin/getenforce | grep Permissive', + } + include stdlib + stage { 'presetup': + before => Stage['setup'], + } + + class { "opnfv::repo": + stage => presetup, + } + +} diff --git a/common/puppet-opnfv/manifests/network.pp b/common/puppet-opnfv/manifests/network.pp new file mode 100644 index 0000000..91e7693 --- /dev/null +++ b/common/puppet-opnfv/manifests/network.pp @@ -0,0 +1,77 @@ +#Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# +# 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. + + +class opnfv::network { + ###use 8081 as a default work around swift service + if $odl_rest_port == '' {$odl_rest_port = '8081'} + + if ($odl_flag != '') and str2bool($odl_flag) { + $ml2_mech_drivers = ['opendaylight'] + $this_agent = 'opendaylight' + class {"opendaylight": + odl_rest_port => $odl_rest_port, + extra_features => ['odl-base-all', 'odl-aaa-authn', 'odl-restconf', 'odl-nsf-all', 'odl-adsal-northbound', 'odl-mdsal-apidocs', 'odl-ovsdb-openstack', 'odl-ovsdb-northbound', 'odl-dlux-core'], + } + } + else { + $ml2_mech_drivers = ['openvswitch','l2population'] + $this_agent = 'ovs' + } + + + + if $ovs_tunnel_if == '' { fail('ovs_tunnel_if is empty') } + if $private_ip == '' { fail('private_ip is empty') } + + if $odl_control_ip == '' { fail('odl_controL_ip is empty, should be the IP of your network node private interface') } + + if $mysql_ip == '' { fail('mysql_ip is empty') } + if $amqp_ip == '' { fail('amqp_ip is empty') } + + if $nova_user_password == '' { fail('nova_user_password is empty') } + if $nova_db_password == '' { fail('nova_db_password is empty') } + + if $neutron_user_password == '' { fail('neutron_user_password is empty') } + if $neutron_db_password == '' { fail('neutron_db_password is empty') } + if $neutron_metadata_shared_secret == '' { fail('neutron_metadata_shared_secret is empty') } + + class { "quickstack::neutron::networker": + agent_type => $this_agent, + neutron_metadata_proxy_secret => $neutron_metadata_shared_secret, + neutron_db_password => $neutron_db_password, + neutron_user_password => $neutron_user_password, + nova_db_password => $nova_db_password, + nova_user_password => $nova_user_password, + + controller_priv_host => $private_ip, + + enable_tunneling => true, + ovs_tunnel_iface => $ovs_tunnel_if, + ovs_tunnel_network => '', + ovs_l2_population => 'True', + ovs_tunnel_types => ['vxlan'], + external_network_bridge => 'br-ex', + tenant_network_type => 'vxlan', + tunnel_id_ranges => '1:1000', + + mysql_host => $mysql_ip, + amqp_host => $amqp_ip, + amqp_username => 'guest', + amqp_password => 'guest', + + ml2_mechanism_drivers => $ml2_mech_drivers, + odl_controller_ip => $odl_control_ip, + } +} diff --git a/common/puppet-opnfv/manifests/repo.pp b/common/puppet-opnfv/manifests/repo.pp new file mode 100644 index 0000000..b11098c --- /dev/null +++ b/common/puppet-opnfv/manifests/repo.pp @@ -0,0 +1,36 @@ +#Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# +# 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. + + +class opnfv::repo { + if $::osfamily == 'RedHat' { + if $proxy_address != '' { + $myline= "proxy=${proxy_address}" + include stdlib + file_line { 'yumProxy': + ensure => present, + path => '/etc/yum.conf', + line => $myline, + before => Yumrepo['openstack-juno'], + } + } + + yumrepo { "openstack-juno": + baseurl => "http://repos.fedorapeople.org/repos/openstack/openstack-juno/epel-7/", + descr => "RDO Community repository", + enabled => 1, + gpgcheck => 0, + } + } +} diff --git a/common/puppet-opnfv/manifests/tempest.pp b/common/puppet-opnfv/manifests/tempest.pp new file mode 100644 index 0000000..86f4212 --- /dev/null +++ b/common/puppet-opnfv/manifests/tempest.pp @@ -0,0 +1,27 @@ +#Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# +# 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. + + +#The required package for tempest is missing in Khaleesi along with EPEL for CentOS. +#This is a workaround for now since we require EPEL with Foreman/Puppet +#Also is a good place to put anything additional that we wish to install on the tempest node. + +class opnfv::tempest { + + if $::osfamily == 'RedHat' { + package { 'subunit-filters': + ensure => present, + } + } +} -- 2.16.6