From fef5c46ec1df47fd7865a93448da7dc563f30cfe Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Tue, 26 Mar 2024 15:01:48 +0100 Subject: [PATCH 01/20] Update unit tests Signed-off-by: Anja Strunk --- cli.py | 6 +- config/config.yaml | 261 +++++++------ generator/common/config.py | 2 + generator/common/const.py | 11 + generator/common/gx_schema.py | 12 +- generator/discovery/openstack/discovery.py | 46 +++ .../openstack/openstack_discovery.py | 47 +-- .../openstack/server_flavor_discovery.py | 324 +++++++++++++++++ .../openstack/vm_images_discovery.py | 184 ++++------ tests/common.py | 66 +++- .../data/{vm_image_2.json => credential.json} | 106 ++++++ tests/test_cli.py | 9 +- tests/test_openstack_discovery.py | 62 ---- tests/test_server_flavor_discovery.py | 342 ++++++++++++++++++ tests/test_vm_image_discovery.py | 6 +- 15 files changed, 1140 insertions(+), 344 deletions(-) create mode 100644 generator/discovery/openstack/discovery.py create mode 100644 generator/discovery/openstack/server_flavor_discovery.py rename tests/data/{vm_image_2.json => credential.json} (58%) delete mode 100644 tests/test_openstack_discovery.py create mode 100644 tests/test_server_flavor_discovery.py diff --git a/cli.py b/cli.py index 242128a..6498f23 100755 --- a/cli.py +++ b/cli.py @@ -15,12 +15,11 @@ import click import openstack as os -import rdflib import yaml import generator.common.json_ld as json_ld from generator.common.config import Config -from generator.discovery.openstack.openstack_discovery import OsCloud +from generator.discovery.openstack.discovery import OsCloud SHAPES_FILE_FORMAT = "turtle" DATA_FILE_FORMAT = "json-ld" @@ -65,11 +64,10 @@ def openstack(cloud, timeout, config): os_cloud = OsCloud(conn, Config(config_dict)) # run discovery - creds = os_cloud.discover_properties() + creds = os_cloud.discover() props = json_ld.get_json_ld_context() props["@graph"] = creds - json_text = json.dumps(props, indent=4, default=json_ld.to_json_ld) print(json.dumps(props, indent=4, default=json_ld.to_json_ld)) diff --git a/config/config.yaml b/config/config.yaml index 1d3201d..7754334 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -1,121 +1,146 @@ -default: - operating system: - Alpine Linux: - copyright owner: "Alpine Linux" - resource policy: "default: allow intent" - license: - - https://gitlab.alpinelinux.org/alpine/aports/-/issues/9074 - Arch Linux: - copyright owner: "Judd Vinet, Aaron Griffin, Levente Polyák and others" - resource policy: "default: allow intent" - license: - - https://gitlab.archlinux.org/archlinux - CentOS Linux: - copyright owner: "The CentOS Project and others" - resource policy: "default: allow intent" - license: - - https://github.com/CentOS/ - Debian: - copyright owner: "Ian Murdock and others" - resource policy: "default: allow intent" - license: - - https://www.debian.org/legal/licenses/index.en.html - Fedora: - copyright owner: "Fedora-Project" - resource policy: "default: allow intent" - license: - - https://docs.fedoraproject.org/en-US/legal/fedora-linux-license/ - FreeBSD: - copyright owner: "The FreeBSD Project" - resource policy: "default: allow intent" - license: - - GPL-3.0-only - - LGPL-2.0 - Gentoo Linux: - copyright owner: "Gentoo Foundation, Inc." - resource policy: "default: allow intent" - license: - - https://www.gentoo.org/glep/glep-0076.html - Mandrakelinux: - copyright owner: "Mandriva Linux" - resource policy: "default: allow intent" - license: - - GPL-3.0-only - Mandriva Linux: - copyright owner: "Mandriva S. A." - resource policy: "default: allow intent" - license: - - GPL-3.0-only - Mandriva Enterprise Server: - copyright owner: "Mandriva S. A." - resource policy: "default: allow intent" - license: - - GPL-3.0-only - MS-DOS: - copyright owner: "Microsoft Corporation" - resource policy: "default: allow intent" - license: - - https://www.microsoft.com/licensing/docs/view/Licensing-Guides - NetBSD: - copyright owner: "The NetBSD Foundation" - resource policy: "default: allow intent" - license: - - https://www.netbsd.org/about/redistribution.html - Novell NetWare: - copyright owner: "Micro Focus International" - resource policy: "default: allow intent" - license: - - https://support.novell.com/techcenter/articles/ana19960702.html - OpenBSD: - copyright owner: "OpenBSD" - resource policy: "default: allow intent" - license: - - https://www.openbsd.org/policy.html - OpenSolaris: - copyright owner: "Sun Microsystems" - resource policy: "default: allow intent" - license: - - https://opensource.apple.com/source/xnu/xnu-2050.7.9/tools/tests/libMicro/OPENSOLARIS.LICENSE.auto.html - openSUSE: - copyright owner: "openSUSE contributors & others" - resource policy: "default: allow intent" - license: - - https://en.opensuse.org/openSUSE:License - Rocky Linux: - copyright owner: "Rocky Enterprise Software Foundation" - resource policy: "default: allow intent" - license: - - https://rockylinux.org/licensing - Red Hat Enterprise Linux: - copyright owner: "Red Hat, Inc." - resource policy: "default: allow intent" - license: - - https://www.redhat.com/en/store/red-hat-enterprise-linux-server - SUSE Linux Enterprise Server: - copyright owner: "SUSE" - resource policy: "default: allow intent" - license: - - https://www.suse.com/products/terms_and_conditions.pdf - Ubuntu: - copyright owner: "Canonical" - resource policy: "default: allow intent" - license: - - https://ubuntu.com/legal/open-source-licences - Microsoft Windows: - copyright owner: "Microsoft Corporation" - resource policy: "default: allow intent" - license: - - https://www.microsoft.com/licensing - CirrOS: - copyright owner: "Canonical Ltd." - resource policy: "default: allow intent" - license: - - GPL-2.0-only - AlmaLinux: - copyright owner: "Canonical Ltd." - resource policy: "default: allow intent" - license: - - https://almalinux.org/p/the-almalinux-os-licensing-policy/ +software resources: + Alpine Linux: + copyright owner: "Alpine Linux" + resource policy: "default: allow intent" + license: + - https://gitlab.alpinelinux.org/alpine/aports/-/issues/9074 + Arch Linux: + copyright owner: "Judd Vinet, Aaron Griffin, Levente Polyák and others" + resource policy: "default: allow intent" + license: + - https://gitlab.archlinux.org/archlinux + CentOS Linux: + copyright owner: "The CentOS Project and others" + resource policy: "default: allow intent" + license: + - https://github.com/CentOS/ + Debian: + copyright owner: "Ian Murdock and others" + resource policy: "default: allow intent" + license: + - https://www.debian.org/legal/licenses/index.en.html + Fedora: + copyright owner: "Fedora-Project" + resource policy: "default: allow intent" + license: + - https://docs.fedoraproject.org/en-US/legal/fedora-linux-license/ + FreeBSD: + copyright owner: "The FreeBSD Project" + resource policy: "default: allow intent" + license: + - GPL-3.0-only + - LGPL-2.0 + Gentoo Linux: + copyright owner: "Gentoo Foundation, Inc." + resource policy: "default: allow intent" + license: + - https://www.gentoo.org/glep/glep-0076.html + Mandrakelinux: + copyright owner: "Mandriva Linux" + resource policy: "default: allow intent" + license: + - GPL-3.0-only + Mandriva Linux: + copyright owner: "Mandriva S. A." + resource policy: "default: allow intent" + license: + - GPL-3.0-only + Mandriva Enterprise Server: + copyright owner: "Mandriva S. A." + resource policy: "default: allow intent" + license: + - GPL-3.0-only + MS-DOS: + copyright owner: "Microsoft Corporation" + resource policy: "default: allow intent" + license: + - https://www.microsoft.com/licensing/docs/view/Licensing-Guides + NetBSD: + copyright owner: "The NetBSD Foundation" + resource policy: "default: allow intent" + license: + - https://www.netbsd.org/about/redistribution.html + Novell NetWare: + copyright owner: "Micro Focus International" + resource policy: "default: allow intent" + license: + - https://support.novell.com/techcenter/articles/ana19960702.html + OpenBSD: + copyright owner: "OpenBSD" + resource policy: "default: allow intent" + license: + - https://www.openbsd.org/policy.html + OpenSolaris: + copyright owner: "Sun Microsystems" + resource policy: "default: allow intent" + license: + - https://opensource.apple.com/source/xnu/xnu-2050.7.9/tools/tests/libMicro/OPENSOLARIS.LICENSE.auto.html + openSUSE: + copyright owner: "openSUSE contributors & others" + resource policy: "default: allow intent" + license: + - https://en.opensuse.org/openSUSE:License + Rocky Linux: + copyright owner: "Rocky Enterprise Software Foundation" + resource policy: "default: allow intent" + license: + - https://rockylinux.org/licensing + Red Hat Enterprise Linux: + copyright owner: "Red Hat, Inc." + resource policy: "default: allow intent" + license: + - https://www.redhat.com/en/store/red-hat-enterprise-linux-server + SUSE Linux Enterprise Server: + copyright owner: "SUSE" + resource policy: "default: allow intent" + license: + - https://www.suse.com/products/terms_and_conditions.pdf + Ubuntu: + copyright owner: "Canonical" + resource policy: "default: allow intent" + license: + - https://ubuntu.com/legal/open-source-licences + Microsoft Windows: + copyright owner: "Microsoft Corporation" + resource policy: "default: allow intent" + license: + - https://www.microsoft.com/licensing + CirrOS: + copyright owner: "Canonical Ltd." + resource policy: "default: allow intent" + license: + - GPL-2.0-only + AlmaLinux: + copyright owner: "Canonical Ltd." + resource policy: "default: allow intent" + license: + - https://almalinux.org/p/the-almalinux-os-licensing-policy/ + Debian 11: + copyright owner: "AlmaLinux OS Foundation" + resource policy: "default: allow intent" + license: + - https://www.debian.org/legal/licenses/ + KVM: + copyright owner: "Qumranet" + resource policy: "default: allow intent" + license: + - GPL-2.0-or-later + - LGPL-3.0-or-later + Xen: + copyright owner: "The Linux Foundation" + resource policy: "default: allow intent" + license: + - GPL-2.0 + vmware: + copyright owner: "Broadcom" + resource policy: "default: allow intent" + license: + - https://www.vmware.com/support/support-resources/licensing.html + hyper-v: + copyright owner: "Microsoft Corporation" + resource policy: "default: allow intent" + license: + - https://www.microsoft.com/windows-server/pricing #cloud resources: # own images: # AlmaLinux 8: diff --git a/generator/common/config.py b/generator/common/config.py index 439fd5e..bb58394 100644 --- a/generator/common/config.py +++ b/generator/common/config.py @@ -1,6 +1,7 @@ from typing import List + def _get_value(config, keys: List[str]): if not keys: return config @@ -19,3 +20,4 @@ def __init__(self, config): def get_value(self, keys: List[str]): return _get_value(self.config, keys) + diff --git a/generator/common/const.py b/generator/common/const.py index 4498967..9bd4bec 100644 --- a/generator/common/const.py +++ b/generator/common/const.py @@ -8,6 +8,7 @@ UNIT_MB = "https://qudt.org/vocab/unit/MegaBYTE" UNIT_GB = "https://qudt.org/vocab/unit/GigaBYTE" +UNIT_GHZ = "https://qudt.org/vocab/unit/GigaHZ" CONFIG_VM_IMAGE = "vm image" CONFIG_RESOURCE_POLICY = "resource policy" @@ -19,9 +20,11 @@ CONFIG_WALLETS = "wallets" CONFIG_DEFAULT = "default" CONFIG_CLOUD_RESOURCES = "cloud resources:" +COMFIG_SOFTWARE = "software resources" CONFIG_FILESYSTEM_WALLET = "filesystem" CONFIG_XFSC_WALLET = "xfsc" + CONFIG_OS_ALP = "Alpine Linux" CONFIG_OS_ARCH = "Arch Linux" CONFIG_OS_CENTOS = "CentOS Linux" @@ -46,4 +49,12 @@ CONFIG_OS_CIRROS = "CirrOS" CONFIG_OS_ALMALINUX = "AlmaLinux" +CONFIG_HV_KVM = "KVM" +CONFIG_HV_QUEMU = "quemu" +CONFIG_HV_XEN = "Xen" +CONFIG_HV_ESXI = "ESXi" +CONFIG_HV_CH = "Cloud Hypervisor" +CONFIG_HV_VMW = "vmware" +CONFIG_HV_HYV = "hyper-v" + CONFIG_FILE = "config/config.yaml" diff --git a/generator/common/gx_schema.py b/generator/common/gx_schema.py index 18ced41..3e4c75f 100644 --- a/generator/common/gx_schema.py +++ b/generator/common/gx_schema.py @@ -2862,12 +2862,12 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.network is not None and not isinstance(self.network, str): self.network = str(self.network) - self._normalize_inlined_as_dict( - slot_name="additionalVolume", - slot_type=Disk, - key_name="diskSize", - keyed=False, - ) + #self._normalize_inlined_as_dict( + # slot_name="additionalVolume", + # slot_type=Disk, + # key_name="diskSize", + # keyed=False, + #) if self.confidentialComputing is not None and not isinstance( self.confidentialComputing, ConfidentialComputing diff --git a/generator/discovery/openstack/discovery.py b/generator/discovery/openstack/discovery.py new file mode 100644 index 0000000..ed5b670 --- /dev/null +++ b/generator/discovery/openstack/discovery.py @@ -0,0 +1,46 @@ +""""General openstack discovery class. + +(c) Anja Strunk , 2/2024 +SPDX-License-Identifier: EPL-2.0 +""" + +from abc import ABCMeta, abstractmethod +from typing import List + +from openstack.connection import Connection + +from generator.common import const +from generator.common.config import Config +from generator.common.json_ld import JsonLdObject +from generator.discovery.openstack.vm_images_discovery import VmDiscovery +from generator.discovery.openstack.server_flavor_discovery import ServerFlavorDiscovery + + +class OsCloud: + """Abstraction for openStack cloud with all its services.""" + + def __init__(self, conn: Connection, config: Config) -> None: + # import copy + self.conn = conn + # self.regions = list(conn.identity.regions()) + self.config = config + + def discover(self) -> List[JsonLdObject]: + """ + Discover all attributes of OS Cloud. + + @return: all attributes as list + @rtype List[JsonLdObject] + """ + creds = list() + + vi_dis = VmDiscovery(self.conn, self.config) + images = vi_dis.discover() + if images: + creds.extend(images) + sf_dis = ServerFlavorDiscovery(self.conn, self.config) + flavors = sf_dis.discover() + if flavors: + creds.extend(sf_dis.discover()) + + return creds \ No newline at end of file diff --git a/generator/discovery/openstack/openstack_discovery.py b/generator/discovery/openstack/openstack_discovery.py index f71a017..d4d6a0c 100644 --- a/generator/discovery/openstack/openstack_discovery.py +++ b/generator/discovery/openstack/openstack_discovery.py @@ -1,42 +1,33 @@ -#!/usr/bin/env python3 -# vim: set ts=4 sw=4 et: -# -# openstack_discovery.py -"""Script to generate GX Credentials in JSON-LD. - -(c) Kurt Garloff , 5/2023 -(c) Anja Strunk , 1/2024 -SPDX-License-Identifier: EPL-2.0 -""" - +from abc import ABCMeta,abstractmethod from typing import List from openstack.connection import Connection +from generator.common import const from generator.common.config import Config from generator.common.json_ld import JsonLdObject -from generator.discovery.openstack.vm_images_discovery import VmDiscovery -class OsCloud: - """Abstraction for openStack cloud with all its services.""" +class OpenStackDiscovery(metaclass=ABCMeta): - def __init__(self, conn: Connection, config: Config) -> None: - # import copy + def __init__(self, conn: Connection, conf: Config) -> None: self.conn = conn - # self.regions = list(conn.identity.regions()) - self.config = config + self.conf = conf + @abstractmethod + def discover(self) -> List[JsonLdObject]: + pass + + import generator.common.const as const + + def get_copyright_owner(self, software: str) -> List[str]: + return self.conf.get_value([const.COMFIG_SOFTWARE, software, const.CONFIG_COPYRIGHT]) + + def get_license(self, software: str) -> List[str]: + return self.conf.get_value([const.COMFIG_SOFTWARE,software,const.CONFIG_LICENSE]) + + def get_resource_policy(self, software: str) -> List[str]: + return self.conf.get_value([const.COMFIG_SOFTWARE,software,const.CONFIG_RESOURCE_POLICY]) - def discover_properties(self) -> List[JsonLdObject]: - """ - Discover all attributes of OS Cloud. - @return: all attributes as list - @rtype List[JsonLdObject] - """ - creds = list() - vm_dis = VmDiscovery(self.conn, self.config) - creds.extend(vm_dis.discover_vm_images()) - return creds diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py new file mode 100644 index 0000000..df0ee76 --- /dev/null +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -0,0 +1,324 @@ +"""Script to discovery server flavor properties. + +(c) Anja Strunk , 2/2024 +SPDX-License-Identifier: EPL-2.0 +""" + +import re +from typing import List, Tuple + +from generator.discovery.openstack.openstack_discovery import OpenStackDiscovery +from openstack.compute.v2.flavor import Flavor as OS_Flavor + +from generator.common import const +from generator.common.gx_schema import CPU +from generator.common.gx_schema import Architectures as CpuArch +from generator.common.gx_schema import (Disk, DiskBusType, DiskType, Frequency, + Hypervisor, Memory, MemorySize, + PermissibleValue) +from generator.common.gx_schema import ServerFlavor as GX_Flavor +from generator.common.json_ld import JsonLdObject + + +class ServerFlavorDiscovery(OpenStackDiscovery): + def discover(self) -> List[JsonLdObject]: + """ + Return one JsonLdObject for each public server flavor discovery at openstack cloud. + + @return: list of public server flavors + @rtype: list[JsonLdObject] + """ + flavors = list() + for fl in self.conn.list_flavors(): + if fl.is_public: + flavors.append(JsonLdObject(self._convert_to_gx(fl), gx_id=fl.id)) + return flavors + + def _convert_to_gx(self, os_flavor: OS_Flavor) -> GX_Flavor: + """ + Convert Openstack flavor to Gaia-X server flavor. + @param os_flavor: Openstack server flavor specification + @type os_flavor: Flavor + @return: Gaia-X server flavor specification + @rtype ServerFlavor + """ + + # Initialize Gaia-X Server Flavor + disks = self._get_disks(os_flavor) + gx_flavor = GX_Flavor( + # name=os_flavor.name, + cpu=self._get_cpu(os_flavor), + ram=self._get_ram(os_flavor), + bootVolume=disks[0], + ) + + if len(disks) > 1: + gx_flavor.additionalVolume = additionalVolume = disks[1:] + + # Discover optional attributes + self._parse_optional_flavor_properties(os_flavor, gx_flavor) + self._add_description(os_flavor, gx_flavor) + + return gx_flavor + + def _get_cpu(self, os_flavor: OS_Flavor) -> CPU: + """ + Return Gaia-X compliance CPU specification of given OpenStack flavor. + @param os_flavor: OpenStack flavor + @type os_flavor: OS_Flavor + @return: Gaia-X compliant CPU definition + @rtype CPU + """ + cpu = CPU(cpuArchitecture=CpuArch.other, numberOfCores=os_flavor.vcpus) + if os_flavor.name.startswith("SCS-"): + # parse SCS flavor name, second part contains CPU properties + parts = os_flavor.name.split("-") + if len(parts) >= 2 and re.search("\d[V,T,C,L]$", parts[1]): + cpu_suffix = parts[1][-1] + cpu.numberOfCores = int(parts[1][-2]) + if cpu_suffix.endswith("i"): + cpu_suffix = parts[1][-2] + cpu.numberOfCores = int(parts[1][-3]) + if cpu_suffix == "C": + cpu.smtEnabled = False + cpu.defaultOversubscriptionRatio = 1 + elif cpu_suffix.endswith("T"): + cpu.smtEnabled = True + cpu.defaultOversubscriptionRatio = 1 + elif cpu_suffix.endswith("V"): + cpu.smtEnabled = True + cpu.defaultOversubscriptionRatio = 5 + elif cpu_suffix.endswith("L"): + cpu.smtEnabled = True + cpu.defaultOversubscriptionRatio = 16 + return cpu + + def _get_ram(self, os_flavor: OS_Flavor) -> Memory: + """ + Return Gaia-X RAM definition specified in given OpenStack flavor. + @param os_flavor: OpenStack Flavor + @type Flavor + @return: Gaia-X compliance RAM definition + @rtype Memory + """ + size = MemorySize(value=float(os_flavor.ram), unit=const.UNIT_MB) + mem = Memory(memorySize=size) + if os_flavor.name.startswith("SCS-"): + # parse SCS flavor name + parts = os_flavor.name.split("-") + if len(parts) >= 3: + mem_cap = parts[2] + if mem_cap.endswith("ou"): + # this order of memory suffixes is not allows + return mem + elif mem_cap.endswith("uo"): + mem.eccEnabled = True + mem.defaultOversubscriptionRatio = 2 + mem.eccEnabled = True + mem.memorySize.value = float(mem_cap[0:-2]) + elif mem_cap.endswith("u"): + mem.eccEnabled = True + mem.memorySize.value = float(mem_cap[0:-1]) + elif mem_cap.endswith("o"): + mem.defaultOversubscriptionRatio = 2 + mem.memorySize.value = float(mem_cap[0:-1]) + else: + mem.memorySize.value = float(mem_cap) + return mem + + def _get_disks(self, os_flavor: OS_Flavor) -> List[Disk]: + """ + Return all disk specification found in given Openstack flavor. + @param os_flavor: Openstack flavor specification + @type os_flavor: Flavor + @return: list of Gaia-X disk specifications + """ + disks = [] + if os_flavor.name.startswith("SCS-"): + # parse SCS flavor name + parts = os_flavor.name.split("-") + if len(parts) < 4: + # either no SCS compliant flavor name or disk spec missing + disks.append( + Disk(diskSize=MemorySize(value=os_flavor.disk, unit=const.UNIT_GB)) + ) + else: + # SCS compliant flavor name with spec of disk capabilities + number, size, disk_type, disk_bus_types = self._get_disk_caps(parts[3]) + for i in range(int(number)): + disks.append( + Disk( + diskSize=MemorySize(value=size, unit=const.UNIT_GB), + diskType=disk_type, + diskBusType=disk_bus_types, + ) + ) + else: + # no SCS compliant flavor name. Use disk property to set disk spec + disks.append( + Disk(diskSize=MemorySize(value=os_flavor.disk, unit=const.UNIT_GB)) + ) + + return disks + + def _get_disk_caps(self, disk_caps: str) -> Tuple[int, int, DiskType, DiskBusType]: + """ + Extracts disk capabilities encoded in flavor name according to SCS flavor naming standard. + @param disk_caps: Disk capabilities encoded as string according to SCS flavor naming standard. + @type disk_caps: str + @return: + """ + disk_type = DiskType.other.text + disk_bus_types = DiskType.other.text + number = 1 + + # parse disk type and disk bus type + if re.search(r"\d+$", disk_caps): + # no disk type set + size = disk_caps[0 : len(disk_caps)] + else: + # disk type set + size = disk_caps[0 : len(disk_caps) - 1] + # parse disk type and disk bus type + if disk_caps.endswith("n"): + disk_type = "shared network storage" + elif disk_caps.endswith("h"): + disk_type = "local HDD" + elif disk_caps.endswith("s"): + disk_type = "local SSD" + elif disk_caps.endswith("p"): + disk_type = "local HDD" + disk_bus_types = "NVMe" + try: + number, size = size.split("x") + except ValueError: + if len(size) == 0: + # no size set + size = 0 + + return int(number), int(size), DiskType(disk_type), DiskBusType(disk_bus_types) + + def _parse_optional_flavor_properties( + self, os_flavor: OS_Flavor, gx_flavor: GX_Flavor + ): + """Parse and return optional flavor properties, such as CPU architecture, CPU frequency or hypervisor. + @param os_flavor Openstack flavor + @type os_flavor Flavor + @param gx_flavor Gaia-X Flavor specification + @type gx_flavor ServerFlavor + """ + parts = os_flavor.name.split("_") + for suffix in parts: + if suffix.startswith("SCS"): + continue + # parse hypervisor + elif suffix == "kvm": + gx_flavor.hypervisor = Hypervisor( + hypervisorType="KVM", + copyrightOwnedBy=self.get_copyright_owner( + const.CONFIG_HV_KVM + ), + license=self.get_license(const.CONFIG_HV_KVM), + resourcePolicy=self.get_resource_policy( + const.CONFIG_HV_KVM + ), + ) + elif suffix == "xen": + gx_flavor.hypervisor = Hypervisor( + hypervisorType="Xen", + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_HV_XEN + ), + license=self.get_license(const.CONFIG_HV_XEN), + resourcePolicy=self.get_resource_policy( + const.CONFIG_HV_XEN + ), + ) + elif suffix == "vmw": + gx_flavor.hypervisor = Hypervisor( + hypervisorType="KVM", + copyrightOwnedBy=self.get_copyright_owner( + const.CONFIG_HV_VMW + ), + license=self.get_license(const.CONFIG_HV_VMW), + resourcePolicy=self.get_resource_policy( + const.CONFIG_HV_VMW + ), + ) + elif suffix == "hyv": + gx_flavor.hypervisor = Hypervisor( + hypervisorType="Hyper-V", + copyrightOwnedBy=self.get_copyright_owner( + const.CONFIG_HV_HYV + ), + license=self.get_license(const.CONFIG_HV_HYV), + resourcePolicy=self.get_resource_policy( + const.CONFIG_HV_HYV + ), + ) + # parse hardware assisted virtualization + elif suffix == "hwv": + gx_flavor.hardwareAssistedVirtualization = True + # parse CPU architecture details + elif suffix.startswith("i"): + # Intel x86-64 + gx_flavor.cpu.cpuArchitecture = CpuArch("x86-64") + gx_flavor.cpu.vendor = "Intel" + if suffix.startswith("i0"): + gx_flavor.cpu.generation = "pre Skylake" + elif suffix.startswith("i1"): + gx_flavor.cpu.generation = "Skylake" + elif suffix.startswith("i2"): + gx_flavor.cpu.generation = "Cascade Lake" + elif suffix.startswith("i3"): + gx_flavor.cpu.generation = "Ice Lake" + elif suffix.startswith("i4"): + gx_flavor.cpu.generation = "Ice Lake" + elif suffix.startswith("z"): + # AMD (Zen) x86-64 + gx_flavor.cpu.cpuArchitecture = CpuArch("x86-64") + gx_flavor.cpu.vendor = "AMD" + if suffix.startswith("z0"): + gx_flavor.cpu.generation = "pre Zen" + elif suffix.startswith("z1"): + gx_flavor.cpu.generation = "Zen-1 (Naples)" + elif suffix.startswith("z2"): + gx_flavor.cpu.generation = "Zen-2 (Rome" + elif suffix.startswith("z3"): + gx_flavor.cpu.generation = "Zen-3 (Milan)" + elif suffix.startswith("z4"): + gx_flavor.cpu.generation = "Zen-4 (Genoa)" + elif suffix.startswith("a"): + # ARM v8+ + gx_flavor.cpu.cpuArchitecture = CpuArch("AArch-64") + gx_flavor.cpu.vendor = "ARM" + if suffix.startswith("a0"): + gx_flavor.cpu.generation = "pre Cortex A76" + elif suffix.startswith("a1"): + gx_flavor.cpu.generation = "A76/NeoN1 class" + elif suffix.startswith("a2"): + gx_flavor.cpu.generation = "A78/x1/NeoV1 class" + elif suffix.startswith("a3"): + gx_flavor.cpu.generation = "A71x/NeoN2 (ARMv9)" + elif suffix.startswith("r"): + # RISC-V + gx_flavor.cpu.cpuArchitecture = CpuArch("RISC-V") + # parse frequency + if suffix.endswith("hhh"): + gx_flavor.cpu.baseFrequency = Frequency(value=3.75, unit=const.UNIT_GHZ) + elif suffix.endswith("hh"): + gx_flavor.cpu.baseFrequency = Frequency(value=3.25, unit=const.UNIT_GHZ) + elif suffix.endswith("h"): + gx_flavor.cpu.baseFrequency = Frequency(value=2.75, unit=const.UNIT_GHZ) + + def _add_description(self, os_flavor: OS_Flavor, gx_flavor: GX_Flavor) -> None: + """ + Add description to flavor. + @param os_flavor OpenStack flavor specification + @type os_flavor: Flavor + @param gx_flavor Gaia-X flavor specification + @type gx_flavor: ServerFlavor + """ + try: + gx_flavor.description = os_flavor.description + except KeyError: + pass diff --git a/generator/discovery/openstack/vm_images_discovery.py b/generator/discovery/openstack/vm_images_discovery.py index de3b4fd..03ca2cc 100644 --- a/generator/discovery/openstack/vm_images_discovery.py +++ b/generator/discovery/openstack/vm_images_discovery.py @@ -1,7 +1,3 @@ -#!/usr/bin/env python3 -# vim: set ts=4 sw=4 et: -# -# vm_images_discovery.py """Script to discovery VM images properties. (c) Anja Strunk , 1/2024 @@ -10,17 +6,15 @@ from datetime import date, datetime from typing import List, Union - +from generator.discovery.openstack.openstack_discovery import OpenStackDiscovery from linkml_runtime.utils.metamodelcore import URI -from openstack.connection import Connection from openstack.image.v2.image import Image as OS_Image import generator.common.const as const -from generator.common.config import Config -from generator.common.gx_schema import CPU, SPDX from generator.common.gx_schema import Architectures as CpuArch from generator.common.gx_schema import ( CheckSum, +CPU, SPDX, ChecksumAlgorithm, Disk, DiskBusType, @@ -34,6 +28,7 @@ RNGTypes, Signature, SignatureAlgorithm, +WatchDogActions, UpdateFrequency, UpdateStrategy, Validity1, @@ -41,7 +36,6 @@ VMDiskType, ) from generator.common.gx_schema import VMImage as GX_Image -from generator.common.gx_schema import WatchDogActions from generator.common.json_ld import JsonLdObject VALID_UNTIL_LOOKUP = { @@ -121,20 +115,11 @@ } -class VmDiscovery: +class VmDiscovery(OpenStackDiscovery): """Discover VM image properties.""" - def __init__(self, conn: Connection, conf: Config) -> None: - """ - Constructor. - @param conn: Openstack Connection - @param conf: configuration - """ - self.conn = conn - self.conf = conf - # def collect_vm_images(self, conn: Connection) -> List[str]: - def discover_vm_images(self) -> List[JsonLdObject]: + def discover(self) -> List[JsonLdObject]: """ Return one credential for each public VM image offered by openstack cloud. @@ -297,177 +282,177 @@ def _get_operation_system(self, os_image: OS_Image) -> OperatingSystem: return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ARCH, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_ARCH), + resourcePolicy=self.get_copyright_owner(const.CONFIG_OS_ARCH), copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_ARCH), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_ARCH)), + license=self._get_license_list(self.get_license(const.CONFIG_OS_ARCH)), ) elif os_image.os_distro.lower() == "centos": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_CENTOS, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_CENTOS), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_CENTOS), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_CENTOS)), + resourcePolicy=self._get_resource_policy(const.CONFIG_OS_CENTOS), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_CENTOS), + license=self._get_license_list(self._get_license(const.CONFIG_OS_CENTOS)), ) elif os_image.os_distro.lower() == "debian": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_DEBIAN, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_DEBIAN), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_DEBIAN), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_DEBIAN)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_DEBIAN), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_DEBIAN), + license=self._get_license_list(self.get_license(const.CONFIG_OS_DEBIAN)), ) elif os_image.os_distro.lower() == "fedora": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_FEDORA, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_FEDORA), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_FEDORA), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_FEDORA)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_FEDORA), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_FEDORA), + license=self._get_license_list(self.get_license(const.CONFIG_OS_FEDORA)), ) elif os_image.os_distro.lower() == "freebsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_FREEBSD, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_FREEBSD), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_FREEBSD), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_FREEBSD)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_FREEBSD), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_FREEBSD), + license=self._get_license_list(self.get_license(const.CONFIG_OS_FREEBSD)), ) elif os_image.os_distro.lower() == "gentoo": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_GENTOO, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_GENTOO), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_GENTOO), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_GENTOO)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_GENTOO), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_GENTOO), + license=self._get_license_list(self.get_license(const.CONFIG_OS_GENTOO)), ) elif os_image.os_distro.lower() == "mandrake": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MANDRAKE, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_MANDRAKE), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_MANDRAKE), copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_MANDRAKE), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_MANDRAKE)), + license=self._get_license_list(self.get_license(const.CONFIG_OS_MANDRAKE)), ) elif os_image.os_distro.lower() == "mandriva": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MANDRIVA, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_MANDRIVA), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_MANDRIVA), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_MANDRIVA)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_MANDRIVA), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_MANDRIVA), + license=self._get_license_list(self.get_license(const.CONFIG_OS_MANDRIVA)), ) elif os_image.os_distro.lower() == "mes": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MES, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_MES), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_MES), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_MES)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_MES), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_MES), + license=self._get_license_list(self.get_license(const.CONFIG_OS_MES)), ) elif os_image.os_distro.lower() == "msdos": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MSDOS, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_MSDOS), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_MSDOS), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_MSDOS)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_MSDOS), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_MSDOS), + license=self._get_license_list(self.get_license(const.CONFIG_OS_MSDOS)), ) elif os_image.os_distro.lower() == "netbsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_NETBSD, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_NETBSD), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_NETBSD), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_NETBSD)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_NETBSD), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_NETBSD), + license=self._get_license_list(self.get_license(const.CONFIG_OS_NETBSD)), ) elif os_image.os_distro.lower() == "netware": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_NOVELL, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_NOVELL), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_NOVELL), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_NOVELL)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_NOVELL), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_NOVELL), + license=self._get_license_list(self.get_license(const.CONFIG_OS_NOVELL)), ) elif os_image.os_distro.lower() == "openbsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_OPENBSD, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_OPENBSD), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_OPENBSD), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_OPENBSD)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_OPENBSD), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_OPENBSD), + license=self._get_license_list(self.get_license(const.CONFIG_OS_OPENBSD)), ) elif os_image.os_distro.lower() == "opensolaris": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_SOLARIS, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_SOLARIS), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_SOLARIS), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_SOLARIS)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_SOLARIS), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_SOLARIS), + license=self._get_license_list(self.get_license(const.CONFIG_OS_SOLARIS)), ) elif os_image.os_distro.lower() == "opensuse": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_OPEN_SUSE, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_OPEN_SUSE), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_OPEN_SUSE), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_OPEN_SUSE)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_OPEN_SUSE), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_OPEN_SUSE), + license=self._get_license_list(self.get_license(const.CONFIG_OS_OPEN_SUSE)), ) elif os_image.os_distro.lower() == "rocky": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ROCKY, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_ROCKY), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_ROCKY), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_ROCKY)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_ROCKY), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_ROCKY), + license=self._get_license_list(self.get_license(const.CONFIG_OS_ROCKY)), ) elif os_image.os_distro.lower() == "rhel": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_RHEL, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_RHEL), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_RHEL), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_RHEL)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_RHEL), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_RHEL), + license=self._get_license_list(self.get_license(const.CONFIG_OS_RHEL)), ) elif os_image.os_distro.lower() == "sled": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_SLED, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_SLED), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_SLED), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_SLED)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_SLED), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_SLED), + license=self._get_license_list(self.get_license(const.CONFIG_OS_SLED)), ) elif os_image.os_distro.lower() == "ubuntu": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_UBUNTU, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_UBUNTU), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_UBUNTU), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_UBUNTU)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_UBUNTU), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_UBUNTU), + license=self._get_license_list(self.get_license(const.CONFIG_OS_UBUNTU)), ) elif os_image.os_distro.lower() == "windows": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_WINDOWS, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_WINDOWS), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_WINDOWS), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_WINDOWS)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_WINDOWS), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_WINDOWS), + license=self._get_license_list(self.get_license(const.CONFIG_OS_WINDOWS)), ) elif os_image.os_distro.lower() == "cirros": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_CIRROS, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_CIRROS), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_CIRROS), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_CIRROS)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_CIRROS), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_CIRROS), + license=self._get_license_list(self.get_license(const.CONFIG_OS_CIRROS)), ) elif os_image.os_distro.lower() == "almalinux": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ALMALINUX, - resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_ALMALINUX), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_ALMALINUX), - license=self._get_license_list(self._get_license_for_os(const.CONFIG_OS_ALMALINUX)), + resourcePolicy=self.get_resource_policy(const.CONFIG_OS_ALMALINUX), + copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_ALMALINUX), + license=self._get_license_list(self.get_license(const.CONFIG_OS_ALMALINUX)), ) else: raise ValueError( @@ -475,37 +460,6 @@ def _get_operation_system(self, os_image: OS_Image) -> OperatingSystem: + os_image.os_distro + "'" ) - - def _get_resource_policy_for_os(self, os: str) -> str: - return self.conf.get_value( - [ - const.CONFIG_DEFAULT, - const.CONFIG_OPERATING_SYSTEM, - os, - const.CONFIG_RESOURCE_POLICY, - ] - ) - - def _get_copyright_owner_for_os(self, os: str) -> List[str]: - return self.conf.get_value( - [ - const.CONFIG_DEFAULT, - const.CONFIG_OPERATING_SYSTEM, - os, - const.CONFIG_COPYRIGHT, - ] - ) - - def _get_license_for_os(self, os: str) -> List[str]: - return self.conf.get_value( - [ - const.CONFIG_DEFAULT, - const.CONFIG_OPERATING_SYSTEM, - os, - const.CONFIG_LICENSE, - ] - ) - def _add_copyright_owner(self, os_image: OS_Image, gx_image: GX_Image) -> None: try: gx_image.copyrightOwnedBy = self.conf.get_value( diff --git a/tests/common.py b/tests/common.py index 5ff5852..44c5553 100644 --- a/tests/common.py +++ b/tests/common.py @@ -4,6 +4,9 @@ import yaml +from openstack.image.v2.image import Image as OS_Image +from openstack.compute.v2.flavor import Flavor as OS_Flavor + from generator.common.config import Config from generator.common.gx_schema import ( CPU, @@ -23,6 +26,8 @@ SoftwareResource, VirtualResource, VMImage, + ServerFlavor, +InstantiationRequirement ) @@ -40,6 +45,7 @@ def get_config() -> Config: class OpenstackTestcase(unittest.TestCase): + def assert_gaia_x_entity(self, ob_1: GaiaXEntity, ob_2: GaiaXEntity): self.assertEqual(ob_1.name, ob_2.name, "GaiaXEntity.name") self.assertEqual(ob_1.description, ob_2.description, "GaiaXEntity.description") @@ -207,19 +213,69 @@ def assert_vm_image(self, exp: VMImage, act: VMImage): self.assertEqual(exp.firmwareType, act.firmwareType, "VM_Image.firmwareType") self.assertEqual(exp.hwRngTypeOfImage, act.hwRngTypeOfImage, "VM_Image.hwRngTypeOfImage") + def check_installation_requirement( + self, ob_1: InstantiationRequirement, ob_2: InstantiationRequirement + ): + self.assert_gaia_x_entity(ob_1, ob_2) + + def check_hypervisor(self, ob_1: Hypervisor, ob_2: Hypervisor): + self.assert_software_resource(ob_1, ob_2) + self.assertEqual( + ob_1.hypervisorType, str(ob_2.hypervisorType), "Hypervisor.hypervisorType") + + def assert_flavor(self, ob_1: ServerFlavor, ob_2: ServerFlavor): + # self.check_installation_requirement(ob_1, ob_2) + self.assert_cpu(ob_1.cpu, ob_2.cpu) + self.assert_mem(ob_1.ram, ob_2.ram) + self.assert_gpu(ob_1.gpu, ob_2.gpu) + self.assert_disk(ob_1.bootVolume, ob_2.bootVolume) + self.assertEqual( + len(ob_1.additionalVolume), + len(ob_2.additionalVolume), + "ServerFlavor.additionalVolume", + ) + if ob_1.hypervisor: + self.check_hypervisor(ob_1.hypervisor, ob_2.hypervisor) + if ob_1.confidentialComputing: + self.assertEqual( + ob_1.confidentialComputing, + str(ob_2.confidentialComputing), + "ServerFlavor.confidentialComputing", + ) + self.assertEqual( + ob_1.hardwareAssistedVirtualization, + ob_2.hardwareAssistedVirtualization, + "ServerFlavor.hardwareAssistedVirtualization", + ) + self.assertEqual( + ob_1.hwRngTypeOfFlavor, + ob_2.hwRngTypeOfFlavor, + "ServerFlavor.hwRngTypeOfFlavor", + ) + + for i in range(9, len(ob_1.additionalVolume) - 1): + self.assert_disk(ob_1.additionalVolume[i], ob_2.additionalVolume[i]) class MockConnection: """ Wrap connection to OpenStack Cluster """ - images = [] - - def __init__(self, images: List[Image]): + def __init__(self, images: List[OS_Image] = None, flavors: List[OS_Flavor] = None): self.images = images + self.flavors = flavors + + def list_images(self) -> List[OS_Image]: + if self.images: + return self.images + else: + return [] - def list_images(self): - return self.images + def list_flavors(self) -> List[OS_Flavor]: + if self.flavors: + return self.flavors + else: + return [] def authorize(self): pass diff --git a/tests/data/vm_image_2.json b/tests/data/credential.json similarity index 58% rename from tests/data/vm_image_2.json rename to tests/data/credential.json index ca9a757..fbeed8e 100644 --- a/tests/data/vm_image_2.json +++ b/tests/data/credential.json @@ -151,6 +151,112 @@ }, "qudt:unit": "https://qudt.org/vocab/unit/GigaBYTE" } + }, + { + "@id": "ex:flavor_2", + "@type": "gx:ServerFlavor", + "gx:cpu": { + "@type": "gx:CPU", + "gx:vendor": "AMD", + "gx:generation": "Zen-3 (Milan)", + "gx:defaultOversubscriptionRatio": 16, + "gx:cpuArchitecture": "x86-64", + "gx:smtEnabled": { + "@type": "xsd:boolean", + "@value": true + }, + "gx:numberOfCores": 4, + "gx:baseFrequency": { + "@type": "qudt:quantitykind/FrequencyDefinition", + "qudt:value": { + "@type": "xsd:float", + "@value": 3.25 + }, + "qudt:unit": "https://qudt.org/vocab/unit/GigaHZ" + } + }, + "gx:ram": { + "@type": "gx:Memory", + "gx:defaultOversubscriptionRatio": 2, + "gx:memorySize": { + "@type": "gx:MemorySize", + "qudt:value": { + "@type": "xsd:float", + "@value": 32.0 + }, + "qudt:unit": "https://qudt.org/vocab/unit/MegaBYTE" + }, + "gx:memoryClass": "other", + "gx:memoryRank": "other", + "gx:eccEnabled": { + "@type": "xsd:boolean", + "@value": true + }, + "gx:hardwareEncryption": { + "@type": "xsd:boolean", + "@value": false + } + }, + "gx:bootVolume": { + "@type": "gx:Disk", + "gx:diskSize": { + "@type": "gx:MemorySize", + "qudt:value": { + "@type": "xsd:float", + "@value": 50.0 + }, + "qudt:unit": "https://qudt.org/vocab/unit/GigaBYTE" + }, + "gx:diskType": "local SSD", + "gx:diskBusType": "other" + }, + "gx:additionalVolume": [ + { + "@type": "gx:Disk", + "gx:diskSize": { + "@type": "gx:MemorySize", + "qudt:value": { + "@type": "xsd:float", + "@value": 50.0 + }, + "qudt:unit": "https://qudt.org/vocab/unit/GigaBYTE" + }, + "gx:diskType": "local SSD", + "gx:diskBusType": "other" + }, + { + "@type": "gx:Disk", + "gx:diskSize": { + "@type": "gx:MemorySize", + "qudt:value": { + "@type": "xsd:float", + "@value": 50.0 + }, + "qudt:unit": "https://qudt.org/vocab/unit/GigaBYTE" + }, + "gx:diskType": "local SSD", + "gx:diskBusType": "other" + } + ], + "gx:hypervisor": { + "@type": "gx:Hypervisor", + "gx:copyrightOwnedBy": [ + "Qumranet" + ], + "gx:license": [ + "GPL-2.0-or-later", + "LGPL-3.0-or-later" + ], + "gx:resourcePolicy": [ + "default: allow intent" + ], + "gx:hypervisorType": "KVM" + }, + "gx:hardwareAssistedVirtualization": { + "@type": "xsd:boolean", + "@value": false + }, + "gx:hwRngTypeOfFlavor": "None" } ] } \ No newline at end of file diff --git a/tests/test_cli.py b/tests/test_cli.py index e298a44..069fabf 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,6 +4,7 @@ from click.testing import CliRunner from openstack.image.v2.image import Image as OS_Image +from openstack.compute.v2.flavor import Flavor as OS_Flavor import cli from generator.common import const @@ -52,19 +53,23 @@ }, ) +OS_FLAVOR_1 = OS_Flavor( + id="flavor_2", name="SCS-4L-32uo-3x50s-_kvm_z3hh", vcpus=2, ram=16, disk=0 +) + class CliTestCase(unittest.TestCase): @patch("openstack.connect") def test_openstack(self, os_connect): # Mock openstack calls - os_connect.return_value = MockConnection(images=[OS_IMAGE_1]) + os_connect.return_value = MockConnection(images=[OS_IMAGE_1], flavors=[OS_FLAVOR_1]) runner = CliRunner() result = runner.invoke( cli.openstack, "myCloud --config=" + get_absolute_path(const.CONFIG_FILE) ) self.assertIsNone(result.exception) self.assertEqual(0, result.exit_code) - with open(get_absolute_path("tests/data/vm_image_2.json"), "r") as json_file: + with open(get_absolute_path("tests/data/credential.json"), "r") as json_file: expected_output = json.load(json_file) received_outout = json.loads(result.output) self.assertEqual(expected_output, received_outout) diff --git a/tests/test_openstack_discovery.py b/tests/test_openstack_discovery.py deleted file mode 100644 index 8647ddb..0000000 --- a/tests/test_openstack_discovery.py +++ /dev/null @@ -1,62 +0,0 @@ -import unittest - -from openstack.image.v2.image import Image as OS_Image - -from generator.discovery.openstack.openstack_discovery import OsCloud -from tests.common import MockConnection, get_config - -OS_IMAGE_1 = OS_Image( - hw_scsi_model="virtio - scsi", - os_distro="windows", - hw_watchdog_action="reset", - hw_rng_model="virtio", - os_version="Stable", - hypervisor_type="qemu", - hw_video_ram=20, - hw_vif_multiqueue_enabled=True, - hw_pmu=False, - hw_disk_bus="SCSI", - hw_cpu_cores=2, - hw_cpu_threads=4, - architecture="x86_64", - name="Image2", - disk_format="RAW", - container_format="bare", - needs_secure_boot=True, - size="9116319744", - virtual_size="9116319744", - checksum="a516d5aea8ebc358dd316dd67266a2ba", - min_ram=1, - min_disk=20, - owner="477ba6f14a5b43abe85b2966be7ebe136", - os_hash_algo="sha512", - os_hash_value="7f8bababc2c2a94880747383750470aee68c7e8840bb8811eaeda1b0ce71d59f40ebb182", - id="image_2", - visibility="public", - properties={ - "image_build_date": "2023-11-01", - "image_description": "Image 2", - "provided_until": "none", - "replace_frequency": "weekly", - "uuid_validity": "last-3", - "patchlevel": "1.5.2", - "license_required": True, - "license_included": False, - "subscription_required": True, - "subscription_included": False, - "maintained_until": "2024-05-31", - }, -) - - -class OpenstackDiscoveryTestCase(unittest.TestCase): - def setUp(self): - self.cloud = OsCloud(MockConnection([OS_IMAGE_1]), config=get_config()) - - def _test_discover_properties(self): - print(self.cloud.discover_properties()) - self.assertEqual(True, False) # add assertion here - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_server_flavor_discovery.py b/tests/test_server_flavor_discovery.py new file mode 100644 index 0000000..f3fc269 --- /dev/null +++ b/tests/test_server_flavor_discovery.py @@ -0,0 +1,342 @@ +import unittest + +from openstack.compute.v2.flavor import Flavor as OS_Flavor + +from generator.common import const +from generator.common.gx_schema import CPU +from generator.common.gx_schema import Architectures as CpuArch +from generator.common.gx_schema import (Disk, DiskBusType, DiskType, Frequency, + Hypervisor, Memory, MemorySize) +from generator.common.gx_schema import ServerFlavor as GX_Flavor +from generator.discovery.openstack.server_flavor_discovery import \ + ServerFlavorDiscovery +from tests.common import MockConnection, OpenstackTestcase, get_config + +OS_FLAVOR_1 = OS_Flavor(id="flavor_1", name="ABC", vcpus=2, ram=16, disk=0) +OS_FLAVOR_2 = OS_Flavor( + id="flavor_2", name="SCS-4L-32uo-3x50s-_kvm_z3hh", vcpus=2, ram=16, disk=0 +) + + +class VMServerFlavorDiscoveryTestcase(OpenstackTestcase): + def setUp(self): + self.discovery = ServerFlavorDiscovery( + conn=MockConnection(flavors=[OS_FLAVOR_1, OS_FLAVOR_2]), conf=get_config()) + + def test_get_cpu(self): + self.assertEqual( + CPU(cpuArchitecture=CpuArch.other, numberOfCores=0), + self.discovery._get_cpu(OS_Flavor(name="ABC", ram=10)), + ) + self.assertEqual( + CPU( + cpuArchitecture=CpuArch.other, + defaultOversubscriptionRatio=1, + numberOfCores=2, + ), + self.discovery._get_cpu(OS_Flavor(name="SCS-2C-4", ram=10)), + ) + self.assertEqual( + CPU( + cpuArchitecture=CpuArch.other, + defaultOversubscriptionRatio=1, + numberOfCores=2, + smtEnabled=True, + ), + self.discovery._get_cpu(OS_Flavor(name="SCS-2T-4", ram=10)), + ) + self.assertEqual( + CPU( + cpuArchitecture=CpuArch.other, + defaultOversubscriptionRatio=5, + numberOfCores=2, + smtEnabled=True, + ), + self.discovery._get_cpu(OS_Flavor(name="SCS-2V-4", ram=10)), + ) + self.assertEqual( + CPU( + cpuArchitecture=CpuArch.other, + defaultOversubscriptionRatio=16, + numberOfCores=2, + smtEnabled=True, + ), + self.discovery._get_cpu(OS_Flavor(name="SCS-2L-4", ram=10)), + ) + self.assertEqual( + CPU( + cpuArchitecture=CpuArch.other, + numberOfCores=4, + ), + self.discovery._get_cpu(OS_Flavor(name="SCS-2:8", ram=10, vcpus=4)), + ) + + def test_get_mem(self): + self.assertEqual( + Memory(memorySize=MemorySize(value=4, unit=const.UNIT_MB)), + self.discovery._get_ram(OS_Flavor(name="SCS-2C-4-10n", ram=10)), + ) + self.assertEqual( + Memory(memorySize=MemorySize(value=3.5, unit=const.UNIT_MB)), + self.discovery._get_ram(OS_Flavor(name="SCS-2C-3.5-10n", ram=10)), + ) + self.assertEqual( + Memory(memorySize=MemorySize(value=4, unit=const.UNIT_MB), eccEnabled=True), + self.discovery._get_ram(OS_Flavor(name="SCS-2C-4u-10n", ram=10)), + ) + self.assertEqual( + Memory( + memorySize=MemorySize(value=4, unit=const.UNIT_MB), + defaultOversubscriptionRatio=2, + ), + self.discovery._get_ram(OS_Flavor(name="SCS-2C-4o-10n", ram=10)), + ) + self.assertEqual( + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), + self.discovery._get_ram(OS_Flavor(name="SCS-2C-4ou-10n", ram=10)), + ) + self.assertEqual( + Memory( + memorySize=MemorySize(value=4, unit=const.UNIT_MB), + eccEnabled=True, + defaultOversubscriptionRatio=2, + ), + self.discovery._get_ram(OS_Flavor(name="SCS-2C-4uo-10n", ram=10)), + ) + self.assertEqual( + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), + self.discovery._get_ram(OS_Flavor(name="SCS-2C_", ram=10)), + ) + self.assertEqual( + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), + self.discovery._get_ram(OS_Flavor(name="SCS-2V:8", ram=10)), + ) + self.assertEqual( + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), + self.discovery._get_ram(OS_Flavor(name="test", ram=10)), + ) + + def test_get_disk_caps(self): + self.assertEqual( + (3, 10, DiskType("local SSD"), DiskBusType("other")), + self.discovery._get_disk_caps("3x10s"), + ) + self.assertEqual( + (1, 10, DiskType("local HDD"), DiskBusType("NVMe")), + self.discovery._get_disk_caps("10p"), + ) + self.assertEqual( + (1, 10, DiskType("other"), DiskBusType("other")), + self.discovery._get_disk_caps("10"), + ) + self.assertEqual( + (1, 0, DiskType("shared network storage"), DiskBusType("other")), + self.discovery._get_disk_caps("n"), + ) + self.assertEqual( + (2, 10, DiskType("other"), DiskBusType("other")), + self.discovery._get_disk_caps("2x10"), + ) + self.assertEqual( + (2, 10, DiskType("local HDD"), DiskBusType("NVMe")), + self.discovery._get_disk_caps("2x10p"), + ) + + def test_get_disks(self): + # no SCS standard compliant flavor name + self.assertEqual( + [Disk(diskSize=MemorySize(value=50, unit=const.UNIT_GB))], + self.discovery._get_disks(OS_Flavor(name="abc", ram=32, disk=50)), + ) + # invalid SCS flavor name + self.assertEqual( + [Disk(diskSize=MemorySize(value=50, unit=const.UNIT_GB))], + self.discovery._get_disks(OS_Flavor(name="SCS-2C:10n", ram=32, disk=50)), + ) + + # SCS compliant flavor name + self.assertEqual( + [ + Disk(diskSize=MemorySize(value=10, unit=const.UNIT_GB)), + Disk(diskSize=MemorySize(value=10, unit=const.UNIT_GB)), + ], + self.discovery._get_disks(OS_Flavor(name="SCS-2C-4-2x10", disk=50)), + ) + + def test_parse_optional_flavor_properties(self): + # check hypervisor + os_flavor = OS_Flavor(name="SCS-2C-4-10_kvm") + gx_flavor = self._init_gx_flavor() + gx_flavor_hv = self._init_gx_flavor(hv=True) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_hv, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10_kvm_hwv") + gx_flavor = self._init_gx_flavor() + gx_flavor_hv = self._init_gx_flavor(hv=True, hw_virt=True) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_hv, gx_flavor) + + # check hardware virtualization + os_flavor = OS_Flavor(name="SCS-2C-4-10_hwv") + gx_flavor = self._init_gx_flavor() + gx_flavor_hw = self._init_gx_flavor(hw_virt=True) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_hw, gx_flavor) + + # check CPU architecture, frequency and generation + os_flavor = OS_Flavor(name="SCS-2C-4-10n_i") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("x86-64"), cpu_vendor="Intel" + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_i3") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("x86-64"), cpu_vendor="Intel", cpu_gen="Ice Lake" + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_i3h") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("x86-64"), + cpu_vendor="Intel", + cpu_gen="Ice Lake", + cpu_freq=Frequency(value=2.75, unit=const.UNIT_GHZ), + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_z") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("x86-64"), cpu_vendor="AMD" + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_z4") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("x86-64"), cpu_vendor="AMD", cpu_gen="Zen-4 (Genoa)" + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_z4hh") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("x86-64"), + cpu_vendor="AMD", + cpu_gen="Zen-4 (Genoa)", + cpu_freq=Frequency(value=3.25, unit=const.UNIT_GHZ), + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_a") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("AArch-64"), cpu_vendor="ARM" + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_a2") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("AArch-64"), cpu_vendor="ARM", cpu_gen="A78/x1/NeoV1 class" + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_a2hhh") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor( + cpu_arc=CpuArch("AArch-64"), + cpu_vendor="ARM", + cpu_gen="A78/x1/NeoV1 class", + cpu_freq=Frequency(value=3.75, unit=const.UNIT_GHZ), + ) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + os_flavor = OS_Flavor(name="SCS-2C-4-10n_r") + gx_flavor = self._init_gx_flavor() + gx_flavor_cpu = self._init_gx_flavor(cpu_arc=CpuArch("RISC-V")) + self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.assertEqual(gx_flavor_cpu, gx_flavor) + + def test_discovery(self): + received_gax_flavors = self.discovery.discover() + + # init expected objects + gax_flavor_1 = self._init_gx_flavor(ram=16, disk=0, number_of_cores=2) + + gax_flavor_2 = self._init_gx_flavor(ram=32, disk=50, cpu_arc=CpuArch("x86-64"), cpu_vendor="AMD", + cpu_gen="Zen-3 (Milan)", cpu_freq=Frequency(value=3.25, unit=const.UNIT_GHZ), number_of_cores=4) + gax_flavor_2.cpu.defaultOversubscriptionRatio = 16 + gax_flavor_2.cpu.smtEnabled = True + gax_flavor_2.ram.eccEnabled = True + gax_flavor_2.ram.defaultOversubscriptionRatio = 2 + gax_flavor_2.bootVolume = Disk( + diskSize=MemorySize(value=50, unit=const.UNIT_GB), + diskType=DiskType("local SSD")) + gax_flavor_2.additionalVolume = [ + Disk( + diskSize=MemorySize(value=50, unit=const.UNIT_GB), + diskType=DiskType("local SSD"), + ), + Disk( + diskSize=MemorySize(value=50, unit=const.UNIT_GB), + diskType=DiskType("local SSD"), + ), + ] + + # compare + self.assert_flavor(gax_flavor_1, received_gax_flavors[0].gx_object) + self.assert_flavor(gax_flavor_2, received_gax_flavors[1].gx_object) + + def _init_gx_flavor( + self, + ram: int = 32, + disk: int = 50, + cpu_arc: CpuArch = CpuArch.other, + number_of_cores=1, + cpu_vendor: str = None, + cpu_gen: str = None, + cpu_freq: Frequency = None, + hw_virt: bool = False, + hv: bool = False + ) -> GX_Flavor: + gx_flavor = GX_Flavor( + # name=os_flavor.name, + cpu=CPU( + cpuArchitecture=cpu_arc, + vendor=cpu_vendor, + generation=cpu_gen, + baseFrequency=cpu_freq, + numberOfCores=number_of_cores, + ), + ram=Memory(memorySize=MemorySize(value=ram, unit=const.UNIT_MB)), + bootVolume=Disk(diskSize=MemorySize(value=disk, unit=const.UNIT_GB)), + hardwareAssistedVirtualization=hw_virt) + if hv: + gx_flavor.hypervisor = Hypervisor( + hypervisorType="KVM", + copyrightOwnedBy=self.discovery.get_copyright_owner(const.CONFIG_HV_KVM), + license=self.discovery.get_license(const.CONFIG_HV_KVM), + resourcePolicy=self.discovery.get_resource_policy(const.CONFIG_HV_KVM)) + + return gx_flavor + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_vm_image_discovery.py b/tests/test_vm_image_discovery.py index 67ae63b..d0f8971 100644 --- a/tests/test_vm_image_discovery.py +++ b/tests/test_vm_image_discovery.py @@ -1,8 +1,6 @@ -import json import unittest from datetime import date, datetime -from linkml_runtime.utils.metamodelcore import XSDDate from openstack.image.v2.image import Image as OS_Image from generator.common import const @@ -25,7 +23,7 @@ ) from generator.common.gx_schema import VMImage as GX_Image from generator.common.gx_schema import WatchDogActions -from generator.common.json_ld import JsonLdObject, get_json_ld_context, to_json_ld +from generator.common.json_ld import JsonLdObject from generator.discovery.openstack.vm_images_discovery import VmDiscovery from tests.common import MockConnection, OpenstackTestcase, get_config @@ -196,7 +194,7 @@ def setUp(self): ) def test_discovery_vm_images(self): - actual_gax_images = self.discovery.discover_vm_images() + actual_gax_images = self.discovery.discover() self.assert_vm_image(GX_IMAGE_1.gx_object, actual_gax_images[0].gx_object) self.assert_vm_image(GX_IMAGE_2.gx_object, actual_gax_images[1].gx_object) From 68ad2e85ebf38874b609cbae0905c7f106469ff4 Mon Sep 17 00:00:00 2001 From: anjastrunk <119566837+anjastrunk@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:52:24 +0200 Subject: [PATCH 02/20] Update generator/discovery/openstack/openstack_discovery.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Büchse Signed-off-by: anjastrunk <119566837+anjastrunk@users.noreply.github.com> --- generator/discovery/openstack/openstack_discovery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/discovery/openstack/openstack_discovery.py b/generator/discovery/openstack/openstack_discovery.py index d4d6a0c..5ed48f1 100644 --- a/generator/discovery/openstack/openstack_discovery.py +++ b/generator/discovery/openstack/openstack_discovery.py @@ -1,4 +1,4 @@ -from abc import ABCMeta,abstractmethod +from abc import ABCMeta, abstractmethod from typing import List from openstack.connection import Connection From f6dbf537349bebb65b3e18e857b7992ea071ee39 Mon Sep 17 00:00:00 2001 From: anjastrunk <119566837+anjastrunk@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:52:33 +0200 Subject: [PATCH 03/20] Update generator/discovery/openstack/openstack_discovery.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Büchse Signed-off-by: anjastrunk <119566837+anjastrunk@users.noreply.github.com> --- generator/discovery/openstack/openstack_discovery.py | 1 + 1 file changed, 1 insertion(+) diff --git a/generator/discovery/openstack/openstack_discovery.py b/generator/discovery/openstack/openstack_discovery.py index 5ed48f1..d157da6 100644 --- a/generator/discovery/openstack/openstack_discovery.py +++ b/generator/discovery/openstack/openstack_discovery.py @@ -13,6 +13,7 @@ class OpenStackDiscovery(metaclass=ABCMeta): def __init__(self, conn: Connection, conf: Config) -> None: self.conn = conn self.conf = conf + @abstractmethod def discover(self) -> List[JsonLdObject]: pass From 859dd4a38ca10aa84859ea770ae2d05221735d76 Mon Sep 17 00:00:00 2001 From: anjastrunk <119566837+anjastrunk@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:53:02 +0200 Subject: [PATCH 04/20] Update generator/discovery/openstack/vm_images_discovery.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Büchse Signed-off-by: anjastrunk <119566837+anjastrunk@users.noreply.github.com> --- generator/discovery/openstack/vm_images_discovery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/discovery/openstack/vm_images_discovery.py b/generator/discovery/openstack/vm_images_discovery.py index 03ca2cc..7a16844 100644 --- a/generator/discovery/openstack/vm_images_discovery.py +++ b/generator/discovery/openstack/vm_images_discovery.py @@ -28,7 +28,7 @@ RNGTypes, Signature, SignatureAlgorithm, -WatchDogActions, + WatchDogActions, UpdateFrequency, UpdateStrategy, Validity1, From fe10fc716a2e6073bd0d573dc3633a24e5aef1b3 Mon Sep 17 00:00:00 2001 From: anjastrunk <119566837+anjastrunk@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:56:17 +0200 Subject: [PATCH 05/20] Update generator/discovery/openstack/server_flavor_discovery.py Co-authored-by: Martin Morgenstern Signed-off-by: anjastrunk <119566837+anjastrunk@users.noreply.github.com> --- generator/discovery/openstack/server_flavor_discovery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index df0ee76..d41fb1f 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -73,7 +73,7 @@ def _get_cpu(self, os_flavor: OS_Flavor) -> CPU: if os_flavor.name.startswith("SCS-"): # parse SCS flavor name, second part contains CPU properties parts = os_flavor.name.split("-") - if len(parts) >= 2 and re.search("\d[V,T,C,L]$", parts[1]): + if len(parts) >= 2 and re.search(r"\d[V,T,C,L]$", parts[1]): cpu_suffix = parts[1][-1] cpu.numberOfCores = int(parts[1][-2]) if cpu_suffix.endswith("i"): From 3be879fe21302d2c6bc4ace569c90a23aa6498e6 Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Mon, 8 Apr 2024 15:12:25 +0200 Subject: [PATCH 06/20] Refactor code Signed-off-by: Anja Strunk --- cli.py | 2 +- generator/common/config.py | 11 + generator/common/gx_schema.py | 1668 ++++++++++++----- generator/common/json_ld.py | 6 +- generator/discovery/openstack/discovery.py | 46 - .../openstack/openstack_discovery.py | 52 +- .../openstack/server_flavor_discovery.py | 60 +- .../openstack/vm_images_discovery.py | 272 ++- gx-cred-generator.py | 2 +- k8s-discovery.py | 2 +- openstack-discovery.py | 4 +- tests/test_server_flavor_discovery.py | 6 +- 12 files changed, 1515 insertions(+), 616 deletions(-) delete mode 100644 generator/discovery/openstack/discovery.py diff --git a/cli.py b/cli.py index 6498f23..b37644a 100755 --- a/cli.py +++ b/cli.py @@ -19,7 +19,7 @@ import generator.common.json_ld as json_ld from generator.common.config import Config -from generator.discovery.openstack.discovery import OsCloud +from generator.discovery.openstack.openstack_discovery import OsCloud SHAPES_FILE_FORMAT = "turtle" DATA_FILE_FORMAT = "json-ld" diff --git a/generator/common/config.py b/generator/common/config.py index bb58394..1c6fcc2 100644 --- a/generator/common/config.py +++ b/generator/common/config.py @@ -1,5 +1,6 @@ from typing import List +from generator.common import const def _get_value(config, keys: List[str]): @@ -21,3 +22,13 @@ def __init__(self, config): def get_value(self, keys: List[str]): return _get_value(self.config, keys) + def get_copyright_owner(self, software: str) -> List[str]: + return self.get_value([const.COMFIG_SOFTWARE, software, const.CONFIG_COPYRIGHT]) + + def get_license(self, software: str) -> List[str]: + return self.get_value([const.COMFIG_SOFTWARE, software, const.CONFIG_LICENSE]) + + def get_resource_policy(self, software: str) -> List[str]: + return self.get_value( + [const.COMFIG_SOFTWARE, software, const.CONFIG_RESOURCE_POLICY] + ) diff --git a/generator/common/gx_schema.py b/generator/common/gx_schema.py index 3e4c75f..2c3526c 100644 --- a/generator/common/gx_schema.py +++ b/generator/common/gx_schema.py @@ -12,10 +12,24 @@ from typing import Any, ClassVar, Dict, List, Optional, Union from jsonasobj2 import JsonObj, as_dict -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue, PvFormulaOptions -from linkml_runtime.linkml_model.types import Boolean, Date, Datetime, Float, Integer, String, Uri +from linkml_runtime.linkml_model.meta import ( + EnumDefinition, + PermissibleValue, + PvFormulaOptions, +) +from linkml_runtime.linkml_model.types import ( + Boolean, + Date, + Datetime, + Float, + Integer, + String, + Uri, +) from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.dataclass_extensions_376 import dataclasses_init_fn_with_kwargs +from linkml_runtime.utils.dataclass_extensions_376 import ( + dataclasses_init_fn_with_kwargs, +) from linkml_runtime.utils.enumerations import EnumDefinitionImpl from linkml_runtime.utils.formatutils import camelcase, sfx, underscore from linkml_runtime.utils.metamodelcore import ( @@ -28,7 +42,12 @@ empty_list, ) from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_float, extended_int, extended_str +from linkml_runtime.utils.yamlutils import ( + YAMLRoot, + extended_float, + extended_int, + extended_str, +) from rdflib import Namespace, URIRef metamodel_version = "1.7.0" @@ -356,7 +375,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.supportedOversubscriptionRatio is not None and not isinstance( self.supportedOversubscriptionRatio, int ): - self.supportedOversubscriptionRatio = int(self.supportedOversubscriptionRatio) + self.supportedOversubscriptionRatio = int( + self.supportedOversubscriptionRatio + ) super().__post_init__(**kwargs) @@ -385,7 +406,9 @@ class CPU(Device): thermalDesignPower: Optional[Union[dict, "Power"]] = None def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): - if self.cpuArchitecture is not None and not isinstance(self.cpuArchitecture, Architectures): + if self.cpuArchitecture is not None and not isinstance( + self.cpuArchitecture, Architectures + ): self.cpuArchitecture = Architectures(self.cpuArchitecture) if not isinstance(self.cpuFlag, list): @@ -398,13 +421,19 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.numberOfCores is not None and not isinstance(self.numberOfCores, int): self.numberOfCores = int(self.numberOfCores) - if self.numberOfThreads is not None and not isinstance(self.numberOfThreads, int): + if self.numberOfThreads is not None and not isinstance( + self.numberOfThreads, int + ): self.numberOfThreads = int(self.numberOfThreads) - if self.baseFrequency is not None and not isinstance(self.baseFrequency, Frequency): + if self.baseFrequency is not None and not isinstance( + self.baseFrequency, Frequency + ): self.baseFrequency = Frequency(**as_dict(self.baseFrequency)) - if self.boostFrequency is not None and not isinstance(self.boostFrequency, Frequency): + if self.boostFrequency is not None and not isinstance( + self.boostFrequency, Frequency + ): self.boostFrequency = Frequency(**as_dict(self.boostFrequency)) if self.lastLevelCacheSize is not None and not isinstance( @@ -412,7 +441,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): ): self.lastLevelCacheSize = MemorySize(**as_dict(self.lastLevelCacheSize)) - if self.thermalDesignPower is not None and not isinstance(self.thermalDesignPower, Power): + if self.thermalDesignPower is not None and not isinstance( + self.thermalDesignPower, Power + ): self.thermalDesignPower = Power(**as_dict(self.thermalDesignPower)) super().__post_init__(**kwargs) @@ -444,7 +475,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.diskType is not None and not isinstance(self.diskType, DiskType): self.diskType = DiskType(self.diskType) - if self.diskBusType is not None and not isinstance(self.diskBusType, DiskBusType): + if self.diskBusType is not None and not isinstance( + self.diskBusType, DiskBusType + ): self.diskBusType = DiskBusType(self.diskBusType) super().__post_init__(**kwargs) @@ -482,7 +515,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.endpointURL is not None and not isinstance(self.endpointURL, URI): self.endpointURL = URI(self.endpointURL) - if self.formalDescription is not None and not isinstance(self.formalDescription, str): + if self.formalDescription is not None and not isinstance( + self.formalDescription, str + ): self.formalDescription = str(self.formalDescription) super().__post_init__(**kwargs) @@ -515,10 +550,14 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): ): self.gpuInterconnection = GPUInterconnetionTypes(self.gpuInterconnection) - if self.gpuProcessingUnits is not None and not isinstance(self.gpuProcessingUnits, int): + if self.gpuProcessingUnits is not None and not isinstance( + self.gpuProcessingUnits, int + ): self.gpuProcessingUnits = int(self.gpuProcessingUnits) - if self.gpuPassthrough is not None and not isinstance(self.gpuPassthrough, Bool): + if self.gpuPassthrough is not None and not isinstance( + self.gpuPassthrough, Bool + ): self.gpuPassthrough = Bool(self.gpuPassthrough) super().__post_init__(**kwargs) @@ -552,7 +591,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): ): self.subscriptionRequired = Bool(self.subscriptionRequired) - if self.maintainedUntil is not None and not isinstance(self.maintainedUntil, XSDDate): + if self.maintainedUntil is not None and not isinstance( + self.maintainedUntil, XSDDate + ): self.maintainedUntil = XSDDate(self.maintainedUntil) super().__post_init__(**kwargs) @@ -654,7 +695,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.issuerTermsAndConditions): self.MissingRequiredField("issuerTermsAndConditions") if not isinstance(self.issuerTermsAndConditions, GaiaXTermsAndConditions): - self.issuerTermsAndConditions = GaiaXTermsAndConditions(self.issuerTermsAndConditions) + self.issuerTermsAndConditions = GaiaXTermsAndConditions( + self.issuerTermsAndConditions + ) super().__post_init__(**kwargs) @@ -798,7 +841,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.memorySize, MemorySize): self.memorySize = MemorySize(**as_dict(self.memorySize)) - if self.memoryClass is not None and not isinstance(self.memoryClass, MemoryClasses): + if self.memoryClass is not None and not isinstance( + self.memoryClass, MemoryClasses + ): self.memoryClass = MemoryClasses(self.memoryClass) if self.memoryRank is not None and not isinstance(self.memoryRank, MemoryRanks): @@ -807,7 +852,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.eccEnabled is not None and not isinstance(self.eccEnabled, Bool): self.eccEnabled = Bool(self.eccEnabled) - if self.hardwareEncryption is not None and not isinstance(self.hardwareEncryption, Bool): + if self.hardwareEncryption is not None and not isinstance( + self.hardwareEncryption, Bool + ): self.hardwareEncryption = Bool(self.hardwareEncryption) super().__post_init__(**kwargs) @@ -1037,7 +1084,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): [self.registrationNumber] if self.registrationNumber is not None else [] ) self.registrationNumber = [ - v if isinstance(v, LegalPersonRegistrationNumber) else LegalPersonRegistrationNumber(v) + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) for v in self.registrationNumber ] @@ -1053,10 +1102,14 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.parentOrganizationOf, list): self.parentOrganizationOf = ( - [self.parentOrganizationOf] if self.parentOrganizationOf is not None else [] + [self.parentOrganizationOf] + if self.parentOrganizationOf is not None + else [] ) self.parentOrganizationOf = [ - v if isinstance(v, LegalPersonRegistrationNumber) else LegalPersonRegistrationNumber(v) + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) for v in self.parentOrganizationOf ] @@ -1065,7 +1118,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): [self.subOrganisationOf] if self.subOrganisationOf is not None else [] ) self.subOrganisationOf = [ - v if isinstance(v, LegalPersonRegistrationNumber) else LegalPersonRegistrationNumber(v) + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) for v in self.subOrganisationOf ] @@ -1091,7 +1146,9 @@ class Resource(GaiaXEntity): def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.aggregationOfResources, list): self.aggregationOfResources = ( - [self.aggregationOfResources] if self.aggregationOfResources is not None else [] + [self.aggregationOfResources] + if self.aggregationOfResources is not None + else [] ) self.aggregationOfResources = [ v if isinstance(v, str) else str(v) for v in self.aggregationOfResources @@ -1125,7 +1182,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): self.copyrightOwnedBy = ( [self.copyrightOwnedBy] if self.copyrightOwnedBy is not None else [] ) - self.copyrightOwnedBy = [v if isinstance(v, str) else str(v) for v in self.copyrightOwnedBy] + self.copyrightOwnedBy = [ + v if isinstance(v, str) else str(v) for v in self.copyrightOwnedBy + ] if self._is_empty(self.license): self.MissingRequiredField("license") @@ -1136,8 +1195,12 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.resourcePolicy): self.MissingRequiredField("resourcePolicy") if not isinstance(self.resourcePolicy, list): - self.resourcePolicy = [self.resourcePolicy] if self.resourcePolicy is not None else [] - self.resourcePolicy = [v if isinstance(v, str) else str(v) for v in self.resourcePolicy] + self.resourcePolicy = ( + [self.resourcePolicy] if self.resourcePolicy is not None else [] + ) + self.resourcePolicy = [ + v if isinstance(v, str) else str(v) for v in self.resourcePolicy + ] super().__post_init__(**kwargs) @@ -1178,9 +1241,13 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.maintainedBy): self.MissingRequiredField("maintainedBy") if not isinstance(self.maintainedBy, list): - self.maintainedBy = [self.maintainedBy] if self.maintainedBy is not None else [] + self.maintainedBy = ( + [self.maintainedBy] if self.maintainedBy is not None else [] + ) self.maintainedBy = [ - v if isinstance(v, LegalPersonRegistrationNumber) else LegalPersonRegistrationNumber(v) + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) for v in self.maintainedBy ] @@ -1193,14 +1260,20 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.ownedBy, list): self.ownedBy = [self.ownedBy] if self.ownedBy is not None else [] self.ownedBy = [ - v if isinstance(v, LegalPersonRegistrationNumber) else LegalPersonRegistrationNumber(v) + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) for v in self.ownedBy ] if not isinstance(self.manufacturedBy, list): - self.manufacturedBy = [self.manufacturedBy] if self.manufacturedBy is not None else [] + self.manufacturedBy = ( + [self.manufacturedBy] if self.manufacturedBy is not None else [] + ) self.manufacturedBy = [ - v if isinstance(v, LegalPersonRegistrationNumber) else LegalPersonRegistrationNumber(v) + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) for v in self.manufacturedBy ] @@ -1317,7 +1390,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.ramReq is not None and not isinstance(self.ramReq, Memory): self.ramReq = Memory(**as_dict(self.ramReq)) - if self.videoRamSize is not None and not isinstance(self.videoRamSize, MemorySize): + if self.videoRamSize is not None and not isinstance( + self.videoRamSize, MemorySize + ): self.videoRamSize = MemorySize(**as_dict(self.videoRamSize)) if self.rootDiskReq is not None and not isinstance(self.rootDiskReq, Disk): @@ -1338,10 +1413,14 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.multiQueues is not None and not isinstance(self.multiQueues, Bool): self.multiQueues = Bool(self.multiQueues) - if self.updateStrategy is not None and not isinstance(self.updateStrategy, UpdateStrategy): + if self.updateStrategy is not None and not isinstance( + self.updateStrategy, UpdateStrategy + ): self.updateStrategy = UpdateStrategy(**as_dict(self.updateStrategy)) - if self.licenseIncluded is not None and not isinstance(self.licenseIncluded, Bool): + if self.licenseIncluded is not None and not isinstance( + self.licenseIncluded, Bool + ): self.licenseIncluded = Bool(self.licenseIncluded) if self.maintenance is not None and not isinstance( @@ -1484,8 +1563,12 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.servicePolicy): self.MissingRequiredField("servicePolicy") if not isinstance(self.servicePolicy, list): - self.servicePolicy = [self.servicePolicy] if self.servicePolicy is not None else [] - self.servicePolicy = [v if isinstance(v, str) else str(v) for v in self.servicePolicy] + self.servicePolicy = ( + [self.servicePolicy] if self.servicePolicy is not None else [] + ) + self.servicePolicy = [ + v if isinstance(v, str) else str(v) for v in self.servicePolicy + ] if self._is_empty(self.dataAccountExport): self.MissingRequiredField("dataAccountExport") @@ -1502,7 +1585,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.aggregationOfResources, list): self.aggregationOfResources = ( - [self.aggregationOfResources] if self.aggregationOfResources is not None else [] + [self.aggregationOfResources] + if self.aggregationOfResources is not None + else [] ) self.aggregationOfResources = [ v if isinstance(v, str) else str(v) for v in self.aggregationOfResources @@ -1510,10 +1595,14 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.dataProtectionRegime, list): self.dataProtectionRegime = ( - [self.dataProtectionRegime] if self.dataProtectionRegime is not None else [] + [self.dataProtectionRegime] + if self.dataProtectionRegime is not None + else [] ) self.dataProtectionRegime = [ - v if isinstance(v, PersonalDataProtectionRegime) else PersonalDataProtectionRegime(v) + v + if isinstance(v, PersonalDataProtectionRegime) + else PersonalDataProtectionRegime(v) for v in self.dataProtectionRegime ] @@ -1521,7 +1610,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): self.keyword = [self.keyword] if self.keyword is not None else [] self.keyword = [v if isinstance(v, str) else str(v) for v in self.keyword] - if self.provisionType is not None and not isinstance(self.provisionType, ProvisionTypes): + if self.provisionType is not None and not isinstance( + self.provisionType, ProvisionTypes + ): self.provisionType = ProvisionTypes(self.provisionType) if self.endpoint is not None and not isinstance(self.endpoint, Endpoint): @@ -1610,7 +1701,9 @@ class VirtualMachineServiceOffering(ComputeServiceOffering): Union[dict, "DataAccountExport"], List[Union[dict, "DataAccountExport"]] ] = None codeArtifact: Union[Union[dict, "VMImage"], List[Union[dict, "VMImage"]]] = None - instantiationReq: Union[Union[dict, "ServerFlavor"], List[Union[dict, "ServerFlavor"]]] = None + instantiationReq: Union[ + Union[dict, "ServerFlavor"], List[Union[dict, "ServerFlavor"]] + ] = None servicePolicy: Union[str, List[str]] = "default:allow intent" def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): @@ -1655,7 +1748,9 @@ class ContainerServiceOffering(ComputeServiceOffering): dataAccountExport: Union[ Union[dict, "DataAccountExport"], List[Union[dict, "DataAccountExport"]] ] = None - codeArtifact: Union[Union[dict, "ContainerImage"], List[Union[dict, "ContainerImage"]]] = None + codeArtifact: Union[ + Union[dict, "ContainerImage"], List[Union[dict, "ContainerImage"]] + ] = None instantiationReq: Union[ Union[dict, "ContainerResourceLimits"], List[Union[dict, "ContainerResourceLimits"]], @@ -1705,7 +1800,9 @@ class BareMetalServiceOffering(ComputeServiceOffering): Union[dict, "DataAccountExport"], List[Union[dict, "DataAccountExport"]] ] = None codeArtifact: Union[Union[dict, PXEImage], List[Union[dict, PXEImage]]] = None - instantiationReq: Union[Union[dict, "ServerFlavor"], List[Union[dict, "ServerFlavor"]]] = None + instantiationReq: Union[ + Union[dict, "ServerFlavor"], List[Union[dict, "ServerFlavor"]] + ] = None servicePolicy: Union[str, List[str]] = "default:allow intent" def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): @@ -1856,7 +1953,9 @@ class DataResource(VirtualResource): dataController: Optional[ Union[Union[dict, Participant], List[Union[dict, Participant]]] ] = empty_list() - consent: Optional[Union[Union[dict, "Consent"], List[Union[dict, "Consent"]]]] = empty_list() + consent: Optional[ + Union[Union[dict, "Consent"], List[Union[dict, "Consent"]]] + ] = empty_list() def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.producedBy): @@ -1867,9 +1966,13 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.exposedThrough): self.MissingRequiredField("exposedThrough") if not isinstance(self.exposedThrough, list): - self.exposedThrough = [self.exposedThrough] if self.exposedThrough is not None else [] + self.exposedThrough = ( + [self.exposedThrough] if self.exposedThrough is not None else [] + ) self.exposedThrough = [ - v if isinstance(v, DataExchangeComponent) else DataExchangeComponent(**as_dict(v)) + v + if isinstance(v, DataExchangeComponent) + else DataExchangeComponent(**as_dict(v)) for v in self.exposedThrough ] @@ -1878,7 +1981,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.containsPII, Bool): self.containsPII = Bool(self.containsPII) - if self.obsoleteDateTime is not None and not isinstance(self.obsoleteDateTime, XSDDateTime): + if self.obsoleteDateTime is not None and not isinstance( + self.obsoleteDateTime, XSDDateTime + ): self.obsoleteDateTime = XSDDateTime(self.obsoleteDateTime) if self.expirationDateTime is not None and not isinstance( @@ -1887,7 +1992,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): self.expirationDateTime = XSDDateTime(self.expirationDateTime) if not isinstance(self.dataController, list): - self.dataController = [self.dataController] if self.dataController is not None else [] + self.dataController = ( + [self.dataController] if self.dataController is not None else [] + ) self.dataController = [ v if isinstance(v, Participant) else Participant(**as_dict(v)) for v in self.dataController @@ -1951,7 +2058,8 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): else [] ) self.consentWithdrawalContactPoint = [ - v if isinstance(v, str) else str(v) for v in self.consentWithdrawalContactPoint + v if isinstance(v, str) else str(v) + for v in self.consentWithdrawalContactPoint ] super().__post_init__(**kwargs) @@ -2011,7 +2119,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): self.MissingRequiredField("aggregationOfResources") if not isinstance(self.aggregationOfResources, list): self.aggregationOfResources = ( - [self.aggregationOfResources] if self.aggregationOfResources is not None else [] + [self.aggregationOfResources] + if self.aggregationOfResources is not None + else [] ) self.aggregationOfResources = [ v if isinstance(v, AvailabilityZone) else AvailabilityZone(**as_dict(v)) @@ -2034,7 +2144,9 @@ class Region(Resource): class_name: ClassVar[str] = "Region" class_model_uri: ClassVar[URIRef] = GX.Region - aggregationOfResources: Union[Union[dict, Datacenter], List[Union[dict, Datacenter]]] = None + aggregationOfResources: Union[ + Union[dict, Datacenter], List[Union[dict, Datacenter]] + ] = None def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.aggregationOfResources): @@ -2072,7 +2184,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.baseContainerImage): self.MissingRequiredField("baseContainerImage") if not isinstance(self.baseContainerImage, BaseContainerImage): - self.baseContainerImage = BaseContainerImage(**as_dict(self.baseContainerImage)) + self.baseContainerImage = BaseContainerImage( + **as_dict(self.baseContainerImage) + ) if self._is_empty(self.containerFormat): self.MissingRequiredField("containerFormat") @@ -2135,7 +2249,9 @@ class ContainerResourceLimits(InstantiationRequirement): memoryLimit: Optional[Union[dict, MemorySize]] = None gpuRequirements: Optional[Union[dict, GPU]] = None gpuLimit: Optional[int] = None - confidentialComputingTechnology: Optional[Union[dict, "ConfidentialComputing"]] = None + confidentialComputingTechnology: Optional[ + Union[dict, "ConfidentialComputing"] + ] = None def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.confidential): @@ -2143,19 +2259,29 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.confidential, Bool): self.confidential = Bool(self.confidential) - if self.cpuRequirements is not None and not isinstance(self.cpuRequirements, CPU): + if self.cpuRequirements is not None and not isinstance( + self.cpuRequirements, CPU + ): self.cpuRequirements = CPU(**as_dict(self.cpuRequirements)) - if self.numberOfCoresLimit is not None and not isinstance(self.numberOfCoresLimit, int): + if self.numberOfCoresLimit is not None and not isinstance( + self.numberOfCoresLimit, int + ): self.numberOfCoresLimit = int(self.numberOfCoresLimit) - if self.memoryRequirements is not None and not isinstance(self.memoryRequirements, Memory): + if self.memoryRequirements is not None and not isinstance( + self.memoryRequirements, Memory + ): self.memoryRequirements = Memory(**as_dict(self.memoryRequirements)) - if self.memoryLimit is not None and not isinstance(self.memoryLimit, MemorySize): + if self.memoryLimit is not None and not isinstance( + self.memoryLimit, MemorySize + ): self.memoryLimit = MemorySize(**as_dict(self.memoryLimit)) - if self.gpuRequirements is not None and not isinstance(self.gpuRequirements, GPU): + if self.gpuRequirements is not None and not isinstance( + self.gpuRequirements, GPU + ): self.gpuRequirements = GPU(**as_dict(self.gpuRequirements)) if self.gpuLimit is not None and not isinstance(self.gpuLimit, int): @@ -2197,7 +2323,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.protectionRetention): self.MissingRequiredField("protectionRetention") if not isinstance(self.protectionRetention, RetentionDuration): - self.protectionRetention = RetentionDuration(**as_dict(self.protectionRetention)) + self.protectionRetention = RetentionDuration( + **as_dict(self.protectionRetention) + ) if self.protectionMethod is not None and not isinstance( self.protectionMethod, ProtectionMethod @@ -2231,9 +2359,12 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.backupLocation): self.MissingRequiredField("backupLocation") if not isinstance(self.backupLocation, list): - self.backupLocation = [self.backupLocation] if self.backupLocation is not None else [] + self.backupLocation = ( + [self.backupLocation] if self.backupLocation is not None else [] + ) self.backupLocation = [ - v if isinstance(v, Resource) else Resource(**as_dict(v)) for v in self.backupLocation + v if isinstance(v, Resource) else Resource(**as_dict(v)) + for v in self.backupLocation ] self._normalize_inlined_as_dict( @@ -2295,7 +2426,9 @@ class ReplicationPolicy(DataProtectionPolicy): consistencyType: Optional[Union[str, "ConsistencyType"]] = None replicaNumber: Optional[Union[int, List[int]]] = empty_list() geoReplication: Optional[ - Union[Union[str, "GeoReplicationScope"], List[Union[str, "GeoReplicationScope"]]] + Union[ + Union[str, "GeoReplicationScope"], List[Union[str, "GeoReplicationScope"]] + ] ] = empty_list() def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): @@ -2310,11 +2443,17 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): self.consistencyType = ConsistencyType(self.consistencyType) if not isinstance(self.replicaNumber, list): - self.replicaNumber = [self.replicaNumber] if self.replicaNumber is not None else [] - self.replicaNumber = [v if isinstance(v, int) else int(v) for v in self.replicaNumber] + self.replicaNumber = ( + [self.replicaNumber] if self.replicaNumber is not None else [] + ) + self.replicaNumber = [ + v if isinstance(v, int) else int(v) for v in self.replicaNumber + ] if not isinstance(self.geoReplication, list): - self.geoReplication = [self.geoReplication] if self.geoReplication is not None else [] + self.geoReplication = ( + [self.geoReplication] if self.geoReplication is not None else [] + ) self.geoReplication = [ v if isinstance(v, GeoReplicationScope) else GeoReplicationScope(v) for v in self.geoReplication @@ -2345,7 +2484,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.metric, Quantity): self.metric = Quantity(**as_dict(self.metric)) - if self.guaranteed is not None and not isinstance(self.guaranteed, FloatPercentage): + if self.guaranteed is not None and not isinstance( + self.guaranteed, FloatPercentage + ): self.guaranteed = FloatPercentage(**as_dict(self.guaranteed)) super().__post_init__(**kwargs) @@ -2370,10 +2511,14 @@ class StorageQoS(YAMLRoot): storageAvailability: Optional[Union[dict, FloatPercentage]] = None def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): - if self.storageThroughput is not None and not isinstance(self.storageThroughput, QoSMetric): + if self.storageThroughput is not None and not isinstance( + self.storageThroughput, QoSMetric + ): self.storageThroughput = QoSMetric(**as_dict(self.storageThroughput)) - if self.storageLatency is not None and not isinstance(self.storageLatency, QoSMetric): + if self.storageLatency is not None and not isinstance( + self.storageLatency, QoSMetric + ): self.storageLatency = QoSMetric(**as_dict(self.storageLatency)) if self.storageIOPS is not None and not isinstance(self.storageIOPS, QoSMetric): @@ -2382,7 +2527,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.storageAvailability is not None and not isinstance( self.storageAvailability, FloatPercentage ): - self.storageAvailability = FloatPercentage(**as_dict(self.storageAvailability)) + self.storageAvailability = FloatPercentage( + **as_dict(self.storageAvailability) + ) super().__post_init__(**kwargs) @@ -2400,12 +2547,18 @@ class StorageConfiguration(InstantiationRequirement): class_name: ClassVar[str] = "StorageConfiguration" class_model_uri: ClassVar[URIRef] = GX.StorageConfiguration - storageEncryption: Union[Union[dict, Encryption], List[Union[dict, Encryption]]] = None + storageEncryption: Union[ + Union[dict, Encryption], List[Union[dict, Encryption]] + ] = None storageCompression: Optional[ - Union[Union[str, "CompressionAlgorithm"], List[Union[str, "CompressionAlgorithm"]]] + Union[ + Union[str, "CompressionAlgorithm"], List[Union[str, "CompressionAlgorithm"]] + ] ] = empty_list() storageDeduplication: Optional[ - Union[Union[str, "DeduplicationMethod"], List[Union[str, "DeduplicationMethod"]]] + Union[ + Union[str, "DeduplicationMethod"], List[Union[str, "DeduplicationMethod"]] + ] ] = empty_list() storageRedundancyMechanism: Optional[ Union[ @@ -2414,7 +2567,9 @@ class StorageConfiguration(InstantiationRequirement): ] ] = empty_list() storageProtection: Optional[ - Union[Union[dict, DataProtectionPolicy], List[Union[dict, DataProtectionPolicy]]] + Union[ + Union[dict, DataProtectionPolicy], List[Union[dict, DataProtectionPolicy]] + ] ] = empty_list() storageQoS: Optional[ Union[Union[dict, StorageQoS], List[Union[dict, StorageQoS]]] @@ -2444,7 +2599,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.storageDeduplication, list): self.storageDeduplication = ( - [self.storageDeduplication] if self.storageDeduplication is not None else [] + [self.storageDeduplication] + if self.storageDeduplication is not None + else [] ) self.storageDeduplication = [ v if isinstance(v, DeduplicationMethod) else DeduplicationMethod(v) @@ -2458,7 +2615,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): else [] ) self.storageRedundancyMechanism = [ - v if isinstance(v, StorageRedundancyMechanism) else StorageRedundancyMechanism(v) + v + if isinstance(v, StorageRedundancyMechanism) + else StorageRedundancyMechanism(v) for v in self.storageRedundancyMechanism ] @@ -2472,7 +2631,8 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.storageQoS, list): self.storageQoS = [self.storageQoS] if self.storageQoS is not None else [] self.storageQoS = [ - v if isinstance(v, StorageQoS) else StorageQoS(**as_dict(v)) for v in self.storageQoS + v if isinstance(v, StorageQoS) else StorageQoS(**as_dict(v)) + for v in self.storageQoS ] self._normalize_inlined_as_dict( @@ -2495,7 +2655,9 @@ class FileStorageConfiguration(StorageConfiguration): class_name: ClassVar[str] = "FileStorageConfiguration" class_model_uri: ClassVar[URIRef] = GX.FileStorageConfiguration - storageEncryption: Union[Union[dict, Encryption], List[Union[dict, Encryption]]] = None + storageEncryption: Union[ + Union[dict, Encryption], List[Union[dict, Encryption]] + ] = None fileSystemType: Optional[ Union[Union[str, "FileSystemType"], List[Union[str, "FileSystemType"]]] ] = empty_list() @@ -2505,14 +2667,19 @@ class FileStorageConfiguration(StorageConfiguration): def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.fileSystemType, list): - self.fileSystemType = [self.fileSystemType] if self.fileSystemType is not None else [] + self.fileSystemType = ( + [self.fileSystemType] if self.fileSystemType is not None else [] + ) self.fileSystemType = [ - v if isinstance(v, FileSystemType) else FileSystemType(v) for v in self.fileSystemType + v if isinstance(v, FileSystemType) else FileSystemType(v) + for v in self.fileSystemType ] if not isinstance(self.highLevelAccessProtocol, list): self.highLevelAccessProtocol = ( - [self.highLevelAccessProtocol] if self.highLevelAccessProtocol is not None else [] + [self.highLevelAccessProtocol] + if self.highLevelAccessProtocol is not None + else [] ) self.highLevelAccessProtocol = [ v if isinstance(v, FileAccessProtocol) else FileAccessProtocol(v) @@ -2535,7 +2702,9 @@ class BlockStorageConfiguration(StorageConfiguration): class_name: ClassVar[str] = "BlockStorageConfiguration" class_model_uri: ClassVar[URIRef] = GX.BlockStorageConfiguration - storageEncryption: Union[Union[dict, Encryption], List[Union[dict, Encryption]]] = None + storageEncryption: Union[ + Union[dict, Encryption], List[Union[dict, Encryption]] + ] = None blockStorageTechnology: Optional[ Union[ Union[str, "BlockStorageTechnology"], @@ -2543,13 +2712,17 @@ class BlockStorageConfiguration(StorageConfiguration): ] ] = empty_list() lowLevelBlockAccessProtocol: Optional[ - Union[Union[str, "BlockAccessProtocol"], List[Union[str, "BlockAccessProtocol"]]] + Union[ + Union[str, "BlockAccessProtocol"], List[Union[str, "BlockAccessProtocol"]] + ] ] = empty_list() def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.blockStorageTechnology, list): self.blockStorageTechnology = ( - [self.blockStorageTechnology] if self.blockStorageTechnology is not None else [] + [self.blockStorageTechnology] + if self.blockStorageTechnology is not None + else [] ) self.blockStorageTechnology = [ v if isinstance(v, BlockStorageTechnology) else BlockStorageTechnology(v) @@ -2604,15 +2777,23 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.storageConfiguration): self.MissingRequiredField("storageConfiguration") if not isinstance(self.storageConfiguration, StorageConfiguration): - self.storageConfiguration = StorageConfiguration(**as_dict(self.storageConfiguration)) + self.storageConfiguration = StorageConfiguration( + **as_dict(self.storageConfiguration) + ) - if self.minimumSize is not None and not isinstance(self.minimumSize, MemorySize): + if self.minimumSize is not None and not isinstance( + self.minimumSize, MemorySize + ): self.minimumSize = MemorySize(**as_dict(self.minimumSize)) - if self.maximumSize is not None and not isinstance(self.maximumSize, MemorySize): + if self.maximumSize is not None and not isinstance( + self.maximumSize, MemorySize + ): self.maximumSize = MemorySize(**as_dict(self.maximumSize)) - if self.lifetimeManagement is not None and not isinstance(self.lifetimeManagement, int): + if self.lifetimeManagement is not None and not isinstance( + self.lifetimeManagement, int + ): self.lifetimeManagement = int(self.lifetimeManagement) if self.versioning is not None and not isinstance(self.versioning, Bool): @@ -2667,7 +2848,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): **as_dict(self.storageConfiguration) ) - if self.accessSemantics is not None and not isinstance(self.accessSemantics, Bool): + if self.accessSemantics is not None and not isinstance( + self.accessSemantics, Bool + ): self.accessSemantics = Bool(self.accessSemantics) if not isinstance(self.accessAttributes, list): @@ -2763,10 +2946,13 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.objectAPICompatibility, list): self.objectAPICompatibility = ( - [self.objectAPICompatibility] if self.objectAPICompatibility is not None else [] + [self.objectAPICompatibility] + if self.objectAPICompatibility is not None + else [] ) self.objectAPICompatibility = [ - v if isinstance(v, StorageAPI) else StorageAPI(v) for v in self.objectAPICompatibility + v if isinstance(v, StorageAPI) else StorageAPI(v) + for v in self.objectAPICompatibility ] super().__post_init__(**kwargs) @@ -2800,16 +2986,24 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): ): self.vmImageDiskFormat = VMDiskType(self.vmImageDiskFormat) - if self.hypervisorType is not None and not isinstance(self.hypervisorType, HypervisorType): + if self.hypervisorType is not None and not isinstance( + self.hypervisorType, HypervisorType + ): self.hypervisorType = HypervisorType(self.hypervisorType) - if self.firmwareType is not None and not isinstance(self.firmwareType, FirmType): + if self.firmwareType is not None and not isinstance( + self.firmwareType, FirmType + ): self.firmwareType = FirmType(self.firmwareType) - if self.hwRngTypeOfImage is not None and not isinstance(self.hwRngTypeOfImage, RNGTypes): + if self.hwRngTypeOfImage is not None and not isinstance( + self.hwRngTypeOfImage, RNGTypes + ): self.hwRngTypeOfImage = RNGTypes(self.hwRngTypeOfImage) - if self.watchDogAction is not None and not isinstance(self.watchDogAction, WatchDogActions): + if self.watchDogAction is not None and not isinstance( + self.watchDogAction, WatchDogActions + ): self.watchDogAction = WatchDogActions(self.watchDogAction) super().__post_init__(**kwargs) @@ -2834,7 +3028,9 @@ class ServerFlavor(InstantiationRequirement): bootVolume: Union[dict, Disk] = None gpu: Optional[Union[dict, GPU]] = None network: Optional[str] = None - additionalVolume: Optional[Union[Union[dict, Disk], List[Union[dict, Disk]]]] = empty_list() + additionalVolume: Optional[ + Union[Union[dict, Disk], List[Union[dict, Disk]]] + ] = empty_list() confidentialComputing: Optional[Union[dict, "ConfidentialComputing"]] = None hypervisor: Optional[Union[dict, Hypervisor]] = None hardwareAssistedVirtualization: Optional[Union[bool, Bool]] = False @@ -2862,12 +3058,12 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.network is not None and not isinstance(self.network, str): self.network = str(self.network) - #self._normalize_inlined_as_dict( + # self._normalize_inlined_as_dict( # slot_name="additionalVolume", # slot_type=Disk, # key_name="diskSize", # keyed=False, - #) + # ) if self.confidentialComputing is not None and not isinstance( self.confidentialComputing, ConfidentialComputing @@ -2882,9 +3078,13 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self.hardwareAssistedVirtualization is not None and not isinstance( self.hardwareAssistedVirtualization, Bool ): - self.hardwareAssistedVirtualization = Bool(self.hardwareAssistedVirtualization) + self.hardwareAssistedVirtualization = Bool( + self.hardwareAssistedVirtualization + ) - if self.hwRngTypeOfFlavor is not None and not isinstance(self.hwRngTypeOfFlavor, RNGTypes): + if self.hwRngTypeOfFlavor is not None and not isinstance( + self.hwRngTypeOfFlavor, RNGTypes + ): self.hwRngTypeOfFlavor = RNGTypes(self.hwRngTypeOfFlavor) super().__post_init__(**kwargs) @@ -2923,7 +3123,9 @@ class CountryNameAlpha2(EnumDefinitionImpl): AX = PermissibleValue(text="AX", description="Alpha2 code for Aland Islands.") AL = PermissibleValue(text="AL", description="Alpha2 code for Albania.") DZ = PermissibleValue(text="DZ", description="Alpha2 code for Algeria.") - VI = PermissibleValue(text="VI", description="Alpha2 code for Virgin Islands (U.S.).") + VI = PermissibleValue( + text="VI", description="Alpha2 code for Virgin Islands (U.S.)." + ) UM = PermissibleValue( text="UM", description="Alpha2 code for United States Minor Outlying Islands (the).", @@ -2935,7 +3137,9 @@ class CountryNameAlpha2(EnumDefinitionImpl): AQ = PermissibleValue(text="AQ", description="Alpha2 code for Antarctica.") AG = PermissibleValue(text="AG", description="Alpha2 code for Antigua and Barbuda.") GQ = PermissibleValue(text="GQ", description="Alpha2 code for Equatorial Guinea.") - SY = PermissibleValue(text="SY", description="Alpha2 code for Syrian Arab Republic.") + SY = PermissibleValue( + text="SY", description="Alpha2 code for Syrian Arab Republic." + ) AR = PermissibleValue(text="AR", description="Alpha2 code for Argentina.") AM = PermissibleValue(text="AM", description="Alpha2 code for Armenia.") AW = PermissibleValue(text="AW", description="Alpha2 code for Aruba.") @@ -2957,11 +3161,15 @@ class CountryNameAlpha2(EnumDefinitionImpl): BQ = PermissibleValue( text="BQ", description="Alpha2 code for Bonaire, Sint Eustatius and Saba." ) - BA = PermissibleValue(text="BA", description="Alpha2 code for Bosnia and Herzegovina.") + BA = PermissibleValue( + text="BA", description="Alpha2 code for Bosnia and Herzegovina." + ) BW = PermissibleValue(text="BW", description="Alpha2 code for Botswana.") BV = PermissibleValue(text="BV", description="Alpha2 code for Bouvet Island.") BR = PermissibleValue(text="BR", description="Alpha2 code for Brazil.") - VG = PermissibleValue(text="VG", description="Alpha2 code for Virgin Islands (British).") + VG = PermissibleValue( + text="VG", description="Alpha2 code for Virgin Islands (British)." + ) IO = PermissibleValue( text="IO", description="Alpha2 code for British Indian Ocean Territory (the)." ) @@ -2989,10 +3197,14 @@ class CountryNameAlpha2(EnumDefinitionImpl): ) DE = PermissibleValue(text="DE", description="Alpha2 code for Germany.") DM = PermissibleValue(text="DM", description="Alpha2 code for Dominica.") - DO = PermissibleValue(text="DO", description="Alpha2 code for Dominican Republic (the).") + DO = PermissibleValue( + text="DO", description="Alpha2 code for Dominican Republic (the)." + ) DJ = PermissibleValue(text="DJ", description="Alpha2 code for Djibouti.") EC = PermissibleValue(text="EC", description="Alpha2 code for Ecuador.") - MK = PermissibleValue(text="MK", description="Alpha2 code for Republic of North Macedonia.") + MK = PermissibleValue( + text="MK", description="Alpha2 code for Republic of North Macedonia." + ) SV = PermissibleValue(text="SV", description="Alpha2 code for El Salvador.") ER = PermissibleValue(text="ER", description="Alpha2 code for Eritrea.") EE = PermissibleValue(text="EE", description="Alpha2 code for Estonia.") @@ -3037,7 +3249,9 @@ class CountryNameAlpha2(EnumDefinitionImpl): IM = PermissibleValue(text="IM", description="Alpha2 code for Isle of Man.") IQ = PermissibleValue(text="IQ", description="Alpha2 code for Iraq.") IE = PermissibleValue(text="IE", description="Alpha2 code for Ireland.") - IR = PermissibleValue(text="IR", description="Alpha2 code for Iran (Islamic Republic of).") + IR = PermissibleValue( + text="IR", description="Alpha2 code for Iran (Islamic Republic of)." + ) IS = PermissibleValue(text="IS", description="Alpha2 code for Iceland.") IL = PermissibleValue(text="IL", description="Alpha2 code for Israel.") IT = PermissibleValue(text="IT", description="Alpha2 code for Italy.") @@ -3046,7 +3260,9 @@ class CountryNameAlpha2(EnumDefinitionImpl): YE = PermissibleValue(text="YE", description="Alpha2 code for Yemen.") JE = PermissibleValue(text="JE", description="Alpha2 code for Jersey.") JO = PermissibleValue(text="JO", description="Alpha2 code for Jordan.") - KY = PermissibleValue(text="KY", description="Alpha2 code for Cayman Islands (the).") + KY = PermissibleValue( + text="KY", description="Alpha2 code for Cayman Islands (the)." + ) KH = PermissibleValue(text="KH", description="Alpha2 code for Cambodia.") CM = PermissibleValue(text="CM", description="Alpha2 code for Cameroon.") CA = PermissibleValue(text="CA", description="Alpha2 code for Canada.") @@ -3055,7 +3271,9 @@ class CountryNameAlpha2(EnumDefinitionImpl): KE = PermissibleValue(text="KE", description="Alpha2 code for Kenya.") KG = PermissibleValue(text="KG", description="Alpha2 code for Kyrgyzstan.") KI = PermissibleValue(text="KI", description="Alpha2 code for Kiribati.") - CC = PermissibleValue(text="CC", description="Alpha2 code for Cocos (Keeling) Islands (the).") + CC = PermissibleValue( + text="CC", description="Alpha2 code for Cocos (Keeling) Islands (the)." + ) CO = PermissibleValue(text="CO", description="Alpha2 code for Colombia.") KM = PermissibleValue(text="KM", description="Alpha2 code for Comoros (the).") CG = PermissibleValue(text="CG", description="Alpha2 code for Congo (the).") @@ -3077,9 +3295,13 @@ class CountryNameAlpha2(EnumDefinitionImpl): MV = PermissibleValue(text="MV", description="Alpha2 code for Maldives.") ML = PermissibleValue(text="ML", description="Alpha2 code for Mali.") MT = PermissibleValue(text="MT", description="Alpha2 code for Malta.") - MP = PermissibleValue(text="MP", description="Alpha2 code for Northern Mariana Islands (the).") + MP = PermissibleValue( + text="MP", description="Alpha2 code for Northern Mariana Islands (the)." + ) MA = PermissibleValue(text="MA", description="Alpha2 code for Morocco.") - MH = PermissibleValue(text="MH", description="Alpha2 code for Marshall Islands (the).") + MH = PermissibleValue( + text="MH", description="Alpha2 code for Marshall Islands (the)." + ) MQ = PermissibleValue(text="MQ", description="Alpha2 code for Martinique.") MR = PermissibleValue(text="MR", description="Alpha2 code for Mauritania.") MU = PermissibleValue(text="MU", description="Alpha2 code for Mauritius.") @@ -3119,17 +3341,25 @@ class CountryNameAlpha2(EnumDefinitionImpl): PL = PermissibleValue(text="PL", description="Alpha2 code for Poland.") PT = PermissibleValue(text="PT", description="Alpha2 code for Portugal.") PR = PermissibleValue(text="PR", description="Alpha2 code for Puerto Rico.") - KR = PermissibleValue(text="KR", description="Alpha2 code for Korea (the Republic of).") - MD = PermissibleValue(text="MD", description="Alpha2 code for Moldova (the Republic of).") + KR = PermissibleValue( + text="KR", description="Alpha2 code for Korea (the Republic of)." + ) + MD = PermissibleValue( + text="MD", description="Alpha2 code for Moldova (the Republic of)." + ) RE = PermissibleValue(text="RE", description="Alpha2 code for Reunion.") RW = PermissibleValue(text="RW", description="Alpha2 code for Rwanda.") RO = PermissibleValue(text="RO", description="Alpha2 code for Romania.") - RU = PermissibleValue(text="RU", description="Alpha2 code for Russian Federation (the).") + RU = PermissibleValue( + text="RU", description="Alpha2 code for Russian Federation (the)." + ) SB = PermissibleValue(text="SB", description="Alpha2 code for Solomon Islands.") ZM = PermissibleValue(text="ZM", description="Alpha2 code for Zambia.") WS = PermissibleValue(text="WS", description="Alpha2 code for Samoa.") SM = PermissibleValue(text="SM", description="Alpha2 code for San Marino.") - ST = PermissibleValue(text="ST", description="Alpha2 code for Sao Tome and Principe.") + ST = PermissibleValue( + text="ST", description="Alpha2 code for Sao Tome and Principe." + ) SA = PermissibleValue(text="SA", description="Alpha2 code for Saudi Arabia.") SE = PermissibleValue(text="SE", description="Alpha2 code for Sweden.") CH = PermissibleValue(text="CH", description="Alpha2 code for Switzerland.") @@ -3149,11 +3379,19 @@ class CountryNameAlpha2(EnumDefinitionImpl): text="SH", description="Alpha2 code for Saint Helena, Ascension and Tristan da Cunha.", ) - KN = PermissibleValue(text="KN", description="Alpha2 code for Saint Kitts and Nevis.") + KN = PermissibleValue( + text="KN", description="Alpha2 code for Saint Kitts and Nevis." + ) LC = PermissibleValue(text="LC", description="Alpha2 code for Saint Lucia.") - MF = PermissibleValue(text="MF", description="Alpha2 code for Saint Martin (French part).") - SX = PermissibleValue(text="SX", description="Alpha2 code for Sint Maarten (Dutch part).") - PM = PermissibleValue(text="PM", description="Alpha2 code for Saint Pierre and Miquelon.") + MF = PermissibleValue( + text="MF", description="Alpha2 code for Saint Martin (French part)." + ) + SX = PermissibleValue( + text="SX", description="Alpha2 code for Sint Maarten (Dutch part)." + ) + PM = PermissibleValue( + text="PM", description="Alpha2 code for Saint Pierre and Miquelon." + ) VC = PermissibleValue( text="VC", description="Alpha2 code for Saint Vincent and the Grenadines." ) @@ -3165,10 +3403,14 @@ class CountryNameAlpha2(EnumDefinitionImpl): ) SS = PermissibleValue(text="SS", description="Alpha2 code for South Sudan.") SR = PermissibleValue(text="SR", description="Alpha2 code for Suriname.") - SJ = PermissibleValue(text="SJ", description="Alpha2 code for Svalbard and Jan Mayen.") + SJ = PermissibleValue( + text="SJ", description="Alpha2 code for Svalbard and Jan Mayen." + ) SZ = PermissibleValue(text="SZ", description="Alpha2 code for Eswatini.") TJ = PermissibleValue(text="TJ", description="Alpha2 code for Tajikistan.") - TW = PermissibleValue(text="TW", description="Alpha2 code for Taiwan (Province of China).") + TW = PermissibleValue( + text="TW", description="Alpha2 code for Taiwan (Province of China)." + ) TH = PermissibleValue(text="TH", description="Alpha2 code for Thailand.") TL = PermissibleValue(text="TL", description="Alpha2 code for Timor-Leste.") TG = PermissibleValue(text="TG", description="Alpha2 code for Togo.") @@ -3180,7 +3422,9 @@ class CountryNameAlpha2(EnumDefinitionImpl): TN = PermissibleValue(text="TN", description="Alpha2 code for Tunisia.") TR = PermissibleValue(text="TR", description="Alpha2 code for Turkey.") TM = PermissibleValue(text="TM", description="Alpha2 code for Turkmenistan.") - TC = PermissibleValue(text="TC", description="Alpha2 code for Turks and Caicos Islands (the).") + TC = PermissibleValue( + text="TC", description="Alpha2 code for Turks and Caicos Islands (the)." + ) TV = PermissibleValue(text="TV", description="Alpha2 code for Tuvalu.") UG = PermissibleValue(text="UG", description="Alpha2 code for Uganda.") UA = PermissibleValue(text="UA", description="Alpha2 code for Ukraine.") @@ -3189,9 +3433,15 @@ class CountryNameAlpha2(EnumDefinitionImpl): UZ = PermissibleValue(text="UZ", description="Alpha2 code for Uzbekistan.") VU = PermissibleValue(text="VU", description="Alpha2 code for Vanuatu.") VA = PermissibleValue(text="VA", description="Alpha2 code for Holy See (the).") - AE = PermissibleValue(text="AE", description="Alpha2 code for United Arab Emirates (the).") - TZ = PermissibleValue(text="TZ", description="Alpha2 code for Tanzania, United Republic of.") - US = PermissibleValue(text="US", description="Alpha2 code for United States of America (the).") + AE = PermissibleValue( + text="AE", description="Alpha2 code for United Arab Emirates (the)." + ) + TZ = PermissibleValue( + text="TZ", description="Alpha2 code for Tanzania, United Republic of." + ) + US = PermissibleValue( + text="US", description="Alpha2 code for United States of America (the)." + ) GB = PermissibleValue( text="GB", description="Alpha2 code for United Kingdom of Great Britain and Northern Ireland (the).", @@ -3201,7 +3451,9 @@ class CountryNameAlpha2(EnumDefinitionImpl): CX = PermissibleValue(text="CX", description="Alpha2 code for Christmas Island.") BY = PermissibleValue(text="BY", description="Alpha2 code for Belarus.") EH = PermissibleValue(text="EH", description="Alpha2 code for Western Sahara.") - CF = PermissibleValue(text="CF", description="Alpha2 code for Central African Republic (the).") + CF = PermissibleValue( + text="CF", description="Alpha2 code for Central African Republic (the)." + ) CY = PermissibleValue(text="CY", description="Alpha2 code for Cyprus.") _defn = EnumDefinition( @@ -3227,7 +3479,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): AGO = PermissibleValue(text="AGO", description="Alpha3 code for Angola.") AIA = PermissibleValue(text="AIA", description="Alpha3 code for Anguilla.") ATA = PermissibleValue(text="ATA", description="Alpha3 code for Antarctica.") - ATG = PermissibleValue(text="ATG", description="Alpha3 code for Antigua and Barbuda.") + ATG = PermissibleValue( + text="ATG", description="Alpha3 code for Antigua and Barbuda." + ) ARG = PermissibleValue(text="ARG", description="Alpha3 code for Argentina.") ARM = PermissibleValue(text="ARM", description="Alpha3 code for Armenia.") ABW = PermissibleValue(text="ABW", description="Alpha3 code for Aruba.") @@ -3250,7 +3504,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): BES = PermissibleValue( text="BES", description="Alpha3 code for Bonaire, Sint Eustatius and Saba." ) - BIH = PermissibleValue(text="BIH", description="Alpha3 code for Bosnia and Herzegovina.") + BIH = PermissibleValue( + text="BIH", description="Alpha3 code for Bosnia and Herzegovina." + ) BWA = PermissibleValue(text="BWA", description="Alpha3 code for Botswana.") BVT = PermissibleValue(text="BVT", description="Alpha3 code for Bouvet Island.") BRA = PermissibleValue(text="BRA", description="Alpha3 code for Brazil.") @@ -3265,7 +3521,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): CMR = PermissibleValue(text="CMR", description="Alpha3 code for Cameroon.") CAN = PermissibleValue(text="CAN", description="Alpha3 code for Canada.") CPV = PermissibleValue(text="CPV", description="Alpha3 code for Cabo Verde.") - CYM = PermissibleValue(text="CYM", description="Alpha3 code for Cayman Islands (the).") + CYM = PermissibleValue( + text="CYM", description="Alpha3 code for Cayman Islands (the)." + ) CAF = PermissibleValue( text="CAF", description="Alpha3 code for Central African Republic (the)." ) @@ -3273,7 +3531,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): CHL = PermissibleValue(text="CHL", description="Alpha3 code for Chile.") CHN = PermissibleValue(text="CHN", description="Alpha3 code for China.") CXR = PermissibleValue(text="CXR", description="Alpha3 code for Christmas Island.") - CCK = PermissibleValue(text="CCK", description="Alpha3 code for Cocos (Keeling) Islands (the).") + CCK = PermissibleValue( + text="CCK", description="Alpha3 code for Cocos (Keeling) Islands (the)." + ) COL = PermissibleValue(text="COL", description="Alpha3 code for Colombia.") COM = PermissibleValue(text="COM", description="Alpha3 code for Comoros (the).") COG = PermissibleValue(text="COG", description="Alpha3 code for Congo (the).") @@ -3281,7 +3541,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): text="COD", description="Alpha3 code for Congo (the Democratic Republic of the).", ) - COK = PermissibleValue(text="COK", description="Alpha3 code for Cook Islands (the).") + COK = PermissibleValue( + text="COK", description="Alpha3 code for Cook Islands (the)." + ) CRI = PermissibleValue(text="CRI", description="Alpha3 code for Costa Rica.") CIV = PermissibleValue(text="CIV", description="Alpha3 code for Cote dIvoire.") HRV = PermissibleValue(text="HRV", description="Alpha3 code for Croatia.") @@ -3292,7 +3554,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): DNK = PermissibleValue(text="DNK", description="Alpha3 code for Denmark.") DJI = PermissibleValue(text="DJI", description="Alpha3 code for Djibouti.") DMA = PermissibleValue(text="DMA", description="Alpha3 code for Dominica.") - DOM = PermissibleValue(text="DOM", description="Alpha3 code for Dominican Republic (the).") + DOM = PermissibleValue( + text="DOM", description="Alpha3 code for Dominican Republic (the)." + ) ECU = PermissibleValue(text="ECU", description="Alpha3 code for Ecuador.") EGY = PermissibleValue(text="EGY", description="Alpha3 code for Egypt.") SLV = PermissibleValue(text="SLV", description="Alpha3 code for El Salvador.") @@ -3303,7 +3567,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): FLK = PermissibleValue( text="FLK", description="Alpha3 code for Falkland Islands (the) [Malvinas]." ) - FRO = PermissibleValue(text="FRO", description="Alpha3 code for Faroe Islands (the).") + FRO = PermissibleValue( + text="FRO", description="Alpha3 code for Faroe Islands (the)." + ) FJI = PermissibleValue(text="FJI", description="Alpha3 code for Fiji.") FIN = PermissibleValue(text="FIN", description="Alpha3 code for Finland.") FRA = PermissibleValue(text="FRA", description="Alpha3 code for France.") @@ -3339,7 +3605,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): ISL = PermissibleValue(text="ISL", description="Alpha3 code for Iceland.") IND = PermissibleValue(text="IND", description="Alpha3 code for India.") IDN = PermissibleValue(text="IDN", description="Alpha3 code for Indonesia.") - IRN = PermissibleValue(text="IRN", description="Alpha3 code for Iran (Islamic Republic of).") + IRN = PermissibleValue( + text="IRN", description="Alpha3 code for Iran (Islamic Republic of)." + ) IRQ = PermissibleValue(text="IRQ", description="Alpha3 code for Iraq.") IRL = PermissibleValue(text="IRL", description="Alpha3 code for Ireland.") IMN = PermissibleValue(text="IMN", description="Alpha3 code for Isle of Man.") @@ -3356,7 +3624,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): text="PRK", description="Alpha3 code for Korea (the Democratic Peoples Republic of).", ) - KOR = PermissibleValue(text="KOR", description="Alpha3 code for Korea (the Republic of).") + KOR = PermissibleValue( + text="KOR", description="Alpha3 code for Korea (the Republic of)." + ) KWT = PermissibleValue(text="KWT", description="Alpha3 code for Kuwait.") KGZ = PermissibleValue(text="KGZ", description="Alpha3 code for Kyrgyzstan.") LAO = PermissibleValue( @@ -3371,14 +3641,18 @@ class CountryNameAlpha3(EnumDefinitionImpl): LTU = PermissibleValue(text="LTU", description="Alpha3 code for Lithuania.") LUX = PermissibleValue(text="LUX", description="Alpha3 code for Luxembourg.") MAC = PermissibleValue(text="MAC", description="Alpha3 code for Macao.") - MKD = PermissibleValue(text="MKD", description="Alpha3 code for Republic of North Macedonia.") + MKD = PermissibleValue( + text="MKD", description="Alpha3 code for Republic of North Macedonia." + ) MDG = PermissibleValue(text="MDG", description="Alpha3 code for Madagascar.") MWI = PermissibleValue(text="MWI", description="Alpha3 code for Malawi.") MYS = PermissibleValue(text="MYS", description="Alpha3 code for Malaysia.") MDV = PermissibleValue(text="MDV", description="Alpha3 code for Maldives.") MLI = PermissibleValue(text="MLI", description="Alpha3 code for Mali.") MLT = PermissibleValue(text="MLT", description="Alpha3 code for Malta.") - MHL = PermissibleValue(text="MHL", description="Alpha3 code for Marshall Islands (the).") + MHL = PermissibleValue( + text="MHL", description="Alpha3 code for Marshall Islands (the)." + ) MTQ = PermissibleValue(text="MTQ", description="Alpha3 code for Martinique.") MRT = PermissibleValue(text="MRT", description="Alpha3 code for Mauritania.") MUS = PermissibleValue(text="MUS", description="Alpha3 code for Mauritius.") @@ -3387,7 +3661,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): FSM = PermissibleValue( text="FSM", description="Alpha3 code for Micronesia (Federated States of)." ) - MDA = PermissibleValue(text="MDA", description="Alpha3 code for Moldova (the Republic of).") + MDA = PermissibleValue( + text="MDA", description="Alpha3 code for Moldova (the Republic of)." + ) MCO = PermissibleValue(text="MCO", description="Alpha3 code for Monaco.") MNG = PermissibleValue(text="MNG", description="Alpha3 code for Mongolia.") MNE = PermissibleValue(text="MNE", description="Alpha3 code for Montenegro.") @@ -3413,7 +3689,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): OMN = PermissibleValue(text="OMN", description="Alpha3 code for Oman.") PAK = PermissibleValue(text="PAK", description="Alpha3 code for Pakistan.") PLW = PermissibleValue(text="PLW", description="Alpha3 code for Palau.") - PSE = PermissibleValue(text="PSE", description="Alpha3 code for Palestine, State of.") + PSE = PermissibleValue( + text="PSE", description="Alpha3 code for Palestine, State of." + ) PAN = PermissibleValue(text="PAN", description="Alpha3 code for Panama.") PNG = PermissibleValue(text="PNG", description="Alpha3 code for Papua New Guinea.") PRY = PermissibleValue(text="PRY", description="Alpha3 code for Paraguay.") @@ -3427,29 +3705,41 @@ class CountryNameAlpha3(EnumDefinitionImpl): SRB = PermissibleValue(text="SRB", description="Alpha3 code for Serbia.") REU = PermissibleValue(text="REU", description="Alpha3 code for Reunion.") ROU = PermissibleValue(text="ROU", description="Alpha3 code for Romania.") - RUS = PermissibleValue(text="RUS", description="Alpha3 code for Russian Federation (the).") + RUS = PermissibleValue( + text="RUS", description="Alpha3 code for Russian Federation (the)." + ) RWA = PermissibleValue(text="RWA", description="Alpha3 code for Rwanda.") BLM = PermissibleValue(text="BLM", description="Alpha3 code for Saint Barthelemy.") SHN = PermissibleValue( text="SHN", description="Alpha3 code for Saint Helena, Ascension and Tristan da Cunha.", ) - KNA = PermissibleValue(text="KNA", description="Alpha3 code for Saint Kitts and Nevis.") + KNA = PermissibleValue( + text="KNA", description="Alpha3 code for Saint Kitts and Nevis." + ) LCA = PermissibleValue(text="LCA", description="Alpha3 code for Saint Lucia.") - MAF = PermissibleValue(text="MAF", description="Alpha3 code for Saint Martin (French part).") - SPM = PermissibleValue(text="SPM", description="Alpha3 code for Saint Pierre and Miquelon.") + MAF = PermissibleValue( + text="MAF", description="Alpha3 code for Saint Martin (French part)." + ) + SPM = PermissibleValue( + text="SPM", description="Alpha3 code for Saint Pierre and Miquelon." + ) VCT = PermissibleValue( text="VCT", description="Alpha3 code for Saint Vincent and the Grenadines." ) WSM = PermissibleValue(text="WSM", description="Alpha3 code for Samoa.") SMR = PermissibleValue(text="SMR", description="Alpha3 code for San Marino.") - STP = PermissibleValue(text="STP", description="Alpha3 code for Sao Tome and Principe.") + STP = PermissibleValue( + text="STP", description="Alpha3 code for Sao Tome and Principe." + ) SAU = PermissibleValue(text="SAU", description="Alpha3 code for Saudi Arabia.") SEN = PermissibleValue(text="SEN", description="Alpha3 code for Senegal.") SYC = PermissibleValue(text="SYC", description="Alpha3 code for Seychelles.") SLE = PermissibleValue(text="SLE", description="Alpha3 code for Sierra Leone.") SGP = PermissibleValue(text="SGP", description="Alpha3 code for Singapore.") - SXM = PermissibleValue(text="SXM", description="Alpha3 code for Sint Maarten (Dutch part).") + SXM = PermissibleValue( + text="SXM", description="Alpha3 code for Sint Maarten (Dutch part)." + ) SVK = PermissibleValue(text="SVK", description="Alpha3 code for Slovakia.") SVN = PermissibleValue(text="SVN", description="Alpha3 code for Slovenia.") SLB = PermissibleValue(text="SLB", description="Alpha3 code for Solomon Islands.") @@ -3464,20 +3754,30 @@ class CountryNameAlpha3(EnumDefinitionImpl): LKA = PermissibleValue(text="LKA", description="Alpha3 code for Sri Lanka.") SDN = PermissibleValue(text="SDN", description="Alpha3 code for Sudan (the).") SUR = PermissibleValue(text="SUR", description="Alpha3 code for Suriname.") - SJM = PermissibleValue(text="SJM", description="Alpha3 code for Svalbard and Jan Mayen.") + SJM = PermissibleValue( + text="SJM", description="Alpha3 code for Svalbard and Jan Mayen." + ) SWZ = PermissibleValue(text="SWZ", description="Alpha3 code for Eswatini.") SWE = PermissibleValue(text="SWE", description="Alpha3 code for Sweden.") CHE = PermissibleValue(text="CHE", description="Alpha3 code for Switzerland.") - SYR = PermissibleValue(text="SYR", description="Alpha3 code for Syrian Arab Republic.") - TWN = PermissibleValue(text="TWN", description="Alpha3 code for Taiwan (Province of China).") + SYR = PermissibleValue( + text="SYR", description="Alpha3 code for Syrian Arab Republic." + ) + TWN = PermissibleValue( + text="TWN", description="Alpha3 code for Taiwan (Province of China)." + ) TJK = PermissibleValue(text="TJK", description="Alpha3 code for Tajikistan.") - TZA = PermissibleValue(text="TZA", description="Alpha3 code for Tanzania, United Republic of.") + TZA = PermissibleValue( + text="TZA", description="Alpha3 code for Tanzania, United Republic of." + ) THA = PermissibleValue(text="THA", description="Alpha3 code for Thailand.") TLS = PermissibleValue(text="TLS", description="Alpha3 code for Timor-Leste.") TGO = PermissibleValue(text="TGO", description="Alpha3 code for Togo.") TKL = PermissibleValue(text="TKL", description="Alpha3 code for Tokelau.") TON = PermissibleValue(text="TON", description="Alpha3 code for Tonga.") - TTO = PermissibleValue(text="TTO", description="Alpha3 code for Trinidad and Tobago.") + TTO = PermissibleValue( + text="TTO", description="Alpha3 code for Trinidad and Tobago." + ) TUN = PermissibleValue(text="TUN", description="Alpha3 code for Tunisia.") TUR = PermissibleValue(text="TUR", description="Alpha3 code for Turkey.") XTX = PermissibleValue( @@ -3490,7 +3790,9 @@ class CountryNameAlpha3(EnumDefinitionImpl): TUV = PermissibleValue(text="TUV", description="Alpha3 code for Tuvalu.") UGA = PermissibleValue(text="UGA", description="Alpha3 code for Uganda.") UKR = PermissibleValue(text="UKR", description="Alpha3 code for Ukraine.") - ARE = PermissibleValue(text="ARE", description="Alpha3 code for United Arab Emirates (the).") + ARE = PermissibleValue( + text="ARE", description="Alpha3 code for United Arab Emirates (the)." + ) GBR = PermissibleValue( text="GBR", description="Alpha3 code for United Kingdom of Great Britain and Northern Ireland (the).", @@ -3509,8 +3811,12 @@ class CountryNameAlpha3(EnumDefinitionImpl): text="VEN", description="Alpha3 code for Venezuela (Bolivarian Republic of)." ) VNM = PermissibleValue(text="VNM", description="Alpha3 code for Viet Nam.") - VGB = PermissibleValue(text="VGB", description="Alpha3 code for Virgin Islands (British).") - VIR = PermissibleValue(text="VIR", description="Alpha3 code for Virgin Islands (U.S.).") + VGB = PermissibleValue( + text="VGB", description="Alpha3 code for Virgin Islands (British)." + ) + VIR = PermissibleValue( + text="VIR", description="Alpha3 code for Virgin Islands (U.S.)." + ) WLF = PermissibleValue(text="WLF", description="Alpha3 code for Wallis and Futuna.") ESH = PermissibleValue(text="ESH", description="Alpha3 code for Western Sahara.") YEM = PermissibleValue(text="YEM", description="Alpha3 code for Yemen.") @@ -3558,7 +3864,9 @@ def _addvals(cls): setattr( cls, "850", - PermissibleValue(text="850", description="Numeric code for Virgin Islands (U.S.)."), + PermissibleValue( + text="850", description="Numeric code for Virgin Islands (U.S.)." + ), ) setattr( cls, @@ -3596,17 +3904,23 @@ def _addvals(cls): setattr( cls, "028", - PermissibleValue(text="028", description="Numeric code for Antigua and Barbuda."), + PermissibleValue( + text="028", description="Numeric code for Antigua and Barbuda." + ), ) setattr( cls, "226", - PermissibleValue(text="226", description="Numeric code for Equatorial Guinea."), + PermissibleValue( + text="226", description="Numeric code for Equatorial Guinea." + ), ) setattr( cls, "760", - PermissibleValue(text="760", description="Numeric code for Syrian Arab Republic."), + PermissibleValue( + text="760", description="Numeric code for Syrian Arab Republic." + ), ) setattr( cls, @@ -3691,7 +4005,9 @@ def _addvals(cls): setattr( cls, "092", - PermissibleValue(text="092", description="Numeric code for Virgin Islands (British)."), + PermissibleValue( + text="092", description="Numeric code for Virgin Islands (British)." + ), ) setattr( cls, @@ -3729,7 +4045,9 @@ def _addvals(cls): setattr( cls, "184", - PermissibleValue(text="184", description="Numeric code for Cook Islands (the)."), + PermissibleValue( + text="184", description="Numeric code for Cook Islands (the)." + ), ) setattr( cls, @@ -3788,7 +4106,9 @@ def _addvals(cls): setattr( cls, "214", - PermissibleValue(text="214", description="Numeric code for Dominican Republic (the)."), + PermissibleValue( + text="214", description="Numeric code for Dominican Republic (the)." + ), ) setattr( cls, @@ -3833,7 +4153,9 @@ def _addvals(cls): setattr( cls, "234", - PermissibleValue(text="234", description="Numeric code for Faroe Islands (the)."), + PermissibleValue( + text="234", description="Numeric code for Faroe Islands (the)." + ), ) setattr( cls, @@ -3874,7 +4196,9 @@ def _addvals(cls): setattr( cls, "258", - PermissibleValue(text="258", description="Numeric code for French Polynesia."), + PermissibleValue( + text="258", description="Numeric code for French Polynesia." + ), ) setattr( cls, @@ -4049,7 +4373,9 @@ def _addvals(cls): setattr( cls, "136", - PermissibleValue(text="136", description="Numeric code for Cayman Islands (the)."), + PermissibleValue( + text="136", description="Numeric code for Cayman Islands (the)." + ), ) setattr( cls, @@ -4220,7 +4546,9 @@ def _addvals(cls): setattr( cls, "584", - PermissibleValue(text="584", description="Numeric code for Marshall Islands (the)."), + PermissibleValue( + text="584", description="Numeric code for Marshall Islands (the)." + ), ) setattr( cls, @@ -4310,7 +4638,9 @@ def _addvals(cls): setattr( cls, "528", - PermissibleValue(text="528", description="Numeric code for Netherlands (the)."), + PermissibleValue( + text="528", description="Numeric code for Netherlands (the)." + ), ) setattr( cls, @@ -4330,7 +4660,9 @@ def _addvals(cls): setattr( cls, "574", - PermissibleValue(text="574", description="Numeric code for Norfolk Island."), + PermissibleValue( + text="574", description="Numeric code for Norfolk Island." + ), ) setattr( cls, @@ -4360,7 +4692,9 @@ def _addvals(cls): setattr( cls, "275", - PermissibleValue(text="275", description="Numeric code for Palestine, State of."), + PermissibleValue( + text="275", description="Numeric code for Palestine, State of." + ), ) setattr( cls, @@ -4370,7 +4704,9 @@ def _addvals(cls): setattr( cls, "598", - PermissibleValue(text="598", description="Numeric code for Papua New Guinea."), + PermissibleValue( + text="598", description="Numeric code for Papua New Guinea." + ), ) setattr( cls, @@ -4385,7 +4721,9 @@ def _addvals(cls): setattr( cls, "608", - PermissibleValue(text="608", description="Numeric code for Philippines (the)."), + PermissibleValue( + text="608", description="Numeric code for Philippines (the)." + ), ) setattr( cls, @@ -4418,12 +4756,16 @@ def _addvals(cls): setattr( cls, "410", - PermissibleValue(text="410", description="Numeric code for Korea (the Republic of)."), + PermissibleValue( + text="410", description="Numeric code for Korea (the Republic of)." + ), ) setattr( cls, "498", - PermissibleValue(text="498", description="Numeric code for Moldova (the Republic of)."), + PermissibleValue( + text="498", description="Numeric code for Moldova (the Republic of)." + ), ) setattr( cls, @@ -4443,12 +4785,16 @@ def _addvals(cls): setattr( cls, "643", - PermissibleValue(text="643", description="Numeric code for Russian Federation (the)."), + PermissibleValue( + text="643", description="Numeric code for Russian Federation (the)." + ), ) setattr( cls, "090", - PermissibleValue(text="090", description="Numeric code for Solomon Islands."), + PermissibleValue( + text="090", description="Numeric code for Solomon Islands." + ), ) setattr( cls, @@ -4468,7 +4814,9 @@ def _addvals(cls): setattr( cls, "678", - PermissibleValue(text="678", description="Numeric code for Sao Tome and Principe."), + PermissibleValue( + text="678", description="Numeric code for Sao Tome and Principe." + ), ) setattr( cls, @@ -4543,7 +4891,9 @@ def _addvals(cls): setattr( cls, "652", - PermissibleValue(text="652", description="Numeric code for Saint Barthelemy."), + PermissibleValue( + text="652", description="Numeric code for Saint Barthelemy." + ), ) setattr( cls, @@ -4556,7 +4906,9 @@ def _addvals(cls): setattr( cls, "659", - PermissibleValue(text="659", description="Numeric code for Saint Kitts and Nevis."), + PermissibleValue( + text="659", description="Numeric code for Saint Kitts and Nevis." + ), ) setattr( cls, @@ -4573,12 +4925,16 @@ def _addvals(cls): setattr( cls, "534", - PermissibleValue(text="534", description="Numeric code for Sint Maarten (Dutch part)."), + PermissibleValue( + text="534", description="Numeric code for Sint Maarten (Dutch part)." + ), ) setattr( cls, "666", - PermissibleValue(text="666", description="Numeric code for Saint Pierre and Miquelon."), + PermissibleValue( + text="666", description="Numeric code for Saint Pierre and Miquelon." + ), ) setattr( cls, @@ -4619,7 +4975,9 @@ def _addvals(cls): setattr( cls, "744", - PermissibleValue(text="744", description="Numeric code for Svalbard and Jan Mayen."), + PermissibleValue( + text="744", description="Numeric code for Svalbard and Jan Mayen." + ), ) setattr( cls, @@ -4666,7 +5024,9 @@ def _addvals(cls): setattr( cls, "780", - PermissibleValue(text="780", description="Numeric code for Trinidad and Tobago."), + PermissibleValue( + text="780", description="Numeric code for Trinidad and Tobago." + ), ) setattr( cls, @@ -4739,7 +5099,9 @@ def _addvals(cls): setattr( cls, "336", - PermissibleValue(text="336", description="Numeric code for Holy See (the)."), + PermissibleValue( + text="336", description="Numeric code for Holy See (the)." + ), ) setattr( cls, @@ -4779,12 +5141,16 @@ def _addvals(cls): setattr( cls, "876", - PermissibleValue(text="876", description="Numeric code for Wallis and Futuna."), + PermissibleValue( + text="876", description="Numeric code for Wallis and Futuna." + ), ) setattr( cls, "162", - PermissibleValue(text="162", description="Numeric code for Christmas Island."), + PermissibleValue( + text="162", description="Numeric code for Christmas Island." + ), ) setattr( cls, @@ -4794,7 +5160,9 @@ def _addvals(cls): setattr( cls, "732", - PermissibleValue(text="732", description="Numeric code for Western Sahara."), + PermissibleValue( + text="732", description="Numeric code for Western Sahara." + ), ) setattr( cls, @@ -4812,7 +5180,9 @@ def _addvals(cls): class Architectures(EnumDefinitionImpl): - other = PermissibleValue(text="other", description="CPU architecture not specified above.") + other = PermissibleValue( + text="other", description="CPU architecture not specified above." + ) _defn = EnumDefinition( name="Architectures", @@ -4823,22 +5193,30 @@ def _addvals(cls): setattr( cls, "x86-32", - PermissibleValue(text="x86-32", description="32 bit version of x86 architecture."), + PermissibleValue( + text="x86-32", description="32 bit version of x86 architecture." + ), ) setattr( cls, "x86-64", - PermissibleValue(text="x86-64", description="64 bit version of x86 architecture."), + PermissibleValue( + text="x86-64", description="64 bit version of x86 architecture." + ), ) setattr( cls, "AArch-32", - PermissibleValue(text="AArch-32", description="32-bit version of ARM architecture."), + PermissibleValue( + text="AArch-32", description="32-bit version of ARM architecture." + ), ) setattr( cls, "AArch-64", - PermissibleValue(text="AArch-64", description="64-bit version of ARM architecture."), + PermissibleValue( + text="AArch-64", description="64-bit version of ARM architecture." + ), ) setattr( cls, @@ -5038,7 +5416,9 @@ def _addvals(cls): class DiskType(EnumDefinitionImpl): - other = PermissibleValue(text="other", description="Storage device no further described.") + other = PermissibleValue( + text="other", description="Storage device no further described." + ) _defn = EnumDefinition( name="DiskType", @@ -5109,7 +5489,9 @@ class DiskBusType(EnumDefinitionImpl): text="NVMe", description="""The Non-volatile Memory Express interface is designed to address tasks that require high-performance computing environments.""", ) - other = PermissibleValue(text="other", description="Disk controller no further described.") + other = PermissibleValue( + text="other", description="Disk controller no further described." + ) _defn = EnumDefinition( name="DiskBusType", @@ -5238,7 +5620,9 @@ class MemoryClasses(EnumDefinitionImpl): text="GDDR6", description="Evolution of GDDR5 memory, designed for high-performance computing.", ) - other = PermissibleValue(text="other", description="Memory class no further described.") + other = PermissibleValue( + text="other", description="Memory class no further described." + ) _defn = EnumDefinition( name="MemoryClasses", @@ -5265,7 +5649,9 @@ def _addvals(cls): class MemoryRanks(EnumDefinitionImpl): - other = PermissibleValue(text="other", description="Memory rank no further described.") + other = PermissibleValue( + text="other", description="Memory rank no further described." + ) _defn = EnumDefinition( name="MemoryRanks", @@ -9511,19 +9897,27 @@ def _addvals(cls): ) setattr(cls, "grammar-ref-list", PermissibleValue(text="grammar-ref-list")) setattr(cls, "jcr-cnd", PermissibleValue(text="jcr-cnd")) - setattr(cls, "provenance-notation", PermissibleValue(text="provenance-notation")) - setattr(cls, "prs.fallenstein.rst", PermissibleValue(text="prs.fallenstein.rst")) + setattr( + cls, "provenance-notation", PermissibleValue(text="provenance-notation") + ) + setattr( + cls, "prs.fallenstein.rst", PermissibleValue(text="prs.fallenstein.rst") + ) setattr(cls, "prs.lines.tag", PermissibleValue(text="prs.lines.tag")) setattr(cls, "prs.prop.logic", PermissibleValue(text="prs.prop.logic")) setattr(cls, "rfc822-headers", PermissibleValue(text="rfc822-headers")) setattr(cls, "rtp-enc-aescm128", PermissibleValue(text="rtp-enc-aescm128")) - setattr(cls, "tab-separated-values", PermissibleValue(text="tab-separated-values")) + setattr( + cls, "tab-separated-values", PermissibleValue(text="tab-separated-values") + ) setattr(cls, "uri-list", PermissibleValue(text="uri-list")) setattr(cls, "vnd.a", PermissibleValue(text="vnd.a")) setattr(cls, "vnd.abc", PermissibleValue(text="vnd.abc")) setattr(cls, "vnd.ascii-art", PermissibleValue(text="vnd.ascii-art")) setattr(cls, "vnd.curl", PermissibleValue(text="vnd.curl")) - setattr(cls, "vnd.debian.copyright", PermissibleValue(text="vnd.debian.copyright")) + setattr( + cls, "vnd.debian.copyright", PermissibleValue(text="vnd.debian.copyright") + ) setattr(cls, "vnd.DMClientScript", PermissibleValue(text="vnd.DMClientScript")) setattr(cls, "vnd.dvb.subtitle", PermissibleValue(text="vnd.dvb.subtitle")) setattr( @@ -9549,8 +9943,12 @@ def _addvals(cls): setattr(cls, "vnd.IPTC.NewsML", PermissibleValue(text="vnd.IPTC.NewsML")) setattr(cls, "vnd.IPTC.NITF", PermissibleValue(text="vnd.IPTC.NITF")) setattr(cls, "vnd.latex-z", PermissibleValue(text="vnd.latex-z")) - setattr(cls, "vnd.motorola.reflex", PermissibleValue(text="vnd.motorola.reflex")) - setattr(cls, "vnd.ms-mediapackage", PermissibleValue(text="vnd.ms-mediapackage")) + setattr( + cls, "vnd.motorola.reflex", PermissibleValue(text="vnd.motorola.reflex") + ) + setattr( + cls, "vnd.ms-mediapackage", PermissibleValue(text="vnd.ms-mediapackage") + ) setattr( cls, "vnd.net2phone.commcenter.command", @@ -9561,8 +9959,12 @@ def _addvals(cls): "vnd.radisys.msml-basic-layout", PermissibleValue(text="vnd.radisys.msml-basic-layout"), ) - setattr(cls, "vnd.senx.warpscript", PermissibleValue(text="vnd.senx.warpscript")) - setattr(cls, "vnd.si.uricatalogue", PermissibleValue(text="vnd.si.uricatalogue")) + setattr( + cls, "vnd.senx.warpscript", PermissibleValue(text="vnd.senx.warpscript") + ) + setattr( + cls, "vnd.si.uricatalogue", PermissibleValue(text="vnd.si.uricatalogue") + ) setattr( cls, "vnd.sun.j2me.app-descriptor", @@ -9597,14 +9999,18 @@ def _addvals(cls): setattr(cls, "aif+cbor", PermissibleValue(text="aif+cbor")) setattr(cls, "aif+json", PermissibleValue(text="aif+json")) setattr(cls, "alto-cdni+json", PermissibleValue(text="alto-cdni+json")) - setattr(cls, "alto-cdnifilter+json", PermissibleValue(text="alto-cdnifilter+json")) + setattr( + cls, "alto-cdnifilter+json", PermissibleValue(text="alto-cdnifilter+json") + ) setattr(cls, "alto-costmap+json", PermissibleValue(text="alto-costmap+json")) setattr( cls, "alto-costmapfilter+json", PermissibleValue(text="alto-costmapfilter+json"), ) - setattr(cls, "alto-directory+json", PermissibleValue(text="alto-directory+json")) + setattr( + cls, "alto-directory+json", PermissibleValue(text="alto-directory+json") + ) setattr( cls, "alto-endpointprop+json", @@ -9631,7 +10037,9 @@ def _addvals(cls): "alto-networkmapfilter+json", PermissibleValue(text="alto-networkmapfilter+json"), ) - setattr(cls, "alto-networkmap+json", PermissibleValue(text="alto-networkmap+json")) + setattr( + cls, "alto-networkmap+json", PermissibleValue(text="alto-networkmap+json") + ) setattr(cls, "alto-propmap+json", PermissibleValue(text="alto-propmap+json")) setattr( cls, @@ -9664,8 +10072,12 @@ def _addvals(cls): setattr(cls, "atsc-rdt+json", PermissibleValue(text="atsc-rdt+json")) setattr(cls, "atsc-rsat+xml", PermissibleValue(text="atsc-rsat+xml")) setattr(cls, "auth-policy+xml", PermissibleValue(text="auth-policy+xml")) - setattr(cls, "automationml-aml+xml", PermissibleValue(text="automationml-aml+xml")) - setattr(cls, "automationml-amlx+zip", PermissibleValue(text="automationml-amlx+zip")) + setattr( + cls, "automationml-aml+xml", PermissibleValue(text="automationml-aml+xml") + ) + setattr( + cls, "automationml-amlx+zip", PermissibleValue(text="automationml-amlx+zip") + ) setattr(cls, "bacnet-xdd+zip", PermissibleValue(text="bacnet-xdd+zip")) setattr(cls, "batch-SMTP", PermissibleValue(text="batch-SMTP")) setattr(cls, "beep+xml", PermissibleValue(text="beep+xml")) @@ -9698,7 +10110,9 @@ def _addvals(cls): "concise-problem-details+cbor", PermissibleValue(text="concise-problem-details+cbor"), ) - setattr(cls, "conference-info+xml", PermissibleValue(text="conference-info+xml")) + setattr( + cls, "conference-info+xml", PermissibleValue(text="conference-info+xml") + ) setattr(cls, "cpl+xml", PermissibleValue(text="cpl+xml")) setattr(cls, "cose-key", PermissibleValue(text="cose-key")) setattr(cls, "cose-key-set", PermissibleValue(text="cose-key-set")) @@ -9781,7 +10195,9 @@ def _addvals(cls): setattr(cls, "emotionml+xml", PermissibleValue(text="emotionml+xml")) setattr(cls, "epp+xml", PermissibleValue(text="epp+xml")) setattr(cls, "epub+zip", PermissibleValue(text="epub+zip")) - setattr(cls, "expect-ct-report+json", PermissibleValue(text="expect-ct-report+json")) + setattr( + cls, "expect-ct-report+json", PermissibleValue(text="expect-ct-report+json") + ) setattr(cls, "fdt+xml", PermissibleValue(text="fdt+xml")) setattr(cls, "fhir+json", PermissibleValue(text="fhir+json")) setattr(cls, "fhir+xml", PermissibleValue(text="fhir+xml")) @@ -9809,8 +10225,10 @@ def _addvals(cls): setattr(cls, "gml+xml", PermissibleValue(text="gml+xml")) setattr(cls, "held+xml", PermissibleValue(text="held+xml")) setattr(cls, "hl7v2+xml", PermissibleValue(text="hl7v2+xml")) - setattr(cls, "ibe-key-request+xml", PermissibleValue(text="ibe-key-request+xml")) - setattr(cls, "ibe-pkg-reply+xml", PermissibleValue(text="ibe-pkg-reply+xml")) + setattr( + cls, "ibe-key-request+xml", PermissibleValue(text="ibe-key-request+xml") + ) + setattr(cls, "ibe-pkg-reply+xml", PermissibleValue(text="ibe-pkg-reply+xml")) setattr(cls, "ibe-pp-data", PermissibleValue(text="ibe-pp-data")) setattr(cls, "im-iscomposing+xml", PermissibleValue(text="im-iscomposing+xml")) setattr(cls, "index.cmd", PermissibleValue(text="index.cmd")) @@ -9860,9 +10278,13 @@ def _addvals(cls): "mbms-associated-procedure-description+xml", PermissibleValue(text="mbms-associated-procedure-description+xml"), ) - setattr(cls, "mbms-deregister+xml", PermissibleValue(text="mbms-deregister+xml")) + setattr( + cls, "mbms-deregister+xml", PermissibleValue(text="mbms-deregister+xml") + ) setattr(cls, "mbms-envelope+xml", PermissibleValue(text="mbms-envelope+xml")) - setattr(cls, "mbms-msk-response+xml", PermissibleValue(text="mbms-msk-response+xml")) + setattr( + cls, "mbms-msk-response+xml", PermissibleValue(text="mbms-msk-response+xml") + ) setattr(cls, "mbms-msk+xml", PermissibleValue(text="mbms-msk+xml")) setattr( cls, @@ -9927,8 +10349,12 @@ def _addvals(cls): setattr(cls, "news-groupinfo", PermissibleValue(text="news-groupinfo")) setattr(cls, "news-transmission", PermissibleValue(text="news-transmission")) setattr(cls, "nlsml+xml", PermissibleValue(text="nlsml+xml")) - setattr(cls, "oauth-authz-req+jwt", PermissibleValue(text="oauth-authz-req+jwt")) - setattr(cls, "oblivious-dns-message", PermissibleValue(text="oblivious-dns-message")) + setattr( + cls, "oauth-authz-req+jwt", PermissibleValue(text="oauth-authz-req+jwt") + ) + setattr( + cls, "oblivious-dns-message", PermissibleValue(text="oblivious-dns-message") + ) setattr(cls, "ocsp-request", PermissibleValue(text="ocsp-request")) setattr(cls, "ocsp-response", PermissibleValue(text="ocsp-response")) setattr(cls, "octet-stream", PermissibleValue(text="octet-stream")) @@ -9938,8 +10364,12 @@ def _addvals(cls): setattr(cls, "opc-nodeset+xml", PermissibleValue(text="opc-nodeset+xml")) setattr(cls, "p21+zip", PermissibleValue(text="p21+zip")) setattr(cls, "p2p-overlay+xml", PermissibleValue(text="p2p-overlay+xml")) - setattr(cls, "patch-ops-error+xml", PermissibleValue(text="patch-ops-error+xml")) - setattr(cls, "pem-certificate-chain", PermissibleValue(text="pem-certificate-chain")) + setattr( + cls, "patch-ops-error+xml", PermissibleValue(text="patch-ops-error+xml") + ) + setattr( + cls, "pem-certificate-chain", PermissibleValue(text="pem-certificate-chain") + ) setattr(cls, "pgp-encrypted", PermissibleValue(text="pgp-encrypted")) setattr(cls, "pgp-keys", PermissibleValue(text="pgp-keys")) setattr(cls, "pgp-signature", PermissibleValue(text="pgp-signature")) @@ -9976,7 +10406,9 @@ def _addvals(cls): "prs.implied-executable", PermissibleValue(text="prs.implied-executable"), ) - setattr(cls, "prs.implied-structure", PermissibleValue(text="prs.implied-structure")) + setattr( + cls, "prs.implied-structure", PermissibleValue(text="prs.implied-structure") + ) setattr(cls, "prs.nprend", PermissibleValue(text="prs.nprend")) setattr(cls, "prs.plucker", PermissibleValue(text="prs.plucker")) setattr(cls, "prs.rdf-xml-crypt", PermissibleValue(text="prs.rdf-xml-crypt")) @@ -10089,23 +10521,31 @@ def _addvals(cls): "tamp-apex-update-confirm", PermissibleValue(text="tamp-apex-update-confirm"), ) - setattr(cls, "tamp-community-update", PermissibleValue(text="tamp-community-update")) + setattr( + cls, "tamp-community-update", PermissibleValue(text="tamp-community-update") + ) setattr( cls, "tamp-community-update-confirm", PermissibleValue(text="tamp-community-update-confirm"), ) setattr(cls, "tamp-error", PermissibleValue(text="tamp-error")) - setattr(cls, "tamp-sequence-adjust", PermissibleValue(text="tamp-sequence-adjust")) + setattr( + cls, "tamp-sequence-adjust", PermissibleValue(text="tamp-sequence-adjust") + ) setattr( cls, "tamp-sequence-adjust-confirm", PermissibleValue(text="tamp-sequence-adjust-confirm"), ) setattr(cls, "tamp-status-query", PermissibleValue(text="tamp-status-query")) - setattr(cls, "tamp-status-response", PermissibleValue(text="tamp-status-response")) + setattr( + cls, "tamp-status-response", PermissibleValue(text="tamp-status-response") + ) setattr(cls, "tamp-update", PermissibleValue(text="tamp-update")) - setattr(cls, "tamp-update-confirm", PermissibleValue(text="tamp-update-confirm")) + setattr( + cls, "tamp-update-confirm", PermissibleValue(text="tamp-update-confirm") + ) setattr(cls, "taxii+json", PermissibleValue(text="taxii+json")) setattr(cls, "td+json", PermissibleValue(text="td+json")) setattr(cls, "tei+xml", PermissibleValue(text="tei+xml")) @@ -10121,14 +10561,18 @@ def _addvals(cls): "token-introspection+jwt", PermissibleValue(text="token-introspection+jwt"), ) - setattr(cls, "trickle-ice-sdpfrag", PermissibleValue(text="trickle-ice-sdpfrag")) + setattr( + cls, "trickle-ice-sdpfrag", PermissibleValue(text="trickle-ice-sdpfrag") + ) setattr(cls, "ttml+xml", PermissibleValue(text="ttml+xml")) setattr(cls, "tve-trigger", PermissibleValue(text="tve-trigger")) setattr(cls, "tzif-leap", PermissibleValue(text="tzif-leap")) setattr(cls, "urc-grpsheet+xml", PermissibleValue(text="urc-grpsheet+xml")) setattr(cls, "urc-ressheet+xml", PermissibleValue(text="urc-ressheet+xml")) setattr(cls, "urc-targetdesc+xml", PermissibleValue(text="urc-targetdesc+xml")) - setattr(cls, "urc-uisocketdesc+xml", PermissibleValue(text="urc-uisocketdesc+xml")) + setattr( + cls, "urc-uisocketdesc+xml", PermissibleValue(text="urc-uisocketdesc+xml") + ) setattr(cls, "vcard+json", PermissibleValue(text="vcard+json")) setattr(cls, "vcard+xml", PermissibleValue(text="vcard+xml")) setattr( @@ -10315,12 +10759,20 @@ def _addvals(cls): "vnd.3gpp.mcvideo-user-profile+xml", PermissibleValue(text="vnd.3gpp.mcvideo-user-profile+xml"), ) - setattr(cls, "vnd.3gpp.mid-call+xml", PermissibleValue(text="vnd.3gpp.mid-call+xml")) + setattr( + cls, "vnd.3gpp.mid-call+xml", PermissibleValue(text="vnd.3gpp.mid-call+xml") + ) setattr(cls, "vnd.3gpp.ngap", PermissibleValue(text="vnd.3gpp.ngap")) setattr(cls, "vnd.3gpp.pfcp", PermissibleValue(text="vnd.3gpp.pfcp")) - setattr(cls, "vnd.3gpp.pic-bw-large", PermissibleValue(text="vnd.3gpp.pic-bw-large")) - setattr(cls, "vnd.3gpp.pic-bw-small", PermissibleValue(text="vnd.3gpp.pic-bw-small")) - setattr(cls, "vnd.3gpp.pic-bw-var", PermissibleValue(text="vnd.3gpp.pic-bw-var")) + setattr( + cls, "vnd.3gpp.pic-bw-large", PermissibleValue(text="vnd.3gpp.pic-bw-large") + ) + setattr( + cls, "vnd.3gpp.pic-bw-small", PermissibleValue(text="vnd.3gpp.pic-bw-small") + ) + setattr( + cls, "vnd.3gpp.pic-bw-var", PermissibleValue(text="vnd.3gpp.pic-bw-var") + ) setattr( cls, "vnd.3gpp-prose-pc3a+xml", @@ -10401,7 +10853,9 @@ def _addvals(cls): PermissibleValue(text="vnd.3gpp.state-and-event-info+xml"), ) setattr(cls, "vnd.3gpp.ussd+xml", PermissibleValue(text="vnd.3gpp.ussd+xml")) - setattr(cls, "vnd.3gpp.vae-info+xml", PermissibleValue(text="vnd.3gpp.vae-info+xml")) + setattr( + cls, "vnd.3gpp.vae-info+xml", PermissibleValue(text="vnd.3gpp.vae-info+xml") + ) setattr( cls, "vnd.3gpp-v2x-local-service-information", @@ -10420,18 +10874,28 @@ def _addvals(cls): "vnd.3lightssoftware.imagescal", PermissibleValue(text="vnd.3lightssoftware.imagescal"), ) - setattr(cls, "vnd.3M.Post-it-Notes", PermissibleValue(text="vnd.3M.Post-it-Notes")) - setattr(cls, "vnd.accpac.simply.aso", PermissibleValue(text="vnd.accpac.simply.aso")) - setattr(cls, "vnd.accpac.simply.imp", PermissibleValue(text="vnd.accpac.simply.imp")) + setattr( + cls, "vnd.3M.Post-it-Notes", PermissibleValue(text="vnd.3M.Post-it-Notes") + ) + setattr( + cls, "vnd.accpac.simply.aso", PermissibleValue(text="vnd.accpac.simply.aso") + ) + setattr( + cls, "vnd.accpac.simply.imp", PermissibleValue(text="vnd.accpac.simply.imp") + ) setattr( cls, "vnd.acm.addressxfer+json", PermissibleValue(text="vnd.acm.addressxfer+json"), ) - setattr(cls, "vnd.acm.chatbot+json", PermissibleValue(text="vnd.acm.chatbot+json")) + setattr( + cls, "vnd.acm.chatbot+json", PermissibleValue(text="vnd.acm.chatbot+json") + ) setattr(cls, "vnd.acucobol", PermissibleValue(text="vnd.acucobol")) setattr(cls, "vnd.acucorp", PermissibleValue(text="vnd.acucorp")) - setattr(cls, "vnd.adobe.flash.movie", PermissibleValue(text="vnd.adobe.flash.movie")) + setattr( + cls, "vnd.adobe.flash.movie", PermissibleValue(text="vnd.adobe.flash.movie") + ) setattr( cls, "vnd.adobe.formscentral.fcdt", @@ -10445,7 +10909,9 @@ def _addvals(cls): ) setattr(cls, "vnd.adobe.xdp+xml", PermissibleValue(text="vnd.adobe.xdp+xml")) setattr(cls, "vnd.aether.imp", PermissibleValue(text="vnd.aether.imp")) - setattr(cls, "vnd.afpc.afplinedata", PermissibleValue(text="vnd.afpc.afplinedata")) + setattr( + cls, "vnd.afpc.afplinedata", PermissibleValue(text="vnd.afpc.afplinedata") + ) setattr( cls, "vnd.afpc.afplinedata-pagedef", @@ -10456,7 +10922,9 @@ def _addvals(cls): "vnd.afpc.cmoca-cmresource", PermissibleValue(text="vnd.afpc.cmoca-cmresource"), ) - setattr(cls, "vnd.afpc.foca-charset", PermissibleValue(text="vnd.afpc.foca-charset")) + setattr( + cls, "vnd.afpc.foca-charset", PermissibleValue(text="vnd.afpc.foca-charset") + ) setattr( cls, "vnd.afpc.foca-codedfont", @@ -10523,7 +10991,9 @@ def _addvals(cls): PermissibleValue(text="vnd.americandynamics.acc"), ) setattr(cls, "vnd.amiga.ami", PermissibleValue(text="vnd.amiga.ami")) - setattr(cls, "vnd.amundsen.maze+xml", PermissibleValue(text="vnd.amundsen.maze+xml")) + setattr( + cls, "vnd.amundsen.maze+xml", PermissibleValue(text="vnd.amundsen.maze+xml") + ) setattr(cls, "vnd.android.ota", PermissibleValue(text="vnd.android.ota")) setattr(cls, "vnd.anki", PermissibleValue(text="vnd.anki")) setattr( @@ -10536,7 +11006,9 @@ def _addvals(cls): "vnd.antix.game-component", PermissibleValue(text="vnd.antix.game-component"), ) - setattr(cls, "vnd.apache.arrow.file", PermissibleValue(text="vnd.apache.arrow.file")) + setattr( + cls, "vnd.apache.arrow.file", PermissibleValue(text="vnd.apache.arrow.file") + ) setattr( cls, "vnd.apache.arrow.stream", @@ -10601,11 +11073,17 @@ def _addvals(cls): setattr(cls, "vnd.autopackage", PermissibleValue(text="vnd.autopackage")) setattr(cls, "vnd.avalon+json", PermissibleValue(text="vnd.avalon+json")) setattr(cls, "vnd.avistar+xml", PermissibleValue(text="vnd.avistar+xml")) - setattr(cls, "vnd.balsamiq.bmml+xml", PermissibleValue(text="vnd.balsamiq.bmml+xml")) - setattr(cls, "vnd.banana-accounting", PermissibleValue(text="vnd.banana-accounting")) + setattr( + cls, "vnd.balsamiq.bmml+xml", PermissibleValue(text="vnd.balsamiq.bmml+xml") + ) + setattr( + cls, "vnd.banana-accounting", PermissibleValue(text="vnd.banana-accounting") + ) setattr(cls, "vnd.bbf.usp.error", PermissibleValue(text="vnd.bbf.usp.error")) setattr(cls, "vnd.bbf.usp.msg", PermissibleValue(text="vnd.bbf.usp.msg")) - setattr(cls, "vnd.bbf.usp.msg+json", PermissibleValue(text="vnd.bbf.usp.msg+json")) + setattr( + cls, "vnd.bbf.usp.msg+json", PermissibleValue(text="vnd.bbf.usp.msg+json") + ) setattr(cls, "vnd.balsamiq.bmpr", PermissibleValue(text="vnd.balsamiq.bmpr")) setattr( cls, @@ -10622,20 +11100,30 @@ def _addvals(cls): "vnd.belightsoft.lhzl+zip", PermissibleValue(text="vnd.belightsoft.lhzl+zip"), ) - setattr(cls, "vnd.bint.med-content", PermissibleValue(text="vnd.bint.med-content")) + setattr( + cls, "vnd.bint.med-content", PermissibleValue(text="vnd.bint.med-content") + ) setattr(cls, "vnd.biopax.rdf+xml", PermissibleValue(text="vnd.biopax.rdf+xml")) setattr( cls, "vnd.blink-idb-value-wrapper", PermissibleValue(text="vnd.blink-idb-value-wrapper"), ) - setattr(cls, "vnd.blueice.multipass", PermissibleValue(text="vnd.blueice.multipass")) - setattr(cls, "vnd.bluetooth.ep.oob", PermissibleValue(text="vnd.bluetooth.ep.oob")) - setattr(cls, "vnd.bluetooth.le.oob", PermissibleValue(text="vnd.bluetooth.le.oob")) + setattr( + cls, "vnd.blueice.multipass", PermissibleValue(text="vnd.blueice.multipass") + ) + setattr( + cls, "vnd.bluetooth.ep.oob", PermissibleValue(text="vnd.bluetooth.ep.oob") + ) + setattr( + cls, "vnd.bluetooth.le.oob", PermissibleValue(text="vnd.bluetooth.le.oob") + ) setattr(cls, "vnd.bmi", PermissibleValue(text="vnd.bmi")) setattr(cls, "vnd.bpf", PermissibleValue(text="vnd.bpf")) setattr(cls, "vnd.bpf3", PermissibleValue(text="vnd.bpf3")) - setattr(cls, "vnd.businessobjects", PermissibleValue(text="vnd.businessobjects")) + setattr( + cls, "vnd.businessobjects", PermissibleValue(text="vnd.businessobjects") + ) setattr(cls, "vnd.byu.uapi+json", PermissibleValue(text="vnd.byu.uapi+json")) setattr(cls, "vnd.cab-jscript", PermissibleValue(text="vnd.cab-jscript")) setattr(cls, "vnd.canon-cpdl", PermissibleValue(text="vnd.canon-cpdl")) @@ -10664,7 +11152,9 @@ def _addvals(cls): ) setattr(cls, "vnd.ciedi", PermissibleValue(text="vnd.ciedi")) setattr(cls, "vnd.cinderella", PermissibleValue(text="vnd.cinderella")) - setattr(cls, "vnd.cirpack.isdn-ext", PermissibleValue(text="vnd.cirpack.isdn-ext")) + setattr( + cls, "vnd.cirpack.isdn-ext", PermissibleValue(text="vnd.cirpack.isdn-ext") + ) setattr( cls, "vnd.citationstyles.style+xml", @@ -10734,7 +11224,9 @@ def _addvals(cls): "vnd.collection.doc+json", PermissibleValue(text="vnd.collection.doc+json"), ) - setattr(cls, "vnd.collection+json", PermissibleValue(text="vnd.collection+json")) + setattr( + cls, "vnd.collection+json", PermissibleValue(text="vnd.collection+json") + ) setattr( cls, "vnd.collection.next+json", @@ -10742,7 +11234,9 @@ def _addvals(cls): ) setattr(cls, "vnd.comicbook-rar", PermissibleValue(text="vnd.comicbook-rar")) setattr(cls, "vnd.comicbook+zip", PermissibleValue(text="vnd.comicbook+zip")) - setattr(cls, "vnd.commerce-battelle", PermissibleValue(text="vnd.commerce-battelle")) + setattr( + cls, "vnd.commerce-battelle", PermissibleValue(text="vnd.commerce-battelle") + ) setattr(cls, "vnd.commonspace", PermissibleValue(text="vnd.commonspace")) setattr( cls, @@ -10777,18 +11271,26 @@ def _addvals(cls): "vnd.criticaltools.wbs+xml", PermissibleValue(text="vnd.criticaltools.wbs+xml"), ) - setattr(cls, "vnd.cryptii.pipe+json", PermissibleValue(text="vnd.cryptii.pipe+json")) - setattr(cls, "vnd.crypto-shade-file", PermissibleValue(text="vnd.crypto-shade-file")) + setattr( + cls, "vnd.cryptii.pipe+json", PermissibleValue(text="vnd.cryptii.pipe+json") + ) + setattr( + cls, "vnd.crypto-shade-file", PermissibleValue(text="vnd.crypto-shade-file") + ) setattr( cls, "vnd.cryptomator.encrypted", PermissibleValue(text="vnd.cryptomator.encrypted"), ) - setattr(cls, "vnd.cryptomator.vault", PermissibleValue(text="vnd.cryptomator.vault")) + setattr( + cls, "vnd.cryptomator.vault", PermissibleValue(text="vnd.cryptomator.vault") + ) setattr(cls, "vnd.ctc-posml", PermissibleValue(text="vnd.ctc-posml")) setattr(cls, "vnd.ctct.ws+xml", PermissibleValue(text="vnd.ctct.ws+xml")) setattr(cls, "vnd.cups-pdf", PermissibleValue(text="vnd.cups-pdf")) - setattr(cls, "vnd.cups-postscript", PermissibleValue(text="vnd.cups-postscript")) + setattr( + cls, "vnd.cups-postscript", PermissibleValue(text="vnd.cups-postscript") + ) setattr(cls, "vnd.cups-ppd", PermissibleValue(text="vnd.cups-ppd")) setattr(cls, "vnd.cups-raster", PermissibleValue(text="vnd.cups-raster")) setattr(cls, "vnd.cups-raw", PermissibleValue(text="vnd.cups-raw")) @@ -10808,10 +11310,16 @@ def _addvals(cls): setattr(cls, "vnd.d3m-dataset", PermissibleValue(text="vnd.d3m-dataset")) setattr(cls, "vnd.d3m-problem", PermissibleValue(text="vnd.d3m-problem")) setattr(cls, "vnd.dart", PermissibleValue(text="vnd.dart")) - setattr(cls, "vnd.data-vision.rdz", PermissibleValue(text="vnd.data-vision.rdz")) + setattr( + cls, "vnd.data-vision.rdz", PermissibleValue(text="vnd.data-vision.rdz") + ) setattr(cls, "vnd.datalog", PermissibleValue(text="vnd.datalog")) - setattr(cls, "vnd.datapackage+json", PermissibleValue(text="vnd.datapackage+json")) - setattr(cls, "vnd.dataresource+json", PermissibleValue(text="vnd.dataresource+json")) + setattr( + cls, "vnd.datapackage+json", PermissibleValue(text="vnd.datapackage+json") + ) + setattr( + cls, "vnd.dataresource+json", PermissibleValue(text="vnd.dataresource+json") + ) setattr(cls, "vnd.dbf", PermissibleValue(text="vnd.dbf")) setattr( cls, @@ -10820,7 +11328,9 @@ def _addvals(cls): ) setattr(cls, "vnd.dece.data", PermissibleValue(text="vnd.dece.data")) setattr(cls, "vnd.dece.ttml+xml", PermissibleValue(text="vnd.dece.ttml+xml")) - setattr(cls, "vnd.dece.unspecified", PermissibleValue(text="vnd.dece.unspecified")) + setattr( + cls, "vnd.dece.unspecified", PermissibleValue(text="vnd.dece.unspecified") + ) setattr(cls, "vnd.dece.zip", PermissibleValue(text="vnd.dece.zip")) setattr( cls, @@ -10833,7 +11343,9 @@ def _addvals(cls): "vnd.dir-bi.plate-dl-nosuffix", PermissibleValue(text="vnd.dir-bi.plate-dl-nosuffix"), ) - setattr(cls, "vnd.dm.delegation+xml", PermissibleValue(text="vnd.dm.delegation+xml")) + setattr( + cls, "vnd.dm.delegation+xml", PermissibleValue(text="vnd.dm.delegation+xml") + ) setattr(cls, "vnd.dna", PermissibleValue(text="vnd.dna")) setattr(cls, "vnd.document+json", PermissibleValue(text="vnd.document+json")) setattr(cls, "vnd.dolby.mobile.1", PermissibleValue(text="vnd.dolby.mobile.1")) @@ -10847,25 +11359,33 @@ def _addvals(cls): setattr(cls, "vnd.dreamfactory", PermissibleValue(text="vnd.dreamfactory")) setattr(cls, "vnd.drive+json", PermissibleValue(text="vnd.drive+json")) setattr(cls, "vnd.dtg.local", PermissibleValue(text="vnd.dtg.local")) - setattr(cls, "vnd.dtg.local.flash", PermissibleValue(text="vnd.dtg.local.flash")) + setattr( + cls, "vnd.dtg.local.flash", PermissibleValue(text="vnd.dtg.local.flash") + ) setattr(cls, "vnd.dtg.local.html", PermissibleValue(text="vnd.dtg.local.html")) setattr(cls, "vnd.dvb.ait", PermissibleValue(text="vnd.dvb.ait")) setattr(cls, "vnd.dvb.dvbisl+xml", PermissibleValue(text="vnd.dvb.dvbisl+xml")) setattr(cls, "vnd.dvb.dvbj", PermissibleValue(text="vnd.dvb.dvbj")) - setattr(cls, "vnd.dvb.esgcontainer", PermissibleValue(text="vnd.dvb.esgcontainer")) + setattr( + cls, "vnd.dvb.esgcontainer", PermissibleValue(text="vnd.dvb.esgcontainer") + ) setattr( cls, "vnd.dvb.ipdcdftnotifaccess", PermissibleValue(text="vnd.dvb.ipdcdftnotifaccess"), ) - setattr(cls, "vnd.dvb.ipdcesgaccess", PermissibleValue(text="vnd.dvb.ipdcesgaccess")) + setattr( + cls, "vnd.dvb.ipdcesgaccess", PermissibleValue(text="vnd.dvb.ipdcesgaccess") + ) setattr( cls, "vnd.dvb.ipdcesgaccess2", PermissibleValue(text="vnd.dvb.ipdcesgaccess2"), ) setattr(cls, "vnd.dvb.ipdcesgpdd", PermissibleValue(text="vnd.dvb.ipdcesgpdd")) - setattr(cls, "vnd.dvb.ipdcroaming", PermissibleValue(text="vnd.dvb.ipdcroaming")) + setattr( + cls, "vnd.dvb.ipdcroaming", PermissibleValue(text="vnd.dvb.ipdcroaming") + ) setattr( cls, "vnd.dvb.iptv.alfec-base", @@ -10934,7 +11454,9 @@ def _addvals(cls): "vnd.ecowin.filerequest", PermissibleValue(text="vnd.ecowin.filerequest"), ) - setattr(cls, "vnd.ecowin.fileupdate", PermissibleValue(text="vnd.ecowin.fileupdate")) + setattr( + cls, "vnd.ecowin.fileupdate", PermissibleValue(text="vnd.ecowin.fileupdate") + ) setattr(cls, "vnd.ecowin.series", PermissibleValue(text="vnd.ecowin.series")) setattr( cls, @@ -10956,10 +11478,14 @@ def _addvals(cls): ) setattr(cls, "vnd.enliven", PermissibleValue(text="vnd.enliven")) setattr(cls, "vnd.enphase.envoy", PermissibleValue(text="vnd.enphase.envoy")) - setattr(cls, "vnd.eprints.data+xml", PermissibleValue(text="vnd.eprints.data+xml")) + setattr( + cls, "vnd.eprints.data+xml", PermissibleValue(text="vnd.eprints.data+xml") + ) setattr(cls, "vnd.epson.esf", PermissibleValue(text="vnd.epson.esf")) setattr(cls, "vnd.epson.msf", PermissibleValue(text="vnd.epson.msf")) - setattr(cls, "vnd.epson.quickanime", PermissibleValue(text="vnd.epson.quickanime")) + setattr( + cls, "vnd.epson.quickanime", PermissibleValue(text="vnd.epson.quickanime") + ) setattr(cls, "vnd.epson.salt", PermissibleValue(text="vnd.epson.salt")) setattr(cls, "vnd.epson.ssf", PermissibleValue(text="vnd.epson.ssf")) setattr( @@ -10967,11 +11493,17 @@ def _addvals(cls): "vnd.ericsson.quickcall", PermissibleValue(text="vnd.ericsson.quickcall"), ) - setattr(cls, "vnd.espass-espass+zip", PermissibleValue(text="vnd.espass-espass+zip")) + setattr( + cls, "vnd.espass-espass+zip", PermissibleValue(text="vnd.espass-espass+zip") + ) setattr(cls, "vnd.eszigno3+xml", PermissibleValue(text="vnd.eszigno3+xml")) setattr(cls, "vnd.etsi.aoc+xml", PermissibleValue(text="vnd.etsi.aoc+xml")) - setattr(cls, "vnd.etsi.asic-s+zip", PermissibleValue(text="vnd.etsi.asic-s+zip")) - setattr(cls, "vnd.etsi.asic-e+zip", PermissibleValue(text="vnd.etsi.asic-e+zip")) + setattr( + cls, "vnd.etsi.asic-s+zip", PermissibleValue(text="vnd.etsi.asic-s+zip") + ) + setattr( + cls, "vnd.etsi.asic-e+zip", PermissibleValue(text="vnd.etsi.asic-e+zip") + ) setattr(cls, "vnd.etsi.cug+xml", PermissibleValue(text="vnd.etsi.cug+xml")) setattr( cls, @@ -11008,7 +11540,9 @@ def _addvals(cls): "vnd.etsi.iptvservice+xml", PermissibleValue(text="vnd.etsi.iptvservice+xml"), ) - setattr(cls, "vnd.etsi.iptvsync+xml", PermissibleValue(text="vnd.etsi.iptvsync+xml")) + setattr( + cls, "vnd.etsi.iptvsync+xml", PermissibleValue(text="vnd.etsi.iptvsync+xml") + ) setattr( cls, "vnd.etsi.iptvueprofile+xml", @@ -11023,7 +11557,9 @@ def _addvals(cls): ) setattr(cls, "vnd.etsi.pstn+xml", PermissibleValue(text="vnd.etsi.pstn+xml")) setattr(cls, "vnd.etsi.sci+xml", PermissibleValue(text="vnd.etsi.sci+xml")) - setattr(cls, "vnd.etsi.simservs+xml", PermissibleValue(text="vnd.etsi.simservs+xml")) + setattr( + cls, "vnd.etsi.simservs+xml", PermissibleValue(text="vnd.etsi.simservs+xml") + ) setattr( cls, "vnd.etsi.timestamp-token", @@ -11047,16 +11583,22 @@ def _addvals(cls): "vnd.evolv.ecig.settings", PermissibleValue(text="vnd.evolv.ecig.settings"), ) - setattr(cls, "vnd.evolv.ecig.theme", PermissibleValue(text="vnd.evolv.ecig.theme")) + setattr( + cls, "vnd.evolv.ecig.theme", PermissibleValue(text="vnd.evolv.ecig.theme") + ) setattr( cls, "vnd.exstream-empower+zip", PermissibleValue(text="vnd.exstream-empower+zip"), ) - setattr(cls, "vnd.exstream-package", PermissibleValue(text="vnd.exstream-package")) + setattr( + cls, "vnd.exstream-package", PermissibleValue(text="vnd.exstream-package") + ) setattr(cls, "vnd.ezpix-album", PermissibleValue(text="vnd.ezpix-album")) setattr(cls, "vnd.ezpix-package", PermissibleValue(text="vnd.ezpix-package")) - setattr(cls, "vnd.f-secure.mobile", PermissibleValue(text="vnd.f-secure.mobile")) + setattr( + cls, "vnd.f-secure.mobile", PermissibleValue(text="vnd.f-secure.mobile") + ) setattr( cls, "vnd.fastcopy-disk-image", @@ -11121,10 +11663,16 @@ def _addvals(cls): setattr(cls, "vnd.fujitsu.oasys", PermissibleValue(text="vnd.fujitsu.oasys")) setattr(cls, "vnd.fujitsu.oasys2", PermissibleValue(text="vnd.fujitsu.oasys2")) setattr(cls, "vnd.fujitsu.oasys3", PermissibleValue(text="vnd.fujitsu.oasys3")) - setattr(cls, "vnd.fujitsu.oasysgp", PermissibleValue(text="vnd.fujitsu.oasysgp")) - setattr(cls, "vnd.fujitsu.oasysprs", PermissibleValue(text="vnd.fujitsu.oasysprs")) + setattr( + cls, "vnd.fujitsu.oasysgp", PermissibleValue(text="vnd.fujitsu.oasysgp") + ) + setattr( + cls, "vnd.fujitsu.oasysprs", PermissibleValue(text="vnd.fujitsu.oasysprs") + ) setattr(cls, "vnd.fujixerox.ART4", PermissibleValue(text="vnd.fujixerox.ART4")) - setattr(cls, "vnd.fujixerox.ART-EX", PermissibleValue(text="vnd.fujixerox.ART-EX")) + setattr( + cls, "vnd.fujixerox.ART-EX", PermissibleValue(text="vnd.fujixerox.ART-EX") + ) setattr(cls, "vnd.fujixerox.ddd", PermissibleValue(text="vnd.fujixerox.ddd")) setattr( cls, @@ -11146,9 +11694,13 @@ def _addvals(cls): setattr(cls, "vnd.futoin+cbor", PermissibleValue(text="vnd.futoin+cbor")) setattr(cls, "vnd.futoin+json", PermissibleValue(text="vnd.futoin+json")) setattr(cls, "vnd.fuzzysheet", PermissibleValue(text="vnd.fuzzysheet")) - setattr(cls, "vnd.genomatix.tuxedo", PermissibleValue(text="vnd.genomatix.tuxedo")) + setattr( + cls, "vnd.genomatix.tuxedo", PermissibleValue(text="vnd.genomatix.tuxedo") + ) setattr(cls, "vnd.genozip", PermissibleValue(text="vnd.genozip")) - setattr(cls, "vnd.gentics.grd+json", PermissibleValue(text="vnd.gentics.grd+json")) + setattr( + cls, "vnd.gentics.grd+json", PermissibleValue(text="vnd.gentics.grd+json") + ) setattr( cls, "vnd.gentoo.catmetadata+xml", @@ -11157,7 +11709,9 @@ def _addvals(cls): setattr(cls, "vnd.gentoo.ebuild", PermissibleValue(text="vnd.gentoo.ebuild")) setattr(cls, "vnd.gentoo.eclass", PermissibleValue(text="vnd.gentoo.eclass")) setattr(cls, "vnd.gentoo.gpkg", PermissibleValue(text="vnd.gentoo.gpkg")) - setattr(cls, "vnd.gentoo.manifest", PermissibleValue(text="vnd.gentoo.manifest")) + setattr( + cls, "vnd.gentoo.manifest", PermissibleValue(text="vnd.gentoo.manifest") + ) setattr(cls, "vnd.gentoo.xpak", PermissibleValue(text="vnd.gentoo.xpak")) setattr( cls, @@ -11177,9 +11731,13 @@ def _addvals(cls): PermissibleValue(text="vnd.geocube+xml (OBSOLETED by request)"), ) setattr(cls, "vnd.geogebra.file", PermissibleValue(text="vnd.geogebra.file")) - setattr(cls, "vnd.geogebra.slides", PermissibleValue(text="vnd.geogebra.slides")) + setattr( + cls, "vnd.geogebra.slides", PermissibleValue(text="vnd.geogebra.slides") + ) setattr(cls, "vnd.geogebra.tool", PermissibleValue(text="vnd.geogebra.tool")) - setattr(cls, "vnd.geometry-explorer", PermissibleValue(text="vnd.geometry-explorer")) + setattr( + cls, "vnd.geometry-explorer", PermissibleValue(text="vnd.geometry-explorer") + ) setattr(cls, "vnd.geonext", PermissibleValue(text="vnd.geonext")) setattr(cls, "vnd.geoplan", PermissibleValue(text="vnd.geoplan")) setattr(cls, "vnd.geospace", PermissibleValue(text="vnd.geospace")) @@ -11194,7 +11752,9 @@ def _addvals(cls): "vnd.globalplatform.card-content-mgt-response", PermissibleValue(text="vnd.globalplatform.card-content-mgt-response"), ) - setattr(cls, "vnd.gmx - DEPRECATED", PermissibleValue(text="vnd.gmx - DEPRECATED")) + setattr( + cls, "vnd.gmx - DEPRECATED", PermissibleValue(text="vnd.gmx - DEPRECATED") + ) setattr( cls, "vnd.gnu.taler.exchange+json", @@ -11210,9 +11770,15 @@ def _addvals(cls): "vnd.google-earth.kml+xml", PermissibleValue(text="vnd.google-earth.kml+xml"), ) - setattr(cls, "vnd.google-earth.kmz", PermissibleValue(text="vnd.google-earth.kmz")) - setattr(cls, "vnd.gov.sk.e-form+xml", PermissibleValue(text="vnd.gov.sk.e-form+xml")) - setattr(cls, "vnd.gov.sk.e-form+zip", PermissibleValue(text="vnd.gov.sk.e-form+zip")) + setattr( + cls, "vnd.google-earth.kmz", PermissibleValue(text="vnd.google-earth.kmz") + ) + setattr( + cls, "vnd.gov.sk.e-form+xml", PermissibleValue(text="vnd.gov.sk.e-form+xml") + ) + setattr( + cls, "vnd.gov.sk.e-form+zip", PermissibleValue(text="vnd.gov.sk.e-form+zip") + ) setattr( cls, "vnd.gov.sk.xmldatacontainer+xml", @@ -11228,7 +11794,9 @@ def _addvals(cls): "vnd.groove-identity-message", PermissibleValue(text="vnd.groove-identity-message"), ) - setattr(cls, "vnd.groove-injector", PermissibleValue(text="vnd.groove-injector")) + setattr( + cls, "vnd.groove-injector", PermissibleValue(text="vnd.groove-injector") + ) setattr( cls, "vnd.groove-tool-message", @@ -11252,7 +11820,9 @@ def _addvals(cls): setattr(cls, "vnd.hcl-bireports", PermissibleValue(text="vnd.hcl-bireports")) setattr(cls, "vnd.hdt", PermissibleValue(text="vnd.hdt")) setattr(cls, "vnd.heroku+json", PermissibleValue(text="vnd.heroku+json")) - setattr(cls, "vnd.hhe.lesson-player", PermissibleValue(text="vnd.hhe.lesson-player")) + setattr( + cls, "vnd.hhe.lesson-player", PermissibleValue(text="vnd.hhe.lesson-player") + ) setattr(cls, "vnd.hp-HPGL", PermissibleValue(text="vnd.hp-HPGL")) setattr(cls, "vnd.hp-hpid", PermissibleValue(text="vnd.hp-hpid")) setattr(cls, "vnd.hp-hps", PermissibleValue(text="vnd.hp-hps")) @@ -11266,10 +11836,16 @@ def _addvals(cls): "vnd.hydrostatix.sof-data", PermissibleValue(text="vnd.hydrostatix.sof-data"), ) - setattr(cls, "vnd.hyper-item+json", PermissibleValue(text="vnd.hyper-item+json")) + setattr( + cls, "vnd.hyper-item+json", PermissibleValue(text="vnd.hyper-item+json") + ) setattr(cls, "vnd.hyper+json", PermissibleValue(text="vnd.hyper+json")) - setattr(cls, "vnd.hyperdrive+json", PermissibleValue(text="vnd.hyperdrive+json")) - setattr(cls, "vnd.hzn-3d-crossword", PermissibleValue(text="vnd.hzn-3d-crossword")) + setattr( + cls, "vnd.hyperdrive+json", PermissibleValue(text="vnd.hyperdrive+json") + ) + setattr( + cls, "vnd.hzn-3d-crossword", PermissibleValue(text="vnd.hzn-3d-crossword") + ) setattr( cls, "vnd.ibm.afplinedata (OBSOLETED in favor of vnd.afpc.afplinedata)", @@ -11313,8 +11889,12 @@ def _addvals(cls): "vnd.imagemeter.image+zip", PermissibleValue(text="vnd.imagemeter.image+zip"), ) - setattr(cls, "vnd.immervision-ivp", PermissibleValue(text="vnd.immervision-ivp")) - setattr(cls, "vnd.immervision-ivu", PermissibleValue(text="vnd.immervision-ivu")) + setattr( + cls, "vnd.immervision-ivp", PermissibleValue(text="vnd.immervision-ivp") + ) + setattr( + cls, "vnd.immervision-ivu", PermissibleValue(text="vnd.immervision-ivu") + ) setattr(cls, "vnd.ims.imsccv1p1", PermissibleValue(text="vnd.ims.imsccv1p1")) setattr(cls, "vnd.ims.imsccv1p2", PermissibleValue(text="vnd.ims.imsccv1p2")) setattr(cls, "vnd.ims.imsccv1p3", PermissibleValue(text="vnd.ims.imsccv1p3")) @@ -11353,7 +11933,9 @@ def _addvals(cls): "vnd.informedcontrol.rms+xml", PermissibleValue(text="vnd.informedcontrol.rms+xml"), ) - setattr(cls, "vnd.infotech.project", PermissibleValue(text="vnd.infotech.project")) + setattr( + cls, "vnd.infotech.project", PermissibleValue(text="vnd.infotech.project") + ) setattr( cls, "vnd.infotech.project+xml", @@ -11372,17 +11954,23 @@ def _addvals(cls): PermissibleValue(text="vnd.innopath.wamp.notification"), ) setattr(cls, "vnd.insors.igm", PermissibleValue(text="vnd.insors.igm")) - setattr(cls, "vnd.intercon.formnet", PermissibleValue(text="vnd.intercon.formnet")) + setattr( + cls, "vnd.intercon.formnet", PermissibleValue(text="vnd.intercon.formnet") + ) setattr(cls, "vnd.intergeo", PermissibleValue(text="vnd.intergeo")) setattr( cls, "vnd.intertrust.digibox", PermissibleValue(text="vnd.intertrust.digibox"), ) - setattr(cls, "vnd.intertrust.nncp", PermissibleValue(text="vnd.intertrust.nncp")) + setattr( + cls, "vnd.intertrust.nncp", PermissibleValue(text="vnd.intertrust.nncp") + ) setattr(cls, "vnd.intu.qbo", PermissibleValue(text="vnd.intu.qbo")) setattr(cls, "vnd.intu.qfx", PermissibleValue(text="vnd.intu.qfx")) - setattr(cls, "vnd.ipfs.ipns-record", PermissibleValue(text="vnd.ipfs.ipns-record")) + setattr( + cls, "vnd.ipfs.ipns-record", PermissibleValue(text="vnd.ipfs.ipns-record") + ) setattr(cls, "vnd.ipld.car", PermissibleValue(text="vnd.ipld.car")) setattr(cls, "vnd.ipld.dag-cbor", PermissibleValue(text="vnd.ipld.dag-cbor")) setattr(cls, "vnd.ipld.dag-json", PermissibleValue(text="vnd.ipld.dag-json")) @@ -11435,7 +12023,9 @@ def _addvals(cls): setattr(cls, "vnd.is-xpr", PermissibleValue(text="vnd.is-xpr")) setattr(cls, "vnd.isac.fcs", PermissibleValue(text="vnd.isac.fcs")) setattr(cls, "vnd.jam", PermissibleValue(text="vnd.jam")) - setattr(cls, "vnd.iso11783-10+zip", PermissibleValue(text="vnd.iso11783-10+zip")) + setattr( + cls, "vnd.iso11783-10+zip", PermissibleValue(text="vnd.iso11783-10+zip") + ) setattr( cls, "vnd.japannet-directory-service", @@ -11501,7 +12091,9 @@ def _addvals(cls): setattr(cls, "vnd.kidspiration", PermissibleValue(text="vnd.kidspiration")) setattr(cls, "vnd.Kinar", PermissibleValue(text="vnd.Kinar")) setattr(cls, "vnd.koan", PermissibleValue(text="vnd.koan")) - setattr(cls, "vnd.kodak-descriptor", PermissibleValue(text="vnd.kodak-descriptor")) + setattr( + cls, "vnd.kodak-descriptor", PermissibleValue(text="vnd.kodak-descriptor") + ) setattr(cls, "vnd.las", PermissibleValue(text="vnd.las")) setattr(cls, "vnd.las.las+json", PermissibleValue(text="vnd.las.las+json")) setattr(cls, "vnd.las.las+xml", PermissibleValue(text="vnd.las.las+xml")) @@ -11530,12 +12122,20 @@ def _addvals(cls): setattr(cls, "vnd.loom", PermissibleValue(text="vnd.loom")) setattr(cls, "vnd.lotus-1-2-3", PermissibleValue(text="vnd.lotus-1-2-3")) setattr(cls, "vnd.lotus-approach", PermissibleValue(text="vnd.lotus-approach")) - setattr(cls, "vnd.lotus-freelance", PermissibleValue(text="vnd.lotus-freelance")) + setattr( + cls, "vnd.lotus-freelance", PermissibleValue(text="vnd.lotus-freelance") + ) setattr(cls, "vnd.lotus-notes", PermissibleValue(text="vnd.lotus-notes")) - setattr(cls, "vnd.lotus-organizer", PermissibleValue(text="vnd.lotus-organizer")) - setattr(cls, "vnd.lotus-screencam", PermissibleValue(text="vnd.lotus-screencam")) + setattr( + cls, "vnd.lotus-organizer", PermissibleValue(text="vnd.lotus-organizer") + ) + setattr( + cls, "vnd.lotus-screencam", PermissibleValue(text="vnd.lotus-screencam") + ) setattr(cls, "vnd.lotus-wordpro", PermissibleValue(text="vnd.lotus-wordpro")) - setattr(cls, "vnd.macports.portpkg", PermissibleValue(text="vnd.macports.portpkg")) + setattr( + cls, "vnd.macports.portpkg", PermissibleValue(text="vnd.macports.portpkg") + ) setattr( cls, "vnd.mapbox-vector-tile", @@ -11556,7 +12156,9 @@ def _addvals(cls): "vnd.marlin.drm.license+xml", PermissibleValue(text="vnd.marlin.drm.license+xml"), ) - setattr(cls, "vnd.marlin.drm.mdcf", PermissibleValue(text="vnd.marlin.drm.mdcf")) + setattr( + cls, "vnd.marlin.drm.mdcf", PermissibleValue(text="vnd.marlin.drm.mdcf") + ) setattr(cls, "vnd.mason+json", PermissibleValue(text="vnd.mason+json")) setattr( cls, @@ -11669,10 +12271,14 @@ def _addvals(cls): PermissibleValue(text="vnd.motorola.flexsuite.wem"), ) setattr(cls, "vnd.motorola.iprm", PermissibleValue(text="vnd.motorola.iprm")) - setattr(cls, "vnd.mozilla.xul+xml", PermissibleValue(text="vnd.mozilla.xul+xml")) + setattr( + cls, "vnd.mozilla.xul+xml", PermissibleValue(text="vnd.mozilla.xul+xml") + ) setattr(cls, "vnd.ms-artgalry", PermissibleValue(text="vnd.ms-artgalry")) setattr(cls, "vnd.ms-asf", PermissibleValue(text="vnd.ms-asf")) - setattr(cls, "vnd.ms-cab-compressed", PermissibleValue(text="vnd.ms-cab-compressed")) + setattr( + cls, "vnd.ms-cab-compressed", PermissibleValue(text="vnd.ms-cab-compressed") + ) setattr(cls, "vnd.ms-3mfdocument", PermissibleValue(text="vnd.ms-3mfdocument")) setattr(cls, "vnd.ms-excel", PermissibleValue(text="vnd.ms-excel")) setattr( @@ -11773,7 +12379,9 @@ def _addvals(cls): "vnd.ms-wmdrm.lic-chlg-req", PermissibleValue(text="vnd.ms-wmdrm.lic-chlg-req"), ) - setattr(cls, "vnd.ms-wmdrm.lic-resp", PermissibleValue(text="vnd.ms-wmdrm.lic-resp")) + setattr( + cls, "vnd.ms-wmdrm.lic-resp", PermissibleValue(text="vnd.ms-wmdrm.lic-resp") + ) setattr( cls, "vnd.ms-wmdrm.meter-chlg-req", @@ -11800,7 +12408,9 @@ def _addvals(cls): setattr(cls, "vnd.msa-disk-image", PermissibleValue(text="vnd.msa-disk-image")) setattr(cls, "vnd.mseq", PermissibleValue(text="vnd.mseq")) setattr(cls, "vnd.msign", PermissibleValue(text="vnd.msign")) - setattr(cls, "vnd.multiad.creator", PermissibleValue(text="vnd.multiad.creator")) + setattr( + cls, "vnd.multiad.creator", PermissibleValue(text="vnd.multiad.creator") + ) setattr( cls, "vnd.multiad.creator.cif", @@ -11817,13 +12427,19 @@ def _addvals(cls): ) setattr(cls, "vnd.ncd.control", PermissibleValue(text="vnd.ncd.control")) setattr(cls, "vnd.ncd.reference", PermissibleValue(text="vnd.ncd.reference")) - setattr(cls, "vnd.nearst.inv+json", PermissibleValue(text="vnd.nearst.inv+json")) + setattr( + cls, "vnd.nearst.inv+json", PermissibleValue(text="vnd.nearst.inv+json") + ) setattr(cls, "vnd.nebumind.line", PermissibleValue(text="vnd.nebumind.line")) setattr(cls, "vnd.nervana", PermissibleValue(text="vnd.nervana")) setattr(cls, "vnd.netfpx", PermissibleValue(text="vnd.netfpx")) - setattr(cls, "vnd.neurolanguage.nlu", PermissibleValue(text="vnd.neurolanguage.nlu")) + setattr( + cls, "vnd.neurolanguage.nlu", PermissibleValue(text="vnd.neurolanguage.nlu") + ) setattr(cls, "vnd.nimn", PermissibleValue(text="vnd.nimn")) - setattr(cls, "vnd.nintendo.snes.rom", PermissibleValue(text="vnd.nintendo.snes.rom")) + setattr( + cls, "vnd.nintendo.snes.rom", PermissibleValue(text="vnd.nintendo.snes.rom") + ) setattr( cls, "vnd.nintendo.nitro.rom", @@ -11835,11 +12451,17 @@ def _addvals(cls): "vnd.noblenet-directory", PermissibleValue(text="vnd.noblenet-directory"), ) - setattr(cls, "vnd.noblenet-sealer", PermissibleValue(text="vnd.noblenet-sealer")) + setattr( + cls, "vnd.noblenet-sealer", PermissibleValue(text="vnd.noblenet-sealer") + ) setattr(cls, "vnd.noblenet-web", PermissibleValue(text="vnd.noblenet-web")) setattr(cls, "vnd.nokia.catalogs", PermissibleValue(text="vnd.nokia.catalogs")) - setattr(cls, "vnd.nokia.conml+wbxml", PermissibleValue(text="vnd.nokia.conml+wbxml")) - setattr(cls, "vnd.nokia.conml+xml", PermissibleValue(text="vnd.nokia.conml+xml")) + setattr( + cls, "vnd.nokia.conml+wbxml", PermissibleValue(text="vnd.nokia.conml+wbxml") + ) + setattr( + cls, "vnd.nokia.conml+xml", PermissibleValue(text="vnd.nokia.conml+xml") + ) setattr( cls, "vnd.nokia.iptv.config+xml", @@ -11871,13 +12493,17 @@ def _addvals(cls): "vnd.nokia.n-gage.ac+xml", PermissibleValue(text="vnd.nokia.n-gage.ac+xml"), ) - setattr(cls, "vnd.nokia.n-gage.data", PermissibleValue(text="vnd.nokia.n-gage.data")) + setattr( + cls, "vnd.nokia.n-gage.data", PermissibleValue(text="vnd.nokia.n-gage.data") + ) setattr( cls, "vnd.nokia.n-gage.symbian.install (OBSOLETE", PermissibleValue(text="vnd.nokia.n-gage.symbian.install (OBSOLETE"), ) - setattr(cls, "vnd.nokia.pcd+wbxml", PermissibleValue(text="vnd.nokia.pcd+wbxml")) + setattr( + cls, "vnd.nokia.pcd+wbxml", PermissibleValue(text="vnd.nokia.pcd+wbxml") + ) setattr(cls, "vnd.nokia.pcd+xml", PermissibleValue(text="vnd.nokia.pcd+xml")) setattr( cls, @@ -12037,7 +12663,9 @@ def _addvals(cls): "vnd.oipf.cspg-hexbinary", PermissibleValue(text="vnd.oipf.cspg-hexbinary"), ) - setattr(cls, "vnd.oipf.dae.svg+xml", PermissibleValue(text="vnd.oipf.dae.svg+xml")) + setattr( + cls, "vnd.oipf.dae.svg+xml", PermissibleValue(text="vnd.oipf.dae.svg+xml") + ) setattr( cls, "vnd.oipf.dae.xhtml+xml", @@ -12054,7 +12682,9 @@ def _addvals(cls): "vnd.oipf.spdiscovery+xml", PermissibleValue(text="vnd.oipf.spdiscovery+xml"), ) - setattr(cls, "vnd.oipf.spdlist+xml", PermissibleValue(text="vnd.oipf.spdlist+xml")) + setattr( + cls, "vnd.oipf.spdlist+xml", PermissibleValue(text="vnd.oipf.spdlist+xml") + ) setattr( cls, "vnd.oipf.ueprofile+xml", @@ -12076,7 +12706,9 @@ def _addvals(cls): "vnd.oma.bcast.drm-trigger+xml", PermissibleValue(text="vnd.oma.bcast.drm-trigger+xml"), ) - setattr(cls, "vnd.oma.bcast.imd+xml", PermissibleValue(text="vnd.oma.bcast.imd+xml")) + setattr( + cls, "vnd.oma.bcast.imd+xml", PermissibleValue(text="vnd.oma.bcast.imd+xml") + ) setattr(cls, "vnd.oma.bcast.ltkm", PermissibleValue(text="vnd.oma.bcast.ltkm")) setattr( cls, @@ -12088,7 +12720,9 @@ def _addvals(cls): "vnd.oma.bcast.provisioningtrigger", PermissibleValue(text="vnd.oma.bcast.provisioningtrigger"), ) - setattr(cls, "vnd.oma.bcast.sgboot", PermissibleValue(text="vnd.oma.bcast.sgboot")) + setattr( + cls, "vnd.oma.bcast.sgboot", PermissibleValue(text="vnd.oma.bcast.sgboot") + ) setattr( cls, "vnd.oma.bcast.sgdd+xml", @@ -12121,7 +12755,9 @@ def _addvals(cls): "vnd.oma.cab-feature-handler+xml", PermissibleValue(text="vnd.oma.cab-feature-handler+xml"), ) - setattr(cls, "vnd.oma.cab-pcc+xml", PermissibleValue(text="vnd.oma.cab-pcc+xml")) + setattr( + cls, "vnd.oma.cab-pcc+xml", PermissibleValue(text="vnd.oma.cab-pcc+xml") + ) setattr( cls, "vnd.oma.cab-subs-invite+xml", @@ -12135,7 +12771,9 @@ def _addvals(cls): setattr(cls, "vnd.oma.dcd", PermissibleValue(text="vnd.oma.dcd")) setattr(cls, "vnd.oma.dcdc", PermissibleValue(text="vnd.oma.dcdc")) setattr(cls, "vnd.oma.dd2+xml", PermissibleValue(text="vnd.oma.dd2+xml")) - setattr(cls, "vnd.oma.drm.risd+xml", PermissibleValue(text="vnd.oma.drm.risd+xml")) + setattr( + cls, "vnd.oma.drm.risd+xml", PermissibleValue(text="vnd.oma.drm.risd+xml") + ) setattr( cls, "vnd.oma.group-usage-list+xml", @@ -12181,11 +12819,19 @@ def _addvals(cls): "vnd.oma.xcap-directory+xml", PermissibleValue(text="vnd.oma.xcap-directory+xml"), ) - setattr(cls, "vnd.omads-email+xml", PermissibleValue(text="vnd.omads-email+xml")) + setattr( + cls, "vnd.omads-email+xml", PermissibleValue(text="vnd.omads-email+xml") + ) setattr(cls, "vnd.omads-file+xml", PermissibleValue(text="vnd.omads-file+xml")) - setattr(cls, "vnd.omads-folder+xml", PermissibleValue(text="vnd.omads-folder+xml")) - setattr(cls, "vnd.omaloc-supl-init", PermissibleValue(text="vnd.omaloc-supl-init")) - setattr(cls, "vnd.oma-scws-config", PermissibleValue(text="vnd.oma-scws-config")) + setattr( + cls, "vnd.omads-folder+xml", PermissibleValue(text="vnd.omads-folder+xml") + ) + setattr( + cls, "vnd.omaloc-supl-init", PermissibleValue(text="vnd.omaloc-supl-init") + ) + setattr( + cls, "vnd.oma-scws-config", PermissibleValue(text="vnd.oma-scws-config") + ) setattr( cls, "vnd.oma-scws-http-request", @@ -12208,7 +12854,9 @@ def _addvals(cls): "vnd.openblox.game-binary", PermissibleValue(text="vnd.openblox.game-binary"), ) - setattr(cls, "vnd.openblox.game+xml", PermissibleValue(text="vnd.openblox.game+xml")) + setattr( + cls, "vnd.openblox.game+xml", PermissibleValue(text="vnd.openblox.game+xml") + ) setattr(cls, "vnd.openeye.oeb", PermissibleValue(text="vnd.openeye.oeb")) setattr( cls, @@ -12223,12 +12871,16 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.custom-properties+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.custom-properties+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.custom-properties+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.customXmlProperties+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.customXmlProperties+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.customXmlProperties+xml" + ), ) setattr( cls, @@ -12238,37 +12890,51 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.drawingml.chart+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.drawingml.chart+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.drawingml.chart+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.drawingml.chartshapes+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.drawingml.chartshapes+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.drawingml.chartshapes+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.drawingml.diagramColors+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.drawingml.diagramColors+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.drawingml.diagramColors+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.drawingml.diagramData+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.drawingml.diagramData+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.drawingml.diagramData+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.extended-properties+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.extended-properties+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.extended-properties+xml" + ), ) setattr( cls, @@ -12280,7 +12946,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.presentationml.comments+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.comments+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.comments+xml" + ), ) setattr( cls, @@ -12306,7 +12974,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.presentationml.presentation", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.presentation"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.presentation" + ), ) setattr( cls, @@ -12318,17 +12988,23 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.presentationml.presProps+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.presProps+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.presProps+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.presentationml.slide", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.slide"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.slide" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.presentationml.slide+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.slide+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.slide+xml" + ), ) setattr( cls, @@ -12347,7 +13023,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.presentationml.slideshow", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.slideshow"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.slideshow" + ), ) setattr( cls, @@ -12373,12 +13051,16 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.presentationml.tags+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.tags+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.tags+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.presentationml.template", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.template"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.template" + ), ) setattr( cls, @@ -12390,22 +13072,30 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.presentationml.viewProps+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.presentationml.viewProps+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.presentationml.viewProps+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.comments+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.comments+xml" + ), ) setattr( cls, @@ -12445,12 +13135,16 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml" + ), ) setattr( cls, @@ -12476,12 +13170,16 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.sheet", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.sheet"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.sheet" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" + ), ) setattr( cls, @@ -12493,12 +13191,16 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.styles+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.table+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.table+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.table+xml" + ), ) setattr( cls, @@ -12510,7 +13212,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.template", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.template"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.template" + ), ) setattr( cls, @@ -12522,7 +13226,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml" + ), ) setattr( cls, @@ -12534,7 +13240,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" + ), ) setattr( cls, @@ -12544,7 +13252,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.themeOverride+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.themeOverride+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.themeOverride+xml" + ), ) setattr( cls, @@ -12561,7 +13271,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.wordprocessingml.document", - PermissibleValue(text="vnd.openxmlformats-officedocument.wordprocessingml.document"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.wordprocessingml.document" + ), ) setattr( cls, @@ -12594,7 +13306,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.wordprocessingml.footer+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" + ), ) setattr( cls, @@ -12620,12 +13334,16 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-officedocument.wordprocessingml.styles+xml", - PermissibleValue(text="vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" + ), ) setattr( cls, "vnd.openxmlformats-officedocument.wordprocessingml.template", - PermissibleValue(text="vnd.openxmlformats-officedocument.wordprocessingml.template"), + PermissibleValue( + text="vnd.openxmlformats-officedocument.wordprocessingml.template" + ), ) setattr( cls, @@ -12649,7 +13367,9 @@ def _addvals(cls): setattr( cls, "vnd.openxmlformats-package.digital-signature-xmlsignature+xml", - PermissibleValue(text="vnd.openxmlformats-package.digital-signature-xmlsignature+xml"), + PermissibleValue( + text="vnd.openxmlformats-package.digital-signature-xmlsignature+xml" + ), ) setattr( cls, @@ -12671,14 +13391,20 @@ def _addvals(cls): setattr(cls, "vnd.osgi.bundle", PermissibleValue(text="vnd.osgi.bundle")) setattr(cls, "vnd.osgi.dp", PermissibleValue(text="vnd.osgi.dp")) setattr(cls, "vnd.osgi.subsystem", PermissibleValue(text="vnd.osgi.subsystem")) - setattr(cls, "vnd.otps.ct-kip+xml", PermissibleValue(text="vnd.otps.ct-kip+xml")) - setattr(cls, "vnd.oxli.countgraph", PermissibleValue(text="vnd.oxli.countgraph")) + setattr( + cls, "vnd.otps.ct-kip+xml", PermissibleValue(text="vnd.otps.ct-kip+xml") + ) + setattr( + cls, "vnd.oxli.countgraph", PermissibleValue(text="vnd.oxli.countgraph") + ) setattr(cls, "vnd.pagerduty+json", PermissibleValue(text="vnd.pagerduty+json")) setattr(cls, "vnd.palm", PermissibleValue(text="vnd.palm")) setattr(cls, "vnd.panoply", PermissibleValue(text="vnd.panoply")) setattr(cls, "vnd.paos.xml", PermissibleValue(text="vnd.paos.xml")) setattr(cls, "vnd.patentdive", PermissibleValue(text="vnd.patentdive")) - setattr(cls, "vnd.patientecommsdoc", PermissibleValue(text="vnd.patientecommsdoc")) + setattr( + cls, "vnd.patientecommsdoc", PermissibleValue(text="vnd.patientecommsdoc") + ) setattr(cls, "vnd.pawaafile", PermissibleValue(text="vnd.pawaafile")) setattr(cls, "vnd.pcos", PermissibleValue(text="vnd.pcos")) setattr(cls, "vnd.pg.format", PermissibleValue(text="vnd.pg.format")) @@ -12697,18 +13423,26 @@ def _addvals(cls): ) setattr(cls, "vnd.pocketlearn", PermissibleValue(text="vnd.pocketlearn")) setattr(cls, "vnd.powerbuilder6", PermissibleValue(text="vnd.powerbuilder6")) - setattr(cls, "vnd.powerbuilder6-s", PermissibleValue(text="vnd.powerbuilder6-s")) + setattr( + cls, "vnd.powerbuilder6-s", PermissibleValue(text="vnd.powerbuilder6-s") + ) setattr(cls, "vnd.powerbuilder7", PermissibleValue(text="vnd.powerbuilder7")) setattr(cls, "vnd.powerbuilder75", PermissibleValue(text="vnd.powerbuilder75")) - setattr(cls, "vnd.powerbuilder75-s", PermissibleValue(text="vnd.powerbuilder75-s")) - setattr(cls, "vnd.powerbuilder7-s", PermissibleValue(text="vnd.powerbuilder7-s")) + setattr( + cls, "vnd.powerbuilder75-s", PermissibleValue(text="vnd.powerbuilder75-s") + ) + setattr( + cls, "vnd.powerbuilder7-s", PermissibleValue(text="vnd.powerbuilder7-s") + ) setattr(cls, "vnd.preminet", PermissibleValue(text="vnd.preminet")) setattr( cls, "vnd.previewsystems.box", PermissibleValue(text="vnd.previewsystems.box"), ) - setattr(cls, "vnd.proteus.magazine", PermissibleValue(text="vnd.proteus.magazine")) + setattr( + cls, "vnd.proteus.magazine", PermissibleValue(text="vnd.proteus.magazine") + ) setattr(cls, "vnd.psfs", PermissibleValue(text="vnd.psfs")) setattr(cls, "vnd.pt.mundusmundi", PermissibleValue(text="vnd.pt.mundusmundi")) setattr( @@ -12717,7 +13451,9 @@ def _addvals(cls): PermissibleValue(text="vnd.publishare-delta-tree"), ) setattr(cls, "vnd.pvi.ptid1", PermissibleValue(text="vnd.pvi.ptid1")) - setattr(cls, "vnd.pwg-multiplexed", PermissibleValue(text="vnd.pwg-multiplexed")) + setattr( + cls, "vnd.pwg-multiplexed", PermissibleValue(text="vnd.pwg-multiplexed") + ) setattr( cls, "vnd.pwg-xhtml-print+xml", @@ -12729,13 +13465,17 @@ def _addvals(cls): PermissibleValue(text="vnd.qualcomm.brew-app-res"), ) setattr(cls, "vnd.quarantainenet", PermissibleValue(text="vnd.quarantainenet")) - setattr(cls, "vnd.Quark.QuarkXPress", PermissibleValue(text="vnd.Quark.QuarkXPress")) + setattr( + cls, "vnd.Quark.QuarkXPress", PermissibleValue(text="vnd.Quark.QuarkXPress") + ) setattr( cls, "vnd.quobject-quoxdocument", PermissibleValue(text="vnd.quobject-quoxdocument"), ) - setattr(cls, "vnd.radisys.moml+xml", PermissibleValue(text="vnd.radisys.moml+xml")) + setattr( + cls, "vnd.radisys.moml+xml", PermissibleValue(text="vnd.radisys.moml+xml") + ) setattr( cls, "vnd.radisys.msml-audit-conf+xml", @@ -12801,7 +13541,9 @@ def _addvals(cls): "vnd.radisys.msml-dialog+xml", PermissibleValue(text="vnd.radisys.msml-dialog+xml"), ) - setattr(cls, "vnd.radisys.msml+xml", PermissibleValue(text="vnd.radisys.msml+xml")) + setattr( + cls, "vnd.radisys.msml+xml", PermissibleValue(text="vnd.radisys.msml+xml") + ) setattr(cls, "vnd.rainstor.data", PermissibleValue(text="vnd.rainstor.data")) setattr(cls, "vnd.rapid", PermissibleValue(text="vnd.rapid")) setattr(cls, "vnd.rar", PermissibleValue(text="vnd.rar")) @@ -12817,8 +13559,12 @@ def _addvals(cls): PermissibleValue(text="vnd.recordare.musicxml+xml"), ) setattr(cls, "vnd.relpipe", PermissibleValue(text="vnd.relpipe")) - setattr(cls, "vnd.RenLearn.rlprint", PermissibleValue(text="vnd.RenLearn.rlprint")) - setattr(cls, "vnd.resilient.logic", PermissibleValue(text="vnd.resilient.logic")) + setattr( + cls, "vnd.RenLearn.rlprint", PermissibleValue(text="vnd.RenLearn.rlprint") + ) + setattr( + cls, "vnd.resilient.logic", PermissibleValue(text="vnd.resilient.logic") + ) setattr(cls, "vnd.restful+json", PermissibleValue(text="vnd.restful+json")) setattr(cls, "vnd.rig.cryptonote", PermissibleValue(text="vnd.rig.cryptonote")) setattr( @@ -12827,7 +13573,9 @@ def _addvals(cls): PermissibleValue(text="vnd.route66.link66+xml"), ) setattr(cls, "vnd.rs-274x", PermissibleValue(text="vnd.rs-274x")) - setattr(cls, "vnd.ruckus.download", PermissibleValue(text="vnd.ruckus.download")) + setattr( + cls, "vnd.ruckus.download", PermissibleValue(text="vnd.ruckus.download") + ) setattr(cls, "vnd.s3sms", PermissibleValue(text="vnd.s3sms")) setattr( cls, @@ -12862,7 +13610,9 @@ def _addvals(cls): setattr(cls, "vnd.sema", PermissibleValue(text="vnd.sema")) setattr(cls, "vnd.semd", PermissibleValue(text="vnd.semd")) setattr(cls, "vnd.semf", PermissibleValue(text="vnd.semf")) - setattr(cls, "vnd.shade-save-file", PermissibleValue(text="vnd.shade-save-file")) + setattr( + cls, "vnd.shade-save-file", PermissibleValue(text="vnd.shade-save-file") + ) setattr( cls, "vnd.shana.informed.formdata", @@ -12883,7 +13633,9 @@ def _addvals(cls): "vnd.shana.informed.package", PermissibleValue(text="vnd.shana.informed.package"), ) - setattr(cls, "vnd.shootproof+json", PermissibleValue(text="vnd.shootproof+json")) + setattr( + cls, "vnd.shootproof+json", PermissibleValue(text="vnd.shootproof+json") + ) setattr(cls, "vnd.shopkick+json", PermissibleValue(text="vnd.shopkick+json")) setattr(cls, "vnd.shp", PermissibleValue(text="vnd.shp")) setattr(cls, "vnd.shx", PermissibleValue(text="vnd.shx")) @@ -12917,14 +13669,18 @@ def _addvals(cls): "vnd.software602.filler.form-xml-zip", PermissibleValue(text="vnd.software602.filler.form-xml-zip"), ) - setattr(cls, "vnd.solent.sdkm+xml", PermissibleValue(text="vnd.solent.sdkm+xml")) + setattr( + cls, "vnd.solent.sdkm+xml", PermissibleValue(text="vnd.solent.sdkm+xml") + ) setattr(cls, "vnd.spotfire.dxp", PermissibleValue(text="vnd.spotfire.dxp")) setattr(cls, "vnd.spotfire.sfs", PermissibleValue(text="vnd.spotfire.sfs")) setattr(cls, "vnd.sqlite3", PermissibleValue(text="vnd.sqlite3")) setattr(cls, "vnd.sss-cod", PermissibleValue(text="vnd.sss-cod")) setattr(cls, "vnd.sss-dtf", PermissibleValue(text="vnd.sss-dtf")) setattr(cls, "vnd.sss-ntf", PermissibleValue(text="vnd.sss-ntf")) - setattr(cls, "vnd.stepmania.package", PermissibleValue(text="vnd.stepmania.package")) + setattr( + cls, "vnd.stepmania.package", PermissibleValue(text="vnd.stepmania.package") + ) setattr( cls, "vnd.stepmania.stepchart", @@ -12943,19 +13699,25 @@ def _addvals(cls): "vnd.syncml.dm.notification", PermissibleValue(text="vnd.syncml.dm.notification"), ) - setattr(cls, "vnd.syncml.dmddf+xml", PermissibleValue(text="vnd.syncml.dmddf+xml")) + setattr( + cls, "vnd.syncml.dmddf+xml", PermissibleValue(text="vnd.syncml.dmddf+xml") + ) setattr( cls, "vnd.syncml.dmtnds+wbxml", PermissibleValue(text="vnd.syncml.dmtnds+wbxml"), ) - setattr(cls, "vnd.syncml.dmtnds+xml", PermissibleValue(text="vnd.syncml.dmtnds+xml")) + setattr( + cls, "vnd.syncml.dmtnds+xml", PermissibleValue(text="vnd.syncml.dmtnds+xml") + ) setattr( cls, "vnd.syncml.dmddf+wbxml", PermissibleValue(text="vnd.syncml.dmddf+wbxml"), ) - setattr(cls, "vnd.syncml.dm+wbxml", PermissibleValue(text="vnd.syncml.dm+wbxml")) + setattr( + cls, "vnd.syncml.dm+wbxml", PermissibleValue(text="vnd.syncml.dm+wbxml") + ) setattr(cls, "vnd.syncml.dm+xml", PermissibleValue(text="vnd.syncml.dm+xml")) setattr( cls, @@ -12963,7 +13725,9 @@ def _addvals(cls): PermissibleValue(text="vnd.syncml.ds.notification"), ) setattr(cls, "vnd.syncml+xml", PermissibleValue(text="vnd.syncml+xml")) - setattr(cls, "vnd.tableschema+json", PermissibleValue(text="vnd.tableschema+json")) + setattr( + cls, "vnd.tableschema+json", PermissibleValue(text="vnd.tableschema+json") + ) setattr( cls, "vnd.tao.intent-module-archive", @@ -12987,7 +13751,9 @@ def _addvals(cls): setattr(cls, "vnd.triscape.mxs", PermissibleValue(text="vnd.triscape.mxs")) setattr(cls, "vnd.trueapp", PermissibleValue(text="vnd.trueapp")) setattr(cls, "vnd.truedoc", PermissibleValue(text="vnd.truedoc")) - setattr(cls, "vnd.ubisoft.webplayer", PermissibleValue(text="vnd.ubisoft.webplayer")) + setattr( + cls, "vnd.ubisoft.webplayer", PermissibleValue(text="vnd.ubisoft.webplayer") + ) setattr(cls, "vnd.ufdl", PermissibleValue(text="vnd.ufdl")) setattr(cls, "vnd.uiq.theme", PermissibleValue(text="vnd.uiq.theme")) setattr(cls, "vnd.umajin", PermissibleValue(text="vnd.umajin")) @@ -13009,20 +13775,26 @@ def _addvals(cls): "vnd.uplanet.bearer-choice-wbxml", PermissibleValue(text="vnd.uplanet.bearer-choice-wbxml"), ) - setattr(cls, "vnd.uplanet.cacheop", PermissibleValue(text="vnd.uplanet.cacheop")) + setattr( + cls, "vnd.uplanet.cacheop", PermissibleValue(text="vnd.uplanet.cacheop") + ) setattr( cls, "vnd.uplanet.cacheop-wbxml", PermissibleValue(text="vnd.uplanet.cacheop-wbxml"), ) - setattr(cls, "vnd.uplanet.channel", PermissibleValue(text="vnd.uplanet.channel")) + setattr( + cls, "vnd.uplanet.channel", PermissibleValue(text="vnd.uplanet.channel") + ) setattr( cls, "vnd.uplanet.channel-wbxml", PermissibleValue(text="vnd.uplanet.channel-wbxml"), ) setattr(cls, "vnd.uplanet.list", PermissibleValue(text="vnd.uplanet.list")) - setattr(cls, "vnd.uplanet.listcmd", PermissibleValue(text="vnd.uplanet.listcmd")) + setattr( + cls, "vnd.uplanet.listcmd", PermissibleValue(text="vnd.uplanet.listcmd") + ) setattr( cls, "vnd.uplanet.listcmd-wbxml", @@ -13044,7 +13816,9 @@ def _addvals(cls): setattr(cls, "vnd.vd-study", PermissibleValue(text="vnd.vd-study")) setattr(cls, "vnd.vectorworks", PermissibleValue(text="vnd.vectorworks")) setattr(cls, "vnd.vel+json", PermissibleValue(text="vnd.vel+json")) - setattr(cls, "vnd.verimatrix.vcas", PermissibleValue(text="vnd.verimatrix.vcas")) + setattr( + cls, "vnd.verimatrix.vcas", PermissibleValue(text="vnd.verimatrix.vcas") + ) setattr( cls, "vnd.veritone.aion+json", @@ -13116,8 +13890,12 @@ def _addvals(cls): setattr(cls, "vnd.xmpie.ppkg", PermissibleValue(text="vnd.xmpie.ppkg")) setattr(cls, "vnd.xmpie.xlim", PermissibleValue(text="vnd.xmpie.xlim")) setattr(cls, "vnd.yamaha.hv-dic", PermissibleValue(text="vnd.yamaha.hv-dic")) - setattr(cls, "vnd.yamaha.hv-script", PermissibleValue(text="vnd.yamaha.hv-script")) - setattr(cls, "vnd.yamaha.hv-voice", PermissibleValue(text="vnd.yamaha.hv-voice")) + setattr( + cls, "vnd.yamaha.hv-script", PermissibleValue(text="vnd.yamaha.hv-script") + ) + setattr( + cls, "vnd.yamaha.hv-voice", PermissibleValue(text="vnd.yamaha.hv-voice") + ) setattr( cls, "vnd.yamaha.openscoreformat.osfpvg+xml", @@ -13133,7 +13911,9 @@ def _addvals(cls): "vnd.yamaha.remote-setup", PermissibleValue(text="vnd.yamaha.remote-setup"), ) - setattr(cls, "vnd.yamaha.smaf-audio", PermissibleValue(text="vnd.yamaha.smaf-audio")) + setattr( + cls, "vnd.yamaha.smaf-audio", PermissibleValue(text="vnd.yamaha.smaf-audio") + ) setattr( cls, "vnd.yamaha.smaf-phrase", @@ -13158,7 +13938,9 @@ def _addvals(cls): setattr( cls, "vnd.youtube.yt (OBSOLETED in favor of video/vnd.youtube.yt)", - PermissibleValue(text="vnd.youtube.yt (OBSOLETED in favor of video/vnd.youtube.yt)"), + PermissibleValue( + text="vnd.youtube.yt (OBSOLETED in favor of video/vnd.youtube.yt)" + ), ) setattr(cls, "vnd.zul", PermissibleValue(text="vnd.zul")) setattr(cls, "vnd.zzazz.deck+xml", PermissibleValue(text="vnd.zzazz.deck+xml")) @@ -13166,17 +13948,23 @@ def _addvals(cls): setattr(cls, "voucher-cms+json", PermissibleValue(text="voucher-cms+json")) setattr(cls, "vq-rtcpxr", PermissibleValue(text="vq-rtcpxr")) setattr(cls, "watcherinfo+xml", PermissibleValue(text="watcherinfo+xml")) - setattr(cls, "webpush-options+json", PermissibleValue(text="webpush-options+json")) + setattr( + cls, "webpush-options+json", PermissibleValue(text="webpush-options+json") + ) setattr(cls, "whoispp-query", PermissibleValue(text="whoispp-query")) setattr(cls, "whoispp-response", PermissibleValue(text="whoispp-response")) setattr(cls, "wordperfect5.1", PermissibleValue(text="wordperfect5.1")) setattr(cls, "wsdl+xml", PermissibleValue(text="wsdl+xml")) setattr(cls, "wspolicy+xml", PermissibleValue(text="wspolicy+xml")) setattr(cls, "x-pki-message", PermissibleValue(text="x-pki-message")) - setattr(cls, "x-www-form-urlencoded", PermissibleValue(text="x-www-form-urlencoded")) + setattr( + cls, "x-www-form-urlencoded", PermissibleValue(text="x-www-form-urlencoded") + ) setattr(cls, "x-x509-ca-cert", PermissibleValue(text="x-x509-ca-cert")) setattr(cls, "x-x509-ca-ra-cert", PermissibleValue(text="x-x509-ca-ra-cert")) - setattr(cls, "x-x509-next-ca-cert", PermissibleValue(text="x-x509-next-ca-cert")) + setattr( + cls, "x-x509-next-ca-cert", PermissibleValue(text="x-x509-next-ca-cert") + ) setattr(cls, "x400-bp", PermissibleValue(text="x400-bp")) setattr(cls, "xacml+xml", PermissibleValue(text="xacml+xml")) setattr(cls, "xcap-att+xml", PermissibleValue(text="xcap-att+xml")) @@ -13278,9 +14066,15 @@ class ContainerFormat(EnumDefinitionImpl): dockerv2 = PermissibleValue( text="dockerv2", description="Container is packaged with Docker v2 format." ) - oci = PermissibleValue(text="oci", description="Container is packaged with OCI format.") - lxc = PermissibleValue(text="lxc", description="Container is packaged with LXC format.") - lxd = PermissibleValue(text="lxd", description="Container is packaged with LXD format.") + oci = PermissibleValue( + text="oci", description="Container is packaged with OCI format." + ) + lxc = PermissibleValue( + text="lxc", description="Container is packaged with LXC format." + ) + lxd = PermissibleValue( + text="lxd", description="Container is packaged with LXD format." + ) _defn = EnumDefinition( name="ContainerFormat", @@ -13442,7 +14236,9 @@ class StorageRedundancyMechanism(EnumDefinitionImpl): text="RS_Code", description="""Reed-Solomon Erasure Code, cf https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction""", ) - Other = PermissibleValue(text="Other", description="Unspecified redundancy mechanism") + Other = PermissibleValue( + text="Other", description="Unspecified redundancy mechanism" + ) _defn = EnumDefinition( name="StorageRedundancyMechanism", @@ -13459,7 +14255,9 @@ class FileAccessProtocol(EnumDefinitionImpl): text="IPFS", description="InterPlanetary File System, cf https://en.wikipedia.org/wiki/IPFS", ) - Other = PermissibleValue(text="Other", description="Any other proprietary access protocol") + Other = PermissibleValue( + text="Other", description="Any other proprietary access protocol" + ) _defn = EnumDefinition( name="FileAccessProtocol", @@ -13503,7 +14301,9 @@ class FileSystemType(EnumDefinitionImpl): text="OneFS", description="Dell One File Fystem,cf https://en.wikipedia.org/wiki/One_File_System", ) - Other = PermissibleValue(text="Other", description="Any other proprietary file system") + Other = PermissibleValue( + text="Other", description="Any other proprietary file system" + ) _defn = EnumDefinition( name="FileSystemType", @@ -13619,7 +14419,9 @@ class CompressionAlgorithm(EnumDefinitionImpl): text="ANS", description="Entropy encoding algorithm, cf https://en.wikipedia.org/wiki/Asymmetric_numeral_systems", ) - Other = PermissibleValue(text="Other", description="Unspecified compression algorithm") + Other = PermissibleValue( + text="Other", description="Unspecified compression algorithm" + ) _defn = EnumDefinition( name="CompressionAlgorithm", @@ -13636,7 +14438,9 @@ def _addvals(cls): setattr( cls, "Read-Only", - PermissibleValue(text="Read-Only", description="Allow for access in read-mode only"), + PermissibleValue( + text="Read-Only", description="Allow for access in read-mode only" + ), ) setattr( cls, @@ -13663,7 +14467,9 @@ class StorageAPI(EnumDefinitionImpl): description="Cloud Data Management Interface API (open ISO standard)", ) S3 = PermissibleValue(text="S3", description="Amazon S3 API") - CloudStorage = PermissibleValue(text="CloudStorage", description="Google Cloud Storage API") + CloudStorage = PermissibleValue( + text="CloudStorage", description="Google Cloud Storage API" + ) _defn = EnumDefinition( name="StorageAPI", @@ -13708,7 +14514,9 @@ class WatchDogActions(EnumDefinitionImpl): poweroff = PermissibleValue( text="poweroff", description="Power of of guest is forced if server hangs." ) - pause = PermissibleValue(text="pause", description="Pause of guest is forced, if server hangs.") + pause = PermissibleValue( + text="pause", description="Pause of guest is forced, if server hangs." + ) none = PermissibleValue( text="none", description="Watchdog is enabled, but not action is defined and performed if server hangs.", @@ -14882,7 +15690,9 @@ class slots: curie=GX.curie("instantiationReq"), model_uri=GX.containerServiceOffering__instantiationReq, domain=None, - range=Union[Union[dict, ContainerResourceLimits], List[Union[dict, ContainerResourceLimits]]], + range=Union[ + Union[dict, ContainerResourceLimits], List[Union[dict, ContainerResourceLimits]] + ], ) slots.bareMetalServiceOffering__codeArtifact = Slot( @@ -14990,7 +15800,9 @@ class slots: curie=GX.curie("exposedThrough"), model_uri=GX.dataResource__exposedThrough, domain=None, - range=Union[Union[dict, DataExchangeComponent], List[Union[dict, DataExchangeComponent]]], + range=Union[ + Union[dict, DataExchangeComponent], List[Union[dict, DataExchangeComponent]] + ], ) slots.dataResource__obsoleteDateTime = Slot( @@ -15242,7 +16054,9 @@ class slots: curie=GX.curie("backupReplication"), model_uri=GX.backupPolicy__backupReplication, domain=None, - range=Optional[Union[Union[dict, ReplicationPolicy], List[Union[dict, ReplicationPolicy]]]], + range=Optional[ + Union[Union[dict, ReplicationPolicy], List[Union[dict, ReplicationPolicy]]] + ], ) slots.snapshotPolicy__snapshotReplication = Slot( @@ -15251,7 +16065,9 @@ class slots: curie=GX.curie("snapshotReplication"), model_uri=GX.snapshotPolicy__snapshotReplication, domain=None, - range=Optional[Union[Union[dict, ReplicationPolicy], List[Union[dict, ReplicationPolicy]]]], + range=Optional[ + Union[Union[dict, ReplicationPolicy], List[Union[dict, ReplicationPolicy]]] + ], ) slots.replicationPolicy__synchronousReplication = Slot( @@ -15288,7 +16104,9 @@ class slots: model_uri=GX.replicationPolicy__geoReplication, domain=None, range=Optional[ - Union[Union[str, "GeoReplicationScope"], List[Union[str, "GeoReplicationScope"]]] + Union[ + Union[str, "GeoReplicationScope"], List[Union[str, "GeoReplicationScope"]] + ] ], ) @@ -15353,7 +16171,9 @@ class slots: model_uri=GX.storageConfiguration__storageCompression, domain=None, range=Optional[ - Union[Union[str, "CompressionAlgorithm"], List[Union[str, "CompressionAlgorithm"]]] + Union[ + Union[str, "CompressionAlgorithm"], List[Union[str, "CompressionAlgorithm"]] + ] ], ) @@ -15364,7 +16184,9 @@ class slots: model_uri=GX.storageConfiguration__storageDeduplication, domain=None, range=Optional[ - Union[Union[str, "DeduplicationMethod"], List[Union[str, "DeduplicationMethod"]]] + Union[ + Union[str, "DeduplicationMethod"], List[Union[str, "DeduplicationMethod"]] + ] ], ) @@ -15398,7 +16220,9 @@ class slots: model_uri=GX.storageConfiguration__storageProtection, domain=None, range=Optional[ - Union[Union[dict, DataProtectionPolicy], List[Union[dict, DataProtectionPolicy]]] + Union[ + Union[dict, DataProtectionPolicy], List[Union[dict, DataProtectionPolicy]] + ] ], ) @@ -15426,7 +16250,9 @@ class slots: curie=GX.curie("fileSystemType"), model_uri=GX.fileStorageConfiguration__fileSystemType, domain=None, - range=Optional[Union[Union[str, "FileSystemType"], List[Union[str, "FileSystemType"]]]], + range=Optional[ + Union[Union[str, "FileSystemType"], List[Union[str, "FileSystemType"]]] + ], ) slots.fileStorageConfiguration__highLevelAccessProtocol = Slot( @@ -15435,7 +16261,9 @@ class slots: curie=GX.curie("highLevelAccessProtocol"), model_uri=GX.fileStorageConfiguration__highLevelAccessProtocol, domain=None, - range=Optional[Union[Union[str, "FileAccessProtocol"], List[Union[str, "FileAccessProtocol"]]]], + range=Optional[ + Union[Union[str, "FileAccessProtocol"], List[Union[str, "FileAccessProtocol"]]] + ], ) slots.blockStorageConfiguration__blockStorageTechnology = Slot( @@ -15459,7 +16287,9 @@ class slots: model_uri=GX.blockStorageConfiguration__lowLevelBlockAccessProtocol, domain=None, range=Optional[ - Union[Union[str, "BlockAccessProtocol"], List[Union[str, "BlockAccessProtocol"]]] + Union[ + Union[str, "BlockAccessProtocol"], List[Union[str, "BlockAccessProtocol"]] + ] ], ) @@ -15559,7 +16389,9 @@ class slots: curie=GX.curie("accessAttributes"), model_uri=GX.fileStorageServiceOffering__accessAttributes, domain=None, - range=Optional[Union[Union[str, "AccessAttribute"], List[Union[str, "AccessAttribute"]]]], + range=Optional[ + Union[Union[str, "AccessAttribute"], List[Union[str, "AccessAttribute"]]] + ], ) slots.blockStorageServiceOffering__storageConfiguration = Slot( @@ -15577,7 +16409,9 @@ class slots: curie=GX.curie("accessAttributes"), model_uri=GX.objectStorageServiceOffering__accessAttributes, domain=None, - range=Optional[Union[Union[str, "AccessAttribute"], List[Union[str, "AccessAttribute"]]]], + range=Optional[ + Union[Union[str, "AccessAttribute"], List[Union[str, "AccessAttribute"]]] + ], ) slots.objectStorageServiceOffering__maximumObjectSize = Slot( diff --git a/generator/common/json_ld.py b/generator/common/json_ld.py index 0053d8f..d5b249c 100644 --- a/generator/common/json_ld.py +++ b/generator/common/json_ld.py @@ -6,7 +6,11 @@ from typing import List from uuid import uuid4 -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue, PvFormulaOptions +from linkml_runtime.linkml_model.meta import ( + EnumDefinition, + PermissibleValue, + PvFormulaOptions, +) from linkml_runtime.utils.enumerations import EnumDefinitionImpl from linkml_runtime.utils.metamodelcore import URI from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str diff --git a/generator/discovery/openstack/discovery.py b/generator/discovery/openstack/discovery.py deleted file mode 100644 index ed5b670..0000000 --- a/generator/discovery/openstack/discovery.py +++ /dev/null @@ -1,46 +0,0 @@ -""""General openstack discovery class. - -(c) Anja Strunk , 2/2024 -SPDX-License-Identifier: EPL-2.0 -""" - -from abc import ABCMeta, abstractmethod -from typing import List - -from openstack.connection import Connection - -from generator.common import const -from generator.common.config import Config -from generator.common.json_ld import JsonLdObject -from generator.discovery.openstack.vm_images_discovery import VmDiscovery -from generator.discovery.openstack.server_flavor_discovery import ServerFlavorDiscovery - - -class OsCloud: - """Abstraction for openStack cloud with all its services.""" - - def __init__(self, conn: Connection, config: Config) -> None: - # import copy - self.conn = conn - # self.regions = list(conn.identity.regions()) - self.config = config - - def discover(self) -> List[JsonLdObject]: - """ - Discover all attributes of OS Cloud. - - @return: all attributes as list - @rtype List[JsonLdObject] - """ - creds = list() - - vi_dis = VmDiscovery(self.conn, self.config) - images = vi_dis.discover() - if images: - creds.extend(images) - sf_dis = ServerFlavorDiscovery(self.conn, self.config) - flavors = sf_dis.discover() - if flavors: - creds.extend(sf_dis.discover()) - - return creds \ No newline at end of file diff --git a/generator/discovery/openstack/openstack_discovery.py b/generator/discovery/openstack/openstack_discovery.py index d157da6..9a6b033 100644 --- a/generator/discovery/openstack/openstack_discovery.py +++ b/generator/discovery/openstack/openstack_discovery.py @@ -1,3 +1,9 @@ +""""General openstack discovery class. + +(c) Anja Strunk , 2/2024 +SPDX-License-Identifier: EPL-2.0 +""" + from abc import ABCMeta, abstractmethod from typing import List @@ -6,29 +12,35 @@ from generator.common import const from generator.common.config import Config from generator.common.json_ld import JsonLdObject +from generator.discovery.openstack.server_flavor_discovery import ServerFlavorDiscovery +from generator.discovery.openstack.vm_images_discovery import VmDiscovery -class OpenStackDiscovery(metaclass=ABCMeta): +class OsCloud: + """Abstraction for openStack cloud with all its services.""" - def __init__(self, conn: Connection, conf: Config) -> None: + def __init__(self, conn: Connection, config: Config) -> None: + # import copy self.conn = conn - self.conf = conf + # self.regions = list(conn.identity.regions()) + self.config = config - @abstractmethod def discover(self) -> List[JsonLdObject]: - pass - - import generator.common.const as const - - def get_copyright_owner(self, software: str) -> List[str]: - return self.conf.get_value([const.COMFIG_SOFTWARE, software, const.CONFIG_COPYRIGHT]) - - def get_license(self, software: str) -> List[str]: - return self.conf.get_value([const.COMFIG_SOFTWARE,software,const.CONFIG_LICENSE]) - - def get_resource_policy(self, software: str) -> List[str]: - return self.conf.get_value([const.COMFIG_SOFTWARE,software,const.CONFIG_RESOURCE_POLICY]) - - - - + """ + Discover all attributes of OS Cloud. + + @return: all attributes as list + @rtype List[JsonLdObject] + """ + creds = list() + + vi_dis = VmDiscovery(self.conn, self.config) + images = vi_dis.discover() + if images: + creds.extend(images) + sf_dis = ServerFlavorDiscovery(self.conn, self.config) + flavors = sf_dis.discover() + if flavors: + creds.extend(sf_dis.discover()) + + return creds diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index d41fb1f..b0ab5ed 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -7,20 +7,31 @@ import re from typing import List, Tuple -from generator.discovery.openstack.openstack_discovery import OpenStackDiscovery from openstack.compute.v2.flavor import Flavor as OS_Flavor +from openstack.connection import Connection from generator.common import const +from generator.common.config import Config from generator.common.gx_schema import CPU from generator.common.gx_schema import Architectures as CpuArch -from generator.common.gx_schema import (Disk, DiskBusType, DiskType, Frequency, - Hypervisor, Memory, MemorySize, - PermissibleValue) +from generator.common.gx_schema import ( + Disk, + DiskBusType, + DiskType, + Frequency, + Hypervisor, + Memory, + MemorySize, +) from generator.common.gx_schema import ServerFlavor as GX_Flavor from generator.common.json_ld import JsonLdObject -class ServerFlavorDiscovery(OpenStackDiscovery): +class ServerFlavorDiscovery: + def __init__(self, conn: Connection, conf: Config) -> None: + self.conn = conn + self.conf = conf + def discover(self) -> List[JsonLdObject]: """ Return one JsonLdObject for each public server flavor discovery at openstack cloud. @@ -215,45 +226,30 @@ def _parse_optional_flavor_properties( elif suffix == "kvm": gx_flavor.hypervisor = Hypervisor( hypervisorType="KVM", - copyrightOwnedBy=self.get_copyright_owner( - const.CONFIG_HV_KVM - ), - license=self.get_license(const.CONFIG_HV_KVM), - resourcePolicy=self.get_resource_policy( - const.CONFIG_HV_KVM - ), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_HV_KVM), + license=self.conf.get_license(const.CONFIG_HV_KVM), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_HV_KVM), ) elif suffix == "xen": gx_flavor.hypervisor = Hypervisor( hypervisorType="Xen", - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_HV_XEN - ), - license=self.get_license(const.CONFIG_HV_XEN), - resourcePolicy=self.get_resource_policy( - const.CONFIG_HV_XEN - ), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_HV_XEN), + license=self.conf.get_license(const.CONFIG_HV_XEN), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_HV_XEN), ) elif suffix == "vmw": gx_flavor.hypervisor = Hypervisor( hypervisorType="KVM", - copyrightOwnedBy=self.get_copyright_owner( - const.CONFIG_HV_VMW - ), - license=self.get_license(const.CONFIG_HV_VMW), - resourcePolicy=self.get_resource_policy( - const.CONFIG_HV_VMW - ), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_HV_VMW), + license=self.conf.get_license(const.CONFIG_HV_VMW), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_HV_VMW), ) elif suffix == "hyv": gx_flavor.hypervisor = Hypervisor( hypervisorType="Hyper-V", - copyrightOwnedBy=self.get_copyright_owner( - const.CONFIG_HV_HYV - ), - license=self.get_license(const.CONFIG_HV_HYV), - resourcePolicy=self.get_resource_policy( - const.CONFIG_HV_HYV - ), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_HV_HYV), + license=self.conf.get_license(const.CONFIG_HV_HYV), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_HV_HYV), ) # parse hardware assisted virtualization elif suffix == "hwv": diff --git a/generator/discovery/openstack/vm_images_discovery.py b/generator/discovery/openstack/vm_images_discovery.py index 7a16844..8717819 100644 --- a/generator/discovery/openstack/vm_images_discovery.py +++ b/generator/discovery/openstack/vm_images_discovery.py @@ -4,17 +4,19 @@ SPDX-License-Identifier: EPL-2.0 """ -from datetime import date, datetime +from datetime import datetime from typing import List, Union -from generator.discovery.openstack.openstack_discovery import OpenStackDiscovery + from linkml_runtime.utils.metamodelcore import URI +from openstack.connection import Connection from openstack.image.v2.image import Image as OS_Image -import generator.common.const as const +from generator.common import const +from generator.common.config import Config +from generator.common.gx_schema import CPU, SPDX from generator.common.gx_schema import Architectures as CpuArch from generator.common.gx_schema import ( CheckSum, -CPU, SPDX, ChecksumAlgorithm, Disk, DiskBusType, @@ -28,7 +30,6 @@ RNGTypes, Signature, SignatureAlgorithm, - WatchDogActions, UpdateFrequency, UpdateStrategy, Validity1, @@ -36,6 +37,7 @@ VMDiskType, ) from generator.common.gx_schema import VMImage as GX_Image +from generator.common.gx_schema import WatchDogActions from generator.common.json_ld import JsonLdObject VALID_UNTIL_LOOKUP = { @@ -115,9 +117,13 @@ } -class VmDiscovery(OpenStackDiscovery): +class VmDiscovery: """Discover VM image properties.""" + def __init__(self, conn: Connection, conf: Config) -> None: + self.conn = conn + self.conf = conf + # def collect_vm_images(self, conn: Connection) -> List[str]: def discover(self) -> List[JsonLdObject]: """ @@ -128,7 +134,11 @@ def discover(self) -> List[JsonLdObject]: images = [] for image in self.conn.list_images(): if image.visibility == "public": - images.append(JsonLdObject(gx_id=image.id, gx_object=self._convert_to_gx_image(image))) + images.append( + JsonLdObject( + gx_id=image.id, gx_object=self._convert_to_gx_image(image) + ) + ) return images def _convert_to_gx_image(self, os_image: OS_Image) -> GX_Image: @@ -182,7 +192,9 @@ def _convert_to_gx_image(self, os_image: OS_Image) -> GX_Image: @staticmethod def _get_disk_format(os_image: OS_Image) -> VMDiskType: if os_image.disk_format is not None: - return VMDiskType(DISK_LOOKUP.get(os_image.disk_format.lower(), VMDiskType.RAW)) + return VMDiskType( + DISK_LOOKUP.get(os_image.disk_format.lower(), VMDiskType.RAW) + ) return VMDiskType(VMDiskType.RAW) @staticmethod @@ -191,7 +203,10 @@ def _get_secure_boot(os_image: OS_Image) -> bool: @staticmethod def _get_firme_ware_type(os_image: OS_Image) -> FirmType: - if os_image.properties is not None and "hw_firmware_type" in os_image.properties: + if ( + os_image.properties is not None + and "hw_firmware_type" in os_image.properties + ): return FirmType( FIRM_WARE_LOOKUP.get( os_image.properties["hw_firmware_type"].lower(), FirmType.other @@ -204,7 +219,9 @@ def _get_firme_ware_type(os_image: OS_Image) -> FirmType: def _get_watchdog_action(os_image: OS_Image) -> WatchDogActions: if os_image.hw_watchdog_action is not None: return WatchDogActions( - WATCH_DOG_LOOKUP.get(os_image.hw_watchdog_action.lower(), WatchDogActions.disabled) + WATCH_DOG_LOOKUP.get( + os_image.hw_watchdog_action.lower(), WatchDogActions.disabled + ) ) return WatchDogActions(WatchDogActions.disabled) @@ -217,7 +234,11 @@ def _get_vmpu(os_image: OS_Image) -> bool: @staticmethod def _get_cpu_req(os_image: OS_Image) -> CPU: - cpu = CPU(cpuArchitecture=CpuArch(ARCH_LOOKUP.get(os_image.architecture, CpuArch.other))) + cpu = CPU( + cpuArchitecture=CpuArch( + ARCH_LOOKUP.get(os_image.architecture, CpuArch.other) + ) + ) if hasattr(os_image, "hw_cpu_cores"): cpu.numberOfCores = os_image.hw_cpu_cores @@ -232,7 +253,9 @@ def _get_multiqueue_enabled(os_image: OS_Image) -> bool: @staticmethod def _get_file_size(os_image: OS_Image) -> MemorySize: if os_image.size is not None: - return MemorySize(value=float(os_image.size * 1.073741824), unit=const.UNIT_GB) + return MemorySize( + value=float(os_image.size * 1.073741824), unit=const.UNIT_GB + ) @staticmethod def _get_checksum(os_image: OS_Image) -> CheckSum: @@ -240,7 +263,9 @@ def _get_checksum(os_image: OS_Image) -> CheckSum: return CheckSum( checkSumValue=os_image.hash_value, checkSumCalculation=ChecksumAlgorithm( - HASH_ALGO_LOOKUP.get(os_image.hash_algo.lower(), ChecksumAlgorithm.other) + HASH_ALGO_LOOKUP.get( + os_image.hash_algo.lower(), ChecksumAlgorithm.other + ) ), ) @@ -254,7 +279,9 @@ def _get_min_ram_req(os_image: OS_Image) -> Memory: # Memory size tend to be measured in MB (1,000,000 bytes) and not MiB (1.048576 bytes) the RAM industry. # But OpenStack uses MiB. mem = Memory( - memorySize=MemorySize(value=float(os_image.min_ram * 1.048576), unit=const.UNIT_MB) + memorySize=MemorySize( + value=float(os_image.min_ram * 1.048576), unit=const.UNIT_MB + ) ) if os_image.properties and "hw_mem_encryption" in os_image.properties: mem.hardwareEncryption = os_image.properties["hw_mem_encryption"] @@ -282,177 +309,211 @@ def _get_operation_system(self, os_image: OS_Image) -> OperatingSystem: return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ARCH, - resourcePolicy=self.get_copyright_owner(const.CONFIG_OS_ARCH), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_ARCH), - license=self._get_license_list(self.get_license(const.CONFIG_OS_ARCH)), + resourcePolicy=self.conf.get_copyright_owner(const.CONFIG_OS_ARCH), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_ARCH), + license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_ARCH)), ) elif os_image.os_distro.lower() == "centos": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_CENTOS, - resourcePolicy=self._get_resource_policy(const.CONFIG_OS_CENTOS), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_CENTOS), - license=self._get_license_list(self._get_license(const.CONFIG_OS_CENTOS)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_CENTOS), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_CENTOS), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_CENTOS) + ), ) elif os_image.os_distro.lower() == "debian": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_DEBIAN, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_DEBIAN), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_DEBIAN), - license=self._get_license_list(self.get_license(const.CONFIG_OS_DEBIAN)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_DEBIAN), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_DEBIAN), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_DEBIAN) + ), ) elif os_image.os_distro.lower() == "fedora": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_FEDORA, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_FEDORA), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_FEDORA), - license=self._get_license_list(self.get_license(const.CONFIG_OS_FEDORA)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_FEDORA), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_FEDORA), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_FEDORA) + ), ) elif os_image.os_distro.lower() == "freebsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_FREEBSD, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_FREEBSD), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_FREEBSD), - license=self._get_license_list(self.get_license(const.CONFIG_OS_FREEBSD)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_FREEBSD), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_FREEBSD), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_FREEBSD) + ), ) elif os_image.os_distro.lower() == "gentoo": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_GENTOO, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_GENTOO), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_GENTOO), - license=self._get_license_list(self.get_license(const.CONFIG_OS_GENTOO)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_GENTOO), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_GENTOO), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_GENTOO) + ), ) elif os_image.os_distro.lower() == "mandrake": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MANDRAKE, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_MANDRAKE), - copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_MANDRAKE), - license=self._get_license_list(self.get_license(const.CONFIG_OS_MANDRAKE)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_MANDRAKE), + copyrightOwnedBy=self.conf.get_copyright_owner( + const.CONFIG_OS_MANDRAKE + ), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_MANDRAKE) + ), ) elif os_image.os_distro.lower() == "mandriva": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MANDRIVA, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_MANDRIVA), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_MANDRIVA), - license=self._get_license_list(self.get_license(const.CONFIG_OS_MANDRIVA)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_MANDRIVA), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_MANDRIVA), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_MANDRIVA) + ), ) elif os_image.os_distro.lower() == "mes": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MES, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_MES), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_MES), - license=self._get_license_list(self.get_license(const.CONFIG_OS_MES)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_MES), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_MES), + license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_MES)), ) elif os_image.os_distro.lower() == "msdos": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MSDOS, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_MSDOS), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_MSDOS), - license=self._get_license_list(self.get_license(const.CONFIG_OS_MSDOS)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_MSDOS), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_MSDOS), + license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_MSDOS)), ) elif os_image.os_distro.lower() == "netbsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_NETBSD, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_NETBSD), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_NETBSD), - license=self._get_license_list(self.get_license(const.CONFIG_OS_NETBSD)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_NETBSD), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_NETBSD), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_NETBSD) + ), ) elif os_image.os_distro.lower() == "netware": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_NOVELL, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_NOVELL), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_NOVELL), - license=self._get_license_list(self.get_license(const.CONFIG_OS_NOVELL)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_NOVELL), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_NOVELL), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_NOVELL) + ), ) elif os_image.os_distro.lower() == "openbsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_OPENBSD, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_OPENBSD), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_OPENBSD), - license=self._get_license_list(self.get_license(const.CONFIG_OS_OPENBSD)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_OPENBSD), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_OPENBSD), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_OPENBSD) + ), ) elif os_image.os_distro.lower() == "opensolaris": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_SOLARIS, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_SOLARIS), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_SOLARIS), - license=self._get_license_list(self.get_license(const.CONFIG_OS_SOLARIS)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_SOLARIS), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_SOLARIS), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_SOLARIS) + ), ) elif os_image.os_distro.lower() == "opensuse": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_OPEN_SUSE, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_OPEN_SUSE), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_OPEN_SUSE), - license=self._get_license_list(self.get_license(const.CONFIG_OS_OPEN_SUSE)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_OPEN_SUSE), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_OPEN_SUSE), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_OPEN_SUSE) + ), ) elif os_image.os_distro.lower() == "rocky": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ROCKY, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_ROCKY), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_ROCKY), - license=self._get_license_list(self.get_license(const.CONFIG_OS_ROCKY)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_ROCKY), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_ROCKY), + license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_ROCKY)), ) elif os_image.os_distro.lower() == "rhel": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_RHEL, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_RHEL), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_RHEL), - license=self._get_license_list(self.get_license(const.CONFIG_OS_RHEL)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_RHEL), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_RHEL), + license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_RHEL)), ) elif os_image.os_distro.lower() == "sled": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_SLED, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_SLED), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_SLED), - license=self._get_license_list(self.get_license(const.CONFIG_OS_SLED)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_SLED), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_SLED), + license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_SLED)), ) elif os_image.os_distro.lower() == "ubuntu": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_UBUNTU, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_UBUNTU), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_UBUNTU), - license=self._get_license_list(self.get_license(const.CONFIG_OS_UBUNTU)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_UBUNTU), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_UBUNTU), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_UBUNTU) + ), ) elif os_image.os_distro.lower() == "windows": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_WINDOWS, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_WINDOWS), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_WINDOWS), - license=self._get_license_list(self.get_license(const.CONFIG_OS_WINDOWS)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_WINDOWS), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_WINDOWS), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_WINDOWS) + ), ) elif os_image.os_distro.lower() == "cirros": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_CIRROS, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_CIRROS), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_CIRROS), - license=self._get_license_list(self.get_license(const.CONFIG_OS_CIRROS)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_CIRROS), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_CIRROS), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_CIRROS) + ), ) elif os_image.os_distro.lower() == "almalinux": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ALMALINUX, - resourcePolicy=self.get_resource_policy(const.CONFIG_OS_ALMALINUX), - copyrightOwnedBy=self.get_copyright_owner(const.CONFIG_OS_ALMALINUX), - license=self._get_license_list(self.get_license(const.CONFIG_OS_ALMALINUX)), + resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_ALMALINUX), + copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_ALMALINUX), + license=self._get_license_list( + self.conf.get_license(const.CONFIG_OS_ALMALINUX) + ), ) else: raise ValueError( @@ -460,6 +521,7 @@ def _get_operation_system(self, os_image: OS_Image) -> OperatingSystem: + os_image.os_distro + "'" ) + def _add_copyright_owner(self, os_image: OS_Image, gx_image: GX_Image) -> None: try: gx_image.copyrightOwnedBy = self.conf.get_value( @@ -526,7 +588,9 @@ def _get_update_strategy(os_image: OS_Image) -> UpdateStrategy: if os_image.properties is not None: update_strategy = UpdateStrategy() if "replace_frequency" in os_image.properties: - rep_freq = UPDATE_STRATEGY_LOOKUP.get(os_image.properties["replace_frequency"]) + rep_freq = UPDATE_STRATEGY_LOOKUP.get( + os_image.properties["replace_frequency"] + ) if rep_freq is not None: update_strategy.replaceFrequency = UpdateFrequency(rep_freq) if "uuid_validity" in os_image.properties: @@ -543,7 +607,9 @@ def _get_update_strategy(os_image: OS_Image) -> UpdateStrategy: ).date() except ValueError: # no date provided, try to lookup - update_strategy.oldVersionsValidUntil = VALID_UNTIL_LOOKUP.get(old_version) + update_strategy.oldVersionsValidUntil = VALID_UNTIL_LOOKUP.get( + old_version + ) if "provided_until" in os_image.properties: provided_until = str(os_image.properties["provided_until"]) try: @@ -552,14 +618,21 @@ def _get_update_strategy(os_image: OS_Image) -> UpdateStrategy: provided_until, "%Y-%m-%d" ).date() except ValueError: - update_strategy.providedUntil = PROVIDED_UNTIL_LOOKUP.get(provided_until) + update_strategy.providedUntil = PROVIDED_UNTIL_LOOKUP.get( + provided_until + ) else: update_strategy.providedUntil = None - if "hotfix_hours" in os_image.properties and os_image.properties["hotfix_hours"]: + if ( + "hotfix_hours" in os_image.properties + and os_image.properties["hotfix_hours"] + ): try: hot_h = int(os_image.properties["hotfix_hours"]) if hot_h >= 0: - update_strategy.hotfixHours = int(os_image.properties["hotfix_hours"]) + update_strategy.hotfixHours = int( + os_image.properties["hotfix_hours"] + ) except ValueError: # int cast fails pass @@ -567,7 +640,10 @@ def _get_update_strategy(os_image: OS_Image) -> UpdateStrategy: @staticmethod def _get_description(os_image: OS_Image) -> str: - if os_image.properties is not None and "image_description" in os_image.properties: + if ( + os_image.properties is not None + and "image_description" in os_image.properties + ): if "managed_by_VENDOR" in os_image.properties: return ( os_image.properties["image_description"] @@ -583,8 +659,13 @@ def _get_name(os_image: OS_Image) -> str: @staticmethod def _get_build_date(os_image: OS_Image) -> datetime: - if os_image.properties is not None and "image_build_date" in os_image.properties: - return datetime.strptime(os_image.properties["image_build_date"], "%Y-%m-%d") + if ( + os_image.properties is not None + and "image_build_date" in os_image.properties + ): + return datetime.strptime( + os_image.properties["image_build_date"], "%Y-%m-%d" + ) @staticmethod def _get_license_included(os_image: OS_Image) -> bool: @@ -600,14 +681,21 @@ def _get_version(os_image: OS_Image) -> str: @staticmethod def _get_maintenance(os_image: OS_Image) -> MaintenanceSubscription: - maint = MaintenanceSubscription(subscriptionRequired=False, subscriptionIncluded=False) + maint = MaintenanceSubscription( + subscriptionRequired=False, subscriptionIncluded=False + ) maint.subscriptionRequired = bool( - os_image.properties and os_image.properties.get("subscription_required", None) + os_image.properties + and os_image.properties.get("subscription_required", None) ) maint.subscriptionIncluded = bool( - os_image.properties and os_image.properties.get("subscription_included", None) + os_image.properties + and os_image.properties.get("subscription_included", None) ) - if os_image.properties is not None and "maintained_until" in os_image.properties: + if ( + os_image.properties is not None + and "maintained_until" in os_image.properties + ): main_until = os_image.properties["maintained_until"] maint.maintainedUntil = datetime.strptime(main_until, "%Y-%m-%d").date() return maint diff --git a/gx-cred-generator.py b/gx-cred-generator.py index 3deb3e1..a30a239 100755 --- a/gx-cred-generator.py +++ b/gx-cred-generator.py @@ -3,7 +3,7 @@ # # gx-sd-generator.py """Script to generate Gaia-X JSON-LD for credentials. - Uses openstack-discovery.py and k8s-discovery.py to + Uses openstack-openstack_discovery.py and k8s-openstack_discovery.py to collect the data. (c) Kurt Garloff , 5/2023 diff --git a/k8s-discovery.py b/k8s-discovery.py index b233bfe..282210d 100755 --- a/k8s-discovery.py +++ b/k8s-discovery.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set ts=4 sw=4 et: # -# k8s-discovery.py +# k8s-openstack_discovery.py """ Talk to K8s APIs to discover environment Save discovered information in classes that reflect G-X attributes diff --git a/openstack-discovery.py b/openstack-discovery.py index 97a19e7..dde742f 100755 --- a/openstack-discovery.py +++ b/openstack-discovery.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set ts=4 sw=4 et: # -# openstack-discovery.py +# openstack-openstack_discovery.py """ Talk to OpenStack APIs to discover environment Save discovered information in classes that reflect G-X attributes @@ -474,7 +474,7 @@ def __str__(self): def usage(err=1): "output help" - print("Usage: openstack-discovery.py [options]", file=sys.stderr) + print("Usage: openstack-openstack_discovery.py [options]", file=sys.stderr) print("Options: -j/--json: output GX JSON-LD instead of YAML") print(" -J/--json-compact: output compact GX JSON-LD instead of YAML") print(" -f FILE/--file=FILE: write output to FILE (default: stdout)") diff --git a/tests/test_server_flavor_discovery.py b/tests/test_server_flavor_discovery.py index f3fc269..2b50d29 100644 --- a/tests/test_server_flavor_discovery.py +++ b/tests/test_server_flavor_discovery.py @@ -331,9 +331,9 @@ def _init_gx_flavor( if hv: gx_flavor.hypervisor = Hypervisor( hypervisorType="KVM", - copyrightOwnedBy=self.discovery.get_copyright_owner(const.CONFIG_HV_KVM), - license=self.discovery.get_license(const.CONFIG_HV_KVM), - resourcePolicy=self.discovery.get_resource_policy(const.CONFIG_HV_KVM)) + copyrightOwnedBy=self.discovery.conf.get_copyright_owner(const.CONFIG_HV_KVM), + license=self.discovery.conf.get_license(const.CONFIG_HV_KVM), + resourcePolicy=self.discovery.conf.get_resource_policy(const.CONFIG_HV_KVM)) return gx_flavor From 1b667ec8e1e88670853a48138925e1e4affd2ba1 Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Mon, 8 Apr 2024 15:31:54 +0200 Subject: [PATCH 07/20] Fix typo Signed-off-by: Anja Strunk --- generator/common/config.py | 6 +++--- generator/common/const.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generator/common/config.py b/generator/common/config.py index 1c6fcc2..b3d2fc7 100644 --- a/generator/common/config.py +++ b/generator/common/config.py @@ -23,12 +23,12 @@ def get_value(self, keys: List[str]): return _get_value(self.config, keys) def get_copyright_owner(self, software: str) -> List[str]: - return self.get_value([const.COMFIG_SOFTWARE, software, const.CONFIG_COPYRIGHT]) + return self.get_value([const.CONFIG_SOFTWARE, software, const.CONFIG_COPYRIGHT]) def get_license(self, software: str) -> List[str]: - return self.get_value([const.COMFIG_SOFTWARE, software, const.CONFIG_LICENSE]) + return self.get_value([const.CONFIG_SOFTWARE, software, const.CONFIG_LICENSE]) def get_resource_policy(self, software: str) -> List[str]: return self.get_value( - [const.COMFIG_SOFTWARE, software, const.CONFIG_RESOURCE_POLICY] + [const.CONFIG_SOFTWARE, software, const.CONFIG_RESOURCE_POLICY] ) diff --git a/generator/common/const.py b/generator/common/const.py index 9bd4bec..475539e 100644 --- a/generator/common/const.py +++ b/generator/common/const.py @@ -20,7 +20,7 @@ CONFIG_WALLETS = "wallets" CONFIG_DEFAULT = "default" CONFIG_CLOUD_RESOURCES = "cloud resources:" -COMFIG_SOFTWARE = "software resources" +CONFIG_SOFTWARE = "software resources" CONFIG_FILESYSTEM_WALLET = "filesystem" CONFIG_XFSC_WALLET = "xfsc" From 9257f509fdd36653f74d4485d0cb5e418a651658 Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Mon, 8 Apr 2024 15:41:38 +0200 Subject: [PATCH 08/20] Refactor OsCloud Signed-off-by: Anja Strunk --- .../openstack/openstack_discovery.py | 16 ++++----------- tests/data/empty_credential.json | 12 +++++++++++ tests/test_cli.py | 20 +++++++++++++++++-- 3 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 tests/data/empty_credential.json diff --git a/generator/discovery/openstack/openstack_discovery.py b/generator/discovery/openstack/openstack_discovery.py index 9a6b033..be1e252 100644 --- a/generator/discovery/openstack/openstack_discovery.py +++ b/generator/discovery/openstack/openstack_discovery.py @@ -32,15 +32,7 @@ def discover(self) -> List[JsonLdObject]: @return: all attributes as list @rtype List[JsonLdObject] """ - creds = list() - - vi_dis = VmDiscovery(self.conn, self.config) - images = vi_dis.discover() - if images: - creds.extend(images) - sf_dis = ServerFlavorDiscovery(self.conn, self.config) - flavors = sf_dis.discover() - if flavors: - creds.extend(sf_dis.discover()) - - return creds + return ( + VmDiscovery(self.conn, self.config).discover() + + ServerFlavorDiscovery(self.conn, self.config).discover() + ) \ No newline at end of file diff --git a/tests/data/empty_credential.json b/tests/data/empty_credential.json new file mode 100644 index 0000000..9f29f3b --- /dev/null +++ b/tests/data/empty_credential.json @@ -0,0 +1,12 @@ +{ + "@context": { + "gx": "https://w3id.org/gaia-x/ONTOLOGY_VERSION/", + "qudt": "http://qudt.org/vocab/", + "schema": "http://schema.org/", + "vcard": "http://www.w3.org/2006/vcard/ns#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "ex": "https://example.com/" + }, + "@graph": [ + ] +} \ No newline at end of file diff --git a/tests/test_cli.py b/tests/test_cli.py index 069fabf..4d70387 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -71,8 +71,24 @@ def test_openstack(self, os_connect): self.assertEqual(0, result.exit_code) with open(get_absolute_path("tests/data/credential.json"), "r") as json_file: expected_output = json.load(json_file) - received_outout = json.loads(result.output) - self.assertEqual(expected_output, received_outout) + received_output = json.loads(result.output) + self.assertEqual(expected_output, received_output) + + @patch("openstack.connect") + def test_openstack_empty(self, os_connect): + # Mock openstack calls + os_connect.return_value = MockConnection() + runner = CliRunner() + result = runner.invoke( + cli.openstack, "myCloud --config=" + get_absolute_path(const.CONFIG_FILE) + ) + + self.assertIsNone(result.exception) + self.assertEqual(0, result.exit_code) + with open(get_absolute_path("tests/data/empty_credential.json"), "r") as json_file: + expected_output = json.load(json_file) + received_output = json.loads(result.output) + self.assertEqual(expected_output, received_output) def test_kubernetes(self): # TODO: Implement test case From 3667c3cd4e286ab257f2cc5feb49bdf31ca05e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Tue, 9 Apr 2024 15:45:47 +0200 Subject: [PATCH 09/20] incorporate scs module for flavor-name parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- .../openstack/server_flavor_discovery.py | 253 +++---- generator/vendor/__init__.py | 0 generator/vendor/flavor_names.py | 701 ++++++++++++++++++ 3 files changed, 789 insertions(+), 165 deletions(-) create mode 100644 generator/vendor/__init__.py create mode 100644 generator/vendor/flavor_names.py diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index b0ab5ed..b5063f2 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -5,7 +5,7 @@ """ import re -from typing import List, Tuple +from typing import List, Tuple, Optional from openstack.compute.v2.flavor import Flavor as OS_Flavor from openstack.connection import Connection @@ -25,6 +25,16 @@ ) from generator.common.gx_schema import ServerFlavor as GX_Flavor from generator.common.json_ld import JsonLdObject +from generator.vendor.flavor_names import Flavorname, parser_v3 + + +# map SCS hypervisor names to corresponding GX type and config key +HYPERVISOR_LOOKUP = { + "kvm": ("KVM", const.CONFIG_HV_KVM), + "xen": ("Xen", const.CONFIG_HV_XEN, + "vmw": ("KVM", const.CONFIG_HV_VMW), # FIXME is this correct? + "hyv": ("Hyper-V", const.CONFIG_HV_HYV), +} class ServerFlavorDiscovery: @@ -54,12 +64,16 @@ def _convert_to_gx(self, os_flavor: OS_Flavor) -> GX_Flavor: @rtype ServerFlavor """ + try: + flavorname = parser_v3(os_flavor.name) + except ValueError: + flavorname = None # Initialize Gaia-X Server Flavor - disks = self._get_disks(os_flavor) + disks = self._get_disks(os_flavor, flavorname) gx_flavor = GX_Flavor( # name=os_flavor.name, - cpu=self._get_cpu(os_flavor), - ram=self._get_ram(os_flavor), + cpu=self._get_cpu(os_flavor, flavorname), + ram=self._get_ram(os_flavor, flavorname), bootVolume=disks[0], ) @@ -67,12 +81,12 @@ def _convert_to_gx(self, os_flavor: OS_Flavor) -> GX_Flavor: gx_flavor.additionalVolume = additionalVolume = disks[1:] # Discover optional attributes - self._parse_optional_flavor_properties(os_flavor, gx_flavor) + self._parse_optional_flavor_properties(flavorname, gx_flavor) self._add_description(os_flavor, gx_flavor) return gx_flavor - def _get_cpu(self, os_flavor: OS_Flavor) -> CPU: + def _get_cpu(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> CPU: """ Return Gaia-X compliance CPU specification of given OpenStack flavor. @param os_flavor: OpenStack flavor @@ -81,30 +95,16 @@ def _get_cpu(self, os_flavor: OS_Flavor) -> CPU: @rtype CPU """ cpu = CPU(cpuArchitecture=CpuArch.other, numberOfCores=os_flavor.vcpus) - if os_flavor.name.startswith("SCS-"): - # parse SCS flavor name, second part contains CPU properties - parts = os_flavor.name.split("-") - if len(parts) >= 2 and re.search(r"\d[V,T,C,L]$", parts[1]): - cpu_suffix = parts[1][-1] - cpu.numberOfCores = int(parts[1][-2]) - if cpu_suffix.endswith("i"): - cpu_suffix = parts[1][-2] - cpu.numberOfCores = int(parts[1][-3]) - if cpu_suffix == "C": - cpu.smtEnabled = False - cpu.defaultOversubscriptionRatio = 1 - elif cpu_suffix.endswith("T"): - cpu.smtEnabled = True - cpu.defaultOversubscriptionRatio = 1 - elif cpu_suffix.endswith("V"): - cpu.smtEnabled = True - cpu.defaultOversubscriptionRatio = 5 - elif cpu_suffix.endswith("L"): - cpu.smtEnabled = True - cpu.defaultOversubscriptionRatio = 16 + if flavorname: + cpu.smtEnabled = flavorname.cpuram.cputype != "C" # FIXME this is unclear to me + cpu.defaultOversubscriptionRatio = 1 + if flavorname.cpuram.cputype == "V": + cpu.defaultOversubscriptionRatio = 5 + elif flavorname.cpuram.cputype == "L": + cpu.defaultOversubscriptionRatio = 16 return cpu - def _get_ram(self, os_flavor: OS_Flavor) -> Memory: + def _get_ram(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> Memory: """ Return Gaia-X RAM definition specified in given OpenStack flavor. @param os_flavor: OpenStack Flavor @@ -114,30 +114,13 @@ def _get_ram(self, os_flavor: OS_Flavor) -> Memory: """ size = MemorySize(value=float(os_flavor.ram), unit=const.UNIT_MB) mem = Memory(memorySize=size) - if os_flavor.name.startswith("SCS-"): - # parse SCS flavor name - parts = os_flavor.name.split("-") - if len(parts) >= 3: - mem_cap = parts[2] - if mem_cap.endswith("ou"): - # this order of memory suffixes is not allows - return mem - elif mem_cap.endswith("uo"): - mem.eccEnabled = True - mem.defaultOversubscriptionRatio = 2 - mem.eccEnabled = True - mem.memorySize.value = float(mem_cap[0:-2]) - elif mem_cap.endswith("u"): - mem.eccEnabled = True - mem.memorySize.value = float(mem_cap[0:-1]) - elif mem_cap.endswith("o"): - mem.defaultOversubscriptionRatio = 2 - mem.memorySize.value = float(mem_cap[0:-1]) - else: - mem.memorySize.value = float(mem_cap) + if flavorname: + mem.eccEnabled = not flavorname.cpuram.raminsecure + if flavorname.cpuram.ramoversubscribed: + mem.defaultOversubscriptionRatio = 2 return mem - def _get_disks(self, os_flavor: OS_Flavor) -> List[Disk]: + def _get_disks(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> List[Disk]: """ Return all disk specification found in given Openstack flavor. @param os_flavor: Openstack flavor specification @@ -145,25 +128,26 @@ def _get_disks(self, os_flavor: OS_Flavor) -> List[Disk]: @return: list of Gaia-X disk specifications """ disks = [] - if os_flavor.name.startswith("SCS-"): - # parse SCS flavor name - parts = os_flavor.name.split("-") - if len(parts) < 4: - # either no SCS compliant flavor name or disk spec missing + if flavorname and flavorname.disk: + disk_type = DiskType.other.text + disk_bus_types = DiskType.other.text + if flavorname.disk.disktype == "n": + disk_type = "shared network storage" + elif flavorname.disk.disktype == "h": + disk_type = "local HDD" + elif flavorname.disk.disktype == "s": + disk_type = "local SSD" + elif flavorname.disk.disktype == "p": + disk_type = "local HDD" + disk_bus_types = "NVMe" + for i in range(int(flavorname.disk.nrdisks)): disks.append( - Disk(diskSize=MemorySize(value=os_flavor.disk, unit=const.UNIT_GB)) - ) - else: - # SCS compliant flavor name with spec of disk capabilities - number, size, disk_type, disk_bus_types = self._get_disk_caps(parts[3]) - for i in range(int(number)): - disks.append( - Disk( - diskSize=MemorySize(value=size, unit=const.UNIT_GB), - diskType=disk_type, - diskBusType=disk_bus_types, - ) + Disk( + diskSize=MemorySize(value=flavorname.disk.disksize, unit=const.UNIT_GB), + diskType=disk_type, + diskBusType=disk_bus_types, ) + ) else: # no SCS compliant flavor name. Use disk property to set disk spec disks.append( @@ -172,45 +156,8 @@ def _get_disks(self, os_flavor: OS_Flavor) -> List[Disk]: return disks - def _get_disk_caps(self, disk_caps: str) -> Tuple[int, int, DiskType, DiskBusType]: - """ - Extracts disk capabilities encoded in flavor name according to SCS flavor naming standard. - @param disk_caps: Disk capabilities encoded as string according to SCS flavor naming standard. - @type disk_caps: str - @return: - """ - disk_type = DiskType.other.text - disk_bus_types = DiskType.other.text - number = 1 - - # parse disk type and disk bus type - if re.search(r"\d+$", disk_caps): - # no disk type set - size = disk_caps[0 : len(disk_caps)] - else: - # disk type set - size = disk_caps[0 : len(disk_caps) - 1] - # parse disk type and disk bus type - if disk_caps.endswith("n"): - disk_type = "shared network storage" - elif disk_caps.endswith("h"): - disk_type = "local HDD" - elif disk_caps.endswith("s"): - disk_type = "local SSD" - elif disk_caps.endswith("p"): - disk_type = "local HDD" - disk_bus_types = "NVMe" - try: - number, size = size.split("x") - except ValueError: - if len(size) == 0: - # no size set - size = 0 - - return int(number), int(size), DiskType(disk_type), DiskBusType(disk_bus_types) - def _parse_optional_flavor_properties( - self, os_flavor: OS_Flavor, gx_flavor: GX_Flavor + self, flavorname: Optional[Flavorname], gx_flavor: GX_Flavor ): """Parse and return optional flavor properties, such as CPU architecture, CPU frequency or hypervisor. @param os_flavor Openstack flavor @@ -218,92 +165,68 @@ def _parse_optional_flavor_properties( @param gx_flavor Gaia-X Flavor specification @type gx_flavor ServerFlavor """ - parts = os_flavor.name.split("_") - for suffix in parts: - if suffix.startswith("SCS"): - continue - # parse hypervisor - elif suffix == "kvm": - gx_flavor.hypervisor = Hypervisor( - hypervisorType="KVM", - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_HV_KVM), - license=self.conf.get_license(const.CONFIG_HV_KVM), - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_HV_KVM), - ) - elif suffix == "xen": - gx_flavor.hypervisor = Hypervisor( - hypervisorType="Xen", - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_HV_XEN), - license=self.conf.get_license(const.CONFIG_HV_XEN), - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_HV_XEN), - ) - elif suffix == "vmw": - gx_flavor.hypervisor = Hypervisor( - hypervisorType="KVM", - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_HV_VMW), - license=self.conf.get_license(const.CONFIG_HV_VMW), - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_HV_VMW), - ) - elif suffix == "hyv": - gx_flavor.hypervisor = Hypervisor( - hypervisorType="Hyper-V", - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_HV_HYV), - license=self.conf.get_license(const.CONFIG_HV_HYV), - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_HV_HYV), - ) - # parse hardware assisted virtualization - elif suffix == "hwv": - gx_flavor.hardwareAssistedVirtualization = True - # parse CPU architecture details - elif suffix.startswith("i"): + if flavorname is None: + return + if flavorname.hype and flavorname.hype.hype in HYPERVISOR_LOOKUP: + hv_type, conf_key = HYPERVISOR_LOOKUP[flavorname.hype.hype] + gx_flavor.hypervisor = Hypervisor( + hypervisorType=hv_type, + copyrightOwnedBy=self.conf.get_copyright_owner(conf_key), + license=self.conf.get_license(conf_key), + resourcePolicy=self.conf.get_resource_policy(conf_key), + ) + if flavorname.hwvirt and flavorname.hwvirt.hwvirt: + gx_flavor.hardwareAssistedVirtualization = True + if flavorname.cpubrand: + if flavorname.cpubrand.cpuvendor == "i": # Intel x86-64 gx_flavor.cpu.cpuArchitecture = CpuArch("x86-64") gx_flavor.cpu.vendor = "Intel" - if suffix.startswith("i0"): + if flavorname.cpubrand.cpugen == 0: gx_flavor.cpu.generation = "pre Skylake" - elif suffix.startswith("i1"): + elif flavorname.cpubrand.cpugen == 1: gx_flavor.cpu.generation = "Skylake" - elif suffix.startswith("i2"): + elif flavorname.cpubrand.cpugen == 2: gx_flavor.cpu.generation = "Cascade Lake" - elif suffix.startswith("i3"): - gx_flavor.cpu.generation = "Ice Lake" - elif suffix.startswith("i4"): + elif flavorname.cpubrand.cpugen == 3: gx_flavor.cpu.generation = "Ice Lake" - elif suffix.startswith("z"): + elif flavorname.cpubrand.cpugen == 4: + gx_flavor.cpu.generation = "Ice Lake" # FIXME is this correct? (Sapphire Rapids) + elif flavorname.cpubrand.cpuvendor == "z": # AMD (Zen) x86-64 gx_flavor.cpu.cpuArchitecture = CpuArch("x86-64") gx_flavor.cpu.vendor = "AMD" - if suffix.startswith("z0"): + if flavorname.cpubrand.cpugen == 0: gx_flavor.cpu.generation = "pre Zen" - elif suffix.startswith("z1"): + elif flavorname.cpubrand.cpugen == 1: gx_flavor.cpu.generation = "Zen-1 (Naples)" - elif suffix.startswith("z2"): - gx_flavor.cpu.generation = "Zen-2 (Rome" - elif suffix.startswith("z3"): + elif flavorname.cpubrand.cpugen == 2: + gx_flavor.cpu.generation = "Zen-2 (Rome" # FIXME is this correct? (closing paren) + elif flavorname.cpubrand.cpugen == 3: gx_flavor.cpu.generation = "Zen-3 (Milan)" - elif suffix.startswith("z4"): + elif flavorname.cpubrand.cpugen == 4: gx_flavor.cpu.generation = "Zen-4 (Genoa)" - elif suffix.startswith("a"): + elif flavorname.cpubrand.cpuvendor == "a": # ARM v8+ gx_flavor.cpu.cpuArchitecture = CpuArch("AArch-64") gx_flavor.cpu.vendor = "ARM" - if suffix.startswith("a0"): + if flavorname.cpubrand.cpugen == 0: gx_flavor.cpu.generation = "pre Cortex A76" - elif suffix.startswith("a1"): + elif flavorname.cpubrand.cpugen == 1: gx_flavor.cpu.generation = "A76/NeoN1 class" - elif suffix.startswith("a2"): + elif flavorname.cpubrand.cpugen == 2: gx_flavor.cpu.generation = "A78/x1/NeoV1 class" - elif suffix.startswith("a3"): + elif flavorname.cpubrand.cpugen == 3: gx_flavor.cpu.generation = "A71x/NeoN2 (ARMv9)" - elif suffix.startswith("r"): + elif flavorname.cpubrand.cpuvendor == "r": # RISC-V gx_flavor.cpu.cpuArchitecture = CpuArch("RISC-V") # parse frequency - if suffix.endswith("hhh"): + if suffix.perf == "hhh": gx_flavor.cpu.baseFrequency = Frequency(value=3.75, unit=const.UNIT_GHZ) - elif suffix.endswith("hh"): + elif suffix.perf == "hh": gx_flavor.cpu.baseFrequency = Frequency(value=3.25, unit=const.UNIT_GHZ) - elif suffix.endswith("h"): + elif suffix.perf == "h": gx_flavor.cpu.baseFrequency = Frequency(value=2.75, unit=const.UNIT_GHZ) def _add_description(self, os_flavor: OS_Flavor, gx_flavor: GX_Flavor) -> None: diff --git a/generator/vendor/__init__.py b/generator/vendor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/generator/vendor/flavor_names.py b/generator/vendor/flavor_names.py new file mode 100644 index 0000000..4d13ebf --- /dev/null +++ b/generator/vendor/flavor_names.py @@ -0,0 +1,701 @@ +#!/usr/bin/env python3 +import os +import os.path +import re +import sys +from pathlib import Path +from typing import Optional + +import yaml + + +CPUTYPE_KEY = {'L': 'crowded-core', 'V': 'shared-core', 'T': 'dedicated-thread', 'C': 'dedicated-core'} +DISKTYPE_KEY = {'n': 'network', 'h': 'hdd', 's': 'ssd', 'p': 'nvme'} +HERE = Path(__file__).parent + + +class TypeCheck: + """class for validating the type of some attribute within a flavor name""" + def __call__(self, attr: str, value): + raise ValueError(f"{attr} can not be set to {value}") + + +class OptionalCheck(TypeCheck): + def __init__(self, check): + self.check = check + + def __call__(self, attr, value): + if value is None: + return + self.check(attr, value) + + +class TblCheck(TypeCheck): + def __init__(self, tbl): + self.tbl = tbl + + def __call__(self, attr, value): + if value not in self.tbl: + raise ValueError(f"{attr} can not be set to {value!r}; must be one of {tuple(self.tbl)}") + + +class BoolCheck(TypeCheck): + def __call__(self, attr, value): + if not isinstance(value, bool): + raise ValueError(f"{attr} can not be set to {value!r}; must be boolean") + + +class IntCheck(TypeCheck): + def __call__(self, attr, value): + if not isinstance(value, int) or value <= 0: + raise ValueError(f"{attr} can not be set to {value!r}; must be positive integer") + + +class FloatCheck(TypeCheck): + def __call__(self, attr, value): + if not isinstance(value, float) or value <= 0 or int(2 * value) != 2 * value: + raise ValueError(f"{attr} can not be set to {value!r}; must be positive multiple of 0.5") + + +class Attr: + """class to represent one attribute, such as brand, of one component, such as gpu, of a flavor name""" + typ = None + default = None + + @staticmethod + def collect(cls): + """return all instances of `Attr` in the dict of given cls""" + return [att for att in cls.__dict__.values() if isinstance(att, Attr)] + + def __init__(self, name, default=None, letter=None): + self.name = name + self.letter = letter + if default != self.default: + self.default = default # instance attribute will override class attibute + # the following will be set automatically via __set_name__ + self.attr = None + self._attr = None + + def get_tbl(self, obj): + return None + + def validate(self, val): + if self.typ is None: + return + self.typ(self.attr, val) + + # the following methods make this class a `Descriptor`, + # see + + def __set_name__(self, owner, name): + if self.letter is None: + self.letter = name + self.attr = name + self._attr = '_' + name + + def __get__(self, obj, objclass=None): + if obj is None: + return self + return getattr(obj, self._attr, self.default) + + def __set__(self, obj, value): + self.validate(value) + setattr(obj, self._attr, value) + + +class IntAttr(Attr): + typ = IntCheck() + + +class OptIntAttr(Attr): + typ = OptionalCheck(IntCheck()) + + +class FloatAttr(Attr): + typ = FloatCheck() + + +class BoolAttr(Attr): + typ = BoolCheck() + + +class TblAttr(Attr): + def __init__(self, name, tbl, default=None): + super().__init__(name, default) + self.tbl = tbl + self.typ = TblCheck(tbl) + + def get_tbl(self, obj): + return self.tbl + + +class DepTblAttr(Attr): + def __init__(self, name, key_attr, deptbl, default=None): + super().__init__(name, default) + self.key_attr = key_attr + self.deptbl = deptbl + self.typs = {key: TblCheck(tbl) for key, tbl in deptbl.items()} + + def get_tbl(self, obj): + return self.deptbl.get(self.key_attr.__get__(obj)) + + def __set__(self, obj, value): + self.typs[self.key_attr.__get__(obj)](self.attr, value) + super().__set__(obj, value) + + +class Main: + """Class representing the first part (CPU+RAM)""" + type = "CPU-RAM" + component_name = "cpuram" + cpus = IntAttr("#vCPUs") + cputype = TblAttr("CPU type", {"L": "LowPerf vCPUs", "V": "vCPUs", "T": "SMT Threads", "C": "Dedicated Cores"}) + cpuinsecure = BoolAttr("?Insec SMT", letter="i") + ram = FloatAttr("##GiB RAM") + raminsecure = BoolAttr("?no ECC", letter="u") + ramoversubscribed = BoolAttr("?RAM Over", letter="o") + + +class Disk: + """Class representing the disk part""" + type = "Disk" + component_name = "disk" + nrdisks = IntAttr("#.NrDisks", default=1) + disksize = OptIntAttr("#.GB Disk") + disktype = TblAttr("Disk type", {'': '(unspecified)', "n": "Networked", "h": "Local HDD", "s": "SSD", "p": "HiPerf NVMe"}) + + +class Hype: + """Class repesenting Hypervisor""" + type = "Hypervisor" + component_name = "hype" + hype = TblAttr(".Hypervisor", {"kvm": "KVM", "xen": "Xen", "hyv": "Hyper-V", "vmw": "VMware", "bms": "Bare Metal System"}) + + +class HWVirt: + """Class repesenting support for hardware virtualization""" + type = "Hardware/NestedVirtualization" + component_name = "hwvirt" + hwvirt = BoolAttr("?HardwareVirt", letter="hwv") + + +class CPUBrand: + """Class repesenting CPU brand""" + type = "CPUBrand" + component_name = "cpubrand" + cpuvendor = TblAttr("CPU Vendor", {"i": "Intel", "z": "AMD", "a": "ARM", "r": "RISC-V"}) + cpugen = DepTblAttr("#.CPU Gen", cpuvendor, { + "i": {None: '(unspecified)', 0: "Unspec/Pre-Skylake", 1: "Skylake", 2: "Cascade Lake", 3: "Ice Lake", 4: "Sapphire Rapids"}, + "z": {None: '(unspecified)', 0: "Unspec/Pre-Zen", 1: "Zen 1", 2: "Zen 2", 3: "Zen 3", 4: "Zen 4"}, + "a": {None: '(unspecified)', 0: "Unspec/Pre-A76", 1: "A76/NeoN1", 2: "A78/X1/NeoV1", 3: "A710/NeoN2"}, + }) + perf = TblAttr("Performance", {"": "Std Perf", "h": "High Perf", "hh": "Very High Perf", "hhh": "Very Very High Perf"}) + + +class GPU: + """Class repesenting GPU support""" + type = "GPU" + component_name = "gpu" + gputype = TblAttr("Type", {"g": "vGPU", "G": "Pass-Through GPU"}) + brand = TblAttr("Brand", {"N": "nVidia", "A": "AMD", "I": "Intel"}) + gen = DepTblAttr("Gen", brand, { + "N": {'': '(unspecified)', "f": "Fermi", "k": "Kepler", "m": "Maxwell", "p": "Pascal", + "v": "Volta", "t": "Turing", "a": "Ampere", "l": "AdaLovelace"}, + "A": {'': '(unspecified)', "0.4": "GCN4.0/Polaris", "0.5": "GCN5.0/Vega", "1": "RDNA1/Navi1x", "2": "RDNA2/Navi2x", "3": "RDNA3/Navi3x"}, + "I": {'': '(unspecified)', "0.9": "Gen9/Skylake", "0.95": "Gen9.5/KabyLake", "1": "Xe1/Gen12.1", "2": "Xe2"}, + }) + cu = OptIntAttr("#.CU/EU/SM") + perf = TblAttr("Performance", {"": "Std Perf", "h": "High Perf", "hh": "Very High Perf", "hhh": "Very Very High Perf"}) + + +class IB: + """Class representing Infiniband""" + type = "Infiniband" + component_name = "ib" + ib = BoolAttr("?IB") + + +class Flavorname: + """A flavor name; merely a bunch of components""" + def __init__( + self, cpuram: Main = None, disk: Disk = None, hype: Hype = None, hwvirt: HWVirt = None, + cpubrand: CPUBrand = None, gpu: GPU = None, ib: IB = None + ): + self.cpuram = cpuram + self.disk = disk + self.hype = hype + self.hwvirt = hwvirt + self.cpubrand = cpubrand + self.gpu = gpu + self.ib = ib + + def shorten(self): + """return canonically shortened name as recommended in the standard""" + if self.hype is None and self.hwvirt is None and self.cpubrand is None: + return self + return Flavorname(cpuram=self.cpuram, disk=self.disk, gpu=self.gpu, ib=self.ib) + + +class Outputter: + """ + Auxiliary class for serializing `Flavorname` instances. + + Use the global instance `outputter` (defined below) like so: `namestr = outputter(flavorname)`. + + Using templating language similar to % formatting: + %? outputs attribute's letter if the attribute is True, otherwise nothing + %f gets converted to %.0f if the number is an integer, otherwise %.1f + %x gets converted to %ix if the number is not the default, otherwise it's left out + %0 gets converted to %i if the number is non-null and != 0, otherwise it's left out + %- gets converted to -%i if number is non-null, otherwise left out + """ + + prefix = "SCS-" + cpuram = "%i%s%?-%f%?%?" + disk = "-%x%0%s" + hype = "_%s" + hwvirt = "_%?" + cpubrand = "_%s%0%s" + gpu = "_%s%s%s%-%s" + ib = "_%?" + + def output_component(self, pattern, component, parts): + if component is None: + return + attr_iter = iter(Attr.collect(component.__class__)) + i = 0 + while i < len(pattern): + j = pattern.find("%", i) + parts.append(pattern[i:j]) + if j == -1: + break + i = j + 1 # skip % + attr = next(attr_iter) + value = attr.__get__(component) + if pattern[i] == "?": + if value: + parts.append(attr.letter) + elif pattern[i] in ("s", "i"): + parts.append(str(value)) + elif pattern[i] == "0": + if value is not None and value != 0: + parts.append(str(value)) + elif pattern[i] == "-": + if value: + parts.append(f"-{value}") + elif pattern[i] == "x": + if value != attr.default: + parts.append(f"{value}x") + elif pattern[i] == "f": + if value == int(value): + parts.append(f"{value:.0f}") + else: + parts.append(f"{value:.1f}") + else: + print(pattern, i) + raise RuntimeError("Pattern problem") + i += 1 + + def __call__(self, flavorname: Flavorname) -> str: + parts = [self.prefix] + self.output_component(self.cpuram, flavorname.cpuram, parts) + self.output_component(self.disk, flavorname.disk, parts) + self.output_component(self.hype, flavorname.hype, parts) + self.output_component(self.hwvirt, flavorname.hwvirt, parts) + self.output_component(self.cpubrand, flavorname.cpubrand, parts) + self.output_component(self.gpu, flavorname.gpu, parts) + self.output_component(self.ib, flavorname.ib, parts) + return "".join(parts) + + +class SyntaxV1: + """ + This class bundles the regular expressions that comprise the syntax for v1 of the standard. + """ + prefix = "SCS-" + cpuram = re.compile(r"([0-9]*)([LVTC])(i|):([0-9\.]*)(u|)(o|)") + disk = re.compile(r":(?:([0-9]*)x|)([0-9]*)([nhsp]|)") + hype = re.compile(r"\-(kvm|xen|vmw|hyv|bms)") + hwvirt = re.compile(r"\-(hwv)") + # cpubrand needs final lookahead assertion to exclude confusion with _ib extension + cpubrand = re.compile(r"\-([izar])([0-9]*)(h*)(?=$|\-)") + gpu = re.compile(r"\-([gG])([NAI])([^:h]*)(?::([0-9]+)|)(h*)") + ib = re.compile(r"\-(ib)") + + @staticmethod + def from_v2(nm: str) -> str: + """v2 to v1 flavor name transformation""" + return nm.replace('-', ':').replace('_', '-').replace('SCS:', 'SCS-') + + +class SyntaxV2: + """ + This class bundles the regular expressions that comprise the syntax for v2 of the standard. + + The change vs. v1 concerns the delimiters only and is best understood by looking at + the classmethods `SyntaxV2.from_v1` and `SyntaxV1.from_v2`. + + Note that the syntax hasn't changed since v2, so this class is still valid. + """ + prefix = "SCS-" + cpuram = re.compile(r"([0-9]*)([LVTC])(i|)\-([0-9\.]*)(u|)(o|)") + disk = re.compile(r"\-(?:([0-9]*)x|)([0-9]*)([nhsp]|)") + hype = re.compile(r"_(kvm|xen|vmw|hyv|bms)") + hwvirt = re.compile(r"_(hwv)") + # cpubrand needs final lookahead assertion to exclude confusion with _ib extension + cpubrand = re.compile(r"_([izar])([0-9]*)(h*)(?=$|_)") + gpu = re.compile(r"_([gG])([NAI])([^\-h]*)(?:\-([0-9]+)|)(h*)") + ib = re.compile(r"_(ib)") + + @staticmethod + def from_v1(nm: str) -> str: + """v1 to v2 flavor name transformation""" + return nm.replace('-', '_').replace(':', '-').replace('SCS_', 'SCS-') + + +class ParseCtx: + """Auxiliary class used during parsing to hold current position in the string""" + def __init__(self, s: str, pos=0): + self.s = s + self.pos = pos + + +class ComponentParser: + """Auxiliary class for parsing a single component of a flavor name""" + def __init__(self, parsestr: re.Pattern, targetcls): + self.parsestr = parsestr # re.Pattern as defined in `SyntaxV1` or `SyntaxV2` + self.targetcls = targetcls # component class such as `Main` or `Disk` + + def parse(self, ctx: ParseCtx): + m = self.parsestr.match(ctx.s, ctx.pos) + if m is None: + return + match_attr = Attr.collect(self.targetcls) + groups = m.groups() + if len(groups) != len(match_attr): + raise ValueError(f"unexpected number of matching groups: {match_attr} vs {groups}") + t = self.targetcls() + for attr, group in zip(match_attr, groups): + if attr.name[:2] == "##": + attr.__set__(t, float(group)) + elif attr.name[:1] == "#": + attr.__set__(t, int(group) if group else attr.default) + elif attr.name[:1] == "?": + attr.__set__(t, bool(group)) + else: + attr.__set__(t, group) + ctx.pos += len(m.group(0)) + return t + + +class Parser: + """ + Auxiliary class for parsing flavorname strings. + + Use the global instances `parser_v1` and `parser_v2` (defined below) like so: + `flavorname = parser_v2(namestr)`. + """ + + def __init__(self, vstr, syntax): + self.vstr = vstr + self.prefix = syntax.prefix + self.cpuram = ComponentParser(syntax.cpuram, Main) + self.disk = ComponentParser(syntax.disk, Disk) + self.hype = ComponentParser(syntax.hype, Hype) + self.hwvirt = ComponentParser(syntax.hwvirt, HWVirt) + self.cpubrand = ComponentParser(syntax.cpubrand, CPUBrand) + self.gpu = ComponentParser(syntax.gpu, GPU) + self.ib = ComponentParser(syntax.ib, IB) + + def __call__(self, s: str, pos=0) -> Flavorname: + if not s[pos:].startswith(self.prefix): + return + ctx = ParseCtx(s, pos + len(self.prefix)) + flavorname = Flavorname() + flavorname.cpuram = self.cpuram.parse(ctx) + if flavorname.cpuram is None: + raise ValueError("Failed to parse main part") + flavorname.disk = self.disk.parse(ctx) + flavorname.hype = self.hype.parse(ctx) + flavorname.hwvirt = self.hwvirt.parse(ctx) + flavorname.cpubrand = self.cpubrand.parse(ctx) + flavorname.gpu = self.gpu.parse(ctx) + flavorname.ib = self.ib.parse(ctx) + if ctx.pos != len(s): + raise ValueError(f"Extra characters: {s[ctx.pos:]}") + return flavorname + + +def _convert_user_input(idx, attr, target, val): + """auxiliary function that converts user-input string `val` to the target attribute type""" + fdesc = attr.name + tbl = attr.get_tbl(target) + if not val and idx == 0 and not isinstance(target, (Main, Disk)): + # BAIL: if you don't want an extension, supply empty first attr + return val + if fdesc[0] == "?": + val = val.upper() + if val == "" or val == "OFF" or val == "0" or val[0] == "N" or val[0] == "F": + val = False + elif val == "1" or val == "ON" or val[0] == "Y" or val[0] == "T": + val = True + else: + raise ValueError + elif fdesc[0:2] == "##": + val = float(val) + elif fdesc[0] == "#": + if fdesc[1] == "." and not val: + val = attr.default + else: + oval = val + val = int(val) + if str(val) != oval: + raise ValueError(val) + elif tbl: + if val in tbl: + pass + elif val.upper() in tbl: + val = val.upper() + elif val.lower() in tbl: + val = val.lower() + else: + raise ValueError(f"{val!r} not in {tbl}") + return val + + +def ask_user_input(idx, attr, target): + """strategy function for `Inputter` class: ask user for input""" + fdesc = attr.name + tbl = attr.get_tbl(target) + if idx == 0: + print(target.type) + if tbl: + print(f" {fdesc} Options:") + for key, v in tbl.items(): + print(f" {'' if key is None else key}: {v}") + while True: + print(f" {fdesc}: ", end="") + val = input() + try: + val = _convert_user_input(idx, attr, target, val) + except BaseException as exc: + print(" " + str(exc)) + print(" INVALID!") + else: + break + return val + + +def lookup_user_input(formdata, idx, attr, target): + """strategy function for `Inputter` class: look up input in `formdata` dict + + Use like so: `form_inputter = Inputter(partial(lookup_user_input, formdata))` + """ + val = formdata.get(f"{target.component_name}.{attr.attr}") + if val is None or val == "NN": + val = "" + return _convert_user_input(idx, attr, target, val) + + +class Inputter: + """Auxiliary class for interactive input of flavor names.""" + def __init__(self, obtain_input=ask_user_input): + self.ask_user_input = staticmethod(obtain_input) + + def input_component(self, targetcls): + target = targetcls() + attrs = [att for att in targetcls.__dict__.values() if isinstance(att, Attr)] + for idx, attr in enumerate(attrs): + val = self.ask_user_input(idx, attr, target) + if not val and idx == 0 and not isinstance(target, (Main, Disk)): + # BAIL: if you don't want an extension, supply empty first attr + return + attr.__set__(target, val) + return target + + def __call__(self): + flavorname = Flavorname() + flavorname.cpuram = self.input_component(Main) + flavorname.disk = self.input_component(Disk) + if flavorname.disk and not (flavorname.disk.nrdisks and flavorname.disk.disksize): + # special case... + flavorname.disk = None + flavorname.hype = self.input_component(Hype) + flavorname.hwvirt = self.input_component(HWVirt) + flavorname.cpubrand = self.input_component(CPUBrand) + flavorname.gpu = self.input_component(GPU) + flavorname.ib = self.input_component(IB) + return flavorname + + +parser_v1 = Parser("v1", SyntaxV1) +parser_v2 = Parser("v2", SyntaxV2) +parser_v3 = Parser("v3", SyntaxV2) # this is the same as parser_v2 except for the vstr +outname = outputter = Outputter() +inputflavor = inputter = Inputter() + + +def flavorname_to_dict(flavorname: Flavorname) -> dict: + name_v2 = outputter(flavorname) + result = { + 'cpus': flavorname.cpuram.cpus, + 'cpu-type': CPUTYPE_KEY[flavorname.cpuram.cputype], + 'ram': flavorname.cpuram.ram, + 'name-v1': SyntaxV1.from_v2(name_v2), + 'name-v2': name_v2, + } + if flavorname.disk: + result['disk'] = flavorname.disk.disksize + for i in range(flavorname.disk.nrdisks): + result[f'disk{i}-type'] = DISKTYPE_KEY[flavorname.disk.disktype or 'n'] + return result + + +def _collectattrs(alist, new): + "collect list of attitbutes" + if alist: + alist += f", {new}" + else: + alist = new + return alist + + +def _tbl_out(item, kind, check=False): + """Look up table value (attach space), skip if entry is 0 or empty string and check is set""" + val = getattr(item, kind) + if check and not val: + return "" + try: + return getattr(item.__class__, kind).get_tbl(item)[val] + " " + except KeyError: + return str(val) + " " + + +def prettyname(flavorname, prefix=""): + """Output a human-readable flavor description""" + # CPU (number, type, attributes) + stg = f"{prefix}SCS flavor with {flavorname.cpuram.cpus} " + if flavorname.cpubrand: + stg += _tbl_out(flavorname.cpubrand, "perf", True) + stg += _tbl_out(flavorname.cpubrand, "cpuvendor") + stg += _tbl_out(flavorname.cpubrand, "cpugen", True) + else: + stg += "generic x86-64 " + stg += _tbl_out(flavorname.cpuram, "cputype") + if flavorname.cpuram.cpuinsecure: + stg += "(insecure) " + # RAM (amount, attributes) + stg += f"with {flavorname.cpuram.ram} GiB RAM " + alist = "" + if flavorname.cpuram.raminsecure: + alist = _collectattrs(alist, "noECC") + if flavorname.cpuram.ramoversubscribed: + alist = _collectattrs(alist, "oversubscribed") + if alist: + stg += f"({alist}) " + # Hypervisor, HVirt + if flavorname.hype: + stg += f'on {_tbl_out(flavorname.hype, "hype")}' + if flavorname.hwvirt: + stg += 'with HW virt ' + # Disk + if flavorname.disk: + stg += "and " + stg += _tbl_out(flavorname.disk, "disktype", True) + if flavorname.disk.nrdisks != 1: + stg += f'{flavorname.disk.nrdisks}x' + stg += f'{flavorname.disk.disksize}GB root volume ' + # GPU + if flavorname.gpu: + stg += "and " + _tbl_out(flavorname.gpu, "gputype") + stg += _tbl_out(flavorname.gpu, "brand") + stg += _tbl_out(flavorname.gpu, "perf", True) + stg += _tbl_out(flavorname.gpu, "gen", True) + if flavorname.gpu.cu is not None: + stg += f"(w/ {flavorname.gpu.cu} CU/EU/SM) " + # IB + if flavorname.ib: + stg += "and Infiniband " + return stg[:-1] + + +class CompatLayer: + """ + This class provides convenience functions previously found in `flavor-name-check.py`. + """ + def __init__(self): + self.verbose = False + self.debug = False + self.quiet = False + self.disallow_old = False + self.prefer_old = False + self.v3_flv = False + self.mandFlavorFile = str(Path(HERE.parent, "SCS-Spec.MandatoryFlavors.yaml")) + bindir = os.path.basename(sys.argv[0]) + self.searchpath = (bindir, ) if bindir else os.environ['PATH'].split(':') + + def parsename(self, namestr: str) -> Optional[Flavorname]: + """ + Parse flavor name: returns None (if non-SCS) or Flavorname instance + raises exception if name appears SCS, but not conforming to syntax + """ + is_old = False + try: + flavorname = parser_v2(namestr) + except Exception: + if self.disallow_old: + raise + # v2 didn't work; try v1, but if that doesn't work either, raise original exception + try: + flavorname = parser_v1(namestr) + except Exception: + pass + else: + is_old = True + if not is_old: + raise + if not self.quiet and flavorname is not None and self.prefer_old != is_old: + print(f"WARNING: flavor name not v{2 - self.prefer_old}: {namestr}") + return flavorname + + def outname(self, flavorname): + return outname(flavorname) + + def old_to_new(self, nm): + return SyntaxV2.from_v1(nm) + + def new_to_old(self, nm): + return SyntaxV1.from_v2(nm) + + def findflvfile(self, fnm): + """Search for flavor file and return found path""" + if os.path.isfile(fnm): + return fnm + raise RuntimeError(f"Flavor yaml file not found: {fnm}") + + def readflavors(self, fnm, v3mode): + """Read mandatory and recommended flavors from passed YAML file""" + fnm = self.findflvfile(fnm) + if self.debug: + print(f"DEBUG: Reading flavors from {fnm}") + with open(fnm, "r", encoding="UTF-8)") as fobj: + yamldict = yaml.safe_load(fobj) + # Translate to old names in-place + if self.prefer_old: + for name_type in yamldict["SCS-Spec"].values(): + for i, name in enumerate(name_type): + name_type[i] = self.new_to_old(name) + mand = yamldict["SCS-Spec"]["MandatoryFlavors"] + recd = yamldict["SCS-Spec"]["RecommendedFlavors"] + if v3mode: + mand.extend(yamldict["SCS-Spec"].get("MandatoryFlavorsV3", ())) + recd.extend(yamldict["SCS-Spec"].get("RecommendedFlavorsV3", ())) + return mand, recd + else: + return [*mand, *recd], [] + + +if __name__ == "__main__": + namestr = "SCS-16T-64-3x10s_bms_hwv_i3h_GNa-64_ib" + print(outputter(parser_v1("SCS-16T:64:3x10s-GNa:64-ib")) == outputter(parser_v2(namestr).shorten())) + print(namestr == outputter(parser_v2(namestr))) From fc46bfa123fd4c27ffeb8c7003fca44e4f2fad75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Wed, 10 Apr 2024 10:00:43 +0200 Subject: [PATCH 10/20] Minor improvements on previous commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- .../openstack/server_flavor_discovery.py | 94 ++++++++----------- 1 file changed, 40 insertions(+), 54 deletions(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index b5063f2..4724cb5 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -4,8 +4,7 @@ SPDX-License-Identifier: EPL-2.0 """ -import re -from typing import List, Tuple, Optional +from typing import List, Optional from openstack.compute.v2.flavor import Flavor as OS_Flavor from openstack.connection import Connection @@ -16,7 +15,6 @@ from generator.common.gx_schema import Architectures as CpuArch from generator.common.gx_schema import ( Disk, - DiskBusType, DiskType, Frequency, Hypervisor, @@ -31,10 +29,37 @@ # map SCS hypervisor names to corresponding GX type and config key HYPERVISOR_LOOKUP = { "kvm": ("KVM", const.CONFIG_HV_KVM), - "xen": ("Xen", const.CONFIG_HV_XEN, + "xen": ("Xen", const.CONFIG_HV_XEN), "vmw": ("KVM", const.CONFIG_HV_VMW), # FIXME is this correct? "hyv": ("Hyper-V", const.CONFIG_HV_HYV), } +# map SCS cpu vendor/architecture letter to architecture, vendor and list of generations +CPUVENDOR_LOOKUP = { + # Intel x86-64 + "i": ( + "x86-64", + "Intel", + ("pre Skylake", "Skylake", "Cascade Lake", "Ice Lake", "Sapphire Rapids"), + ), + # AMD (Zen) x86-64 + "z": ( + "x86-64", + "AMD", + ("pre Zen", "Zen-1 (Naples)", "Zen-2 (Rome)", "Zen-3 (Milan)", "Zen-4 (Genoa)"), + ), + # ARM v8+ + "a": ( + "AArch-64", + "ARM", + ("pre Cortex A76", "A76/NeoN1 class", "A78/x1/NeoV1 class", "A71x/NeoN2 (ARMv9)"), + ), + # RISC-V + "r": ( + "RISC-V", + None, + (), + ), +} class ServerFlavorDiscovery: @@ -78,7 +103,7 @@ def _convert_to_gx(self, os_flavor: OS_Flavor) -> GX_Flavor: ) if len(disks) > 1: - gx_flavor.additionalVolume = additionalVolume = disks[1:] + gx_flavor.additionalVolume = disks[1:] # Discover optional attributes self._parse_optional_flavor_properties(flavorname, gx_flavor) @@ -178,56 +203,17 @@ def _parse_optional_flavor_properties( if flavorname.hwvirt and flavorname.hwvirt.hwvirt: gx_flavor.hardwareAssistedVirtualization = True if flavorname.cpubrand: - if flavorname.cpubrand.cpuvendor == "i": - # Intel x86-64 - gx_flavor.cpu.cpuArchitecture = CpuArch("x86-64") - gx_flavor.cpu.vendor = "Intel" - if flavorname.cpubrand.cpugen == 0: - gx_flavor.cpu.generation = "pre Skylake" - elif flavorname.cpubrand.cpugen == 1: - gx_flavor.cpu.generation = "Skylake" - elif flavorname.cpubrand.cpugen == 2: - gx_flavor.cpu.generation = "Cascade Lake" - elif flavorname.cpubrand.cpugen == 3: - gx_flavor.cpu.generation = "Ice Lake" - elif flavorname.cpubrand.cpugen == 4: - gx_flavor.cpu.generation = "Ice Lake" # FIXME is this correct? (Sapphire Rapids) - elif flavorname.cpubrand.cpuvendor == "z": - # AMD (Zen) x86-64 - gx_flavor.cpu.cpuArchitecture = CpuArch("x86-64") - gx_flavor.cpu.vendor = "AMD" - if flavorname.cpubrand.cpugen == 0: - gx_flavor.cpu.generation = "pre Zen" - elif flavorname.cpubrand.cpugen == 1: - gx_flavor.cpu.generation = "Zen-1 (Naples)" - elif flavorname.cpubrand.cpugen == 2: - gx_flavor.cpu.generation = "Zen-2 (Rome" # FIXME is this correct? (closing paren) - elif flavorname.cpubrand.cpugen == 3: - gx_flavor.cpu.generation = "Zen-3 (Milan)" - elif flavorname.cpubrand.cpugen == 4: - gx_flavor.cpu.generation = "Zen-4 (Genoa)" - elif flavorname.cpubrand.cpuvendor == "a": - # ARM v8+ - gx_flavor.cpu.cpuArchitecture = CpuArch("AArch-64") - gx_flavor.cpu.vendor = "ARM" - if flavorname.cpubrand.cpugen == 0: - gx_flavor.cpu.generation = "pre Cortex A76" - elif flavorname.cpubrand.cpugen == 1: - gx_flavor.cpu.generation = "A76/NeoN1 class" - elif flavorname.cpubrand.cpugen == 2: - gx_flavor.cpu.generation = "A78/x1/NeoV1 class" - elif flavorname.cpubrand.cpugen == 3: - gx_flavor.cpu.generation = "A71x/NeoN2 (ARMv9)" - elif flavorname.cpubrand.cpuvendor == "r": - # RISC-V - gx_flavor.cpu.cpuArchitecture = CpuArch("RISC-V") + arch, vendor, gens = CPUVENDOR_LOOKUP[flavorname.cpubrand.cpuvendor] + gx_flavor.cpu.cpuArchitecture = CpuArch(arch) + if vendor is not None: + gx_flavor.cpu.vendor = vendor + idx = flavorname.cpubrand.generation + if idx is not None and idx < len(gens): + gx_flavor.cpu.generation = gens[idx] # parse frequency - if suffix.perf == "hhh": - gx_flavor.cpu.baseFrequency = Frequency(value=3.75, unit=const.UNIT_GHZ) - elif suffix.perf == "hh": - gx_flavor.cpu.baseFrequency = Frequency(value=3.25, unit=const.UNIT_GHZ) - elif suffix.perf == "h": - gx_flavor.cpu.baseFrequency = Frequency(value=2.75, unit=const.UNIT_GHZ) + if flavorname.perf: + freq = 0.5 * len(flavorname.perf) + 2.25 + gx_flavor.cpu.baseFrequency = Frequency(value=freq, unit=const.UNIT_GHZ) def _add_description(self, os_flavor: OS_Flavor, gx_flavor: GX_Flavor) -> None: """ From ebb5b48ee0648494579f05c396c57ca8a5397193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Wed, 10 Apr 2024 10:19:18 +0200 Subject: [PATCH 11/20] remove FIXME regarding vmware hypervisor type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- generator/discovery/openstack/server_flavor_discovery.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index 4724cb5..1055146 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -18,6 +18,7 @@ DiskType, Frequency, Hypervisor, + HypervisorType, Memory, MemorySize, ) @@ -28,10 +29,10 @@ # map SCS hypervisor names to corresponding GX type and config key HYPERVISOR_LOOKUP = { - "kvm": ("KVM", const.CONFIG_HV_KVM), - "xen": ("Xen", const.CONFIG_HV_XEN), - "vmw": ("KVM", const.CONFIG_HV_VMW), # FIXME is this correct? - "hyv": ("Hyper-V", const.CONFIG_HV_HYV), + "kvm": (HypervisorType.KVM, const.CONFIG_HV_KVM), + "xen": (HypervisorType.Xen, const.CONFIG_HV_XEN), + "vmw": (HypervisorType.other, const.CONFIG_HV_VMW), + "hyv": (getattr(HypervisorType, "Hyper-V"), const.CONFIG_HV_HYV), } # map SCS cpu vendor/architecture letter to architecture, vendor and list of generations CPUVENDOR_LOOKUP = { From fbc395d7db128f0690e8701d7ba236e009b13311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCchse?= Date: Wed, 10 Apr 2024 10:55:01 +0200 Subject: [PATCH 12/20] fix a few unit tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matthias Büchse --- .../openstack/server_flavor_discovery.py | 8 +- generator/vendor/flavor_names.py | 1 + tests/test_server_flavor_discovery.py | 124 +++++++----------- 3 files changed, 56 insertions(+), 77 deletions(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index 1055146..351cf7b 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -122,6 +122,7 @@ def _get_cpu(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> CP """ cpu = CPU(cpuArchitecture=CpuArch.other, numberOfCores=os_flavor.vcpus) if flavorname: + cpu.numberOfCores = flavorname.cpuram.cpus cpu.smtEnabled = flavorname.cpuram.cputype != "C" # FIXME this is unclear to me cpu.defaultOversubscriptionRatio = 1 if flavorname.cpuram.cputype == "V": @@ -141,6 +142,7 @@ def _get_ram(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> Me size = MemorySize(value=float(os_flavor.ram), unit=const.UNIT_MB) mem = Memory(memorySize=size) if flavorname: + mem.memorySize.value = float(flavorname.cpuram.ram) mem.eccEnabled = not flavorname.cpuram.raminsecure if flavorname.cpuram.ramoversubscribed: mem.defaultOversubscriptionRatio = 2 @@ -208,12 +210,12 @@ def _parse_optional_flavor_properties( gx_flavor.cpu.cpuArchitecture = CpuArch(arch) if vendor is not None: gx_flavor.cpu.vendor = vendor - idx = flavorname.cpubrand.generation + idx = flavorname.cpubrand.cpugen if idx is not None and idx < len(gens): gx_flavor.cpu.generation = gens[idx] # parse frequency - if flavorname.perf: - freq = 0.5 * len(flavorname.perf) + 2.25 + if flavorname.cpubrand.perf: + freq = 0.5 * len(flavorname.cpubrand.perf) + 2.25 gx_flavor.cpu.baseFrequency = Frequency(value=freq, unit=const.UNIT_GHZ) def _add_description(self, os_flavor: OS_Flavor, gx_flavor: GX_Flavor) -> None: diff --git a/generator/vendor/flavor_names.py b/generator/vendor/flavor_names.py index 4d13ebf..88b51da 100644 --- a/generator/vendor/flavor_names.py +++ b/generator/vendor/flavor_names.py @@ -188,6 +188,7 @@ class CPUBrand: "i": {None: '(unspecified)', 0: "Unspec/Pre-Skylake", 1: "Skylake", 2: "Cascade Lake", 3: "Ice Lake", 4: "Sapphire Rapids"}, "z": {None: '(unspecified)', 0: "Unspec/Pre-Zen", 1: "Zen 1", 2: "Zen 2", 3: "Zen 3", 4: "Zen 4"}, "a": {None: '(unspecified)', 0: "Unspec/Pre-A76", 1: "A76/NeoN1", 2: "A78/X1/NeoV1", 3: "A710/NeoN2"}, + "r": {None: '(unspecified)', 0: "Unspec"}, }) perf = TblAttr("Performance", {"": "Std Perf", "h": "High Perf", "hh": "Very High Perf", "hhh": "Very Very High Perf"}) diff --git a/tests/test_server_flavor_discovery.py b/tests/test_server_flavor_discovery.py index 2b50d29..5deadc7 100644 --- a/tests/test_server_flavor_discovery.py +++ b/tests/test_server_flavor_discovery.py @@ -10,11 +10,12 @@ from generator.common.gx_schema import ServerFlavor as GX_Flavor from generator.discovery.openstack.server_flavor_discovery import \ ServerFlavorDiscovery +from generator.vendor.flavor_names import Flavorname, parser_v3 from tests.common import MockConnection, OpenstackTestcase, get_config OS_FLAVOR_1 = OS_Flavor(id="flavor_1", name="ABC", vcpus=2, ram=16, disk=0) OS_FLAVOR_2 = OS_Flavor( - id="flavor_2", name="SCS-4L-32uo-3x50s-_kvm_z3hh", vcpus=2, ram=16, disk=0 + id="flavor_2", name="SCS-4L-32uo-3x50s_kvm_z3hh", vcpus=2, ram=16, disk=0 ) @@ -26,7 +27,7 @@ def setUp(self): def test_get_cpu(self): self.assertEqual( CPU(cpuArchitecture=CpuArch.other, numberOfCores=0), - self.discovery._get_cpu(OS_Flavor(name="ABC", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="ABC", ram=10)).cpu, ) self.assertEqual( CPU( @@ -34,7 +35,7 @@ def test_get_cpu(self): defaultOversubscriptionRatio=1, numberOfCores=2, ), - self.discovery._get_cpu(OS_Flavor(name="SCS-2C-4", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4", ram=10)).cpu, ) self.assertEqual( CPU( @@ -43,7 +44,7 @@ def test_get_cpu(self): numberOfCores=2, smtEnabled=True, ), - self.discovery._get_cpu(OS_Flavor(name="SCS-2T-4", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2T-4", ram=10)).cpu, ) self.assertEqual( CPU( @@ -52,7 +53,7 @@ def test_get_cpu(self): numberOfCores=2, smtEnabled=True, ), - self.discovery._get_cpu(OS_Flavor(name="SCS-2V-4", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2V-4", ram=10)).cpu, ) self.assertEqual( CPU( @@ -61,39 +62,39 @@ def test_get_cpu(self): numberOfCores=2, smtEnabled=True, ), - self.discovery._get_cpu(OS_Flavor(name="SCS-2L-4", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2L-4", ram=10)).cpu, ) self.assertEqual( CPU( cpuArchitecture=CpuArch.other, numberOfCores=4, ), - self.discovery._get_cpu(OS_Flavor(name="SCS-2:8", ram=10, vcpus=4)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2:8", ram=10, vcpus=4)).cpu, ) def test_get_mem(self): self.assertEqual( Memory(memorySize=MemorySize(value=4, unit=const.UNIT_MB)), - self.discovery._get_ram(OS_Flavor(name="SCS-2C-4-10n", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4-10n", ram=10)).ram, ) self.assertEqual( Memory(memorySize=MemorySize(value=3.5, unit=const.UNIT_MB)), - self.discovery._get_ram(OS_Flavor(name="SCS-2C-3.5-10n", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-3.5-10n", ram=10)).ram, ) self.assertEqual( Memory(memorySize=MemorySize(value=4, unit=const.UNIT_MB), eccEnabled=True), - self.discovery._get_ram(OS_Flavor(name="SCS-2C-4u-10n", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4u-10n", ram=10)).ram, ) self.assertEqual( Memory( memorySize=MemorySize(value=4, unit=const.UNIT_MB), defaultOversubscriptionRatio=2, ), - self.discovery._get_ram(OS_Flavor(name="SCS-2C-4o-10n", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4o-10n", ram=10)).ram, ) self.assertEqual( Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), - self.discovery._get_ram(OS_Flavor(name="SCS-2C-4ou-10n", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4ou-10n", ram=10)).ram, ) self.assertEqual( Memory( @@ -101,108 +102,83 @@ def test_get_mem(self): eccEnabled=True, defaultOversubscriptionRatio=2, ), - self.discovery._get_ram(OS_Flavor(name="SCS-2C-4uo-10n", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4uo-10n", ram=10)).ram, ) self.assertEqual( Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), - self.discovery._get_ram(OS_Flavor(name="SCS-2C_", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C_", ram=10)).ram, ) self.assertEqual( Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), - self.discovery._get_ram(OS_Flavor(name="SCS-2V:8", ram=10)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2V:8", ram=10)).ram, ) self.assertEqual( Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), - self.discovery._get_ram(OS_Flavor(name="test", ram=10)), - ) - - def test_get_disk_caps(self): - self.assertEqual( - (3, 10, DiskType("local SSD"), DiskBusType("other")), - self.discovery._get_disk_caps("3x10s"), - ) - self.assertEqual( - (1, 10, DiskType("local HDD"), DiskBusType("NVMe")), - self.discovery._get_disk_caps("10p"), - ) - self.assertEqual( - (1, 10, DiskType("other"), DiskBusType("other")), - self.discovery._get_disk_caps("10"), - ) - self.assertEqual( - (1, 0, DiskType("shared network storage"), DiskBusType("other")), - self.discovery._get_disk_caps("n"), - ) - self.assertEqual( - (2, 10, DiskType("other"), DiskBusType("other")), - self.discovery._get_disk_caps("2x10"), - ) - self.assertEqual( - (2, 10, DiskType("local HDD"), DiskBusType("NVMe")), - self.discovery._get_disk_caps("2x10p"), + self.discovery._convert_to_gx(OS_Flavor(name="test", ram=10)).ram, ) def test_get_disks(self): # no SCS standard compliant flavor name self.assertEqual( - [Disk(diskSize=MemorySize(value=50, unit=const.UNIT_GB))], - self.discovery._get_disks(OS_Flavor(name="abc", ram=32, disk=50)), + Disk(diskSize=MemorySize(value=50, unit=const.UNIT_GB)), + self.discovery._convert_to_gx(OS_Flavor(name="abc", ram=32, disk=50)).bootVolume, ) # invalid SCS flavor name self.assertEqual( - [Disk(diskSize=MemorySize(value=50, unit=const.UNIT_GB))], - self.discovery._get_disks(OS_Flavor(name="SCS-2C:10n", ram=32, disk=50)), + Disk(diskSize=MemorySize(value=50, unit=const.UNIT_GB)), + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C:10n", ram=32, disk=50)).bootVolume, ) # SCS compliant flavor name + gx_flavor = self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4-2x10", disk=50)) self.assertEqual( [ Disk(diskSize=MemorySize(value=10, unit=const.UNIT_GB)), Disk(diskSize=MemorySize(value=10, unit=const.UNIT_GB)), ], - self.discovery._get_disks(OS_Flavor(name="SCS-2C-4-2x10", disk=50)), + [gx_flavor.bootVolume] + gx_flavor.additionalVolume, ) def test_parse_optional_flavor_properties(self): # check hypervisor - os_flavor = OS_Flavor(name="SCS-2C-4-10_kvm") + flavorname = parser_v3("SCS-2C-4-10_kvm") gx_flavor = self._init_gx_flavor() gx_flavor_hv = self._init_gx_flavor(hv=True) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_hv, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10_kvm_hwv") + flavorname = parser_v3("SCS-2C-4-10_kvm_hwv") gx_flavor = self._init_gx_flavor() gx_flavor_hv = self._init_gx_flavor(hv=True, hw_virt=True) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_hv, gx_flavor) # check hardware virtualization - os_flavor = OS_Flavor(name="SCS-2C-4-10_hwv") + flavorname = parser_v3("SCS-2C-4-10_hwv") gx_flavor = self._init_gx_flavor() gx_flavor_hw = self._init_gx_flavor(hw_virt=True) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_hw, gx_flavor) # check CPU architecture, frequency and generation - os_flavor = OS_Flavor(name="SCS-2C-4-10n_i") + flavorname = parser_v3("SCS-2C-4-10n_i") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("x86-64"), cpu_vendor="Intel" ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_i3") + flavorname = parser_v3("SCS-2C-4-10n_i3") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("x86-64"), cpu_vendor="Intel", cpu_gen="Ice Lake" ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_i3h") + flavorname = parser_v3("SCS-2C-4-10n_i3h") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("x86-64"), @@ -210,26 +186,26 @@ def test_parse_optional_flavor_properties(self): cpu_gen="Ice Lake", cpu_freq=Frequency(value=2.75, unit=const.UNIT_GHZ), ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_z") + flavorname = parser_v3("SCS-2C-4-10n_z") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("x86-64"), cpu_vendor="AMD" ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_z4") + flavorname = parser_v3("SCS-2C-4-10n_z4") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("x86-64"), cpu_vendor="AMD", cpu_gen="Zen-4 (Genoa)" ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_z4hh") + flavorname = parser_v3("SCS-2C-4-10n_z4hh") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("x86-64"), @@ -237,27 +213,27 @@ def test_parse_optional_flavor_properties(self): cpu_gen="Zen-4 (Genoa)", cpu_freq=Frequency(value=3.25, unit=const.UNIT_GHZ), ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_a") + flavorname = parser_v3("SCS-2C-4-10n_a") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("AArch-64"), cpu_vendor="ARM" ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_a2") + flavorname = parser_v3("SCS-2C-4-10n_a2") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("AArch-64"), cpu_vendor="ARM", cpu_gen="A78/x1/NeoV1 class" ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_a2hhh") + flavorname = parser_v3("SCS-2C-4-10n_a2hhh") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor( cpu_arc=CpuArch("AArch-64"), @@ -265,13 +241,13 @@ def test_parse_optional_flavor_properties(self): cpu_gen="A78/x1/NeoV1 class", cpu_freq=Frequency(value=3.75, unit=const.UNIT_GHZ), ) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) - os_flavor = OS_Flavor(name="SCS-2C-4-10n_r") + flavorname = parser_v3("SCS-2C-4-10n_r") gx_flavor = self._init_gx_flavor() gx_flavor_cpu = self._init_gx_flavor(cpu_arc=CpuArch("RISC-V")) - self.discovery._parse_optional_flavor_properties(os_flavor, gx_flavor) + self.discovery._parse_optional_flavor_properties(flavorname, gx_flavor) self.assertEqual(gx_flavor_cpu, gx_flavor) def test_discovery(self): @@ -284,7 +260,7 @@ def test_discovery(self): cpu_gen="Zen-3 (Milan)", cpu_freq=Frequency(value=3.25, unit=const.UNIT_GHZ), number_of_cores=4) gax_flavor_2.cpu.defaultOversubscriptionRatio = 16 gax_flavor_2.cpu.smtEnabled = True - gax_flavor_2.ram.eccEnabled = True + gax_flavor_2.ram.eccEnabled = False gax_flavor_2.ram.defaultOversubscriptionRatio = 2 gax_flavor_2.bootVolume = Disk( diskSize=MemorySize(value=50, unit=const.UNIT_GB), From 9f4fa54aa98737b6394a4359c92c7fd5e68d9905 Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Wed, 10 Apr 2024 15:10:20 +0200 Subject: [PATCH 13/20] Remove obsolete assigment of ram size and number of cpu from flavor name Signed-off-by: Anja Strunk --- generator/discovery/openstack/server_flavor_discovery.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index 351cf7b..14618a9 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -122,7 +122,6 @@ def _get_cpu(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> CP """ cpu = CPU(cpuArchitecture=CpuArch.other, numberOfCores=os_flavor.vcpus) if flavorname: - cpu.numberOfCores = flavorname.cpuram.cpus cpu.smtEnabled = flavorname.cpuram.cputype != "C" # FIXME this is unclear to me cpu.defaultOversubscriptionRatio = 1 if flavorname.cpuram.cputype == "V": @@ -142,7 +141,6 @@ def _get_ram(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> Me size = MemorySize(value=float(os_flavor.ram), unit=const.UNIT_MB) mem = Memory(memorySize=size) if flavorname: - mem.memorySize.value = float(flavorname.cpuram.ram) mem.eccEnabled = not flavorname.cpuram.raminsecure if flavorname.cpuram.ramoversubscribed: mem.defaultOversubscriptionRatio = 2 From bc1b56aa37ac20a76c932ce1dee918cb87075771 Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Wed, 10 Apr 2024 21:30:43 +0200 Subject: [PATCH 14/20] Fix unit tests Signed-off-by: Anja Strunk --- .../openstack/server_flavor_discovery.py | 2 +- tests/data/credential.json | 6 +-- tests/test_cli.py | 2 +- tests/test_server_flavor_discovery.py | 46 +++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index 14618a9..46b4a66 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -92,7 +92,7 @@ def _convert_to_gx(self, os_flavor: OS_Flavor) -> GX_Flavor: try: flavorname = parser_v3(os_flavor.name) - except ValueError: + except ValueError as e: flavorname = None # Initialize Gaia-X Server Flavor disks = self._get_disks(os_flavor, flavorname) diff --git a/tests/data/credential.json b/tests/data/credential.json index fbeed8e..50cbb64 100644 --- a/tests/data/credential.json +++ b/tests/data/credential.json @@ -165,7 +165,7 @@ "@type": "xsd:boolean", "@value": true }, - "gx:numberOfCores": 4, + "gx:numberOfCores": 2, "gx:baseFrequency": { "@type": "qudt:quantitykind/FrequencyDefinition", "qudt:value": { @@ -182,7 +182,7 @@ "@type": "gx:MemorySize", "qudt:value": { "@type": "xsd:float", - "@value": 32.0 + "@value": 16.0 }, "qudt:unit": "https://qudt.org/vocab/unit/MegaBYTE" }, @@ -190,7 +190,7 @@ "gx:memoryRank": "other", "gx:eccEnabled": { "@type": "xsd:boolean", - "@value": true + "@value": false }, "gx:hardwareEncryption": { "@type": "xsd:boolean", diff --git a/tests/test_cli.py b/tests/test_cli.py index 4d70387..f799311 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -54,7 +54,7 @@ ) OS_FLAVOR_1 = OS_Flavor( - id="flavor_2", name="SCS-4L-32uo-3x50s-_kvm_z3hh", vcpus=2, ram=16, disk=0 + id="flavor_2", name="SCS-4L-32uo-3x50s_kvm_z3hh", vcpus=2, ram=16, disk=0 ) diff --git a/tests/test_server_flavor_discovery.py b/tests/test_server_flavor_discovery.py index 5deadc7..ed5fefe 100644 --- a/tests/test_server_flavor_discovery.py +++ b/tests/test_server_flavor_discovery.py @@ -27,93 +27,93 @@ def setUp(self): def test_get_cpu(self): self.assertEqual( CPU(cpuArchitecture=CpuArch.other, numberOfCores=0), - self.discovery._convert_to_gx(OS_Flavor(name="ABC", ram=10)).cpu, + self.discovery._convert_to_gx(OS_Flavor(name="ABC")).cpu, ) self.assertEqual( CPU( cpuArchitecture=CpuArch.other, defaultOversubscriptionRatio=1, - numberOfCores=2, + numberOfCores=4, ), - self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4", ram=10)).cpu, + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4", vcpus=4)).cpu, ) self.assertEqual( CPU( cpuArchitecture=CpuArch.other, defaultOversubscriptionRatio=1, - numberOfCores=2, + numberOfCores=4, smtEnabled=True, ), - self.discovery._convert_to_gx(OS_Flavor(name="SCS-2T-4", ram=10)).cpu, + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2T-4", vcpus=4)).cpu, ) self.assertEqual( CPU( cpuArchitecture=CpuArch.other, defaultOversubscriptionRatio=5, - numberOfCores=2, + numberOfCores=4, smtEnabled=True, ), - self.discovery._convert_to_gx(OS_Flavor(name="SCS-2V-4", ram=10)).cpu, + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2V-4", vcpus=4)).cpu, ) self.assertEqual( CPU( cpuArchitecture=CpuArch.other, defaultOversubscriptionRatio=16, - numberOfCores=2, + numberOfCores=4, smtEnabled=True, ), - self.discovery._convert_to_gx(OS_Flavor(name="SCS-2L-4", ram=10)).cpu, + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2L-4", vcpus=4)).cpu, ) self.assertEqual( CPU( cpuArchitecture=CpuArch.other, - numberOfCores=4, + numberOfCores=4 ), - self.discovery._convert_to_gx(OS_Flavor(name="SCS-2:8", ram=10, vcpus=4)).cpu, + self.discovery._convert_to_gx(OS_Flavor(name="SCS-2:8", vcpus=4)).cpu, ) def test_get_mem(self): self.assertEqual( - Memory(memorySize=MemorySize(value=4, unit=const.UNIT_MB)), + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB), eccEnabled=True), self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4-10n", ram=10)).ram, ) self.assertEqual( - Memory(memorySize=MemorySize(value=3.5, unit=const.UNIT_MB)), + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB), eccEnabled=True), self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-3.5-10n", ram=10)).ram, ) self.assertEqual( - Memory(memorySize=MemorySize(value=4, unit=const.UNIT_MB), eccEnabled=True), + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB), eccEnabled=False), self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4u-10n", ram=10)).ram, ) self.assertEqual( Memory( - memorySize=MemorySize(value=4, unit=const.UNIT_MB), + memorySize=MemorySize(value=10, unit=const.UNIT_MB), eccEnabled=True, defaultOversubscriptionRatio=2, ), self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4o-10n", ram=10)).ram, ) self.assertEqual( - Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB), eccEnabled=False), self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4ou-10n", ram=10)).ram, ) self.assertEqual( Memory( - memorySize=MemorySize(value=4, unit=const.UNIT_MB), - eccEnabled=True, + memorySize=MemorySize(value=10, unit=const.UNIT_MB), + eccEnabled=False, defaultOversubscriptionRatio=2, ), self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4uo-10n", ram=10)).ram, ) self.assertEqual( - Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB), eccEnabled=False), self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C_", ram=10)).ram, ) self.assertEqual( - Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB), eccEnabled=False), self.discovery._convert_to_gx(OS_Flavor(name="SCS-2V:8", ram=10)).ram, ) self.assertEqual( - Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB)), + Memory(memorySize=MemorySize(value=10, unit=const.UNIT_MB), eccEnabled=False), self.discovery._convert_to_gx(OS_Flavor(name="test", ram=10)).ram, ) @@ -256,8 +256,8 @@ def test_discovery(self): # init expected objects gax_flavor_1 = self._init_gx_flavor(ram=16, disk=0, number_of_cores=2) - gax_flavor_2 = self._init_gx_flavor(ram=32, disk=50, cpu_arc=CpuArch("x86-64"), cpu_vendor="AMD", - cpu_gen="Zen-3 (Milan)", cpu_freq=Frequency(value=3.25, unit=const.UNIT_GHZ), number_of_cores=4) + gax_flavor_2 = self._init_gx_flavor(ram=16, disk=50, cpu_arc=CpuArch("x86-64"), cpu_vendor="AMD", + cpu_gen="Zen-3 (Milan)", cpu_freq=Frequency(value=3.25, unit=const.UNIT_GHZ), number_of_cores=2) gax_flavor_2.cpu.defaultOversubscriptionRatio = 16 gax_flavor_2.cpu.smtEnabled = True gax_flavor_2.ram.eccEnabled = False From ea06af5414251652c93d87596c979c487c02f80b Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Wed, 10 Apr 2024 21:48:04 +0200 Subject: [PATCH 15/20] Increase code coverage of server_flavor_discovery.py to 100% Signed-off-by: Anja Strunk --- .../openstack/server_flavor_discovery.py | 6 ++--- tests/test_server_flavor_discovery.py | 26 +++++++++++++++---- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index 46b4a66..6932547 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -224,7 +224,5 @@ def _add_description(self, os_flavor: OS_Flavor, gx_flavor: GX_Flavor) -> None: @param gx_flavor Gaia-X flavor specification @type gx_flavor: ServerFlavor """ - try: - gx_flavor.description = os_flavor.description - except KeyError: - pass + gx_flavor.description = os_flavor.description + \ No newline at end of file diff --git a/tests/test_server_flavor_discovery.py b/tests/test_server_flavor_discovery.py index ed5fefe..355dbaf 100644 --- a/tests/test_server_flavor_discovery.py +++ b/tests/test_server_flavor_discovery.py @@ -13,7 +13,7 @@ from generator.vendor.flavor_names import Flavorname, parser_v3 from tests.common import MockConnection, OpenstackTestcase, get_config -OS_FLAVOR_1 = OS_Flavor(id="flavor_1", name="ABC", vcpus=2, ram=16, disk=0) +OS_FLAVOR_1 = OS_Flavor(id="flavor_1", name="ABC", vcpus=2, ram=16, disk=0, description=None) OS_FLAVOR_2 = OS_Flavor( id="flavor_2", name="SCS-4L-32uo-3x50s_kvm_z3hh", vcpus=2, ram=16, disk=0 ) @@ -129,7 +129,7 @@ def test_get_disks(self): self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C:10n", ram=32, disk=50)).bootVolume, ) - # SCS compliant flavor name + # SCS compliant flavor names gx_flavor = self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4-2x10", disk=50)) self.assertEqual( [ @@ -138,6 +138,21 @@ def test_get_disks(self): ], [gx_flavor.bootVolume] + gx_flavor.additionalVolume, ) + gx_flavor = self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4-10p", disk=50)) + self.assertEqual( + [ + Disk(diskSize=MemorySize(value=10, unit=const.UNIT_GB), diskType=DiskType("local HDD"), + diskBusType=DiskBusType.NVMe) + ], + [gx_flavor.bootVolume] + gx_flavor.additionalVolume, + ) + gx_flavor = self.discovery._convert_to_gx(OS_Flavor(name="SCS-2C-4-10h", disk=50)) + self.assertEqual( + [ + Disk(diskSize=MemorySize(value=10, unit=const.UNIT_GB), diskType=DiskType("local HDD"),) + ], + [gx_flavor.bootVolume] + gx_flavor.additionalVolume, + ) def test_parse_optional_flavor_properties(self): # check hypervisor @@ -257,14 +272,15 @@ def test_discovery(self): gax_flavor_1 = self._init_gx_flavor(ram=16, disk=0, number_of_cores=2) gax_flavor_2 = self._init_gx_flavor(ram=16, disk=50, cpu_arc=CpuArch("x86-64"), cpu_vendor="AMD", - cpu_gen="Zen-3 (Milan)", cpu_freq=Frequency(value=3.25, unit=const.UNIT_GHZ), number_of_cores=2) + cpu_gen="Zen-3 (Milan)", + cpu_freq=Frequency(value=3.25, unit=const.UNIT_GHZ), number_of_cores=2) gax_flavor_2.cpu.defaultOversubscriptionRatio = 16 gax_flavor_2.cpu.smtEnabled = True gax_flavor_2.ram.eccEnabled = False gax_flavor_2.ram.defaultOversubscriptionRatio = 2 gax_flavor_2.bootVolume = Disk( - diskSize=MemorySize(value=50, unit=const.UNIT_GB), - diskType=DiskType("local SSD")) + diskSize=MemorySize(value=50, unit=const.UNIT_GB), + diskType=DiskType("local SSD")) gax_flavor_2.additionalVolume = [ Disk( diskSize=MemorySize(value=50, unit=const.UNIT_GB), From f974b97318961ad4510d353c309c843967638a9d Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Thu, 11 Apr 2024 10:26:24 +0200 Subject: [PATCH 16/20] Reformt files to solve flake8 errors Signed-off-by: Anja Strunk --- devops/dags/gaiax-pipeline.py | 33 +- generator/common/gx_schema.py | 108 +++--- generator/common/json_ld.py | 9 +- .../openstack/openstack_discovery.py | 8 +- .../openstack/server_flavor_discovery.py | 26 +- .../openstack/vm_images_discovery.py | 313 +++++++++++------- generator/vendor/flavor_names.py | 218 +++++++++--- gx-cred-generator.py | 2 - gx_context.py | 2 +- k8s-discovery.py | 2 +- openstack-discovery.py | 28 +- tests/common.py | 5 +- tests/test_json_ld.py | 2 +- tests/test_server_flavor_discovery.py | 2 +- 14 files changed, 493 insertions(+), 265 deletions(-) diff --git a/devops/dags/gaiax-pipeline.py b/devops/dags/gaiax-pipeline.py index 30825be..35a929d 100755 --- a/devops/dags/gaiax-pipeline.py +++ b/devops/dags/gaiax-pipeline.py @@ -1,33 +1,34 @@ -from datetime import timedelta -from datetime import datetime +import logging +from datetime import datetime, timedelta from airflow import DAG from airflow.operators.python import PythonOperator -import logging + def extract(): logging.info("extract process") default_args = { - 'owner': 'airflow', - 'depends_on_past': False, - 'email': ['airflow@example.com'], - 'email_on_failure': False, - 'email_on_retry': False, - 'retries': 6, - 'retry_delay': timedelta(minutes=30), + "owner": "airflow", + "depends_on_past": False, + "email": ["airflow@example.com"], + "email_on_failure": False, + "email_on_retry": False, + "retries": 6, + "retry_delay": timedelta(minutes=30), } -dag = DAG('gaiax', +dag = DAG( + "gaiax", default_args=default_args, - description='gaiax pipeline', + description="gaiax pipeline", start_date=datetime(2023, 5, 3), - tags=['gaiax'], - schedule_interval="0 1 * * *") # Intervalo de ejecución) - + tags=["gaiax"], + schedule_interval="0 1 * * *", +) # Intervalo de ejecución) extract_os_task = PythonOperator(task_id="extract_os", python_callable=extract, dag=dag) extract_os_task -#process_task >> backup_task +# process_task >> backup_task diff --git a/generator/common/gx_schema.py b/generator/common/gx_schema.py index 2c3526c..45b0568 100644 --- a/generator/common/gx_schema.py +++ b/generator/common/gx_schema.py @@ -1084,9 +1084,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): [self.registrationNumber] if self.registrationNumber is not None else [] ) self.registrationNumber = [ - v - if isinstance(v, LegalPersonRegistrationNumber) - else LegalPersonRegistrationNumber(v) + ( + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) + ) for v in self.registrationNumber ] @@ -1107,9 +1109,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): else [] ) self.parentOrganizationOf = [ - v - if isinstance(v, LegalPersonRegistrationNumber) - else LegalPersonRegistrationNumber(v) + ( + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) + ) for v in self.parentOrganizationOf ] @@ -1118,9 +1122,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): [self.subOrganisationOf] if self.subOrganisationOf is not None else [] ) self.subOrganisationOf = [ - v - if isinstance(v, LegalPersonRegistrationNumber) - else LegalPersonRegistrationNumber(v) + ( + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) + ) for v in self.subOrganisationOf ] @@ -1245,9 +1251,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): [self.maintainedBy] if self.maintainedBy is not None else [] ) self.maintainedBy = [ - v - if isinstance(v, LegalPersonRegistrationNumber) - else LegalPersonRegistrationNumber(v) + ( + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) + ) for v in self.maintainedBy ] @@ -1260,9 +1268,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if not isinstance(self.ownedBy, list): self.ownedBy = [self.ownedBy] if self.ownedBy is not None else [] self.ownedBy = [ - v - if isinstance(v, LegalPersonRegistrationNumber) - else LegalPersonRegistrationNumber(v) + ( + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) + ) for v in self.ownedBy ] @@ -1271,9 +1281,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): [self.manufacturedBy] if self.manufacturedBy is not None else [] ) self.manufacturedBy = [ - v - if isinstance(v, LegalPersonRegistrationNumber) - else LegalPersonRegistrationNumber(v) + ( + v + if isinstance(v, LegalPersonRegistrationNumber) + else LegalPersonRegistrationNumber(v) + ) for v in self.manufacturedBy ] @@ -1600,9 +1612,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): else [] ) self.dataProtectionRegime = [ - v - if isinstance(v, PersonalDataProtectionRegime) - else PersonalDataProtectionRegime(v) + ( + v + if isinstance(v, PersonalDataProtectionRegime) + else PersonalDataProtectionRegime(v) + ) for v in self.dataProtectionRegime ] @@ -1953,9 +1967,9 @@ class DataResource(VirtualResource): dataController: Optional[ Union[Union[dict, Participant], List[Union[dict, Participant]]] ] = empty_list() - consent: Optional[ - Union[Union[dict, "Consent"], List[Union[dict, "Consent"]]] - ] = empty_list() + consent: Optional[Union[Union[dict, "Consent"], List[Union[dict, "Consent"]]]] = ( + empty_list() + ) def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.producedBy): @@ -1970,9 +1984,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): [self.exposedThrough] if self.exposedThrough is not None else [] ) self.exposedThrough = [ - v - if isinstance(v, DataExchangeComponent) - else DataExchangeComponent(**as_dict(v)) + ( + v + if isinstance(v, DataExchangeComponent) + else DataExchangeComponent(**as_dict(v)) + ) for v in self.exposedThrough ] @@ -2249,9 +2265,9 @@ class ContainerResourceLimits(InstantiationRequirement): memoryLimit: Optional[Union[dict, MemorySize]] = None gpuRequirements: Optional[Union[dict, GPU]] = None gpuLimit: Optional[int] = None - confidentialComputingTechnology: Optional[ - Union[dict, "ConfidentialComputing"] - ] = None + confidentialComputingTechnology: Optional[Union[dict, "ConfidentialComputing"]] = ( + None + ) def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.confidential): @@ -2547,9 +2563,9 @@ class StorageConfiguration(InstantiationRequirement): class_name: ClassVar[str] = "StorageConfiguration" class_model_uri: ClassVar[URIRef] = GX.StorageConfiguration - storageEncryption: Union[ - Union[dict, Encryption], List[Union[dict, Encryption]] - ] = None + storageEncryption: Union[Union[dict, Encryption], List[Union[dict, Encryption]]] = ( + None + ) storageCompression: Optional[ Union[ Union[str, "CompressionAlgorithm"], List[Union[str, "CompressionAlgorithm"]] @@ -2615,9 +2631,11 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): else [] ) self.storageRedundancyMechanism = [ - v - if isinstance(v, StorageRedundancyMechanism) - else StorageRedundancyMechanism(v) + ( + v + if isinstance(v, StorageRedundancyMechanism) + else StorageRedundancyMechanism(v) + ) for v in self.storageRedundancyMechanism ] @@ -2655,9 +2673,9 @@ class FileStorageConfiguration(StorageConfiguration): class_name: ClassVar[str] = "FileStorageConfiguration" class_model_uri: ClassVar[URIRef] = GX.FileStorageConfiguration - storageEncryption: Union[ - Union[dict, Encryption], List[Union[dict, Encryption]] - ] = None + storageEncryption: Union[Union[dict, Encryption], List[Union[dict, Encryption]]] = ( + None + ) fileSystemType: Optional[ Union[Union[str, "FileSystemType"], List[Union[str, "FileSystemType"]]] ] = empty_list() @@ -2702,9 +2720,9 @@ class BlockStorageConfiguration(StorageConfiguration): class_name: ClassVar[str] = "BlockStorageConfiguration" class_model_uri: ClassVar[URIRef] = GX.BlockStorageConfiguration - storageEncryption: Union[ - Union[dict, Encryption], List[Union[dict, Encryption]] - ] = None + storageEncryption: Union[Union[dict, Encryption], List[Union[dict, Encryption]]] = ( + None + ) blockStorageTechnology: Optional[ Union[ Union[str, "BlockStorageTechnology"], @@ -3028,9 +3046,9 @@ class ServerFlavor(InstantiationRequirement): bootVolume: Union[dict, Disk] = None gpu: Optional[Union[dict, GPU]] = None network: Optional[str] = None - additionalVolume: Optional[ - Union[Union[dict, Disk], List[Union[dict, Disk]]] - ] = empty_list() + additionalVolume: Optional[Union[Union[dict, Disk], List[Union[dict, Disk]]]] = ( + empty_list() + ) confidentialComputing: Optional[Union[dict, "ConfidentialComputing"]] = None hypervisor: Optional[Union[dict, Hypervisor]] = None hardwareAssistedVirtualization: Optional[Union[bool, Bool]] = False diff --git a/generator/common/json_ld.py b/generator/common/json_ld.py index d5b249c..19ed4dc 100644 --- a/generator/common/json_ld.py +++ b/generator/common/json_ld.py @@ -1,19 +1,16 @@ """ Methods and classes needed/useful for JSON-LD serialization. """ + import inspect from datetime import date, datetime from typing import List from uuid import uuid4 -from linkml_runtime.linkml_model.meta import ( - EnumDefinition, - PermissibleValue, - PvFormulaOptions, -) +from linkml_runtime.linkml_model.meta import PermissibleValue from linkml_runtime.utils.enumerations import EnumDefinitionImpl from linkml_runtime.utils.metamodelcore import URI -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str +from linkml_runtime.utils.yamlutils import YAMLRoot from generator.common.gx_schema import GX, QUDT, SCHEMA, VCARD, slots diff --git a/generator/discovery/openstack/openstack_discovery.py b/generator/discovery/openstack/openstack_discovery.py index be1e252..2b282c2 100644 --- a/generator/discovery/openstack/openstack_discovery.py +++ b/generator/discovery/openstack/openstack_discovery.py @@ -4,12 +4,10 @@ SPDX-License-Identifier: EPL-2.0 """ -from abc import ABCMeta, abstractmethod from typing import List from openstack.connection import Connection -from generator.common import const from generator.common.config import Config from generator.common.json_ld import JsonLdObject from generator.discovery.openstack.server_flavor_discovery import ServerFlavorDiscovery @@ -32,7 +30,5 @@ def discover(self) -> List[JsonLdObject]: @return: all attributes as list @rtype List[JsonLdObject] """ - return ( - VmDiscovery(self.conn, self.config).discover() - + ServerFlavorDiscovery(self.conn, self.config).discover() - ) \ No newline at end of file + return (VmDiscovery(self.conn, self.config).discover() + ServerFlavorDiscovery(self.conn, + self.config).discover()) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index 6932547..0b08b5b 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -52,7 +52,12 @@ "a": ( "AArch-64", "ARM", - ("pre Cortex A76", "A76/NeoN1 class", "A78/x1/NeoV1 class", "A71x/NeoN2 (ARMv9)"), + ( + "pre Cortex A76", + "A76/NeoN1 class", + "A78/x1/NeoV1 class", + "A71x/NeoN2 (ARMv9)", + ), ), # RISC-V "r": ( @@ -92,7 +97,7 @@ def _convert_to_gx(self, os_flavor: OS_Flavor) -> GX_Flavor: try: flavorname = parser_v3(os_flavor.name) - except ValueError as e: + except ValueError: flavorname = None # Initialize Gaia-X Server Flavor disks = self._get_disks(os_flavor, flavorname) @@ -122,7 +127,9 @@ def _get_cpu(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> CP """ cpu = CPU(cpuArchitecture=CpuArch.other, numberOfCores=os_flavor.vcpus) if flavorname: - cpu.smtEnabled = flavorname.cpuram.cputype != "C" # FIXME this is unclear to me + cpu.smtEnabled = ( + flavorname.cpuram.cputype != "C" + ) # FIXME this is unclear to me cpu.defaultOversubscriptionRatio = 1 if flavorname.cpuram.cputype == "V": cpu.defaultOversubscriptionRatio = 5 @@ -130,7 +137,9 @@ def _get_cpu(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> CP cpu.defaultOversubscriptionRatio = 16 return cpu - def _get_ram(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> Memory: + def _get_ram( + self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname] + ) -> Memory: """ Return Gaia-X RAM definition specified in given OpenStack flavor. @param os_flavor: OpenStack Flavor @@ -146,7 +155,9 @@ def _get_ram(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> Me mem.defaultOversubscriptionRatio = 2 return mem - def _get_disks(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> List[Disk]: + def _get_disks( + self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname] + ) -> List[Disk]: """ Return all disk specification found in given Openstack flavor. @param os_flavor: Openstack flavor specification @@ -169,7 +180,9 @@ def _get_disks(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> for i in range(int(flavorname.disk.nrdisks)): disks.append( Disk( - diskSize=MemorySize(value=flavorname.disk.disksize, unit=const.UNIT_GB), + diskSize=MemorySize( + value=flavorname.disk.disksize, unit=const.UNIT_GB + ), diskType=disk_type, diskBusType=disk_bus_types, ) @@ -225,4 +238,3 @@ def _add_description(self, os_flavor: OS_Flavor, gx_flavor: GX_Flavor) -> None: @type gx_flavor: ServerFlavor """ gx_flavor.description = os_flavor.description - \ No newline at end of file diff --git a/generator/discovery/openstack/vm_images_discovery.py b/generator/discovery/openstack/vm_images_discovery.py index 8717819..eb18bdc 100644 --- a/generator/discovery/openstack/vm_images_discovery.py +++ b/generator/discovery/openstack/vm_images_discovery.py @@ -1,9 +1,12 @@ +#!/usr/bin/env python3 +# vim: set ts=4 sw=4 et: +# +# vm_images_discovery.py """Script to discovery VM images properties. (c) Anja Strunk , 1/2024 SPDX-License-Identifier: EPL-2.0 """ - from datetime import datetime from typing import List, Union @@ -11,31 +14,18 @@ from openstack.connection import Connection from openstack.image.v2.image import Image as OS_Image -from generator.common import const +import generator.common.const as const from generator.common.config import Config from generator.common.gx_schema import CPU, SPDX from generator.common.gx_schema import Architectures as CpuArch -from generator.common.gx_schema import ( - CheckSum, - ChecksumAlgorithm, - Disk, - DiskBusType, - FirmType, - HypervisorType, - LatestN, - MaintenanceSubscription, - Memory, - MemorySize, - OperatingSystem, - RNGTypes, - Signature, - SignatureAlgorithm, - UpdateFrequency, - UpdateStrategy, - Validity1, - Validity2, - VMDiskType, -) +from generator.common.gx_schema import (CheckSum, ChecksumAlgorithm, Disk, + DiskBusType, FirmType, HypervisorType, + LatestN, MaintenanceSubscription, + Memory, MemorySize, OperatingSystem, + RNGTypes, Signature, + SignatureAlgorithm, UpdateFrequency, + UpdateStrategy, Validity1, Validity2, + VMDiskType) from generator.common.gx_schema import VMImage as GX_Image from generator.common.gx_schema import WatchDogActions from generator.common.json_ld import JsonLdObject @@ -121,11 +111,16 @@ class VmDiscovery: """Discover VM image properties.""" def __init__(self, conn: Connection, conf: Config) -> None: + """ + Constructor. + @param conn: Openstack Connection + @param conf: configuration + """ self.conn = conn self.conf = conf # def collect_vm_images(self, conn: Connection) -> List[str]: - def discover(self) -> List[JsonLdObject]: + def discover_vm_images(self) -> List[JsonLdObject]: """ Return one credential for each public VM image offered by openstack cloud. @@ -204,8 +199,7 @@ def _get_secure_boot(os_image: OS_Image) -> bool: @staticmethod def _get_firme_ware_type(os_image: OS_Image) -> FirmType: if ( - os_image.properties is not None - and "hw_firmware_type" in os_image.properties + os_image.properties is not None and "hw_firmware_type" in os_image.properties ): return FirmType( FIRM_WARE_LOOKUP.get( @@ -309,218 +303,306 @@ def _get_operation_system(self, os_image: OS_Image) -> OperatingSystem: return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ARCH, - resourcePolicy=self.conf.get_copyright_owner(const.CONFIG_OS_ARCH), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_ARCH), - license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_ARCH)), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_ARCH), + copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_ARCH), + license=self._get_license_list( + self._get_license_for_os(const.CONFIG_OS_ARCH) + ), ) elif os_image.os_distro.lower() == "centos": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_CENTOS, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_CENTOS), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_CENTOS), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_CENTOS), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_CENTOS + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_CENTOS) + self._get_license_for_os(const.CONFIG_OS_CENTOS) ), ) elif os_image.os_distro.lower() == "debian": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_DEBIAN, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_DEBIAN), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_DEBIAN), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_DEBIAN), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_DEBIAN + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_DEBIAN) + self._get_license_for_os(const.CONFIG_OS_DEBIAN) ), ) elif os_image.os_distro.lower() == "fedora": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_FEDORA, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_FEDORA), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_FEDORA), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_FEDORA), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_FEDORA + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_FEDORA) + self._get_license_for_os(const.CONFIG_OS_FEDORA) ), ) elif os_image.os_distro.lower() == "freebsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_FREEBSD, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_FREEBSD), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_FREEBSD), + resourcePolicy=self._get_resource_policy_for_os( + const.CONFIG_OS_FREEBSD + ), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_FREEBSD + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_FREEBSD) + self._get_license_for_os(const.CONFIG_OS_FREEBSD) ), ) elif os_image.os_distro.lower() == "gentoo": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_GENTOO, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_GENTOO), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_GENTOO), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_GENTOO), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_GENTOO + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_GENTOO) + self._get_license_for_os(const.CONFIG_OS_GENTOO) ), ) elif os_image.os_distro.lower() == "mandrake": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MANDRAKE, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_MANDRAKE), - copyrightOwnedBy=self.conf.get_copyright_owner( + resourcePolicy=self._get_resource_policy_for_os( + const.CONFIG_OS_MANDRAKE + ), + copyrightOwnedBy=self._get_copyright_owner_for_os( const.CONFIG_OS_MANDRAKE ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_MANDRAKE) + self._get_license_for_os(const.CONFIG_OS_MANDRAKE) ), ) elif os_image.os_distro.lower() == "mandriva": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MANDRIVA, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_MANDRIVA), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_MANDRIVA), + resourcePolicy=self._get_resource_policy_for_os( + const.CONFIG_OS_MANDRIVA + ), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_MANDRIVA + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_MANDRIVA) + self._get_license_for_os(const.CONFIG_OS_MANDRIVA) ), ) elif os_image.os_distro.lower() == "mes": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MES, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_MES), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_MES), - license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_MES)), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_MES), + copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_MES), + license=self._get_license_list( + self._get_license_for_os(const.CONFIG_OS_MES) + ), ) elif os_image.os_distro.lower() == "msdos": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_MSDOS, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_MSDOS), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_MSDOS), - license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_MSDOS)), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_MSDOS), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_MSDOS + ), + license=self._get_license_list( + self._get_license_for_os(const.CONFIG_OS_MSDOS) + ), ) elif os_image.os_distro.lower() == "netbsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_NETBSD, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_NETBSD), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_NETBSD), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_NETBSD), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_NETBSD + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_NETBSD) + self._get_license_for_os(const.CONFIG_OS_NETBSD) ), ) elif os_image.os_distro.lower() == "netware": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_NOVELL, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_NOVELL), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_NOVELL), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_NOVELL), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_NOVELL + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_NOVELL) + self._get_license_for_os(const.CONFIG_OS_NOVELL) ), ) elif os_image.os_distro.lower() == "openbsd": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_OPENBSD, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_OPENBSD), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_OPENBSD), + resourcePolicy=self._get_resource_policy_for_os( + const.CONFIG_OS_OPENBSD + ), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_OPENBSD + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_OPENBSD) + self._get_license_for_os(const.CONFIG_OS_OPENBSD) ), ) elif os_image.os_distro.lower() == "opensolaris": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_SOLARIS, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_SOLARIS), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_SOLARIS), + resourcePolicy=self._get_resource_policy_for_os( + const.CONFIG_OS_SOLARIS + ), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_SOLARIS + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_SOLARIS) + self._get_license_for_os(const.CONFIG_OS_SOLARIS) ), ) elif os_image.os_distro.lower() == "opensuse": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_OPEN_SUSE, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_OPEN_SUSE), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_OPEN_SUSE), + resourcePolicy=self._get_resource_policy_for_os( + const.CONFIG_OS_OPEN_SUSE + ), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_OPEN_SUSE + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_OPEN_SUSE) + self._get_license_for_os(const.CONFIG_OS_OPEN_SUSE) ), ) elif os_image.os_distro.lower() == "rocky": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ROCKY, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_ROCKY), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_ROCKY), - license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_ROCKY)), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_ROCKY), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_ROCKY + ), + license=self._get_license_list( + self._get_license_for_os(const.CONFIG_OS_ROCKY) + ), ) elif os_image.os_distro.lower() == "rhel": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_RHEL, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_RHEL), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_RHEL), - license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_RHEL)), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_RHEL), + copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_RHEL), + license=self._get_license_list( + self._get_license_for_os(const.CONFIG_OS_RHEL) + ), ) elif os_image.os_distro.lower() == "sled": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_SLED, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_SLED), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_SLED), - license=self._get_license_list(self.conf.get_license(const.CONFIG_OS_SLED)), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_SLED), + copyrightOwnedBy=self._get_copyright_owner_for_os(const.CONFIG_OS_SLED), + license=self._get_license_list( + self._get_license_for_os(const.CONFIG_OS_SLED) + ), ) elif os_image.os_distro.lower() == "ubuntu": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_UBUNTU, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_UBUNTU), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_UBUNTU), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_UBUNTU), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_UBUNTU + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_UBUNTU) + self._get_license_for_os(const.CONFIG_OS_UBUNTU) ), ) elif os_image.os_distro.lower() == "windows": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_WINDOWS, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_WINDOWS), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_WINDOWS), + resourcePolicy=self._get_resource_policy_for_os( + const.CONFIG_OS_WINDOWS + ), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_WINDOWS + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_WINDOWS) + self._get_license_for_os(const.CONFIG_OS_WINDOWS) ), ) elif os_image.os_distro.lower() == "cirros": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_CIRROS, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_CIRROS), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_CIRROS), + resourcePolicy=self._get_resource_policy_for_os(const.CONFIG_OS_CIRROS), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_CIRROS + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_CIRROS) + self._get_license_for_os(const.CONFIG_OS_CIRROS) ), ) elif os_image.os_distro.lower() == "almalinux": return OperatingSystem( version=os_image.os_version, osDistribution=const.CONFIG_OS_ALMALINUX, - resourcePolicy=self.conf.get_resource_policy(const.CONFIG_OS_ALMALINUX), - copyrightOwnedBy=self.conf.get_copyright_owner(const.CONFIG_OS_ALMALINUX), + resourcePolicy=self._get_resource_policy_for_os( + const.CONFIG_OS_ALMALINUX + ), + copyrightOwnedBy=self._get_copyright_owner_for_os( + const.CONFIG_OS_ALMALINUX + ), license=self._get_license_list( - self.conf.get_license(const.CONFIG_OS_ALMALINUX) + self._get_license_for_os(const.CONFIG_OS_ALMALINUX) ), ) else: - raise ValueError( - "Unsupported value for operating system distribution found: '" - + os_image.os_distro - + "'" - ) + raise ValueError("Unsupported value for operating system distribution found: '" + os_image.os_distro + "'") + + def _get_resource_policy_for_os(self, os: str) -> str: + return self.conf.get_value( + [ + const.CONFIG_DEFAULT, + const.CONFIG_OPERATING_SYSTEM, + os, + const.CONFIG_RESOURCE_POLICY, + ] + ) + + def _get_copyright_owner_for_os(self, os: str) -> List[str]: + return self.conf.get_value( + [ + const.CONFIG_DEFAULT, + const.CONFIG_OPERATING_SYSTEM, + os, + const.CONFIG_COPYRIGHT, + ] + ) + + def _get_license_for_os(self, os: str) -> List[str]: + return self.conf.get_value( + [ + const.CONFIG_DEFAULT, + const.CONFIG_OPERATING_SYSTEM, + os, + const.CONFIG_LICENSE, + ] + ) def _add_copyright_owner(self, os_image: OS_Image, gx_image: GX_Image) -> None: try: @@ -623,10 +705,7 @@ def _get_update_strategy(os_image: OS_Image) -> UpdateStrategy: ) else: update_strategy.providedUntil = None - if ( - "hotfix_hours" in os_image.properties - and os_image.properties["hotfix_hours"] - ): + if "hotfix_hours" in os_image.properties and os_image.properties["hotfix_hours"]: try: hot_h = int(os_image.properties["hotfix_hours"]) if hot_h >= 0: @@ -640,16 +719,10 @@ def _get_update_strategy(os_image: OS_Image) -> UpdateStrategy: @staticmethod def _get_description(os_image: OS_Image) -> str: - if ( - os_image.properties is not None - and "image_description" in os_image.properties - ): + if os_image.properties is not None and "image_description" in os_image.properties: if "managed_by_VENDOR" in os_image.properties: - return ( - os_image.properties["image_description"] - + " Managed by " - + os_image.properties["managed_by_VENDOR"] - ) + return os_image.properties["image_description"] + " Managed by " + os_image.properties[ + "managed_by_VENDOR"] else: return os_image.properties["image_description"] @@ -659,10 +732,7 @@ def _get_name(os_image: OS_Image) -> str: @staticmethod def _get_build_date(os_image: OS_Image) -> datetime: - if ( - os_image.properties is not None - and "image_build_date" in os_image.properties - ): + if os_image.properties is not None and "image_build_date" in os_image.properties: return datetime.strptime( os_image.properties["image_build_date"], "%Y-%m-%d" ) @@ -684,18 +754,11 @@ def _get_maintenance(os_image: OS_Image) -> MaintenanceSubscription: maint = MaintenanceSubscription( subscriptionRequired=False, subscriptionIncluded=False ) - maint.subscriptionRequired = bool( - os_image.properties - and os_image.properties.get("subscription_required", None) - ) maint.subscriptionIncluded = bool( - os_image.properties - and os_image.properties.get("subscription_included", None) - ) - if ( - os_image.properties is not None - and "maintained_until" in os_image.properties - ): + os_image.properties and os_image.properties.get("subscription_included", None)) + maint.subscriptionRequired = bool( + os_image.properties and os_image.properties.get("subscription_required", None)) + if os_image.properties is not None and "maintained_until" in os_image.properties: main_until = os_image.properties["maintained_until"] maint.maintainedUntil = datetime.strptime(main_until, "%Y-%m-%d").date() return maint diff --git a/generator/vendor/flavor_names.py b/generator/vendor/flavor_names.py index 88b51da..f60c796 100644 --- a/generator/vendor/flavor_names.py +++ b/generator/vendor/flavor_names.py @@ -9,13 +9,19 @@ import yaml -CPUTYPE_KEY = {'L': 'crowded-core', 'V': 'shared-core', 'T': 'dedicated-thread', 'C': 'dedicated-core'} -DISKTYPE_KEY = {'n': 'network', 'h': 'hdd', 's': 'ssd', 'p': 'nvme'} +CPUTYPE_KEY = { + "L": "crowded-core", + "V": "shared-core", + "T": "dedicated-thread", + "C": "dedicated-core", +} +DISKTYPE_KEY = {"n": "network", "h": "hdd", "s": "ssd", "p": "nvme"} HERE = Path(__file__).parent class TypeCheck: """class for validating the type of some attribute within a flavor name""" + def __call__(self, attr: str, value): raise ValueError(f"{attr} can not be set to {value}") @@ -36,7 +42,9 @@ def __init__(self, tbl): def __call__(self, attr, value): if value not in self.tbl: - raise ValueError(f"{attr} can not be set to {value!r}; must be one of {tuple(self.tbl)}") + raise ValueError( + f"{attr} can not be set to {value!r}; must be one of {tuple(self.tbl)}" + ) class BoolCheck(TypeCheck): @@ -48,17 +56,22 @@ def __call__(self, attr, value): class IntCheck(TypeCheck): def __call__(self, attr, value): if not isinstance(value, int) or value <= 0: - raise ValueError(f"{attr} can not be set to {value!r}; must be positive integer") + raise ValueError( + f"{attr} can not be set to {value!r}; must be positive integer" + ) class FloatCheck(TypeCheck): def __call__(self, attr, value): if not isinstance(value, float) or value <= 0 or int(2 * value) != 2 * value: - raise ValueError(f"{attr} can not be set to {value!r}; must be positive multiple of 0.5") + raise ValueError( + f"{attr} can not be set to {value!r}; must be positive multiple of 0.5" + ) class Attr: """class to represent one attribute, such as brand, of one component, such as gpu, of a flavor name""" + typ = None default = None @@ -91,7 +104,7 @@ def __set_name__(self, owner, name): if self.letter is None: self.letter = name self.attr = name - self._attr = '_' + name + self._attr = "_" + name def __get__(self, obj, objclass=None): if obj is None: @@ -146,10 +159,19 @@ def __set__(self, obj, value): class Main: """Class representing the first part (CPU+RAM)""" + type = "CPU-RAM" component_name = "cpuram" cpus = IntAttr("#vCPUs") - cputype = TblAttr("CPU type", {"L": "LowPerf vCPUs", "V": "vCPUs", "T": "SMT Threads", "C": "Dedicated Cores"}) + cputype = TblAttr( + "CPU type", + { + "L": "LowPerf vCPUs", + "V": "vCPUs", + "T": "SMT Threads", + "C": "Dedicated Cores", + }, + ) cpuinsecure = BoolAttr("?Insec SMT", letter="i") ram = FloatAttr("##GiB RAM") raminsecure = BoolAttr("?no ECC", letter="u") @@ -158,22 +180,43 @@ class Main: class Disk: """Class representing the disk part""" + type = "Disk" component_name = "disk" nrdisks = IntAttr("#.NrDisks", default=1) disksize = OptIntAttr("#.GB Disk") - disktype = TblAttr("Disk type", {'': '(unspecified)', "n": "Networked", "h": "Local HDD", "s": "SSD", "p": "HiPerf NVMe"}) + disktype = TblAttr( + "Disk type", + { + "": "(unspecified)", + "n": "Networked", + "h": "Local HDD", + "s": "SSD", + "p": "HiPerf NVMe", + }, + ) class Hype: """Class repesenting Hypervisor""" + type = "Hypervisor" component_name = "hype" - hype = TblAttr(".Hypervisor", {"kvm": "KVM", "xen": "Xen", "hyv": "Hyper-V", "vmw": "VMware", "bms": "Bare Metal System"}) + hype = TblAttr( + ".Hypervisor", + { + "kvm": "KVM", + "xen": "Xen", + "hyv": "Hyper-V", + "vmw": "VMware", + "bms": "Bare Metal System", + }, + ) class HWVirt: """Class repesenting support for hardware virtualization""" + type = "Hardware/NestedVirtualization" component_name = "hwvirt" hwvirt = BoolAttr("?HardwareVirt", letter="hwv") @@ -181,36 +224,107 @@ class HWVirt: class CPUBrand: """Class repesenting CPU brand""" + type = "CPUBrand" component_name = "cpubrand" - cpuvendor = TblAttr("CPU Vendor", {"i": "Intel", "z": "AMD", "a": "ARM", "r": "RISC-V"}) - cpugen = DepTblAttr("#.CPU Gen", cpuvendor, { - "i": {None: '(unspecified)', 0: "Unspec/Pre-Skylake", 1: "Skylake", 2: "Cascade Lake", 3: "Ice Lake", 4: "Sapphire Rapids"}, - "z": {None: '(unspecified)', 0: "Unspec/Pre-Zen", 1: "Zen 1", 2: "Zen 2", 3: "Zen 3", 4: "Zen 4"}, - "a": {None: '(unspecified)', 0: "Unspec/Pre-A76", 1: "A76/NeoN1", 2: "A78/X1/NeoV1", 3: "A710/NeoN2"}, - "r": {None: '(unspecified)', 0: "Unspec"}, - }) - perf = TblAttr("Performance", {"": "Std Perf", "h": "High Perf", "hh": "Very High Perf", "hhh": "Very Very High Perf"}) + cpuvendor = TblAttr( + "CPU Vendor", {"i": "Intel", "z": "AMD", "a": "ARM", "r": "RISC-V"} + ) + cpugen = DepTblAttr( + "#.CPU Gen", + cpuvendor, + { + "i": { + None: "(unspecified)", + 0: "Unspec/Pre-Skylake", + 1: "Skylake", + 2: "Cascade Lake", + 3: "Ice Lake", + 4: "Sapphire Rapids", + }, + "z": { + None: "(unspecified)", + 0: "Unspec/Pre-Zen", + 1: "Zen 1", + 2: "Zen 2", + 3: "Zen 3", + 4: "Zen 4", + }, + "a": { + None: "(unspecified)", + 0: "Unspec/Pre-A76", + 1: "A76/NeoN1", + 2: "A78/X1/NeoV1", + 3: "A710/NeoN2", + }, + "r": {None: "(unspecified)", 0: "Unspec"}, + }, + ) + perf = TblAttr( + "Performance", + { + "": "Std Perf", + "h": "High Perf", + "hh": "Very High Perf", + "hhh": "Very Very High Perf", + }, + ) class GPU: """Class repesenting GPU support""" + type = "GPU" component_name = "gpu" gputype = TblAttr("Type", {"g": "vGPU", "G": "Pass-Through GPU"}) brand = TblAttr("Brand", {"N": "nVidia", "A": "AMD", "I": "Intel"}) - gen = DepTblAttr("Gen", brand, { - "N": {'': '(unspecified)', "f": "Fermi", "k": "Kepler", "m": "Maxwell", "p": "Pascal", - "v": "Volta", "t": "Turing", "a": "Ampere", "l": "AdaLovelace"}, - "A": {'': '(unspecified)', "0.4": "GCN4.0/Polaris", "0.5": "GCN5.0/Vega", "1": "RDNA1/Navi1x", "2": "RDNA2/Navi2x", "3": "RDNA3/Navi3x"}, - "I": {'': '(unspecified)', "0.9": "Gen9/Skylake", "0.95": "Gen9.5/KabyLake", "1": "Xe1/Gen12.1", "2": "Xe2"}, - }) + gen = DepTblAttr( + "Gen", + brand, + { + "N": { + "": "(unspecified)", + "f": "Fermi", + "k": "Kepler", + "m": "Maxwell", + "p": "Pascal", + "v": "Volta", + "t": "Turing", + "a": "Ampere", + "l": "AdaLovelace", + }, + "A": { + "": "(unspecified)", + "0.4": "GCN4.0/Polaris", + "0.5": "GCN5.0/Vega", + "1": "RDNA1/Navi1x", + "2": "RDNA2/Navi2x", + "3": "RDNA3/Navi3x", + }, + "I": { + "": "(unspecified)", + "0.9": "Gen9/Skylake", + "0.95": "Gen9.5/KabyLake", + "1": "Xe1/Gen12.1", + "2": "Xe2", + }, + }, + ) cu = OptIntAttr("#.CU/EU/SM") - perf = TblAttr("Performance", {"": "Std Perf", "h": "High Perf", "hh": "Very High Perf", "hhh": "Very Very High Perf"}) + perf = TblAttr( + "Performance", + { + "": "Std Perf", + "h": "High Perf", + "hh": "Very High Perf", + "hhh": "Very Very High Perf", + }, + ) class IB: """Class representing Infiniband""" + type = "Infiniband" component_name = "ib" ib = BoolAttr("?IB") @@ -218,9 +332,16 @@ class IB: class Flavorname: """A flavor name; merely a bunch of components""" + def __init__( - self, cpuram: Main = None, disk: Disk = None, hype: Hype = None, hwvirt: HWVirt = None, - cpubrand: CPUBrand = None, gpu: GPU = None, ib: IB = None + self, + cpuram: Main = None, + disk: Disk = None, + hype: Hype = None, + hwvirt: HWVirt = None, + cpubrand: CPUBrand = None, + gpu: GPU = None, + ib: IB = None, ): self.cpuram = cpuram self.disk = disk @@ -313,6 +434,7 @@ class SyntaxV1: """ This class bundles the regular expressions that comprise the syntax for v1 of the standard. """ + prefix = "SCS-" cpuram = re.compile(r"([0-9]*)([LVTC])(i|):([0-9\.]*)(u|)(o|)") disk = re.compile(r":(?:([0-9]*)x|)([0-9]*)([nhsp]|)") @@ -326,7 +448,7 @@ class SyntaxV1: @staticmethod def from_v2(nm: str) -> str: """v2 to v1 flavor name transformation""" - return nm.replace('-', ':').replace('_', '-').replace('SCS:', 'SCS-') + return nm.replace("-", ":").replace("_", "-").replace("SCS:", "SCS-") class SyntaxV2: @@ -338,6 +460,7 @@ class SyntaxV2: Note that the syntax hasn't changed since v2, so this class is still valid. """ + prefix = "SCS-" cpuram = re.compile(r"([0-9]*)([LVTC])(i|)\-([0-9\.]*)(u|)(o|)") disk = re.compile(r"\-(?:([0-9]*)x|)([0-9]*)([nhsp]|)") @@ -351,11 +474,12 @@ class SyntaxV2: @staticmethod def from_v1(nm: str) -> str: """v1 to v2 flavor name transformation""" - return nm.replace('-', '_').replace(':', '-').replace('SCS_', 'SCS-') + return nm.replace("-", "_").replace(":", "-").replace("SCS_", "SCS-") class ParseCtx: """Auxiliary class used during parsing to hold current position in the string""" + def __init__(self, s: str, pos=0): self.s = s self.pos = pos @@ -363,6 +487,7 @@ def __init__(self, s: str, pos=0): class ComponentParser: """Auxiliary class for parsing a single component of a flavor name""" + def __init__(self, parsestr: re.Pattern, targetcls): self.parsestr = parsestr # re.Pattern as defined in `SyntaxV1` or `SyntaxV2` self.targetcls = targetcls # component class such as `Main` or `Disk` @@ -374,7 +499,9 @@ def parse(self, ctx: ParseCtx): match_attr = Attr.collect(self.targetcls) groups = m.groups() if len(groups) != len(match_attr): - raise ValueError(f"unexpected number of matching groups: {match_attr} vs {groups}") + raise ValueError( + f"unexpected number of matching groups: {match_attr} vs {groups}" + ) t = self.targetcls() for attr, group in zip(match_attr, groups): if attr.name[:2] == "##": @@ -500,6 +627,7 @@ def lookup_user_input(formdata, idx, attr, target): class Inputter: """Auxiliary class for interactive input of flavor names.""" + def __init__(self, obtain_input=ask_user_input): self.ask_user_input = staticmethod(obtain_input) @@ -518,7 +646,9 @@ def __call__(self): flavorname = Flavorname() flavorname.cpuram = self.input_component(Main) flavorname.disk = self.input_component(Disk) - if flavorname.disk and not (flavorname.disk.nrdisks and flavorname.disk.disksize): + if flavorname.disk and not ( + flavorname.disk.nrdisks and flavorname.disk.disksize + ): # special case... flavorname.disk = None flavorname.hype = self.input_component(Hype) @@ -539,16 +669,16 @@ def __call__(self): def flavorname_to_dict(flavorname: Flavorname) -> dict: name_v2 = outputter(flavorname) result = { - 'cpus': flavorname.cpuram.cpus, - 'cpu-type': CPUTYPE_KEY[flavorname.cpuram.cputype], - 'ram': flavorname.cpuram.ram, - 'name-v1': SyntaxV1.from_v2(name_v2), - 'name-v2': name_v2, + "cpus": flavorname.cpuram.cpus, + "cpu-type": CPUTYPE_KEY[flavorname.cpuram.cputype], + "ram": flavorname.cpuram.ram, + "name-v1": SyntaxV1.from_v2(name_v2), + "name-v2": name_v2, } if flavorname.disk: - result['disk'] = flavorname.disk.disksize + result["disk"] = flavorname.disk.disksize for i in range(flavorname.disk.nrdisks): - result[f'disk{i}-type'] = DISKTYPE_KEY[flavorname.disk.disktype or 'n'] + result[f"disk{i}-type"] = DISKTYPE_KEY[flavorname.disk.disktype or "n"] return result @@ -598,14 +728,14 @@ def prettyname(flavorname, prefix=""): if flavorname.hype: stg += f'on {_tbl_out(flavorname.hype, "hype")}' if flavorname.hwvirt: - stg += 'with HW virt ' + stg += "with HW virt " # Disk if flavorname.disk: stg += "and " stg += _tbl_out(flavorname.disk, "disktype", True) if flavorname.disk.nrdisks != 1: - stg += f'{flavorname.disk.nrdisks}x' - stg += f'{flavorname.disk.disksize}GB root volume ' + stg += f"{flavorname.disk.nrdisks}x" + stg += f"{flavorname.disk.disksize}GB root volume " # GPU if flavorname.gpu: stg += "and " + _tbl_out(flavorname.gpu, "gputype") @@ -624,6 +754,7 @@ class CompatLayer: """ This class provides convenience functions previously found in `flavor-name-check.py`. """ + def __init__(self): self.verbose = False self.debug = False @@ -633,7 +764,7 @@ def __init__(self): self.v3_flv = False self.mandFlavorFile = str(Path(HERE.parent, "SCS-Spec.MandatoryFlavors.yaml")) bindir = os.path.basename(sys.argv[0]) - self.searchpath = (bindir, ) if bindir else os.environ['PATH'].split(':') + self.searchpath = (bindir,) if bindir else os.environ["PATH"].split(":") def parsename(self, namestr: str) -> Optional[Flavorname]: """ @@ -698,5 +829,8 @@ def readflavors(self, fnm, v3mode): if __name__ == "__main__": namestr = "SCS-16T-64-3x10s_bms_hwv_i3h_GNa-64_ib" - print(outputter(parser_v1("SCS-16T:64:3x10s-GNa:64-ib")) == outputter(parser_v2(namestr).shorten())) + print( + outputter(parser_v1("SCS-16T:64:3x10s-GNa:64-ib")) + == outputter(parser_v2(namestr).shorten()) + ) print(namestr == outputter(parser_v2(namestr))) diff --git a/gx-cred-generator.py b/gx-cred-generator.py index a30a239..6f41bce 100755 --- a/gx-cred-generator.py +++ b/gx-cred-generator.py @@ -10,9 +10,7 @@ SPDX-License-Identifier: EPL-2.0 """ -import sys import getopt -import importlib import json import sys import yaml diff --git a/gx_context.py b/gx_context.py index b7f2810..5cf3268 100755 --- a/gx_context.py +++ b/gx_context.py @@ -12,7 +12,7 @@ gxcontext = {"@context": { "gx": "https://https://registry.lab.gaia-x.eu//v1$/gx#", "xsd": "http://www.w3.org/2001/XMLSchema#" - } +} } gxtype = {"@type": "gx:ServiceOffering"} diff --git a/k8s-discovery.py b/k8s-discovery.py index 282210d..847fc46 100755 --- a/k8s-discovery.py +++ b/k8s-discovery.py @@ -177,7 +177,7 @@ def main(argv): "Entry point for main program" global cloud, outjson, indent global debug, ofile - timeout = 12 + # timeout = 12 conn = kubeconn(None, None, None) my_kube = KubeCluster(conn) if ofile == "/dev/stdout": diff --git a/openstack-discovery.py b/openstack-discovery.py index dde742f..0b821e3 100755 --- a/openstack-discovery.py +++ b/openstack-discovery.py @@ -40,7 +40,7 @@ def appenddicts(dct1, *kwd): "Return dict d1 with items from kwd added" dct = dct1 for k in kwd: - assert(k is not None) + assert (k is not None) dct.update(k) return dct @@ -92,6 +92,7 @@ def versinfo(connprox, stype, region): class osServiceCat: "OpenStack service catalog" + def __init__(self, dct, regfilter): self.id = dct["id"] self.region = regfilter @@ -114,6 +115,7 @@ def __str__(self): class osService: "A generic openStack service, with a proxy connection object from SDK" + def __init__(self, conn, stype, name, region, prj_id, ept, quiet=True): "c'tor for the OpenStack service to be caled by subclasses" global errors @@ -165,8 +167,9 @@ def __init__(self, conn, stype, name, region, prj_id, ept, quiet=True): self.extensions = list(map(lambda x: x.alias, self.conn.extensions())) except Exception as exc: if not quiet: - print(f"#WARNING: Service {self.fulltype} in region {region} does not support getting extensions.\n{exc}", - file=sys.stderr) + print( + f"#WARNING: Service {self.fulltype} in region {region} does not support getting extensions.\n{exc}", + file=sys.stderr) try: self.azs = list(filter(lambda x: x.state['available'] is True, self.conn.availability_zones())) except Exception: @@ -207,6 +210,7 @@ def __str__(self): class osFlavor: "Abstraction for flavors" + def __init__(self, flv): self.name = flv['name'] # Note: cpuType, cpuGeneration, diskType are MR34 ideas, @@ -215,14 +219,14 @@ def __init__(self, flv): self.cpuType = "" self.cpuGeneration = "" self.numberOfvCPUs = flv['vcpus'] - self.ramSize = flv['ram'] # MiB - self.diskSize = flv['disk'] # GB + self.ramSize = flv['ram'] # MiB + self.diskSize = flv['disk'] # GB self.diskType = "" def values(self): - ydct = dict(name = self.name, - numberOfvCPUs = self.numberOfvCPUs, - ramSize = dict(Value=self.ramSize/1024, Unit='GiB')) + ydct = dict(name=self.name, + numberOfvCPUs=self.numberOfvCPUs, + ramSize=dict(Value=self.ramSize / 1024, Unit='GiB')) if self.diskSize: ydct['diskSize'] = dict(Value=self.diskSize, Unit='GB') # TODO: cpuType, cpuGen, diskType output @@ -262,6 +266,7 @@ def get_openstack_flavors(self): class azInfo: "Convert zoneXxx dict into class with Xxx attributes for availability zones" + def __init__(self, dct): for key in dct: if key[:4] == "zone": @@ -328,6 +333,7 @@ def values(self): dct[self.stype]["flavors"] = self.flavors return dct + # TODO: List of public images with properties @@ -366,6 +372,7 @@ def values(self): class nonOSService: "Non-OpenStack services listed in the service catalogue" + def __init__(self, stype, name, url): self.stype = stype self.name = name @@ -382,6 +389,7 @@ def __str__(self): class osCloud: "Abstraction for openStack cloud with all its services" + def __init__(self, conn): # import copy self.conn = conn @@ -488,12 +496,12 @@ def usage(err=1): def ostackconn(cloud, timeout): "Establish connection to OpenStack cloud cloud (timeout timeout)" - conn = openstack.connect(cloud=cloud, timeout=timeout, api_timeout=timeout*1.5+4) + conn = openstack.connect(cloud=cloud, timeout=timeout, api_timeout=timeout * 1.5 + 4) try: conn.authorize() except Exception: print("INFO: Retry connection with 'default' domain", file=sys.stderr) - conn = openstack.connect(cloud=cloud, timeout=timeout, api_timeout=timeout*1.5+4, + conn = openstack.connect(cloud=cloud, timeout=timeout, api_timeout=timeout * 1.5 + 4, default_domain='default', project_domain_id='default') conn.authorize() return conn diff --git a/tests/common.py b/tests/common.py index 44c5553..e04f47d 100644 --- a/tests/common.py +++ b/tests/common.py @@ -27,7 +27,7 @@ VirtualResource, VMImage, ServerFlavor, -InstantiationRequirement + InstantiationRequirement ) @@ -214,7 +214,7 @@ def assert_vm_image(self, exp: VMImage, act: VMImage): self.assertEqual(exp.hwRngTypeOfImage, act.hwRngTypeOfImage, "VM_Image.hwRngTypeOfImage") def check_installation_requirement( - self, ob_1: InstantiationRequirement, ob_2: InstantiationRequirement + self, ob_1: InstantiationRequirement, ob_2: InstantiationRequirement ): self.assert_gaia_x_entity(ob_1, ob_2) @@ -256,6 +256,7 @@ def assert_flavor(self, ob_1: ServerFlavor, ob_2: ServerFlavor): for i in range(9, len(ob_1.additionalVolume) - 1): self.assert_disk(ob_1.additionalVolume[i], ob_2.additionalVolume[i]) + class MockConnection: """ Wrap connection to OpenStack Cluster diff --git a/tests/test_json_ld.py b/tests/test_json_ld.py index dad0704..fb4b9dc 100644 --- a/tests/test_json_ld.py +++ b/tests/test_json_ld.py @@ -1,6 +1,6 @@ import unittest -from generator.common.gx_schema import GaiaX, GaiaXEntity, InstantiationRequirement, ServerFlavor +from generator.common.gx_schema import GaiaX, GaiaXEntity, ServerFlavor from generator.common.json_ld import get_json_ld_types, get_slot_curie diff --git a/tests/test_server_flavor_discovery.py b/tests/test_server_flavor_discovery.py index 355dbaf..75508de 100644 --- a/tests/test_server_flavor_discovery.py +++ b/tests/test_server_flavor_discovery.py @@ -10,7 +10,7 @@ from generator.common.gx_schema import ServerFlavor as GX_Flavor from generator.discovery.openstack.server_flavor_discovery import \ ServerFlavorDiscovery -from generator.vendor.flavor_names import Flavorname, parser_v3 +from generator.vendor.flavor_names import parser_v3 from tests.common import MockConnection, OpenstackTestcase, get_config OS_FLAVOR_1 = OS_Flavor(id="flavor_1", name="ABC", vcpus=2, ram=16, disk=0, description=None) From de072c9f0fc000703def89e4f91915b553a3bc13 Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Thu, 11 Apr 2024 10:32:34 +0200 Subject: [PATCH 17/20] Revert unintended renaming of discovery --> openstack_discovery Signed-off-by: Anja Strunk --- gx-cred-generator.py | 2 +- k8s-discovery.py | 2 +- openstack-discovery.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gx-cred-generator.py b/gx-cred-generator.py index 6f41bce..564c062 100755 --- a/gx-cred-generator.py +++ b/gx-cred-generator.py @@ -3,7 +3,7 @@ # # gx-sd-generator.py """Script to generate Gaia-X JSON-LD for credentials. - Uses openstack-openstack_discovery.py and k8s-openstack_discovery.py to + Uses openstack-discovery.py and k8s-discovery.py to collect the data. (c) Kurt Garloff , 5/2023 diff --git a/k8s-discovery.py b/k8s-discovery.py index 847fc46..eba98d7 100755 --- a/k8s-discovery.py +++ b/k8s-discovery.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set ts=4 sw=4 et: # -# k8s-openstack_discovery.py +# k8s-discovery.py """ Talk to K8s APIs to discover environment Save discovered information in classes that reflect G-X attributes diff --git a/openstack-discovery.py b/openstack-discovery.py index 0b821e3..288b142 100755 --- a/openstack-discovery.py +++ b/openstack-discovery.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set ts=4 sw=4 et: # -# openstack-openstack_discovery.py +# openstack-discovery.py """ Talk to OpenStack APIs to discover environment Save discovered information in classes that reflect G-X attributes @@ -482,7 +482,7 @@ def __str__(self): def usage(err=1): "output help" - print("Usage: openstack-openstack_discovery.py [options]", file=sys.stderr) + print("Usage: openstack-discovery.py [options]", file=sys.stderr) print("Options: -j/--json: output GX JSON-LD instead of YAML") print(" -J/--json-compact: output compact GX JSON-LD instead of YAML") print(" -f FILE/--file=FILE: write output to FILE (default: stdout)") From 09f8a5899845b880a8068967190ee12cf30c38c7 Mon Sep 17 00:00:00 2001 From: anjastrunk <119566837+anjastrunk@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:42:32 +0200 Subject: [PATCH 18/20] Update tests/common.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Büchse Signed-off-by: anjastrunk <119566837+anjastrunk@users.noreply.github.com> --- tests/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common.py b/tests/common.py index e04f47d..3ff4b7e 100644 --- a/tests/common.py +++ b/tests/common.py @@ -213,7 +213,7 @@ def assert_vm_image(self, exp: VMImage, act: VMImage): self.assertEqual(exp.firmwareType, act.firmwareType, "VM_Image.firmwareType") self.assertEqual(exp.hwRngTypeOfImage, act.hwRngTypeOfImage, "VM_Image.hwRngTypeOfImage") - def check_installation_requirement( + def check_instantiation_requirement( self, ob_1: InstantiationRequirement, ob_2: InstantiationRequirement ): self.assert_gaia_x_entity(ob_1, ob_2) From 0012be6390ae38077008b8c5ca702a67dccb877a Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Thu, 11 Apr 2024 11:13:14 +0200 Subject: [PATCH 19/20] Simplify tests/common.py Signed-off-by: Anja Strunk --- .../openstack/server_flavor_discovery.py | 6 +++--- tests/common.py | 16 +++++----------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index 0b08b5b..baa2d90 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -127,9 +127,9 @@ def _get_cpu(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> CP """ cpu = CPU(cpuArchitecture=CpuArch.other, numberOfCores=os_flavor.vcpus) if flavorname: - cpu.smtEnabled = ( - flavorname.cpuram.cputype != "C" - ) # FIXME this is unclear to me + #cpu.smtEnabled = ( + # flavorname.cpuram.cputype != "C" + #) # FIXME this is unclear to me, see #85 cpu.defaultOversubscriptionRatio = 1 if flavorname.cpuram.cputype == "V": cpu.defaultOversubscriptionRatio = 5 diff --git a/tests/common.py b/tests/common.py index e04f47d..964e1cb 100644 --- a/tests/common.py +++ b/tests/common.py @@ -263,20 +263,14 @@ class MockConnection: """ def __init__(self, images: List[OS_Image] = None, flavors: List[OS_Flavor] = None): - self.images = images - self.flavors = flavors + self.images = images or [] + self.flavors = flavors or [] def list_images(self) -> List[OS_Image]: - if self.images: - return self.images - else: - return [] + return self.images def list_flavors(self) -> List[OS_Flavor]: - if self.flavors: - return self.flavors - else: - return [] - + return self.flavors + def authorize(self): pass From 648541b92922c728e74c3dbccda7da68ccc600f8 Mon Sep 17 00:00:00 2001 From: Anja Strunk Date: Thu, 11 Apr 2024 11:26:16 +0200 Subject: [PATCH 20/20] Fix unit tests and flake8 errors Signed-off-by: Anja Strunk --- .../discovery/openstack/server_flavor_discovery.py | 11 ++++------- generator/discovery/openstack/vm_images_discovery.py | 11 ++++------- tests/common.py | 4 ++-- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/generator/discovery/openstack/server_flavor_discovery.py b/generator/discovery/openstack/server_flavor_discovery.py index baa2d90..8936604 100644 --- a/generator/discovery/openstack/server_flavor_discovery.py +++ b/generator/discovery/openstack/server_flavor_discovery.py @@ -26,7 +26,6 @@ from generator.common.json_ld import JsonLdObject from generator.vendor.flavor_names import Flavorname, parser_v3 - # map SCS hypervisor names to corresponding GX type and config key HYPERVISOR_LOOKUP = { "kvm": (HypervisorType.KVM, const.CONFIG_HV_KVM), @@ -127,9 +126,7 @@ def _get_cpu(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> CP """ cpu = CPU(cpuArchitecture=CpuArch.other, numberOfCores=os_flavor.vcpus) if flavorname: - #cpu.smtEnabled = ( - # flavorname.cpuram.cputype != "C" - #) # FIXME this is unclear to me, see #85 + cpu.smtEnabled = (flavorname.cpuram.cputype != "C") # FIXME this is unclear to me, see #85 cpu.defaultOversubscriptionRatio = 1 if flavorname.cpuram.cputype == "V": cpu.defaultOversubscriptionRatio = 5 @@ -138,7 +135,7 @@ def _get_cpu(self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname]) -> CP return cpu def _get_ram( - self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname] + self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname] ) -> Memory: """ Return Gaia-X RAM definition specified in given OpenStack flavor. @@ -156,7 +153,7 @@ def _get_ram( return mem def _get_disks( - self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname] + self, os_flavor: OS_Flavor, flavorname: Optional[Flavorname] ) -> List[Disk]: """ Return all disk specification found in given Openstack flavor. @@ -196,7 +193,7 @@ def _get_disks( return disks def _parse_optional_flavor_properties( - self, flavorname: Optional[Flavorname], gx_flavor: GX_Flavor + self, flavorname: Optional[Flavorname], gx_flavor: GX_Flavor ): """Parse and return optional flavor properties, such as CPU architecture, CPU frequency or hypervisor. @param os_flavor Openstack flavor diff --git a/generator/discovery/openstack/vm_images_discovery.py b/generator/discovery/openstack/vm_images_discovery.py index eb18bdc..8b28269 100644 --- a/generator/discovery/openstack/vm_images_discovery.py +++ b/generator/discovery/openstack/vm_images_discovery.py @@ -120,7 +120,7 @@ def __init__(self, conn: Connection, conf: Config) -> None: self.conf = conf # def collect_vm_images(self, conn: Connection) -> List[str]: - def discover_vm_images(self) -> List[JsonLdObject]: + def discover(self) -> List[JsonLdObject]: """ Return one credential for each public VM image offered by openstack cloud. @@ -577,8 +577,7 @@ def _get_operation_system(self, os_image: OS_Image) -> OperatingSystem: def _get_resource_policy_for_os(self, os: str) -> str: return self.conf.get_value( [ - const.CONFIG_DEFAULT, - const.CONFIG_OPERATING_SYSTEM, + const.CONFIG_SOFTWARE, os, const.CONFIG_RESOURCE_POLICY, ] @@ -587,8 +586,7 @@ def _get_resource_policy_for_os(self, os: str) -> str: def _get_copyright_owner_for_os(self, os: str) -> List[str]: return self.conf.get_value( [ - const.CONFIG_DEFAULT, - const.CONFIG_OPERATING_SYSTEM, + const.CONFIG_SOFTWARE, os, const.CONFIG_COPYRIGHT, ] @@ -597,8 +595,7 @@ def _get_copyright_owner_for_os(self, os: str) -> List[str]: def _get_license_for_os(self, os: str) -> List[str]: return self.conf.get_value( [ - const.CONFIG_DEFAULT, - const.CONFIG_OPERATING_SYSTEM, + const.CONFIG_SOFTWARE, os, const.CONFIG_LICENSE, ] diff --git a/tests/common.py b/tests/common.py index dd2c3f8..8d08720 100644 --- a/tests/common.py +++ b/tests/common.py @@ -263,7 +263,7 @@ class MockConnection: """ def __init__(self, images: List[OS_Image] = None, flavors: List[OS_Flavor] = None): - self.images = images or [] + self.images = images or [] self.flavors = flavors or [] def list_images(self) -> List[OS_Image]: @@ -271,6 +271,6 @@ def list_images(self) -> List[OS_Image]: def list_flavors(self) -> List[OS_Flavor]: return self.flavors - + def authorize(self): pass