Adds SSL custom type/provider

New type for configuring SSL in OVS.  Bootstrap mode allows the switch
to accept an initial CA certificate offered by the controller.
Otherwise specify the location of the CA certificate to use in comparing
the controller's cert.  OVS only supports a single instance of SSL
configuration so the provider limits the resource declaration to a
single instance named 'system'.

Partially-Implements: blueprint opendaylight-ssl-support

Change-Id: Ic026ee0bc4f385e0f8cd7076b3044feeb935ae45
Signed-off-by: Tim Rozet <trozet@redhat.com>
This commit is contained in:
Tim Rozet 2018-01-02 17:15:14 -05:00
parent 8a49f0963a
commit 6e3d77e9e4
5 changed files with 224 additions and 0 deletions

View File

@ -0,0 +1,100 @@
Puppet::Type.type(:vs_ssl).provide(:ovs) do
commands :vsctl => 'ovs-vsctl'
bootstrap_ca_cert = '/etc/openvswitch/cacert.pem'
def singleton_check
if not @resource[:name].eql? 'system'
raise Puppet::Error, "OVS ssl provider only supports singleton instance with name 'system'"
end
end
def parse_ssl_output(filter=false)
output = vsctl('get=ssl').split("\n")
if output.empty?
return false
end
if filter == false
return output
end
output.each do |line|
key, value = line.split(': ').map(&:strip)
if key.eql? filter
return value
end
end
raise Puppet::Error, "Unable to parse ssl output for filter: #{filter} in ssl output: #{output}"
end
def create
singleton_check
unless File.file?(@resource[:key_file])
raise Puppet::Error, "Key file not found: #{@resource[:key_file]}"
end
unless File.file?(@resource[:cert_file])
raise Puppet::Error, "Certificate file not found: #{@resource[:cert_file]}"
end
if @resource[:bootstrap]
vsctl('--', '--bootstrap', 'set-ssl', @resource[:key_file], @resource[:cert_file], bootstrap_ca_cert)
else
unless File.file?(@resource[:ca_file])
raise Puppet::Error, "CA Certificate file not found: #{@resource[:ca_file]}"
end
vsctl('--', 'set-ssl', @resource[:key_file], @resource[:cert_file], @resource[:ca_file])
end
end
def destroy
vsctl('del-ssl')
end
def exists?
singleton_check
output = vsctl('get-ssl')
if output.empty?
return false
else
return true
end
end
def key_file
return parse_ssl_output('Private key')
end
def key_file=(key_file)
destroy
create
end
def cert_file
return parse_ssl_output('Certificate')
end
def cert_file=(cert_file)
destroy
create
end
def ca_file
return parse_ssl_output('CA Certificate')
end
def ca_file=(ca_file)
destroy
create
end
def bootstrap
return parse_ssl_output('Bootstrap')
end
def bootstrap=(bootstrap)
destroy
create
end
end

43
lib/puppet/type/vs_ssl.rb Normal file
View File

@ -0,0 +1,43 @@
Puppet::Type.newtype(:vs_ssl) do
ensurable
newparam(:name, :namevar => true) do
desc "Name of SSL configuration"
newvalues(/^\w+$/)
end
newparam(:key_file) do
desc "Private key file path"
validate do |value|
if !value.is_a?(String)
raise ArgumentError, "Key file path must be a string"
end
end
end
newparam(:cert_file) do
desc "Certificate filepath"
validate do |value|
if !value.is_a?(String)
raise ArgumentError, "Certificate file path must be a string"
end
end
end
newparam(:ca_file) do
desc "CA authority certificate file path"
validate do |value|
if value
if !value.is_a?(String)
raise ArgumentError, "CA cert file path must be a string"
end
end
end
end
newparam(:bootstrap, :boolean => true) do
desc "Enable bootstrapping without CA certificate and accept controller CA cert"
defaultto false
end
end

View File

@ -0,0 +1,5 @@
---
features:
- |
Adds new custom type for configuring SSL (keys and certificates) within
vswitch. Includes single provider for Open vSwitch.

View File

@ -0,0 +1,55 @@
require 'spec_helper'
describe Puppet::Type.type(:vs_ssl).provider(:ovs) do
let :ssl_attrs do
{
:name => 'system',
:ensure => 'present',
}
end
let :resource do
Puppet::Type::Vs_ssl.new(ssl_attrs)
end
let :provider do
described_class.new(resource)
end
context 'when changing cert_file' do
it 'should recreate ssl config' do
File.stubs(:file?).returns(true)
provider.expects(:destroy)
provider.expects(:create)
provider.cert_file = '/tmp/blah.crt'
end
end
context 'when changing key_file' do
it 'should recreate ssl config' do
File.stubs(:file?).returns(true)
provider.expects(:destroy)
provider.expects(:create)
provider.key_file = '/tmp/blah.pem'
end
end
context 'when changing ca_file' do
it 'should recreate ssl config' do
File.stubs(:file?).returns(true)
provider.expects(:destroy)
provider.expects(:create)
provider.ca_file = '/tmp/blah.crt'
end
end
context 'when creating with non-singleton name, system' do
it 'should fail' do
expect{described_class.new(Puppet::Type::Vs_ssl.new(
{
:name => 'dummy',
:ensure => :present})).create}.to raise_error(Puppet::Error)
end
end
end

View File

@ -0,0 +1,21 @@
require 'spec_helper'
describe Puppet::Type.type(:vs_ssl) do
it "should support present as a value for ensure" do
expect do
described_class.new(:name => 'system', :ensure => :present)
end.to_not raise_error
end
it "should accept key_file, cert_file, ca_file, bootstrap options" do
expect do
described_class.new({
:name => 'system',
:ensure => :present,
:key_file => '/tmp/dummyfile.pem',
:cert_file => '/tmp/dummyfile.crt',
:ca_file => '/tmp/dummyca.crt',
:bootstrap => false})
end.to_not raise_error
end
end