diff --git a/lib/puppet/parser/functions/check_array_of_hash.rb b/lib/puppet/parser/functions/check_array_of_hash.rb new file mode 100644 index 000000000..be75db296 --- /dev/null +++ b/lib/puppet/parser/functions/check_array_of_hash.rb @@ -0,0 +1,27 @@ +require 'json' + +def array_of_hash?(list) + return false unless !list.empty? && list.class == Array + list.each do |e| + return false unless e.class == Hash + end + true +end + +module Puppet::Parser::Functions + newfunction(:check_array_of_hash, :arity =>1, :type => :rvalue, :doc => "Check + input String is a valid Array of Hash in JSON style") do |arg| + if arg[0].class == String + begin + list = JSON.load(arg[0].gsub("'","\"")) + rescue JSON::ParserError + raise Puppet::ParseError, "Syntax error: #{arg[0]} is invalid" + else + return arg[0] if array_of_hash?(list) + end + else + raise Puppet::ParseError, "Syntax error: #{arg[0]} is not a String" + end + return '' + end +end diff --git a/manifests/api.pp b/manifests/api.pp index abdf7f0d8..da5d2bc68 100644 --- a/manifests/api.pp +++ b/manifests/api.pp @@ -102,6 +102,12 @@ # (optional) Shared secret to validate proxies Neutron metadata requests # Defaults to undef # +# [*pci_alias*] +# (optional) Pci passthrough for controller: +# Defaults to undef +# Example +# "[ {'vendor_id':'1234', 'product_id':'5678', 'name':'default'}, {...} ]" +# # [*ratelimits*] # (optional) A string that is a semicolon-separated list of 5-tuples. # See http://docs.openstack.org/trunk/config-reference/content/configuring-compute-API.html @@ -161,6 +167,7 @@ class nova::api( $sync_db = true, $neutron_metadata_proxy_shared_secret = undef, $osapi_v3 = false, + $pci_alias = undef, $ratelimits = undef, $ratelimits_factory = 'nova.api.openstack.compute.limits:RateLimitingMiddleware.factory', @@ -319,6 +326,12 @@ class nova::api( 'filter:authtoken/auth_admin_prefix': ensure => absent; } + if $pci_alias { + nova_config { + 'DEFAULT/pci_alias': value => check_array_of_hash($pci_alias); + } + } + if $validate { $defaults = { 'nova-api' => { @@ -328,5 +341,4 @@ class nova::api( $validation_options_hash = merge ($defaults, $validation_options) create_resources('openstacklib::service_validation', $validation_options_hash, {'subscribe' => 'Service[nova-api]'}) } - } diff --git a/manifests/compute.pp b/manifests/compute.pp index 9870561b6..e15809a5c 100644 --- a/manifests/compute.pp +++ b/manifests/compute.pp @@ -99,6 +99,13 @@ # (optional) The availability zone to show internal services under. # Defaults to internal # +# [*pci_passthrough_whitelist*] +# (optional) Pci passthrough hash in format of: +# Defaults to undef +# Example +# "[ { 'vendor_id':'1234','product_id':'5678' }, +# { 'vendor_id':'4321','product_id':'8765','physical_network':'default' } ] " +# class nova::compute ( $enabled = false, $manage_service = true, @@ -123,6 +130,7 @@ class nova::compute ( $default_schedule_zone = undef, $internal_service_availability_zone = 'internal', $heal_instance_info_cache_interval = '60', + $pci_passthrough = undef, ) { include nova::params @@ -218,4 +226,9 @@ class nova::compute ( } } + if ($pci_passthrough) { + nova_config { + 'DEFAULT/pci_passthrough_whitelist': value => check_array_of_hash($pci_passthrough); + } + } } diff --git a/spec/classes/nova_api_spec.rb b/spec/classes/nova_api_spec.rb index 0486fd6f3..ab76d995c 100644 --- a/spec/classes/nova_api_spec.rb +++ b/spec/classes/nova_api_spec.rb @@ -99,6 +99,7 @@ describe 'nova::api' do :metadata_workers => 2, :osapi_v3 => true, :keystone_ec2_url => 'https://example.com:5000/v2.0/ec2tokens', + :pci_alias => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\",\"name\":\"graphic_card\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"name\":\"network_card\"}]" }) end @@ -155,6 +156,12 @@ describe 'nova::api' do it 'configure nova api v3' do should contain_nova_config('osapi_v3/enabled').with('value' => true) end + + it 'configures nova pci_alias entries' do + should contain_nova_config('DEFAULT/pci_alias').with( + 'value' => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\",\"name\":\"graphic_card\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"name\":\"network_card\"}]" + ) + end end [ diff --git a/spec/classes/nova_compute_spec.rb b/spec/classes/nova_compute_spec.rb index 84bf130c9..0659e87ab 100644 --- a/spec/classes/nova_compute_spec.rb +++ b/spec/classes/nova_compute_spec.rb @@ -58,6 +58,7 @@ describe 'nova::compute' do :default_schedule_zone => 'az2', :internal_service_availability_zone => 'az_int1', :heal_instance_info_cache_interval => '120', + :pci_passthrough => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"physical_network\":\"physnet1\"}]" } end @@ -101,6 +102,12 @@ describe 'nova::compute' do it { should contain_nova_config('DEFAULT/heal_instance_info_cache_interval').with_value('120') } it { should contain_nova_config('DEFAULT/force_raw_images').with(:value => false) } + + it 'configures nova pci_passthrough_whitelist entries' do + should contain_nova_config('DEFAULT/pci_passthrough_whitelist').with( + 'value' => "[{\"vendor_id\":\"8086\",\"product_id\":\"0126\"},{\"vendor_id\":\"9096\",\"product_id\":\"1520\",\"physical_network\":\"physnet1\"}]" + ) + end end context 'with neutron_enabled set to false' do