diff --git a/ironic_python_agent/config.py b/ironic_python_agent/config.py index c7afee015..b3c7eb15c 100644 --- a/ironic_python_agent/config.py +++ b/ironic_python_agent/config.py @@ -282,6 +282,11 @@ cli_opts = [ 'ipa-image-download-connection-retry-interval', 10), help='Interval (in seconds) between two attempts to establish ' 'connection when downloading an image.'), + cfg.StrOpt('ironic_api_version', + default=APARAMS.get('ipa-ironic-api-version', None), + help='Ironic API version in format "x.x". If not set, version ' + 'will be auto-detected. This is not a recommended ' + 'configuration.') ] diff --git a/ironic_python_agent/ironic_api_client.py b/ironic_python_agent/ironic_api_client.py index 4dbbf498d..141ed7bd8 100644 --- a/ironic_python_agent/ironic_api_client.py +++ b/ironic_python_agent/ironic_api_client.py @@ -88,19 +88,31 @@ class APIClient(object): return {'X-OpenStack-Ironic-API-Version': '%d.%d' % version} def _get_ironic_api_version(self): - if not self._ironic_api_version: + if self._ironic_api_version: + return self._ironic_api_version + + if CONF.ironic_api_version is not None: try: - response = self._request('GET', '/') - data = jsonutils.loads(response.content) - version = data['default_version']['version'].split('.') + version = CONF.ironic_api_version.split('.') self._ironic_api_version = (int(version[0]), int(version[1])) + return self._ironic_api_version except Exception: - LOG.exception("An error occurred while attempting to discover " - "the available Ironic API versions, falling " - "back to using version %s", - ".".join(map(str, MIN_IRONIC_VERSION))) - return MIN_IRONIC_VERSION - return self._ironic_api_version + LOG.exception("An error occurred while attempting to parse" + "the ironic_api_version. Will fall back to " + "auto-detection") + + try: + response = self._request('GET', '/') + data = jsonutils.loads(response.content) + version = data['default_version']['version'].split('.') + self._ironic_api_version = (int(version[0]), int(version[1])) + return self._ironic_api_version + except Exception: + LOG.exception("An error occurred while attempting to discover " + "the available Ironic API versions, falling " + "back to using version %s", + ".".join(map(str, MIN_IRONIC_VERSION))) + return MIN_IRONIC_VERSION def supports_auto_tls(self): return self._get_ironic_api_version() >= AGENT_VERIFY_CA_IRONIC_VERSION diff --git a/ironic_python_agent/tests/unit/test_ironic_api_client.py b/ironic_python_agent/tests/unit/test_ironic_api_client.py index 7773aa755..07f6f0cba 100644 --- a/ironic_python_agent/tests/unit/test_ironic_api_client.py +++ b/ironic_python_agent/tests/unit/test_ironic_api_client.py @@ -14,6 +14,7 @@ from unittest import mock +from oslo_config import cfg from oslo_serialization import jsonutils import requests @@ -25,6 +26,8 @@ from ironic_python_agent import version API_URL = 'http://agent-api.ironic.example.org/' +CONF = cfg.CONF + class FakeResponse(object): def __init__(self, content=None, status_code=200, headers=None): @@ -74,6 +77,16 @@ class TestBaseIronicPythonAgent(base.IronicAgentTest): self.assertEqual(ironic_api_client.MIN_IRONIC_VERSION, self.api_client._get_ironic_api_version()) + def test__get_ironic_api_version_set_via_conf(self): + self.api_client._ironic_api_version = None + CONF.set_override('ironic_api_version', "1.47") + self.api_client.session.request = mock.create_autospec( + self.api_client.session.request, + return_value=None) + + self.assertEqual((1, 47), self.api_client._get_ironic_api_version()) + self.assertFalse(self.api_client.session.request.called) + def test__get_ironic_api_version_error(self): self.api_client._ironic_api_version = None self.api_client.session.request = mock.create_autospec( diff --git a/releasenotes/notes/manually-configure-ironic-api-version-517afd0a423036ad.yaml b/releasenotes/notes/manually-configure-ironic-api-version-517afd0a423036ad.yaml new file mode 100644 index 000000000..3f4e02bc2 --- /dev/null +++ b/releasenotes/notes/manually-configure-ironic-api-version-517afd0a423036ad.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Deployers in highly-secure environments can now manually set Ironic API + version instead of relying on unauthentication autodetection via + ipa-ironic-api-version on the kernel command line. This is not a + reccomended configuration.