Add functions to parse tripleo RHOSP release
Change-Id: Ifa7bad7af07e0ab517d76a9d386f986f175bf643
This commit is contained in:
parent
ff0c3d84fd
commit
3b56760264
@ -204,13 +204,17 @@ class UnknowOpenStackContainerNameError(tobiko.TobikoException):
|
|||||||
"topology class '{topology_class}'")
|
"topology class '{topology_class}'")
|
||||||
|
|
||||||
|
|
||||||
class OpenStackTopologyNode(object):
|
class OpenStackTopologyNode:
|
||||||
|
|
||||||
_docker_client = None
|
_docker_client = None
|
||||||
_podman_client = None
|
_podman_client = None
|
||||||
|
|
||||||
def __init__(self, topology, name: str, ssh_client: ssh.SSHClientFixture,
|
def __init__(self,
|
||||||
addresses: typing.Iterable[netaddr.IPAddress], hostname: str):
|
topology: 'OpenStackTopology',
|
||||||
|
name: str,
|
||||||
|
ssh_client: ssh.SSHClientFixture,
|
||||||
|
addresses: typing.Iterable[netaddr.IPAddress],
|
||||||
|
hostname: str):
|
||||||
self._topology = weakref.ref(topology)
|
self._topology = weakref.ref(topology)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.ssh_client = ssh_client
|
self.ssh_client = ssh_client
|
||||||
@ -411,7 +415,8 @@ class OpenStackTopology(tobiko.SharedFixture):
|
|||||||
hostname: typing.Optional[str] = None,
|
hostname: typing.Optional[str] = None,
|
||||||
address: typing.Optional[str] = None,
|
address: typing.Optional[str] = None,
|
||||||
group: typing.Optional[str] = None,
|
group: typing.Optional[str] = None,
|
||||||
ssh_client: typing.Optional[ssh.SSHClientFixture] = None) \
|
ssh_client: typing.Optional[ssh.SSHClientFixture] = None,
|
||||||
|
**create_params) \
|
||||||
-> OpenStackTopologyNode:
|
-> OpenStackTopologyNode:
|
||||||
if ssh_client is not None:
|
if ssh_client is not None:
|
||||||
# detect all global addresses from remote server
|
# detect all global addresses from remote server
|
||||||
@ -434,7 +439,8 @@ class OpenStackTopology(tobiko.SharedFixture):
|
|||||||
except _exception.NoSuchOpenStackTopologyNode:
|
except _exception.NoSuchOpenStackTopologyNode:
|
||||||
node = self._add_node(addresses=addresses,
|
node = self._add_node(addresses=addresses,
|
||||||
hostname=hostname,
|
hostname=hostname,
|
||||||
ssh_client=ssh_client)
|
ssh_client=ssh_client,
|
||||||
|
**create_params)
|
||||||
|
|
||||||
if group:
|
if group:
|
||||||
# Add group anyway even if the node hasn't been added
|
# Add group anyway even if the node hasn't been added
|
||||||
@ -448,7 +454,8 @@ class OpenStackTopology(tobiko.SharedFixture):
|
|||||||
def _add_node(self,
|
def _add_node(self,
|
||||||
addresses: typing.List[netaddr.IPAddress],
|
addresses: typing.List[netaddr.IPAddress],
|
||||||
hostname: str = None,
|
hostname: str = None,
|
||||||
ssh_client: typing.Optional[ssh.SSHClientFixture] = None):
|
ssh_client: ssh.SSHClientFixture = None,
|
||||||
|
**create_params):
|
||||||
if ssh_client is None:
|
if ssh_client is None:
|
||||||
ssh_client = self._ssh_connect(hostname=hostname,
|
ssh_client = self._ssh_connect(hostname=hostname,
|
||||||
addresses=addresses)
|
addresses=addresses)
|
||||||
@ -467,7 +474,8 @@ class OpenStackTopology(tobiko.SharedFixture):
|
|||||||
self._names[name] = node = self.create_node(name=name,
|
self._names[name] = node = self.create_node(name=name,
|
||||||
hostname=hostname,
|
hostname=hostname,
|
||||||
ssh_client=ssh_client,
|
ssh_client=ssh_client,
|
||||||
addresses=addresses)
|
addresses=addresses,
|
||||||
|
**create_params)
|
||||||
|
|
||||||
for address in addresses:
|
for address in addresses:
|
||||||
address_node = self._addresses.setdefault(address, node)
|
address_node = self._addresses.setdefault(address, node)
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@ -146,3 +147,11 @@ class OvercloudProcessesTest(testtools.TestCase):
|
|||||||
def test_overcloud_processes(self):
|
def test_overcloud_processes(self):
|
||||||
ops = processes.OvercloudProcessesStatus()
|
ops = processes.OvercloudProcessesStatus()
|
||||||
self.assertTrue(ops.basic_overcloud_processes_running)
|
self.assertTrue(ops.basic_overcloud_processes_running)
|
||||||
|
|
||||||
|
|
||||||
|
class OvercloudVersionTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@tripleo.skip_if_missing_undercloud
|
||||||
|
def test_overcloud_version(self):
|
||||||
|
version = tripleo.overcloud_version()
|
||||||
|
self.assertTrue(tobiko.match_version(version, min_version='13.0.0'))
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
|
import tobiko
|
||||||
from tobiko import config
|
from tobiko import config
|
||||||
from tobiko.shell import sh
|
from tobiko.shell import sh
|
||||||
from tobiko.openstack import keystone
|
from tobiko.openstack import keystone
|
||||||
@ -69,3 +72,11 @@ class UndercloudKeystoneClientTest(testtools.TestCase):
|
|||||||
client = tripleo.undercloud_keystone_client()
|
client = tripleo.undercloud_keystone_client()
|
||||||
services = keystone.list_services(client=client)
|
services = keystone.list_services(client=client)
|
||||||
self.assertTrue(services)
|
self.assertTrue(services)
|
||||||
|
|
||||||
|
|
||||||
|
class UndercloudVersionTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@tripleo.skip_if_missing_undercloud
|
||||||
|
def test_undercloud_version(self):
|
||||||
|
version = tripleo.undercloud_version()
|
||||||
|
self.assertTrue(tobiko.match_version(version, min_version='13.0.0'))
|
||||||
|
@ -15,6 +15,7 @@ from __future__ import absolute_import
|
|||||||
|
|
||||||
from tobiko.tripleo import _ansible
|
from tobiko.tripleo import _ansible
|
||||||
from tobiko.tripleo import _overcloud as overcloud
|
from tobiko.tripleo import _overcloud as overcloud
|
||||||
|
from tobiko.tripleo import _rhosp
|
||||||
from tobiko.tripleo import _topology as topology
|
from tobiko.tripleo import _topology as topology
|
||||||
from tobiko.tripleo import _undercloud as undercloud
|
from tobiko.tripleo import _undercloud as undercloud
|
||||||
|
|
||||||
@ -40,8 +41,12 @@ load_overcloud_rcfile = overcloud.load_overcloud_rcfile
|
|||||||
overcloud_host_config = overcloud.overcloud_host_config
|
overcloud_host_config = overcloud.overcloud_host_config
|
||||||
overcloud_node_ip_address = overcloud.overcloud_node_ip_address
|
overcloud_node_ip_address = overcloud.overcloud_node_ip_address
|
||||||
overcloud_ssh_client = overcloud.overcloud_ssh_client
|
overcloud_ssh_client = overcloud.overcloud_ssh_client
|
||||||
|
overcloud_version = overcloud.overcloud_version
|
||||||
skip_if_missing_overcloud = overcloud.skip_if_missing_overcloud
|
skip_if_missing_overcloud = overcloud.skip_if_missing_overcloud
|
||||||
|
|
||||||
|
get_rhosp_release = _rhosp.get_rhosp_release
|
||||||
|
get_rhosp_version = _rhosp.get_rhosp_version
|
||||||
|
|
||||||
TripleoTopology = topology.TripleoTopology
|
TripleoTopology = topology.TripleoTopology
|
||||||
|
|
||||||
load_undercloud_rcfile = undercloud.load_undercloud_rcfile
|
load_undercloud_rcfile = undercloud.load_undercloud_rcfile
|
||||||
@ -52,3 +57,4 @@ undercloud_keystone_client = undercloud.undercloud_keystone_client
|
|||||||
undercloud_keystone_credentials = undercloud.undercloud_keystone_credentials
|
undercloud_keystone_credentials = undercloud.undercloud_keystone_credentials
|
||||||
undercloud_keystone_session = undercloud.undercloud_keystone_session
|
undercloud_keystone_session = undercloud.undercloud_keystone_session
|
||||||
undercloud_ssh_client = undercloud.undercloud_ssh_client
|
undercloud_ssh_client = undercloud.undercloud_ssh_client
|
||||||
|
undercloud_version = undercloud.undercloud_version
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import functools
|
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import typing
|
import typing
|
||||||
@ -41,19 +40,18 @@ def has_overcloud(min_version: str = None,
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if min_version or max_version:
|
if min_version or max_version:
|
||||||
if not tobiko.match_version(get_overcloud_version(),
|
if not tobiko.match_version(overcloud_version(),
|
||||||
min_version=min_version,
|
min_version=min_version,
|
||||||
max_version=max_version):
|
max_version=max_version):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache()
|
def overcloud_version() -> tobiko.Version:
|
||||||
def get_overcloud_version() -> tobiko.VersionType:
|
from tobiko.tripleo import _topology
|
||||||
ssh_client = topology.find_openstack_node(group='controller').ssh_client
|
node = topology.find_openstack_node(group='overcloud')
|
||||||
release = sh.execute('cat /etc/rhosp-release',
|
assert isinstance(node, _topology.TripleoTopologyNode)
|
||||||
ssh_client=ssh_client).stdout
|
return node.rhosp_version
|
||||||
return tobiko.parse_version(release)
|
|
||||||
|
|
||||||
|
|
||||||
def load_overcloud_rcfile() -> typing.Dict[str, str]:
|
def load_overcloud_rcfile() -> typing.Dict[str, str]:
|
||||||
|
35
tobiko/tripleo/_rhosp.py
Normal file
35
tobiko/tripleo/_rhosp.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# 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 functools
|
||||||
|
|
||||||
|
import tobiko
|
||||||
|
from tobiko.shell import sh
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache()
|
||||||
|
def get_rhosp_release(connection: sh.ShellConnectionType = None) \
|
||||||
|
-> str:
|
||||||
|
connection = sh.shell_connection(connection)
|
||||||
|
with connection.open_file('/etc/rhosp-release', 'r') as fd:
|
||||||
|
rhosp_release = fd.read().strip()
|
||||||
|
if isinstance(rhosp_release, bytes):
|
||||||
|
rhosp_release = rhosp_release.decode('UTF-8', 'ignore')
|
||||||
|
return rhosp_release
|
||||||
|
|
||||||
|
|
||||||
|
def get_rhosp_version(connection: sh.ShellConnectionType = None) \
|
||||||
|
-> tobiko.Version:
|
||||||
|
return tobiko.parse_version(get_rhosp_release(connection))
|
@ -17,17 +17,20 @@ import re
|
|||||||
import typing
|
import typing
|
||||||
|
|
||||||
import metalsmith
|
import metalsmith
|
||||||
|
import netaddr
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
|
import tobiko
|
||||||
from tobiko.openstack import neutron
|
from tobiko.openstack import neutron
|
||||||
from tobiko.openstack import nova
|
from tobiko.openstack import nova
|
||||||
from tobiko.openstack import topology
|
from tobiko.openstack import topology
|
||||||
from tobiko.shell import files
|
from tobiko.shell import files
|
||||||
from tobiko.shell import sh
|
from tobiko.shell import sh
|
||||||
|
from tobiko.shell import ssh
|
||||||
from tobiko.tripleo import _overcloud
|
from tobiko.tripleo import _overcloud
|
||||||
|
from tobiko.tripleo import _rhosp
|
||||||
from tobiko.tripleo import _undercloud
|
from tobiko.tripleo import _undercloud
|
||||||
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -89,7 +92,7 @@ class TripleoTopology(topology.OpenStackTopology):
|
|||||||
ssh_client=ssh_client)
|
ssh_client=ssh_client)
|
||||||
|
|
||||||
def discover_overcloud_nodes(self):
|
def discover_overcloud_nodes(self):
|
||||||
if _overcloud.has_overcloud():
|
if _undercloud.has_undercloud():
|
||||||
for instance in _overcloud.list_overcloud_nodes():
|
for instance in _overcloud.list_overcloud_nodes():
|
||||||
try:
|
try:
|
||||||
_overcloud.power_on_overcloud_node(instance)
|
_overcloud.power_on_overcloud_node(instance)
|
||||||
@ -103,9 +106,9 @@ class TripleoTopology(topology.OpenStackTopology):
|
|||||||
host_config=host_config)
|
host_config=host_config)
|
||||||
node = self.add_node(address=host_config.hostname,
|
node = self.add_node(address=host_config.hostname,
|
||||||
group='overcloud',
|
group='overcloud',
|
||||||
ssh_client=ssh_client)
|
ssh_client=ssh_client,
|
||||||
|
overcloud_instance=instance)
|
||||||
assert isinstance(node, TripleoTopologyNode)
|
assert isinstance(node, TripleoTopologyNode)
|
||||||
node.overcloud_instance = instance
|
|
||||||
self.discover_overcloud_node_subgroups(node)
|
self.discover_overcloud_node_subgroups(node)
|
||||||
|
|
||||||
def discover_overcloud_node_subgroups(self, node):
|
def discover_overcloud_node_subgroups(self, node):
|
||||||
@ -138,7 +141,32 @@ class TripleoTopology(topology.OpenStackTopology):
|
|||||||
|
|
||||||
class TripleoTopologyNode(topology.OpenStackTopologyNode):
|
class TripleoTopologyNode(topology.OpenStackTopologyNode):
|
||||||
|
|
||||||
overcloud_instance: typing.Optional[metalsmith.Instance] = None
|
def __init__(self,
|
||||||
|
topology: topology.OpenStackTopology,
|
||||||
|
name: str,
|
||||||
|
ssh_client: ssh.SSHClientFixture,
|
||||||
|
addresses: typing.Iterable[netaddr.IPAddress],
|
||||||
|
hostname: str,
|
||||||
|
overcloud_instance: metalsmith.Instance = None,
|
||||||
|
rhosp_version: tobiko.Version = None):
|
||||||
|
# pylint: disable=redefined-outer-name
|
||||||
|
super().__init__(topology=topology,
|
||||||
|
name=name,
|
||||||
|
ssh_client=ssh_client,
|
||||||
|
addresses=addresses,
|
||||||
|
hostname=hostname)
|
||||||
|
self._overcloud_instance = overcloud_instance
|
||||||
|
self._rhosp_version = rhosp_version
|
||||||
|
|
||||||
|
@property
|
||||||
|
def overcloud_instance(self) -> typing.Optional[metalsmith.Instance]:
|
||||||
|
return self.overcloud_instance
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rhosp_version(self) -> tobiko.Version:
|
||||||
|
if self._rhosp_version is None:
|
||||||
|
self._rhosp_version = self._get_rhosp_version()
|
||||||
|
return self._rhosp_version
|
||||||
|
|
||||||
l3_agent_conf_path = (
|
l3_agent_conf_path = (
|
||||||
'/var/lib/config-data/neutron/etc/neutron/l3_agent.ini')
|
'/var/lib/config-data/neutron/etc/neutron/l3_agent.ini')
|
||||||
@ -202,6 +230,9 @@ class TripleoTopologyNode(topology.OpenStackTopologyNode):
|
|||||||
_overcloud.power_off_overcloud_node(instance=self.overcloud_instance)
|
_overcloud.power_off_overcloud_node(instance=self.overcloud_instance)
|
||||||
LOG.debug(f"Overcloud server node {self.name} power is off.")
|
LOG.debug(f"Overcloud server node {self.name} power is off.")
|
||||||
|
|
||||||
|
def _get_rhosp_version(self) -> tobiko.Version:
|
||||||
|
return _rhosp.get_rhosp_version(connection=self.connection)
|
||||||
|
|
||||||
|
|
||||||
def is_valid_overcloud_group_name(group_name: str, node_name: str = None):
|
def is_valid_overcloud_group_name(group_name: str, node_name: str = None):
|
||||||
if not group_name:
|
if not group_name:
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import functools
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import typing
|
import typing
|
||||||
@ -24,6 +25,8 @@ from tobiko import config
|
|||||||
from tobiko.openstack import keystone
|
from tobiko.openstack import keystone
|
||||||
from tobiko.shell import ssh
|
from tobiko.shell import ssh
|
||||||
from tobiko.shell import sh
|
from tobiko.shell import sh
|
||||||
|
from tobiko.tripleo import _rhosp
|
||||||
|
|
||||||
|
|
||||||
CONF = config.CONF
|
CONF = config.CONF
|
||||||
|
|
||||||
@ -197,3 +200,9 @@ def undercloud_keystone_session():
|
|||||||
|
|
||||||
def undercloud_keystone_credentials():
|
def undercloud_keystone_credentials():
|
||||||
return tobiko.setup_fixture(_get_keystone_credentials()).credentials
|
return tobiko.setup_fixture(_get_keystone_credentials()).credentials
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache()
|
||||||
|
def undercloud_version() -> tobiko.Version:
|
||||||
|
ssh_client = undercloud_ssh_client()
|
||||||
|
return _rhosp.get_rhosp_version(connection=ssh_client)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user