Merge "Fix endpoint update when one endpoint is missing."

This commit is contained in:
Jenkins 2016-06-24 12:01:45 +00:00 committed by Gerrit Code Review
commit 0da5dcc6cc
4 changed files with 142 additions and 33 deletions

View File

@ -9,6 +9,8 @@ Puppet::Type.type(:keystone_endpoint).provide(
include PuppetX::Keystone::CompositeNamevar::Helpers
attr_accessor :property_hash, :property_flush
@endpoints = nil
@services = nil
@credentials = Puppet::Provider::Openstack::CredentialsV3.new
@ -31,30 +33,18 @@ Puppet::Type.type(:keystone_endpoint).provide(
if self.class.do_not_manage
fail("Not managing Keystone_endpoint[#{@resource[:name]}] due to earlier Keystone API failures.")
end
# Reset the cache.
self.class.services = nil
name = resource[:name]
region = resource[:region]
type = resource[:type]
type = self.class.type_from_service(name) unless set?(:type)
@property_hash[:type] = type
services = self.class.services.find_all { |s| s[:name] == name }
service = services.find { |s| s[:type] == type }
if service.nil? && services.count == 1
# For backward comptatibility, match the service by name only.
name = services[0][:id]
else
# Math the service by id.
name = service[:id] if service
end
ids = []
s_id = service_id
created = false
[:admin_url, :internal_url, :public_url].each do |scope|
if resource[scope]
created = true
ids << endpoint_create(name, region, scope.to_s.sub(/_url$/, ''),
ids << endpoint_create(s_id, region, scope.to_s.sub(/_url$/, ''),
resource[scope])[:id]
end
end
@ -134,11 +124,11 @@ Puppet::Type.type(:keystone_endpoint).provide(
new(
:name => endpoint[:name],
:ensure => :present,
:id => "#{endpoint[:admin][:id]},#{endpoint[:internal][:id]},#{endpoint[:public][:id]}",
:region => endpoint[:admin][:region],
:admin_url => endpoint[:admin][:url],
:internal_url => endpoint[:internal][:url],
:public_url => endpoint[:public][:url]
:id => make_id(endpoint),
:region => get_region(endpoint),
:admin_url => get_url(endpoint, :admin),
:internal_url => get_url(endpoint, :internal),
:public_url => get_url(endpoint, :public)
)
end
end
@ -153,19 +143,27 @@ Puppet::Type.type(:keystone_endpoint).provide(
end
def flush
if @property_flush && @property_hash[:id]
ids = @property_hash[:id].split(',')
if @property_flush[:admin_url]
self.class.request('endpoint', 'set', [ids[0], "--url=#{resource[:admin_url]}"])
end
if @property_flush[:internal_url]
self.class.request('endpoint', 'set', [ids[1], "--url=#{resource[:internal_url]}"])
end
if @property_flush[:public_url]
self.class.request('endpoint', 'set', [ids[2], "--url=#{resource[:public_url]}"])
if property_flush && property_hash[:id]
scopes = [:admin_url, :internal_url, :public_url]
ids = Hash[scopes.zip(property_hash[:id].split(','))]
scopes.each do |scope|
if property_flush[scope]
if ids[scope].nil? || ids[scope].empty?
ids[scope] = endpoint_create(service_id, resource[:region],
scope.to_s.sub(/_url$/, ''),
property_flush[scope])[:id]
else
self.class.request('endpoint',
'set',
[ids[scope],
"--url=#{resource[scope]}"])
end
end
end
@property_hash = resource.to_hash
@property_hash[:id] = scopes.map { |s| ids[s] }.join(',')
@property_hash[:ensure] = :present
end
@property_hash = resource.to_hash
end
private
@ -252,4 +250,47 @@ Puppet::Type.type(:keystone_endpoint).provide(
"#{region}/#{name}::#{type}"
end
end
def self.make_id(endpoint)
id_str = ''
id_sep = ''
[:admin, :internal, :public].each do |type|
id_str += "#{id_sep}#{endpoint[type][:id]}" if endpoint[type]
id_sep = ','
end
id_str
end
def self.get_region(endpoint)
type = [:admin, :internal, :public].detect { |t| endpoint.key? t }
type ? endpoint[type][:region] : ''
end
def self.get_url(endpoint, type, default='')
endpoint[type][:url] rescue default
end
def service_id
# Reset the cache.
self.class.services = nil
name = resource[:name]
type = resource[:type]
services = self.class.services.find_all { |s| s[:name] == name }
service = services.find { |s| s[:type] == type }
service_id = ''
if service.nil? && services.count == 1
# For backward comptatibility, match the service by name only.
service_id = services[0][:id]
else
# Math the service by id.
service_id = service[:id] if service
end
if service_id.nil? || service_id.empty?
title = self.class.transform_name(resource[:region], resource[:name], resource[:type])
fail(Puppet::Error, "Cannot find service associated with #{title}")
end
service_id
end
end

View File

@ -0,0 +1,6 @@
---
fixes:
- Fixes `bug 1559013
<https://bugs.launchpad.net/puppet-keystone/+bug/1559013>`__ so
update of a keystone_endpoint does not recreate all endpoints when
one or two network endpoint are missing.

View File

@ -233,9 +233,9 @@ describe 'keystone server running with Apache/WSGI with resources' do
ensure => present,
region => 'RegionOne',
type => 'type_1',
public_url => 'http://public_url/',
internal_url => 'http://public_url/',
admin_url => 'http://public_url/'
public_url => 'http://public_service1_type1/',
internal_url => 'http://internal_service1_type1/',
admin_url => 'http://admin_service1_type1/'
}
EOM
end

View File

@ -326,5 +326,67 @@ region="region"
end
end
end
describe '#flush' do
let(:endpoint_attrs) do
{
:title => 'region/service_1',
:ensure => 'present',
:public_url => 'http://127.0.0.1:5000',
:internal_url => 'http://127.0.0.1:5001',
:admin_url => 'http://127.0.0.1:4999',
:type => 'service_type1'
}
end
context '#update a missing endpoint' do
it 'creates an endpoint' do
described_class.expects(:openstack)
.with('endpoint', 'create', '--format', 'shell',
['service_id_1', 'admin', 'http://127.0.0.1:4999',
'--region', 'region'])
.returns(<<-eoo
enabled="True"
id="endpoint1_id"
interface="internal"
region="None"
region_id="None"
service_id="service_id_1"
service_name="service_1"
service_type="service_type1"
url="http://127.0.0.1:5001"
eoo
)
provider.expects(:property_flush)
.times(5)
.returns({:admin_url => 'http://127.0.0.1:4999'})
provider.expects(:property_hash)
.twice
.returns({:id => ',endpoint2_id,endpoint3_id'})
provider.expects(:service_id)
.returns('service_id_1')
provider.flush
expect(provider.exists?).to be_truthy
expect(provider.id).to eq('endpoint1_id,endpoint2_id,endpoint3_id')
end
end
context 'adjust a url' do
it 'update the url' do
described_class.expects(:openstack)
.with('endpoint', 'set',
['endpoint1_id', '--url=http://127.0.0.1:4999'])
provider.expects(:property_flush)
.times(4)
.returns({:admin_url => 'http://127.0.0.1:4999'})
provider.expects(:property_hash)
.twice
.returns({:id => 'endpoint1_id,endpoint2_id,endpoint3_id'})
provider.flush
expect(provider.exists?).to be_truthy
expect(provider.id).to eq('endpoint1_id,endpoint2_id,endpoint3_id')
end
end
end
end
end