Skip to content

Commit

Permalink
Fix properties in glance_image provider for osc >= 4.0.0
Browse files Browse the repository at this point in the history
Similar to I6a68505d15473b140c85a199a09d2fee45864800

Openstackclient 4.0.0 changed the way some properties are displayed
on screen.

Old:
...,"Properties"
...,"foo='bar'"

New:
...,"Properties"
...,"{u'foo': u'bar'}"
or
...,"{'foo': 'bar'}"

This is breaking idempotency on the glance_image provider, since it
does not detect them correctly. This patch aims at fixing this, by
trying to detect the new format, and using JSON parsing in that case.

Change-Id: I1829c7e59058fa72690dc08b3e2f65afcad7ea46
  • Loading branch information
karelyatin committed Oct 9, 2019
1 parent a2915d3 commit 1365358
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
20 changes: 19 additions & 1 deletion lib/puppet/provider/glance_image/openstack.rb
Expand Up @@ -135,7 +135,7 @@ def self.instances
list = request('image', 'list', '--long')
list.collect do |image|
attrs = request('image', 'show', image[:id])
properties = Hash[attrs[:properties].scan(/(\S+)='([^']*)'/)] rescue nil
properties = parsestring(attrs[:properties]) rescue nil
new(
:ensure => :present,
:name => attrs[:name],
Expand Down Expand Up @@ -195,4 +195,22 @@ def props_to_s(props)
['--property', "#{k}=#{v}"] unless hidden.include?(k)
}.compact
end

def self.string2hash(input)
return Hash[input.scan(/(\S+)='([^']*)'/)]
end

def self.pythondict2hash(input)
return JSON.parse(input.gsub(/u'(\w*)'/, '"\1"').gsub(/'/, '"').gsub(/False/,'false').gsub(/True/,'true'))
end

def self.parsestring(input)
if input[0] == '{'
# 4.0.0+ output, python dict
return self.pythondict2hash(input)
else
# Pre-4.0.0 output, key=value
return self.string2hash(input)
end
end
end
2 changes: 1 addition & 1 deletion spec/acceptance/basic_glance_spec.rb
Expand Up @@ -38,7 +38,7 @@
expect(r.stdout).to match(/visibility="public"/)
expect(r.stdout).to match(/container_format="bare"/)
expect(r.stdout).to match(/disk_format="qcow2"/)
expect(r.stdout).to include('properties="icanhaz=\'cheezburger\'')
expect(r.stdout).to match(/properties=.*icanhaz.*cheezburger/)
expect(r.stdout).to match(/min_ram="64"/)
expect(r.stdout).to match(/min_disk="1024"/)
end
Expand Down
29 changes: 29 additions & 0 deletions spec/unit/provider/glance_image_spec.rb
Expand Up @@ -76,6 +76,35 @@

end

describe '#pythondict2hash' do
it 'should return a hash with key-value when provided with a unicode python dict' do
s = "{u'key': 'value', u'key2': 'value2'}"
expect(provider_class.pythondict2hash(s)).to eq({"key"=>"value", "key2"=>"value2"})
end

it 'should return a hash with key-value when provided with a python dict' do
s = "{'key': 'value', 'key2': 'value2'}"
expect(provider_class.pythondict2hash(s)).to eq({"key"=>"value", "key2"=>"value2"})
end

it 'should convert boolean to json compatible hash when provided with a python dict' do
s = "{'key': 'value', 'key2': False}"
expect(provider_class.pythondict2hash(s)).to eq({"key"=>"value", "key2"=>false})
end
end

describe '#parsestring' do
it 'should call string2hash when provided with a string' do
s = "key='value', key2='value2'"
expect(provider_class.parsestring(s)).to eq({"key"=>"value", "key2"=>"value2"})
end

it 'should call pythondict2hash when provided with a hash' do
s = "{u'key': 'value', u'key2': 'value2'}"
expect(provider_class.parsestring(s)).to eq({"key"=>"value", "key2"=>"value2"})
end
end

describe '.instances' do
it 'finds every image' do
provider.class.stubs(:openstack)
Expand Down

0 comments on commit 1365358

Please sign in to comment.