Nova cells support for nova_aggregate provider
Updates the nova_aggregate provider to support nova cells routing info in the naming of hosts and hosts aggregate. Change-Id: I29131e378184262a74b9e99a85a8215282787f65 Closes-bug: 1533423
This commit is contained in:
@@ -175,9 +175,10 @@ class Puppet::Provider::Nova < Puppet::Provider
|
|||||||
def self.nova_get_host_by_name_and_type(host_name, service_type)
|
def self.nova_get_host_by_name_and_type(host_name, service_type)
|
||||||
#find the host by name and service type
|
#find the host by name and service type
|
||||||
nova_hosts.each do |entry|
|
nova_hosts.each do |entry|
|
||||||
if entry["host_name"] == host_name
|
# (mdorman) Support api!cell_name@host_name -style output of nova host-list under nova cells
|
||||||
|
if entry["host_name"] =~ /^([a-zA-Z0-9\-_]+![a-zA-Z0-9\-_]+@)?#{Regexp.quote(host_name)}$/
|
||||||
if entry["service"] == service_type
|
if entry["service"] == service_type
|
||||||
return entry["host_name"]
|
return host_name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -198,7 +199,10 @@ class Puppet::Provider::Nova < Puppet::Provider
|
|||||||
@nova_aggregate_resources_ids = cliout2list(cmd_output)
|
@nova_aggregate_resources_ids = cliout2list(cmd_output)
|
||||||
#only interessted in Id and Name
|
#only interessted in Id and Name
|
||||||
@nova_aggregate_resources_ids.map{ |e| e.delete("Availability Zone")}
|
@nova_aggregate_resources_ids.map{ |e| e.delete("Availability Zone")}
|
||||||
@nova_aggregate_resources_ids.map{ |e| e['Id'] = e['Id'].to_i}
|
@nova_aggregate_resources_ids.map{ |e|
|
||||||
|
if e['Id'] =~ /^[0-9]+$/
|
||||||
|
e['Id'] = e['Id'].to_i
|
||||||
|
end }
|
||||||
@nova_aggregate_resources_ids
|
@nova_aggregate_resources_ids
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
|
|
||||||
def self.instances
|
def self.instances
|
||||||
nova_aggregate_resources_ids().collect do |el|
|
nova_aggregate_resources_ids().collect do |el|
|
||||||
attrs = nova_aggregate_resources_attr(el['Id'])
|
attrs = nova_aggregate_resources_attr(el['Name'])
|
||||||
new(
|
new(
|
||||||
:ensure => :present,
|
:ensure => :present,
|
||||||
:name => attrs['Name'],
|
:name => attrs['Name'],
|
||||||
@@ -74,7 +74,7 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
#add metadata
|
#add metadata
|
||||||
if not @resource[:metadata].nil? and not @resource[:metadata].empty?
|
if not @resource[:metadata].nil? and not @resource[:metadata].empty?
|
||||||
@resource[:metadata].each do |key, value|
|
@resource[:metadata].each do |key, value|
|
||||||
set_metadata_helper(id, key, value)
|
set_metadata_helper(resource[:name], key, value)
|
||||||
end
|
end
|
||||||
@property_hash[:metadata] = resource[:metadata]
|
@property_hash[:metadata] = resource[:metadata]
|
||||||
end
|
end
|
||||||
@@ -86,7 +86,7 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
# this solves weird ordering issues with a compute node that's
|
# this solves weird ordering issues with a compute node that's
|
||||||
# not 100% up being added to the host aggregate
|
# not 100% up being added to the host aggregate
|
||||||
if is_host_in_nova?(host)
|
if is_host_in_nova?(host)
|
||||||
auth_nova("aggregate-add-host", id, "#{host}")
|
auth_nova("aggregate-add-host", resource[:name], "#{host}")
|
||||||
else
|
else
|
||||||
warning("Cannot add #{host} to host aggregate, it's not available yet in nova host-list")
|
warning("Cannot add #{host} to host aggregate, it's not available yet in nova host-list")
|
||||||
end
|
end
|
||||||
@@ -101,12 +101,11 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
|
|
||||||
def hosts=(val)
|
def hosts=(val)
|
||||||
#get current hosts
|
#get current hosts
|
||||||
id = self.class.nova_aggregate_resources_get_name_by_id(name)
|
attrs = self.class.nova_aggregate_resources_attr(name)
|
||||||
attrs = self.class.nova_aggregate_resources_attr(id)
|
|
||||||
#remove all hosts which are not in new value list
|
#remove all hosts which are not in new value list
|
||||||
attrs['Hosts'].each do |h|
|
attrs['Hosts'].each do |h|
|
||||||
if not val.include? h
|
if not val.include? h
|
||||||
auth_nova("aggregate-remove-host", id, "#{h}")
|
auth_nova("aggregate-remove-host", name, "#{h}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -114,7 +113,7 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
val.each do |h|
|
val.each do |h|
|
||||||
if not attrs['Hosts'].include? h
|
if not attrs['Hosts'].include? h
|
||||||
if is_host_in_nova?(h)
|
if is_host_in_nova?(h)
|
||||||
auth_nova("aggregate-add-host", id, "#{h}")
|
auth_nova("aggregate-add-host", name, "#{h}")
|
||||||
else
|
else
|
||||||
warning("Cannot add #{h} to host aggregate, it's not available yet in nova host-list")
|
warning("Cannot add #{h} to host aggregate, it's not available yet in nova host-list")
|
||||||
end
|
end
|
||||||
@@ -128,8 +127,7 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
|
|
||||||
def metadata
|
def metadata
|
||||||
#get current metadata
|
#get current metadata
|
||||||
id = self.class.nova_aggregate_resources_get_name_by_id(name)
|
attrs = self.class.nova_aggregate_resources_attr(name)
|
||||||
attrs = self.class.nova_aggregate_resources_attr(id)
|
|
||||||
#just ignore the availability_zone. that's handled directly by nova
|
#just ignore the availability_zone. that's handled directly by nova
|
||||||
attrs['Metadata'].delete('availability_zone')
|
attrs['Metadata'].delete('availability_zone')
|
||||||
return attrs['Metadata']
|
return attrs['Metadata']
|
||||||
@@ -137,8 +135,7 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
|
|
||||||
def metadata=(val)
|
def metadata=(val)
|
||||||
#get current metadata
|
#get current metadata
|
||||||
id = self.class.nova_aggregate_resources_get_name_by_id(name)
|
attrs = self.class.nova_aggregate_resources_attr(name)
|
||||||
attrs = self.class.nova_aggregate_resources_attr(id)
|
|
||||||
#get keys which are in current metadata but not in val. Make sure it has data first!
|
#get keys which are in current metadata but not in val. Make sure it has data first!
|
||||||
if attrs['Metadata'].length > 0
|
if attrs['Metadata'].length > 0
|
||||||
obsolete_keys = attrs['Metadata'].keys - val.keys
|
obsolete_keys = attrs['Metadata'].keys - val.keys
|
||||||
@@ -147,7 +144,7 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
if obsolete_keys
|
if obsolete_keys
|
||||||
obsolete_keys.each do |key|
|
obsolete_keys.each do |key|
|
||||||
if not key.include? 'availability_zone'
|
if not key.include? 'availability_zone'
|
||||||
auth_nova("aggregate-set-metadata", id, "#{key}")
|
auth_nova("aggregate-set-metadata", name, "#{key}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
#handle keys (with obsolete keys)
|
#handle keys (with obsolete keys)
|
||||||
@@ -160,14 +157,13 @@ Puppet::Type.type(:nova_aggregate).provide(
|
|||||||
new_keys.each do |key|
|
new_keys.each do |key|
|
||||||
if val[key] != attrs['Metadata'][key.to_s]
|
if val[key] != attrs['Metadata'][key.to_s]
|
||||||
value = val[key]
|
value = val[key]
|
||||||
set_metadata_helper(id, key, value)
|
set_metadata_helper(name, key, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def availability_zone=(val)
|
def availability_zone=(val)
|
||||||
id = self.class.nova_aggregate_resources_get_name_by_id(name)
|
auth_nova("aggregate-set-metadata", name, "availability_zone=#{val}")
|
||||||
auth_nova("aggregate-set-metadata", id, "availability_zone=#{val}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@@ -214,6 +214,76 @@ EOT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'when parsing cli output with cells enabled' do
|
||||||
|
|
||||||
|
it 'should return a list with hashes' do
|
||||||
|
output = <<-EOT
|
||||||
|
+-------------+----------------+-------------------+
|
||||||
|
| Id | Name | Availability Zone |
|
||||||
|
+-------------+----------------+-------------------+
|
||||||
|
| api!cell@1 | api!cell@haha | haha2 |
|
||||||
|
| api!cell@2 | api!cell@haha2 | - |
|
||||||
|
+-------------+----------------+-------------------+
|
||||||
|
EOT
|
||||||
|
res = klass.cliout2list(output)
|
||||||
|
expect(res).to eq([{"Id"=>"api!cell@1", "Name"=>"api!cell@haha", "Availability Zone"=>"haha2"},
|
||||||
|
{"Id"=>"api!cell@2", "Name"=>"api!cell@haha2", "Availability Zone"=>""}])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return a list with hashes' do
|
||||||
|
output = <<-EOT
|
||||||
|
+-------------+----------------+-------------------+-------+--------------------------------------------------+
|
||||||
|
| Id | Name | Availability Zone | Hosts | Metadata |
|
||||||
|
+-------------+----------------+-------------------+-------+--------------------------------------------------+
|
||||||
|
| api!cell@16 | api!cell@agg94 | my_-zone1 | | 'a=b', 'availability_zone= my_-zone1', 'x_q-r=y' |
|
||||||
|
+-------------+----------------+-------------------+-------+--------------------------------------------------+
|
||||||
|
EOT
|
||||||
|
res = klass.cliout2list(output)
|
||||||
|
expect(res).to eq([{"Id"=>"api!cell@16",
|
||||||
|
"Name"=>"api!cell@agg94",
|
||||||
|
"Availability Zone"=>"my_-zone1",
|
||||||
|
"Hosts"=>"",
|
||||||
|
"Metadata"=> {
|
||||||
|
"a"=>"b",
|
||||||
|
"availability_zone"=>" my_-zone1",
|
||||||
|
"x_q-r"=>"y"
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return a empty list' do
|
||||||
|
output = <<-EOT
|
||||||
|
+----+------+-------------------+
|
||||||
|
| Id | Name | Availability Zone |
|
||||||
|
+----+------+-------------------+
|
||||||
|
+----+------+-------------------+
|
||||||
|
EOT
|
||||||
|
res = klass.cliout2list(output)
|
||||||
|
expect(res).to eq([])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return a empty list because no input available' do
|
||||||
|
output = <<-EOT
|
||||||
|
EOT
|
||||||
|
res = klass.cliout2list(output)
|
||||||
|
expect(res).to eq([])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return a list with hashes' do
|
||||||
|
output = <<-EOT
|
||||||
|
+-------------+-------------------------+-------------------+
|
||||||
|
| Id | Name | Availability Zone |
|
||||||
|
+-------------+-------------------------+-------------------+
|
||||||
|
| api!cell@6 | api!cell@my | zone1 |
|
||||||
|
| api!cell@8 | api!cell@my2 | - |
|
||||||
|
+-------------+-------------------------+-------------------+
|
||||||
|
EOT
|
||||||
|
res = klass.cliout2list(output)
|
||||||
|
expect(res).to eq([{"Id"=>"api!cell@6", "Name"=>"api!cell@my", "Availability Zone"=>"zone1"},
|
||||||
|
{"Id"=>"api!cell@8", "Name"=>"api!cell@my2", "Availability Zone"=>""}])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'when handling cli output' do
|
describe 'when handling cli output' do
|
||||||
it 'should return the availble Id' do
|
it 'should return the availble Id' do
|
||||||
output = <<-EOT
|
output = <<-EOT
|
||||||
@@ -245,6 +315,37 @@ EOT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'when handling cli output with cells enabled' do
|
||||||
|
it 'should return the availble Id' do
|
||||||
|
output = <<-EOT
|
||||||
|
+-------------+----------------+-------------------+
|
||||||
|
| Id | Name | Availability Zone |
|
||||||
|
+-------------+----------------+-------------------+
|
||||||
|
| api!cell@1 | api!cell@haha | haha2 |
|
||||||
|
| api!cell@2 | api!cell@haha2 | - |
|
||||||
|
+-------------+----------------+-------------------+
|
||||||
|
EOT
|
||||||
|
klass.expects(:auth_nova).returns(output)
|
||||||
|
res = klass.nova_aggregate_resources_get_name_by_id("api!cell@haha2", true)
|
||||||
|
expect(res).to eq("api!cell@2")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return nil because given name is not available' do
|
||||||
|
output = <<-EOT
|
||||||
|
+----+-------+-------------------+
|
||||||
|
| Id | Name | Availability Zone |
|
||||||
|
+----+-------+-------------------+
|
||||||
|
| api!cell@1 | api!cell@haha | haha2 |
|
||||||
|
| api!cell@2 | api!cell@haha2 | - |
|
||||||
|
+----+-------+-------------------+
|
||||||
|
EOT
|
||||||
|
# used the cache copy, don't call nova again
|
||||||
|
klass.expects(:auth_nova).never()
|
||||||
|
res = klass.nova_aggregate_resources_get_name_by_id("notavailable")
|
||||||
|
expect(res).to eql(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'when getting details for given Id' do
|
describe 'when getting details for given Id' do
|
||||||
it 'should return a Hash with the details' do
|
it 'should return a Hash with the details' do
|
||||||
output = <<-EOT
|
output = <<-EOT
|
||||||
@@ -270,6 +371,31 @@ EOT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'when getting details for given Id with cells enabled' do
|
||||||
|
it 'should return a Hash with the details' do
|
||||||
|
output = <<-EOT
|
||||||
|
+-------------+----------------+-------------------+-------+--------------------------------------------------+
|
||||||
|
| Id | Name | Availability Zone | Hosts | Metadata |
|
||||||
|
+-------------+----------------+-------------------+-------+--------------------------------------------------+
|
||||||
|
| api!cell@16 | api!cell@agg94 | my_-zone1 | | 'a=b', 'availability_zone= my_-zone1', 'x_q-r=y' |
|
||||||
|
+-------------+----------------+-------------------+-------+--------------------------------------------------+
|
||||||
|
EOT
|
||||||
|
klass.expects(:auth_nova).returns(output)
|
||||||
|
res = klass.nova_aggregate_resources_attr(16)
|
||||||
|
expect(res).to eq({
|
||||||
|
"Id"=>"api!cell@16",
|
||||||
|
"Name"=>"api!cell@agg94",
|
||||||
|
"Availability Zone"=>"my_-zone1",
|
||||||
|
"Hosts"=>[],
|
||||||
|
"Metadata"=>{
|
||||||
|
"a"=>"b",
|
||||||
|
"availability_zone"=>" my_-zone1",
|
||||||
|
"x_q-r"=>"y"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'when searching for a host/type combo' do
|
describe 'when searching for a host/type combo' do
|
||||||
it 'should find the hostname if there is a match' do
|
it 'should find the hostname if there is a match' do
|
||||||
output = <<-EOT
|
output = <<-EOT
|
||||||
|
Reference in New Issue
Block a user