From 9a8352637aeb32ddffd83f4477695ec290da8429 Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud Date: Wed, 23 Aug 2017 16:31:18 +0200 Subject: [PATCH] Fix ipa config-mod --ca-renewal-master commit bddb90f38a3505a2768862d2f814c5e749a7dcde added the support for multivalued server attributes (for pkinit_server_server), but this introduced an API change where the setter and getter of ServerAttribute are expecting list of values. When a SingleValuedServerAttribute is used, we need to convert one elem into a list containing this elem and vice-versa, so that the ipa config-mod and ipa config_show APIs are not modified. https://pagure.io/freeipa/issue/7120 Reviewed-By: Alexander Bokovoy Reviewed-By: Fraser Tweedale --- ipaserver/plugins/serverroles.py | 16 +++++++++++++++- ipatests/test_ipaserver/test_serverroles.py | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ipaserver/plugins/serverroles.py b/ipaserver/plugins/serverroles.py index e81635c3315cc3fca84450f43fb7df883aae57d9..04e21090657197b9267f2ffc05048399a7ce3d38 100644 --- a/ipaserver/plugins/serverroles.py +++ b/ipaserver/plugins/serverroles.py @@ -46,6 +46,7 @@ from ipalib import errors, _ from ipalib.backend import Backend from ipalib.plugable import Registry from ipaserver.servroles import (attribute_instances, ENABLED, role_instances) +from ipaserver.servroles import SingleValuedServerAttribute if six.PY3: @@ -136,13 +137,26 @@ class serverroles(Backend): for name, attr in assoc_attributes.items(): attr_value = attr.get(self.api) - result.update({name: attr_value}) + + if attr_value: + # attr can be a SingleValuedServerAttribute + # in this case, the API expects a value, not a list of values + if isinstance(attr, SingleValuedServerAttribute): + attr_value = attr_value[0] + result.update({name: attr_value}) return result def config_update(self, **attrs_values): for attr, value in attrs_values.items(): try: + # when the attribute is single valued, it will be stored + # in a SingleValuedServerAttribute. The set method expects + # a list containing a single value. + # We need to convert value to a list containing value + if isinstance(self.attributes[attr], + SingleValuedServerAttribute): + value = [value] self.attributes[attr].set(self.api, value) except KeyError: raise errors.NotFound( diff --git a/ipatests/test_ipaserver/test_serverroles.py b/ipatests/test_ipaserver/test_serverroles.py index 985c750b64f109e0a83686f31ddb3b8d4171072d..e8967517d0c65fb6e3daebf220cae7df38bfe044 100644 --- a/ipatests/test_ipaserver/test_serverroles.py +++ b/ipatests/test_ipaserver/test_serverroles.py @@ -715,7 +715,7 @@ class TestServerAttributes(object): non_ca_fqdn = mock_masters.get_fqdn('trust-controller-dns') with pytest.raises(errors.ValidationError): - self.config_update(mock_api, **{attr_name: [non_ca_fqdn]}) + self.config_update(mock_api, **{attr_name: non_ca_fqdn}) def test_set_unknown_attribute_on_master_raises_notfound( self, mock_api, mock_masters): @@ -732,7 +732,7 @@ class TestServerAttributes(object): original_renewal_master = self.config_retrieve( role_name, mock_api)[attr_name] - other_ca_server = [mock_masters.get_fqdn('trust-controller-ca')] + other_ca_server = mock_masters.get_fqdn('trust-controller-ca') for host in (other_ca_server, original_renewal_master): self.config_update(mock_api, **{attr_name: host}) -- 2.13.5