From d6ca0f7c41209be032745551b497bc33210f23ab Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Mon, 7 Oct 2024 16:28:07 +0900 Subject: [PATCH] cinder_qos: Handle python dict for properties osc changed how dict values are formatted in outputs in 4.0.0 . This imports the change we earlier made in cinder_type to fix compatibility between cinder_qos and osc>=4.0.0. Closes-Bug: #2083822 Change-Id: I74e4f706304ecb07188fc3ae45ea218795efb05c (cherry picked from commit 3fcf9d907f9fb9837b4dfd9c7db39e8bddbf7135) --- lib/puppet/provider/cinder_qos/openstack.rb | 21 +++++++++- .../provider/cinder_qos/openstack_spec.rb | 41 ++++++++++++++++--- .../provider/cinder_type/openstack_spec.rb | 5 --- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/lib/puppet/provider/cinder_qos/openstack.rb b/lib/puppet/provider/cinder_qos/openstack.rb index 9649ac4d..677f87bb 100644 --- a/lib/puppet/provider/cinder_qos/openstack.rb +++ b/lib/puppet/provider/cinder_qos/openstack.rb @@ -72,7 +72,7 @@ Puppet::Type.type(:cinder_qos).provide( :name => qos[:name], :ensure => :present, :id => qos[:id], - :properties => string2array(properties), + :properties => parsestring(properties), :consumer => qos[:consumer], :associations => string2array(qos[:associations]) }) @@ -91,4 +91,23 @@ Puppet::Type.type(:cinder_qos).provide( def self.string2array(input) return input.delete("'").split(/,\s/) end + + def self.pythondict2array(input) + json_input = JSON.parse(input.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_qos/openstack_spec.rb b/spec/unit/provider/cinder_qos/openstack_spec.rb index 65ac0641..e740d9f7 100644 --- a/spec/unit/provider/cinder_qos/openstack_spec.rb +++ b/spec/unit/provider/cinder_qos/openstack_spec.rb @@ -57,7 +57,7 @@ properties="key1=\'value1\', key2=\'value2\'" it 'finds qos' do expect(provider_class).to receive(:openstack) .with('volume qos', 'list', '--quiet', '--format', 'csv', []) - .and_return('"ID","Name","Consumer","Associations","Specs" + .and_return('"ID","Name","Consumer","Associations","Properties" "28b632e8-6694-4bba-bf68-67b19f619019","qos-1","front-end","my_type1, my_type2","read_iops=\'value1\', write_iops=\'value2\'" "4f992f69-14ec-4132-9313-55cc06a6f1f6","qos-2","both","","" ') @@ -72,14 +72,26 @@ properties="key1=\'value1\', key2=\'value2\'" expect(instances[1].associations).to eq([]) expect(instances[1].properties).to eq([]) end - end - #Test with python-openstackclient => 3.8.0 output (column header change from 'Specs' to 'Properties') - describe '#instances' do - it 'finds qos' do + it 'finds qos with a Properties hash' do expect(provider_class).to receive(:openstack) .with('volume qos', 'list', '--quiet', '--format', 'csv', []) .and_return('"ID","Name","Consumer","Associations","Properties" +"28b632e8-6694-4bba-bf68-67b19f619019","qos-1","front-end","my_type1, my_type2","{\'read_iops\': \'value1\', \'write_iops\': \'value2\'}" +"4f992f69-14ec-4132-9313-55cc06a6f1f6","qos-2","both","","{}" +') + instances = provider_class.instances + expect(instances.count).to eq(2) + expect(instances[0].properties).to eq(['read_iops=value1', 'write_iops=value2']) + expect(instances[1].properties).to eq([]) + end + + #Test with python-openstackclient < 3.8.0 output + #(column header change from 'Specs' to 'Properties') + it 'finds qos with old field name' do + expect(provider_class).to receive(:openstack) + .with('volume qos', 'list', '--quiet', '--format', 'csv', []) + .and_return('"ID","Name","Consumer","Associations","Specs" "28b632e8-6694-4bba-bf68-67b19f619019","qos-1","front-end","my_type1","read_iops=\'value1\'" ') instances = provider_class.instances @@ -97,5 +109,24 @@ properties="key1=\'value1\', key2=\'value2\'" 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 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 = "{'key': 'value', 'key2': 'value2'}" + expect(provider_class.parsestring(s)).to eq(['key=value', 'key2=value2']) + end + end end end diff --git a/spec/unit/provider/cinder_type/openstack_spec.rb b/spec/unit/provider/cinder_type/openstack_spec.rb index f3d0ff9e..0b8438a9 100644 --- a/spec/unit/provider/cinder_type/openstack_spec.rb +++ b/spec/unit/provider/cinder_type/openstack_spec.rb @@ -116,11 +116,6 @@ access_project_ids="54f4d231201b4944a5fa4587a09bda23, 54f4d231201b4944a5fa4587a0 end describe '#pythondict2array' do - it 'should return an array with key-value when provided with a unicode python dict' do - s = "{'key': 'value', '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'])