Merge "Nova cells support for nova_aggregate provider"

This commit is contained in:
Jenkins 2016-01-26 15:21:17 +00:00 committed by Gerrit Code Review
commit ac28d69299
3 changed files with 144 additions and 18 deletions

View File

@ -186,9 +186,10 @@ class Puppet::Provider::Nova < Puppet::Provider
def self.nova_get_host_by_name_and_type(host_name, service_type)
#find the host by name and service type
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
return entry["host_name"]
return host_name
end
end
end
@ -209,7 +210,10 @@ class Puppet::Provider::Nova < Puppet::Provider
@nova_aggregate_resources_ids = cliout2list(cmd_output)
#only interessted in Id and Name
@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
end

View File

@ -14,7 +14,7 @@ Puppet::Type.type(:nova_aggregate).provide(
def self.instances
nova_aggregate_resources_ids().collect do |el|
attrs = nova_aggregate_resources_attr(el['Id'])
attrs = nova_aggregate_resources_attr(el['Name'])
new(
:ensure => :present,
:name => attrs['Name'],
@ -74,7 +74,7 @@ Puppet::Type.type(:nova_aggregate).provide(
#add metadata
if not @resource[:metadata].nil? and not @resource[:metadata].empty?
@resource[:metadata].each do |key, value|
set_metadata_helper(id, key, value)
set_metadata_helper(resource[:name], key, value)
end
@property_hash[:metadata] = resource[:metadata]
end
@ -86,7 +86,7 @@ Puppet::Type.type(:nova_aggregate).provide(
# this solves weird ordering issues with a compute node that's
# not 100% up being added to the host aggregate
if is_host_in_nova?(host)
auth_nova("aggregate-add-host", id, "#{host}")
auth_nova("aggregate-add-host", resource[:name], "#{host}")
else
warning("Cannot add #{host} to host aggregate, it's not available yet in nova host-list")
end
@ -101,12 +101,11 @@ Puppet::Type.type(:nova_aggregate).provide(
def hosts=(val)
#get current hosts
id = self.class.nova_aggregate_resources_get_name_by_id(name)
attrs = self.class.nova_aggregate_resources_attr(id)
attrs = self.class.nova_aggregate_resources_attr(name)
#remove all hosts which are not in new value list
attrs['Hosts'].each do |h|
if not val.include? h
auth_nova("aggregate-remove-host", id, "#{h}")
auth_nova("aggregate-remove-host", name, "#{h}")
end
end
@ -114,7 +113,7 @@ Puppet::Type.type(:nova_aggregate).provide(
val.each do |h|
if not attrs['Hosts'].include? h
if is_host_in_nova?(h)
auth_nova("aggregate-add-host", id, "#{h}")
auth_nova("aggregate-add-host", name, "#{h}")
else
warning("Cannot add #{h} to host aggregate, it's not available yet in nova host-list")
end
@ -128,8 +127,7 @@ Puppet::Type.type(:nova_aggregate).provide(
def metadata
#get current metadata
id = self.class.nova_aggregate_resources_get_name_by_id(name)
attrs = self.class.nova_aggregate_resources_attr(id)
attrs = self.class.nova_aggregate_resources_attr(name)
#just ignore the availability_zone. that's handled directly by nova
attrs['Metadata'].delete('availability_zone')
return attrs['Metadata']
@ -137,8 +135,7 @@ Puppet::Type.type(:nova_aggregate).provide(
def metadata=(val)
#get current metadata
id = self.class.nova_aggregate_resources_get_name_by_id(name)
attrs = self.class.nova_aggregate_resources_attr(id)
attrs = self.class.nova_aggregate_resources_attr(name)
#get keys which are in current metadata but not in val. Make sure it has data first!
if attrs['Metadata'].length > 0
obsolete_keys = attrs['Metadata'].keys - val.keys
@ -147,7 +144,7 @@ Puppet::Type.type(:nova_aggregate).provide(
if obsolete_keys
obsolete_keys.each do |key|
if not key.include? 'availability_zone'
auth_nova("aggregate-set-metadata", id, "#{key}")
auth_nova("aggregate-set-metadata", name, "#{key}")
end
end
#handle keys (with obsolete keys)
@ -160,14 +157,13 @@ Puppet::Type.type(:nova_aggregate).provide(
new_keys.each do |key|
if val[key] != attrs['Metadata'][key.to_s]
value = val[key]
set_metadata_helper(id, key, value)
set_metadata_helper(name, key, value)
end
end
end
def availability_zone=(val)
id = self.class.nova_aggregate_resources_get_name_by_id(name)
auth_nova("aggregate-set-metadata", id, "availability_zone=#{val}")
auth_nova("aggregate-set-metadata", name, "availability_zone=#{val}")
end
end

View File

@ -214,6 +214,76 @@ EOT
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
it 'should return the availble Id' do
output = <<-EOT
@ -245,6 +315,37 @@ EOT
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
it 'should return a Hash with the details' do
output = <<-EOT
@ -270,6 +371,31 @@ EOT
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
it 'should find the hostname if there is a match' do
output = <<-EOT