diff --git a/tobiko/shiftstack/__init__.py b/tobiko/shiftstack/__init__.py index 3429fd0fc..d65951c28 100644 --- a/tobiko/shiftstack/__init__.py +++ b/tobiko/shiftstack/__init__.py @@ -14,6 +14,13 @@ from __future__ import absolute_import from tobiko.shiftstack import _clouds_file +from tobiko.shiftstack import _nova +from tobiko.shiftstack import _skip ShiftStackCloudsFileFixture = _clouds_file.ShiftStackCloudsFileFixture get_clouds_file_path = _clouds_file.get_clouds_file_path + +find_shiftstack_node = _nova.find_shiftstack_node +list_shiftstack_nodes = _nova.list_shiftstack_nodes + +skip_unless_has_shiftstack = _skip.skip_unless_has_shiftstack diff --git a/tobiko/shiftstack/_keystone.py b/tobiko/shiftstack/_keystone.py new file mode 100644 index 000000000..47dda1acb --- /dev/null +++ b/tobiko/shiftstack/_keystone.py @@ -0,0 +1,49 @@ +# Copyright 2022 Red Hat +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from __future__ import absolute_import + +import tobiko +from tobiko.openstack import keystone +from tobiko.shiftstack import _clouds_file + + +class ShiftstackKeystoneCredentialsFixture( + keystone.CloudsFileKeystoneCredentialsFixture): + + clouds_file_fixture = tobiko.required_fixture( + _clouds_file.ShiftStackCloudsFileFixture, setup=False) + + def __init__(self, + cloud_name: str = None, + clouds_file: str = None): + if clouds_file is None: + clouds_file = self.clouds_file_fixture.local_clouds_file_path + if cloud_name is None: + cloud_name = tobiko.tobiko_config().shiftstack.cloud_name + super().__init__(clouds_file=clouds_file, + cloud_name=cloud_name) + + def setup_fixture(self): + tobiko.setup_fixture(self.clouds_file_fixture) + super().setup_fixture() + + +def shiftstack_keystone_session(): + return keystone.get_keystone_session( + credentials=ShiftstackKeystoneCredentialsFixture) + + +def shiftstack_keystone_credentials(): + return tobiko.setup_fixture( + ShiftstackKeystoneCredentialsFixture).credentials diff --git a/tobiko/shiftstack/_nova.py b/tobiko/shiftstack/_nova.py new file mode 100644 index 000000000..ec2ea4cf2 --- /dev/null +++ b/tobiko/shiftstack/_nova.py @@ -0,0 +1,42 @@ +# Copyright 2022 Red Hat +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from __future__ import absolute_import + +import tobiko +from tobiko.openstack import nova +from tobiko.shiftstack import _keystone + + +def shiftstack_nova_client(obj: nova.NovaClientType) -> nova.NovaClient: + if obj is None: + return get_shiftstack_nova_client() + else: + return tobiko.check_valid_type(obj, nova.NovaClient) + + +def get_shiftstack_nova_client() -> nova.NovaClient: + session = _keystone.shiftstack_keystone_session() + return nova.get_nova_client(session=session) + + +def list_shiftstack_nodes(client: nova.NovaClientType = None, + **params): + client = shiftstack_nova_client(client) + return nova.list_servers(client=client, **params) + + +def find_shiftstack_node(client: nova.NovaClientType = None, + **params): + client = shiftstack_nova_client(client) + return nova.find_server(client=client, **params) diff --git a/tobiko/shiftstack/_skip.py b/tobiko/shiftstack/_skip.py new file mode 100644 index 000000000..df1ad1444 --- /dev/null +++ b/tobiko/shiftstack/_skip.py @@ -0,0 +1,51 @@ +# Copyright 2022 Red Hat +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from __future__ import absolute_import + +from oslo_log import log + +import tobiko +from tobiko.shiftstack import _keystone + + +LOG = log.getLogger(__name__) + + +class HasShiftstackFixture(tobiko.SharedFixture): + + def __init__(self, + has_shiftstack: bool = None): + # pylint: disable=redefined-outer-name + super(HasShiftstackFixture, self).__init__() + self.has_shiftstack = has_shiftstack + + def setup_fixture(self): + if self.has_shiftstack is None: + try: + _keystone.shiftstack_keystone_session() + except Exception: + LOG.debug('Shifstack credentials not found', exc_info=1) + self.has_shiftstack = False + else: + LOG.debug('Shifstack credentials was found') + self.has_shiftstack = True + + +def has_shiftstack() -> bool: + return tobiko.setup_fixture(HasShiftstackFixture).has_shiftstack + + +def skip_unless_has_shiftstack(): + return tobiko.skip_unless("Shifstack credentials not found", + predicate=has_shiftstack) diff --git a/tobiko/shiftstack/config.py b/tobiko/shiftstack/config.py index a84c578c5..083f1d391 100644 --- a/tobiko/shiftstack/config.py +++ b/tobiko/shiftstack/config.py @@ -27,6 +27,9 @@ OPTIONS = [ cfg.StrOpt('remote_clouds_file_path', default='~/clouds.yaml', help="remote clouds file path on undercloud-0 host"), + cfg.StrOpt('cloud_name', + default='shiftstack', + help="Keystone credentials cloud name"), ] diff --git a/tobiko/tests/functional/shiftstack/__init__.py b/tobiko/tests/functional/shiftstack/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tobiko/tests/functional/shiftstack/test_nova.py b/tobiko/tests/functional/shiftstack/test_nova.py new file mode 100644 index 000000000..084654cdf --- /dev/null +++ b/tobiko/tests/functional/shiftstack/test_nova.py @@ -0,0 +1,34 @@ +# Copyright 2022 Red Hat +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from __future__ import absolute_import + +import testtools + +import tobiko +from tobiko import shiftstack + + +@shiftstack.skip_unless_has_shiftstack() +class ShiftstackNovaTest(testtools.TestCase): + + def test_list_shifstack_nodes(self): + nodes = shiftstack.list_shiftstack_nodes() + self.assertIsInstance(nodes, tobiko.Selection) + self.assertNotEqual([], nodes) + return nodes + + def test_find_shifstack_nodes(self): + nodes = self.test_list_shifstack_nodes() + node = shiftstack.find_shiftstack_node(name=nodes.first.name) + self.assertEqual(nodes.first.id, node.id)