diff --git a/heat/common/config.py b/heat/common/config.py index 12f6c0a300..c070cabcf7 100644 --- a/heat/common/config.py +++ b/heat/common/config.py @@ -191,16 +191,18 @@ engine_opts = [ default=10, help=_('Number of times to check whether an interface has ' 'been attached or detached.')), - cfg.FloatOpt('max_nova_api_microversion', - help=_('Maximum nova API version for client plugin. With ' - 'this limitation, any nova feature supported with ' - 'microversion number above max_nova_api_microversion ' - 'will not be available.')), - cfg.FloatOpt('max_ironic_api_microversion', - help=_('Maximum ironic API version for client plugin. With ' - 'this limitation, any ironic feature supported with ' - 'microversion number above ' - 'max_ironic_api_microversion will not be available.')), + cfg.StrOpt('max_nova_api_microversion', + regex=r'^\d+\.\d+$', + help=_('Maximum nova API version for client plugin. With ' + 'this limitation, any nova feature supported with ' + 'microversion number above max_nova_api_microversion ' + 'will not be available.')), + cfg.StrOpt('max_ironic_api_microversion', + regex=r'^\d+\.\d+$', + help=_('Maximum ironic API version for client plugin. With ' + 'this limitation, any ironic feature supported with ' + 'microversion number above ' + 'max_ironic_api_microversion will not be available.')), cfg.IntOpt('event_purge_batch_size', min=1, default=200, diff --git a/heat/engine/clients/os/ironic.py b/heat/engine/clients/os/ironic.py index 59ade7b4be..ed155138f0 100644 --- a/heat/engine/clients/os/ironic.py +++ b/heat/engine/clients/os/ironic.py @@ -14,6 +14,7 @@ from ironicclient.common.apiclient import exceptions as ic_exc from ironicclient.v1 import client as ironic_client from oslo_config import cfg +from oslo_utils import versionutils from heat.common import exception from heat.engine.clients import client_plugin @@ -25,11 +26,11 @@ CLIENT_NAME = 'ironic' class IronicClientPlugin(client_plugin.ClientPlugin): service_types = [BAREMETAL] = ['baremetal'] - IRONIC_API_VERSION = 1.58 + IRONIC_API_VERSION = '1.58' max_ironic_api_microversion = cfg.CONF.max_ironic_api_microversion max_microversion = max_ironic_api_microversion if ( - max_ironic_api_microversion is not None and ( - IRONIC_API_VERSION > max_ironic_api_microversion) + max_ironic_api_microversion and not versionutils.is_compatible( + IRONIC_API_VERSION, max_ironic_api_microversion) ) else IRONIC_API_VERSION def _create(self): diff --git a/heat/engine/resources/openstack/ironic/port.py b/heat/engine/resources/openstack/ironic/port.py index 1b98040a52..471c9cec53 100644 --- a/heat/engine/resources/openstack/ironic/port.py +++ b/heat/engine/resources/openstack/ironic/port.py @@ -11,6 +11,8 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_utils import versionutils + from heat.common import exception from heat.common.i18n import _ from heat.engine import attributes @@ -43,10 +45,11 @@ class Port(resource.Resource): 'physical_network', 'extra', 'is_smartnic', ) PROPERTIES_MIN_SUPPORT_VERSION = ( - (PXE_ENABLED, 1.19), - (LOCAL_LINK_CONNECTION, 1.191), - (PORTGROUP, 1.24), (PHYSICAL_NETWORK, 1.34), - (IS_SMARTNIC, 1.53) + (PXE_ENABLED, '1.19'), + (LOCAL_LINK_CONNECTION, '1.19'), + (PORTGROUP, '1.24'), + (PHYSICAL_NETWORK, '1.34'), + (IS_SMARTNIC, '1.53') ) ATTRIBUTES = ( @@ -186,9 +189,10 @@ class Port(resource.Resource): def _check_supported(self, properties): # TODO(ricolin) Implement version support in property schema. + max_microversion = self.client_plugin().max_microversion for k, v in self.PROPERTIES_MIN_SUPPORT_VERSION: if k in properties and properties[k] is not None and ( - self.client_plugin().max_microversion < v + not versionutils.is_compatible(v, max_microversion) ): raise exception.NotSupported( feature="OS::Ironic::Port with %s property" % k) diff --git a/heat/tests/openstack/ironic/test_port.py b/heat/tests/openstack/ironic/test_port.py index 4e9326f544..ad99b3e340 100644 --- a/heat/tests/openstack/ironic/test_port.py +++ b/heat/tests/openstack/ironic/test_port.py @@ -65,7 +65,7 @@ RESOURCE_TYPE = 'OS::Ironic::Port' class TestIronicPort(common.HeatTestCase): def setUp(self): super(TestIronicPort, self).setUp() - cfg.CONF.set_override('max_ironic_api_microversion', 1.11) + cfg.CONF.set_override('max_ironic_api_microversion', '1.11') cfg.CONF.set_override('action_retry_limit', 0) self.fake_node_name = 'node_1' self.fake_portgroup_name = 'pg1' @@ -182,7 +182,7 @@ class TestIronicPort(common.HeatTestCase): p = self._create_resource('port-with-%s' % property_name, new_port, self.stack) - p.client_plugin().max_microversion = version - 0.01 + p.client_plugin().max_microversion = version feature = "OS::Ironic::Port with %s property" % property_name err = self.assertRaises(exception.ResourceFailure, @@ -193,19 +193,19 @@ class TestIronicPort(common.HeatTestCase): str(err)) def test_port_create_with_pxe_enabled_not_supported(self): - self._property_not_supported(port.Port.PXE_ENABLED, 1.19) + self._property_not_supported(port.Port.PXE_ENABLED, '1.18') def test_port_create_with_local_link_connection_not_supported(self): - self._property_not_supported(port.Port.LOCAL_LINK_CONNECTION, 1.19) + self._property_not_supported(port.Port.LOCAL_LINK_CONNECTION, '1.18') def test_port_create_with_portgroup_not_supported(self): - self._property_not_supported(port.Port.PORTGROUP, 1.24) + self._property_not_supported(port.Port.PORTGROUP, '1.23') def test_port_create_with_physical_network_not_supported(self): - self._property_not_supported(port.Port.PHYSICAL_NETWORK, 1.34) + self._property_not_supported(port.Port.PHYSICAL_NETWORK, '1.33') def test_port_create_with_is_smartnic_not_supported(self): - self._property_not_supported(port.Port.IS_SMARTNIC, 1.53) + self._property_not_supported(port.Port.IS_SMARTNIC, '1.52') def test_port_check_create_complete(self): b = self._create_resource('port', self.rsrc_defn, self.stack) diff --git a/releasenotes/notes/microversion-string-2e6dd033e046420f.yaml b/releasenotes/notes/microversion-string-2e6dd033e046420f.yaml new file mode 100644 index 0000000000..bd0943fef3 --- /dev/null +++ b/releasenotes/notes/microversion-string-2e6dd033e046420f.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Changed type of the following parameters from integer to string, to + correctly parse micro versions with trailing zero (e.g. 2.20). + + - ``[DEFAULT] max_nova_api_microversion`` + - ``[DEFAULT] max_ironic_api_microversion``