diff --git a/lib/puppet/provider/cinder_type/openstack.rb b/lib/puppet/provider/cinder_type/openstack.rb index 1a5f277d..791bae78 100644 --- a/lib/puppet/provider/cinder_type/openstack.rb +++ b/lib/puppet/provider/cinder_type/openstack.rb @@ -80,7 +80,7 @@ Puppet::Type.type(:cinder_type).provide( list.each do |type| if type[:is_public] == 'False' type_details = request('volume type', 'show', type[:id]) - type[:access_project_ids] = string2array(type_details[:access_project_ids]) + type[:access_project_ids] = parsestring(type_details[:access_project_ids]) type[:is_public] = false else type[:access_project_ids] = [] @@ -93,7 +93,7 @@ Puppet::Type.type(:cinder_type).provide( :name => type[:name], :ensure => :present, :id => type[:id], - :properties => string2array(type[:properties]), + :properties => parsestring(type[:properties]), :is_public => type[:is_public], :access_project_ids => type[:access_project_ids] }) @@ -112,4 +112,23 @@ Puppet::Type.type(:cinder_type).provide( def self.string2array(input) return input.delete("'").split(/,\s/) end + + def self.pythondict2array(input) + json_input = JSON.parse(input.gsub(/u'(\w*)'/, '"\1"').gsub(/'/, '"')) + output = [] + json_input.each do | k, v | + output = output + ["#{k}=#{v}"] + end + return output + end + + def self.parsestring(input) + if input[0] == '{' + # 4.0.0+ output, python dict + return self.pythondict2array(input) + else + # Pre-4.0.0 output, key=value + return self.string2array(input) + end + end end diff --git a/spec/unit/provider/cinder_type/openstack_spec.rb b/spec/unit/provider/cinder_type/openstack_spec.rb index c556158e..3f458028 100644 --- a/spec/unit/provider/cinder_type/openstack_spec.rb +++ b/spec/unit/provider/cinder_type/openstack_spec.rb @@ -89,6 +89,28 @@ access_project_ids="54f4d231201b4944a5fa4587a09bda23, 54f4d231201b4944a5fa4587a0 expect(instances[0].access_project_ids).to match_array([]) expect(instances[1].access_project_ids).to match_array(['54f4d231201b4944a5fa4587a09bda23', '54f4d231201b4944a5fa4587a09bda28']) end + + it 'finds types with a Properties hash' do + provider_class.expects(:openstack) + .with('volume type', 'list', '--quiet', '--format', 'csv', '--long') + .returns('"ID","Name","Is Public","Properties" +"28b632e8-6694-4bba-bf68-67b19f619019","type-1","True","{\'key1\': \'value1\'}" +"4f992f69-14ec-4132-9313-55cc06a6f1f6","type-2","False","{\'key2\': \'value2\'}" +') + provider_class.expects(:openstack) + .with('volume type', 'show', '--format', 'shell', '4f992f69-14ec-4132-9313-55cc06a6f1f6') + .returns(' +id="4f992f69-14ec-4132-9313-55cc06a6f1f6" +name="type-2" +properties="key2=\'value2\'" +is_public="False" +access_project_ids="54f4d231201b4944a5fa4587a09bda23, 54f4d231201b4944a5fa4587a09bda28" +') + instances = provider_class.instances + expect(instances.count).to eq(2) + expect(instances[0].properties).to eq(["key1=value1"]) + expect(instances[1].properties).to eq(["key2=value2"]) + end end describe '#string2array' do @@ -97,5 +119,29 @@ access_project_ids="54f4d231201b4944a5fa4587a09bda23, 54f4d231201b4944a5fa4587a0 expect(provider_class.string2array(s)).to eq(['key=value', 'key2=value2']) end end + + describe '#pythondict2array' do + it 'should return an array with key-value when provided with a unicode python dict' do + s = "{u'key': 'value', u'key2': 'value2'}" + expect(provider_class.pythondict2array(s)).to eq(['key=value', 'key2=value2']) + end + + it 'should return an array with key-value when provided with a python dict' do + s = "{'key': 'value', 'key2': 'value2'}" + expect(provider_class.pythondict2array(s)).to eq(['key=value', 'key2=value2']) + end + end + + describe '#parsestring' do + it 'should call string2array 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 pythondict2array 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 end end