Merge "Add quantum_router custom type."
This commit is contained in:
commit
cc253f6bd7
|
@ -3,6 +3,10 @@
|
|||
# resources necessary to boot a vm with network connectivity provided
|
||||
# by quantum.
|
||||
#
|
||||
# Note that a quantum_router resouce must declare a dependency on the
|
||||
# first subnet of the gateway network. Other dependencies for the
|
||||
# resources used in this example can be automatically determined.
|
||||
#
|
||||
|
||||
keystone_tenant { 'admin':
|
||||
ensure => present,
|
||||
|
@ -36,3 +40,11 @@ quantum_subnet { 'private_subnet':
|
|||
network_name => 'private',
|
||||
tenant_name => 'demo',
|
||||
}
|
||||
|
||||
# Tenant-private router - assumes network namespace isolation
|
||||
quantum_router { 'demo_router':
|
||||
ensure => present,
|
||||
tenant_name => 'demo',
|
||||
gateway_network_name => 'public',
|
||||
require => Quantum_subnet['public_subnet'],
|
||||
}
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
require File.join(File.dirname(__FILE__), '..','..','..',
|
||||
'puppet/provider/quantum')
|
||||
|
||||
Puppet::Type.type(:quantum_router).provide(
|
||||
:quantum,
|
||||
:parent => Puppet::Provider::Quantum
|
||||
) do
|
||||
desc <<-EOT
|
||||
Quantum provider to manage quantum_router type.
|
||||
|
||||
Assumes that the quantum service is configured on the same host.
|
||||
EOT
|
||||
|
||||
commands :quantum => 'quantum'
|
||||
|
||||
mk_resource_methods
|
||||
|
||||
def self.instances
|
||||
list_quantum_resources('router').collect do |id|
|
||||
attrs = get_quantum_resource_attrs('router', id)
|
||||
new(
|
||||
:ensure => :present,
|
||||
:name => attrs['name'],
|
||||
:id => attrs['id'],
|
||||
:admin_state_up => attrs['admin_state_up'],
|
||||
:external_gateway_info => attrs['external_gateway_info'],
|
||||
:status => attrs['status'],
|
||||
:tenant_id => attrs['tenant_id']
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
instances_ = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = instances_.find{ |instance| instance.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def exists?
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def create
|
||||
opts = Array.new
|
||||
|
||||
if @resource[:admin_state_up] == 'False'
|
||||
opts << '--admin-state-down'
|
||||
end
|
||||
|
||||
if @resource[:tenant_name]
|
||||
opts << "--tenant_id=#{get_tenant_id}"
|
||||
elsif @resource[:tenant_id]
|
||||
opts << "--tenant_id=#{@resource[:tenant_id]}"
|
||||
end
|
||||
|
||||
results = auth_quantum("router-create", '--format=shell',
|
||||
opts, resource[:name])
|
||||
|
||||
if results =~ /Created a new router:/
|
||||
@router = Hash.new
|
||||
results.split("\n").compact do |line|
|
||||
@router[line.split('=').first] = \
|
||||
line.split('=', 2)[1].gsub(/\A"|"\Z/, '')
|
||||
end
|
||||
|
||||
@property_hash = {
|
||||
:ensure => :present,
|
||||
:name => resource[:name],
|
||||
:id => @router[:id],
|
||||
:admin_state_up => @router[:admin_state_up],
|
||||
:external_gateway_info => @router[:external_gateway_info],
|
||||
:status => @router[:status],
|
||||
:tenant_id => @router[:tenant_id],
|
||||
}
|
||||
|
||||
if @resource[:gateway_network_name]
|
||||
results = auth_quantum('router-gateway-set',
|
||||
@resource[:name],
|
||||
@resource[:gateway_network_name])
|
||||
if results =~ /Set gateway for router/
|
||||
attrs = self.class.get_quantum_resource_attrs('router',
|
||||
@resource[:name])
|
||||
@property_hash[:external_gateway_info] = \
|
||||
attrs['external_gateway_info']
|
||||
else
|
||||
fail(<<-EOT
|
||||
did not get expected message on setting router gateway, got #{results}
|
||||
EOT
|
||||
)
|
||||
end
|
||||
end
|
||||
else
|
||||
fail("did not get expected message on router creation, got #{results}")
|
||||
end
|
||||
end
|
||||
|
||||
def get_tenant_id
|
||||
@tenant_id ||= model.catalog.resource( \
|
||||
"Keystone_tenant[#{resource[:tenant_name]}]").provider.id
|
||||
end
|
||||
|
||||
def destroy
|
||||
auth_quantum('router-delete', name)
|
||||
@property_hash[:ensure] = :absent
|
||||
end
|
||||
|
||||
def gateway_network_name
|
||||
if @gateway_network_name == nil and gateway_network_id
|
||||
Puppet::Type.type('quantum_network').instances.each do |instance|
|
||||
if instance.provider.id == gateway_network_id
|
||||
@gateway_network_name = instance.provider.name
|
||||
end
|
||||
end
|
||||
end
|
||||
@gateway_network_name
|
||||
end
|
||||
|
||||
def gateway_network_name=(value)
|
||||
if value == ''
|
||||
auth_quantum('router-gateway-clear', name)
|
||||
else
|
||||
auth_quantum('router-gateway-set', name, value)
|
||||
end
|
||||
end
|
||||
|
||||
def parse_gateway_network_id(external_gateway_info_)
|
||||
match_data = /\{"network_id": "(.*)"\}/.match(external_gateway_info_)
|
||||
if match_data
|
||||
match_data[1]
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
def gateway_network_id
|
||||
@gateway_network_id ||= parse_gateway_network_id(external_gateway_info)
|
||||
end
|
||||
|
||||
def admin_state_up=(value)
|
||||
auth_quantum('router-update', "--admin-state-up=#{value}", name)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,91 @@
|
|||
Puppet::Type.newtype(:quantum_router) do
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'Symbolic name for the router'
|
||||
newvalues(/.*/)
|
||||
end
|
||||
|
||||
newproperty(:id) do
|
||||
desc 'The unique id of the router'
|
||||
validate do |v|
|
||||
raise(Puppet::Error, 'This is a read only property')
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:admin_state_up) do
|
||||
desc 'The administrative status of the router'
|
||||
newvalues(/(t|T)rue/, /(f|F)alse/)
|
||||
munge do |v|
|
||||
v.to_s.capitalize
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:external_gateway_info) do
|
||||
desc <<-EOT
|
||||
External network that this router connects to for gateway services
|
||||
(e.g., NAT).
|
||||
EOT
|
||||
validate do |v|
|
||||
raise(Puppet::Error, 'This is a read only property')
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:gateway_network_name) do
|
||||
desc <<-EOT
|
||||
The name of the external network that this router connects to
|
||||
for gateway services (e.g. NAT).
|
||||
EOT
|
||||
end
|
||||
|
||||
newproperty(:gateway_network_id) do
|
||||
desc <<-EOT
|
||||
The uuid of the external network that this router connects to
|
||||
for gateway services (e.g. NAT).
|
||||
EOT
|
||||
validate do |v|
|
||||
raise(Puppet::Error, 'This is a read only property')
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:status) do
|
||||
desc 'Whether the router is currently operational or not.'
|
||||
validate do |v|
|
||||
raise(Puppet::Error, 'This is a read only property')
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:tenant_name) do
|
||||
desc 'The name of the tenant which will own the router.'
|
||||
end
|
||||
|
||||
newproperty(:tenant_id) do
|
||||
desc 'A uuid identifying the tenant which will own the router.'
|
||||
end
|
||||
|
||||
autorequire(:service) do
|
||||
['quantum-server']
|
||||
end
|
||||
|
||||
autorequire(:keystone_tenant) do
|
||||
[self[:tenant_name]] if self[:tenant_name]
|
||||
end
|
||||
|
||||
autorequire(:quantum_network) do
|
||||
[self[:gateway_network_name]] if self[:gateway_network_name]
|
||||
end
|
||||
|
||||
validate do
|
||||
if self[:ensure] != :present
|
||||
return
|
||||
end
|
||||
if self[:tenant_id] && self[:tenant_name]
|
||||
raise(Puppet::Error, <<-EOT
|
||||
Please provide a value for only one of tenant_name and tenant_id.
|
||||
EOT
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/quantum_router/quantum'
|
||||
|
||||
provider_class = Puppet::Type.type(:quantum_router).provider(:quantum)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
let :router_name do
|
||||
'router1'
|
||||
end
|
||||
|
||||
let :router_attrs do
|
||||
{
|
||||
:name => router_name,
|
||||
:ensure => 'present',
|
||||
:admin_state_up => 'True',
|
||||
:tenant_id => '',
|
||||
}
|
||||
end
|
||||
|
||||
describe 'when updating a router' do
|
||||
let :resource do
|
||||
Puppet::Type::Quantum_router.new(router_attrs)
|
||||
end
|
||||
|
||||
let :provider do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
it 'should call router-update to change admin_state_up' do
|
||||
provider.expects(:auth_quantum).with('router-update',
|
||||
'--admin-state-up=False',
|
||||
router_name)
|
||||
provider.admin_state_up=('False')
|
||||
end
|
||||
|
||||
it 'should call router-gateway-clear for an empty network name' do
|
||||
provider.expects(:auth_quantum).with('router-gateway-clear',
|
||||
router_name)
|
||||
provider.gateway_network_name=('')
|
||||
end
|
||||
|
||||
it 'should call router-gateway-set to configure an external network' do
|
||||
provider.expects(:auth_quantum).with('router-gateway-set',
|
||||
router_name,
|
||||
'net1')
|
||||
provider.gateway_network_name=('net1')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue