osi-dump 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- osi_dump/batch_handler/external_port_batch_handler.py +8 -26
- osi_dump/batch_handler/flavor_batch_handler.py +4 -18
- osi_dump/batch_handler/hypervisor_batch_handler.py +5 -17
- osi_dump/batch_handler/image_batch_handler.py +4 -18
- osi_dump/batch_handler/network_batch_handler.py +5 -19
- osi_dump/batch_handler/project_batch_handler.py +5 -17
- osi_dump/batch_handler/router_batch_handler.py +4 -16
- osi_dump/batch_handler/volume_batch_handler.py +4 -10
- osi_dump/exporter/external_port/excel_external_port_exporter.py +16 -11
- osi_dump/exporter/external_port/external_port_exporter.py +4 -3
- osi_dump/exporter/flavor/excel_flavor_exporter.py +10 -9
- osi_dump/exporter/flavor/flavor_exporter.py +4 -2
- osi_dump/exporter/floating_ip/excel_floating_ip_exporter.py +17 -11
- osi_dump/exporter/floating_ip/floating_ip_exporter.py +4 -2
- osi_dump/exporter/hypervisor/excel_hypervisor_exporter.py +14 -13
- osi_dump/exporter/hypervisor/hypervisor_exporter.py +4 -3
- osi_dump/exporter/image/excel_image_exporter.py +10 -7
- osi_dump/exporter/image/image_exporter.py +4 -2
- osi_dump/exporter/network/excel_network_exporter.py +13 -11
- osi_dump/exporter/network/network_exporter.py +4 -3
- osi_dump/exporter/project/excel_project_exporter.py +11 -11
- osi_dump/exporter/project/project_exporter.py +4 -3
- osi_dump/exporter/router/excel_router_exporter.py +9 -8
- osi_dump/exporter/router/router_exporter.py +3 -2
- osi_dump/exporter/volume/excel_volume_exporter.py +10 -8
- osi_dump/exporter/volume/volume_exporter.py +4 -2
- osi_dump/importer/external_port/external_port_importer.py +3 -4
- osi_dump/importer/external_port/openstack_external_port_importer.py +44 -131
- osi_dump/importer/flavor/flavor_importer.py +3 -3
- osi_dump/importer/flavor/openstack_flavor_importer.py +13 -35
- osi_dump/importer/floating_ip/floating_ip_importer.py +3 -3
- osi_dump/importer/floating_ip/openstack_floating_ip_importer.py +11 -38
- osi_dump/importer/hypervisor/hypervisor_importer.py +3 -4
- osi_dump/importer/hypervisor/openstack_hypervisor_importer.py +44 -88
- osi_dump/importer/image/image_importer.py +3 -3
- osi_dump/importer/image/openstack_image_importer.py +16 -44
- osi_dump/importer/network/network_importer.py +3 -4
- osi_dump/importer/network/openstack_network_importer.py +23 -52
- osi_dump/importer/project/openstack_project_importer.py +45 -83
- osi_dump/importer/project/project_importer.py +3 -4
- osi_dump/importer/router/openstack_router_importer.py +18 -53
- osi_dump/importer/router/router_importer.py +2 -3
- osi_dump/importer/volume/openstack_volume_importer.py +15 -45
- osi_dump/importer/volume/volume_importer.py +3 -4
- {osi_dump-0.1.5.dist-info → osi_dump-0.1.6.dist-info}/METADATA +1 -1
- {osi_dump-0.1.5.dist-info → osi_dump-0.1.6.dist-info}/RECORD +49 -49
- {osi_dump-0.1.5.dist-info → osi_dump-0.1.6.dist-info}/WHEEL +0 -0
- {osi_dump-0.1.5.dist-info → osi_dump-0.1.6.dist-info}/entry_points.txt +0 -0
- {osi_dump-0.1.5.dist-info → osi_dump-0.1.6.dist-info}/top_level.txt +0 -0
@@ -1,28 +1,31 @@
|
|
1
1
|
import pandas as pd
|
2
|
-
|
3
2
|
import logging
|
4
|
-
|
3
|
+
from typing import Generator
|
5
4
|
|
6
5
|
from osi_dump import util
|
7
6
|
from osi_dump.exporter.image.image_exporter import ImageExporter
|
8
|
-
|
9
7
|
from osi_dump.model.image import Image
|
10
8
|
|
11
9
|
logger = logging.getLogger(__name__)
|
12
10
|
|
13
|
-
|
14
11
|
class ExcelImageExporter(ImageExporter):
|
15
12
|
def __init__(self, sheet_name: str, output_file: str):
|
16
13
|
self.sheet_name = sheet_name
|
17
14
|
self.output_file = output_file
|
18
15
|
|
19
|
-
def export_images(self, images:
|
20
|
-
df = pd.json_normalize(
|
16
|
+
def export_images(self, images: Generator[Image, None, None]):
|
17
|
+
df = pd.json_normalize(image.model_dump() for image in images)
|
18
|
+
|
19
|
+
if df.empty:
|
20
|
+
logger.info(f"No images to export for {self.sheet_name}")
|
21
|
+
return
|
22
|
+
|
23
|
+
if 'image_name' in df.columns:
|
24
|
+
df.sort_values(by='image_name', inplace=True, na_position='last')
|
21
25
|
|
22
26
|
logger.info(f"Exporting images for {self.sheet_name}")
|
23
27
|
try:
|
24
28
|
util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
|
25
|
-
|
26
29
|
logger.info(f"Exported images for {self.sheet_name}")
|
27
30
|
except Exception as e:
|
28
31
|
logger.warning(f"Exporting images for {self.sheet_name} error: {e}")
|
@@ -1,7 +1,9 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
|
2
|
+
from typing import Generator
|
3
|
+
from osi_dump.model.image import Image
|
3
4
|
|
4
5
|
class ImageExporter(ABC):
|
5
6
|
@abstractmethod
|
6
|
-
def export_images(self, images,
|
7
|
+
def export_images(self, images: Generator[Image, None, None]):
|
7
8
|
pass
|
9
|
+
|
@@ -1,32 +1,34 @@
|
|
1
1
|
import logging
|
2
|
-
|
3
|
-
|
4
2
|
import pandas as pd
|
5
|
-
|
3
|
+
from typing import Generator
|
6
4
|
|
7
5
|
from osi_dump.exporter.network.network_exporter import NetworkExporter
|
8
|
-
|
9
6
|
from osi_dump.model.network import Network
|
10
|
-
|
11
7
|
from osi_dump import util
|
12
8
|
|
13
9
|
logger = logging.getLogger(__name__)
|
14
10
|
|
15
|
-
|
16
11
|
class ExcelNetworkExporter(NetworkExporter):
|
17
12
|
def __init__(self, sheet_name: str, output_file: str):
|
18
13
|
self.sheet_name = sheet_name
|
19
14
|
self.output_file = output_file
|
20
15
|
|
21
|
-
def export_networks(self, networks:
|
22
|
-
df = pd.
|
16
|
+
def export_networks(self, networks: Generator[Network, None, None]):
|
17
|
+
df = pd.DataFrame(network.model_dump() for network in networks)
|
23
18
|
|
24
|
-
df
|
19
|
+
if df.empty:
|
20
|
+
logger.info(f"No networks to export for {self.sheet_name}")
|
21
|
+
return
|
22
|
+
|
23
|
+
if 'subnets' in df.columns:
|
24
|
+
df = util.expand_list_column(df, "subnets")
|
25
|
+
|
26
|
+
if 'name' in df.columns:
|
27
|
+
df.sort_values(by='name', inplace=True, na_position='last')
|
25
28
|
|
26
29
|
logger.info(f"Exporting networks for {self.sheet_name}")
|
27
30
|
try:
|
28
31
|
util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
|
29
|
-
|
30
32
|
logger.info(f"Exported networks for {self.sheet_name}")
|
31
33
|
except Exception as e:
|
32
|
-
logger.warning(f"Exporting networks for {self.sheet_name} error: {e}")
|
34
|
+
logger.warning(f"Exporting networks for {self.sheet_name} error: {e}")
|
@@ -1,7 +1,8 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
|
2
|
+
from typing import Generator
|
3
|
+
from osi_dump.model.network import Network
|
3
4
|
|
4
5
|
class NetworkExporter(ABC):
|
5
6
|
@abstractmethod
|
6
|
-
def export_networks(self, networks,
|
7
|
-
pass
|
7
|
+
def export_networks(self, networks: Generator[Network, None, None]):
|
8
|
+
pass
|
@@ -1,30 +1,30 @@
|
|
1
1
|
import pandas as pd
|
2
|
-
|
3
2
|
import logging
|
4
|
-
|
5
|
-
from openpyxl import load_workbook
|
6
|
-
|
3
|
+
from typing import Generator
|
7
4
|
from osi_dump import util
|
8
5
|
from osi_dump.exporter.project.project_exporter import ProjectExporter
|
9
|
-
|
10
6
|
from osi_dump.model.project import Project
|
11
7
|
|
12
8
|
logger = logging.getLogger(__name__)
|
13
9
|
|
14
|
-
|
15
10
|
class ExcelProjectExporter(ProjectExporter):
|
16
11
|
def __init__(self, sheet_name: str, output_file: str):
|
17
12
|
self.sheet_name = sheet_name
|
18
13
|
self.output_file = output_file
|
19
14
|
|
20
|
-
def export_projects(self, projects:
|
21
|
-
|
22
|
-
|
15
|
+
def export_projects(self, projects: Generator[Project, None, None]):
|
16
|
+
df = pd.DataFrame(p.model_dump() for p in projects)
|
17
|
+
|
18
|
+
if df.empty:
|
19
|
+
logger.info(f"No projects to export for {self.sheet_name}")
|
20
|
+
return
|
21
|
+
|
22
|
+
if 'project_name' in df.columns:
|
23
|
+
df.sort_values(by='project_name', inplace=True, na_position='last')
|
23
24
|
|
24
25
|
logger.info(f"Exporting projects for {self.sheet_name}")
|
25
26
|
try:
|
26
27
|
util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
|
27
|
-
|
28
28
|
logger.info(f"Exported projects for {self.sheet_name}")
|
29
29
|
except Exception as e:
|
30
|
-
logger.warning(f"Exporting projects for {self.sheet_name} error: {e}")
|
30
|
+
logger.warning(f"Exporting projects for {self.sheet_name} error: {e}")
|
@@ -1,7 +1,8 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
|
2
|
+
from typing import Generator
|
3
|
+
from osi_dump.model.project import Project
|
3
4
|
|
4
5
|
class ProjectExporter(ABC):
|
5
6
|
@abstractmethod
|
6
|
-
def export_projects(self, projects,
|
7
|
-
pass
|
7
|
+
def export_projects(self, projects: Generator[Project, None, None]):
|
8
|
+
pass
|
@@ -1,30 +1,31 @@
|
|
1
1
|
import pandas as pd
|
2
|
-
|
3
2
|
import logging
|
4
|
-
|
5
|
-
from openpyxl import load_workbook
|
3
|
+
from typing import Generator
|
6
4
|
|
7
5
|
from osi_dump import util
|
8
6
|
from osi_dump.exporter.router.router_exporter import RouterExporter
|
9
|
-
|
10
7
|
from osi_dump.model.router import Router
|
11
8
|
|
12
9
|
logger = logging.getLogger(__name__)
|
13
10
|
|
14
|
-
|
15
11
|
class ExcelRouterExporter(RouterExporter):
|
16
12
|
def __init__(self, sheet_name: str, output_file: str):
|
17
13
|
self.sheet_name = sheet_name
|
18
14
|
self.output_file = output_file
|
19
15
|
|
20
|
-
def export_routers(self, routers:
|
16
|
+
def export_routers(self, routers: Generator[Router, None, None]):
|
17
|
+
df = pd.DataFrame(router.model_dump() for router in routers)
|
21
18
|
|
22
|
-
df
|
19
|
+
if df.empty:
|
20
|
+
logger.info(f"No routers to export for {self.sheet_name}")
|
21
|
+
return
|
22
|
+
|
23
|
+
if 'name' in df.columns:
|
24
|
+
df.sort_values(by='name', inplace=True, na_position='last')
|
23
25
|
|
24
26
|
logger.info(f"Exporting routers for {self.sheet_name}")
|
25
27
|
try:
|
26
28
|
util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
|
27
|
-
|
28
29
|
logger.info(f"Exported routers for {self.sheet_name}")
|
29
30
|
except Exception as e:
|
30
31
|
logger.warning(f"Exporting routers for {self.sheet_name} error: {e}")
|
@@ -1,7 +1,8 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
|
2
|
+
from typing import Generator
|
3
|
+
from osi_dump.model.router import Router
|
3
4
|
|
4
5
|
class RouterExporter(ABC):
|
5
6
|
@abstractmethod
|
6
|
-
def export_routers(self, routers,
|
7
|
+
def export_routers(self, routers: Generator[Router, None, None]):
|
7
8
|
pass
|
@@ -1,29 +1,31 @@
|
|
1
1
|
import pandas as pd
|
2
|
-
|
3
2
|
import logging
|
4
|
-
|
3
|
+
from typing import Generator
|
5
4
|
|
6
5
|
from osi_dump import util
|
7
|
-
|
8
6
|
from osi_dump.exporter.volume.volume_exporter import VolumeExporter
|
9
|
-
|
10
7
|
from osi_dump.model.volume import Volume
|
11
8
|
|
12
9
|
logger = logging.getLogger(__name__)
|
13
10
|
|
14
|
-
|
15
11
|
class ExcelVolumeExporter(VolumeExporter):
|
16
12
|
def __init__(self, sheet_name: str, output_file: str):
|
17
13
|
self.sheet_name = sheet_name
|
18
14
|
self.output_file = output_file
|
19
15
|
|
20
|
-
def export_volumes(self, volumes:
|
21
|
-
df = pd.DataFrame(
|
16
|
+
def export_volumes(self, volumes: Generator[Volume, None, None]):
|
17
|
+
df = pd.DataFrame(volume.model_dump() for volume in volumes)
|
18
|
+
|
19
|
+
if df.empty:
|
20
|
+
logger.info(f"No volumes to export for {self.sheet_name}")
|
21
|
+
return
|
22
|
+
|
23
|
+
if 'volume_name' in df.columns:
|
24
|
+
df.sort_values(by='volume_name', inplace=True, na_position='last')
|
22
25
|
|
23
26
|
logger.info(f"Exporting volumes for {self.sheet_name}")
|
24
27
|
try:
|
25
28
|
util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
|
26
|
-
|
27
29
|
logger.info(f"Exported volumes for {self.sheet_name}")
|
28
30
|
except Exception as e:
|
29
31
|
logger.warning(f"Exporting volumes for {self.sheet_name} error: {e}")
|
@@ -1,7 +1,9 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
|
2
|
+
from typing import Generator
|
3
|
+
from osi_dump.model.volume import Volume
|
3
4
|
|
4
5
|
class VolumeExporter(ABC):
|
5
6
|
@abstractmethod
|
6
|
-
def export_volumes(self, volumes,
|
7
|
+
def export_volumes(self, volumes: Generator[Volume, None, None]):
|
7
8
|
pass
|
9
|
+
|
@@ -1,9 +1,8 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
|
2
|
+
from typing import Generator
|
3
3
|
from osi_dump.model.external_port import ExternalPort
|
4
4
|
|
5
|
-
|
6
5
|
class ExternalPortImporter(ABC):
|
7
6
|
@abstractmethod
|
8
|
-
def import_external_ports(self) ->
|
9
|
-
pass
|
7
|
+
def import_external_ports(self) -> Generator[ExternalPort, None, None]:
|
8
|
+
pass
|
@@ -1,146 +1,74 @@
|
|
1
1
|
import logging
|
2
|
-
|
3
2
|
import ipaddress
|
4
|
-
|
5
|
-
import concurrent
|
6
|
-
|
7
|
-
import numpy as np
|
8
|
-
|
3
|
+
from typing import Generator
|
9
4
|
from openstack.connection import Connection
|
10
5
|
from openstack.network.v2.port import Port as OSPort
|
11
6
|
from openstack.network.v2.subnet import Subnet as OSSubnet
|
12
|
-
from openstack.network.v2.floating_ip import FloatingIP as OSFloatingIP
|
13
|
-
from openstack.network.v2.router import Router as OSRouter
|
14
7
|
from openstack.network.v2.network import Network as OSNetwork
|
15
8
|
|
16
9
|
from osi_dump.importer.external_port.external_port_importer import ExternalPortImporter
|
17
10
|
from osi_dump.model.external_port import ExternalPort
|
18
|
-
|
19
11
|
import osi_dump.api.neutron as osi_neutron
|
20
12
|
|
21
13
|
logger = logging.getLogger(__name__)
|
22
14
|
|
23
|
-
|
24
15
|
class OpenStackExternalPortImporter(ExternalPortImporter):
|
25
16
|
def __init__(self, connection: Connection):
|
26
17
|
self.connection = connection
|
27
18
|
|
28
|
-
def
|
29
|
-
|
30
|
-
# Get all external networks
|
31
|
-
networks = self.connection.network.networks(
|
32
|
-
is_router_external=True,
|
33
|
-
)
|
34
|
-
|
35
|
-
external_ports = []
|
36
|
-
|
37
|
-
for network in networks:
|
38
|
-
ex_ports = list(self.connection.network.ports(network_id=network.id))
|
39
|
-
|
40
|
-
for ex_port in ex_ports:
|
41
|
-
external_ports.append(ex_port)
|
42
|
-
|
43
|
-
# Get all port on those networks
|
44
|
-
|
45
|
-
return external_ports
|
46
|
-
|
47
|
-
def import_external_ports(self) -> list[ExternalPort]:
|
48
|
-
"""Import external_ports information from Openstack
|
49
|
-
|
50
|
-
|
51
|
-
Raises:
|
52
|
-
Exception: Raises exception if fetching external_port failed
|
53
|
-
|
54
|
-
Returns:
|
55
|
-
list[Instance]: _description_
|
56
|
-
"""
|
57
|
-
|
58
|
-
logger.info(f"Importing external_ports for {self.connection.auth['auth_url']}")
|
59
|
-
|
19
|
+
def _get_external_ports_stream(self) -> Generator[OSPort, None, None]:
|
20
|
+
"""Generator để lấy về từng port trên các network ngoại vi."""
|
60
21
|
try:
|
61
|
-
|
22
|
+
external_networks = self.connection.network.networks(is_router_external=True)
|
23
|
+
|
24
|
+
for network in external_networks:
|
25
|
+
ports_on_network = self.connection.network.ports(network_id=network.id)
|
26
|
+
yield from ports_on_network
|
62
27
|
except Exception as e:
|
63
|
-
|
64
|
-
f"Can not fetch external_ports for {self.connection.auth['auth_url']} {e}"
|
65
|
-
) from e
|
28
|
+
logger.error(f"Failed to stream external networks/ports: {e}")
|
66
29
|
|
67
|
-
external_ports: list[ExternalPort] = []
|
68
30
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
logger.info(f"Imported external_ports for {self.connection.auth['auth_url']}")
|
78
|
-
|
79
|
-
external_ports = sorted(
|
80
|
-
external_ports,
|
81
|
-
key=lambda external_port: (
|
82
|
-
external_port.network_id,
|
83
|
-
(
|
84
|
-
ipaddress.ip_address(external_port.ip_address)
|
85
|
-
if external_port.ip_address
|
86
|
-
else ipaddress.ip_address("0.0.0.0")
|
87
|
-
),
|
88
|
-
),
|
89
|
-
)
|
90
|
-
|
91
|
-
return external_ports
|
31
|
+
def import_external_ports(self) -> Generator[ExternalPort, None, None]:
|
32
|
+
logger.info(f"Importing external ports for {self.connection.auth['auth_url']}")
|
33
|
+
|
34
|
+
for os_port in self._get_external_ports_stream():
|
35
|
+
yield self._get_external_port_info(os_port)
|
36
|
+
|
37
|
+
logger.info(f"Finished importing external ports for {self.connection.auth['auth_url']}")
|
92
38
|
|
93
39
|
def _get_external_port_info(self, external_port: OSPort) -> ExternalPort:
|
94
|
-
|
95
40
|
subnet_id = None
|
96
41
|
ip_address = None
|
97
42
|
subnet_cidr = None
|
98
43
|
|
99
|
-
|
100
|
-
ip_address = external_port.fixed_ips[0]
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
mapped_device_project = ["network:floatingip", "network:router_gateway"]
|
117
|
-
|
118
|
-
project_id = (
|
119
|
-
external_port.project_id
|
120
|
-
if external_port.device_owner not in mapped_device_project
|
121
|
-
else self._map_project_id(
|
44
|
+
if external_port.fixed_ips:
|
45
|
+
ip_address = external_port.fixed_ips[0].get("ip_address")
|
46
|
+
subnet_id = external_port.fixed_ips[0].get("subnet_id")
|
47
|
+
|
48
|
+
if subnet_id:
|
49
|
+
try:
|
50
|
+
subnet: OSSubnet = self.connection.get_subnet(subnet_id)
|
51
|
+
if subnet:
|
52
|
+
subnet_cidr = subnet.cidr
|
53
|
+
except Exception as e:
|
54
|
+
logger.warning(f"Could not get subnet cidr for {subnet_id}: {e}")
|
55
|
+
|
56
|
+
project_id = external_port.project_id
|
57
|
+
mapped_device_projects = ["network:floatingip", "network:router_gateway"]
|
58
|
+
if external_port.device_owner in mapped_device_projects and external_port.device_id:
|
59
|
+
project_id = self._map_project_id(
|
122
60
|
device_owner=external_port.device_owner,
|
123
61
|
device_id=external_port.device_id,
|
124
62
|
)
|
125
|
-
)
|
126
63
|
|
127
|
-
network: OSNetwork = self.connection.get_network(
|
128
|
-
|
129
|
-
vlan_id = None
|
64
|
+
network: OSNetwork = self.connection.get_network(external_port.network_id)
|
65
|
+
vlan_id = network.provider_segmentation_id if network else None
|
130
66
|
|
131
|
-
|
132
|
-
if not network.segments:
|
133
|
-
vlan_id = network.provider_segmentation_id
|
134
|
-
else:
|
135
|
-
logger.warning(f"Multiple segments mapped for net id {network.id}")
|
136
|
-
except Exception as e:
|
137
|
-
logger.warning(f"Can not get vlan ID for external port {external_port.id}, net id {network.id}")
|
138
|
-
|
139
|
-
external_port_ret = ExternalPort(
|
67
|
+
return ExternalPort(
|
140
68
|
port_id=external_port.id,
|
141
69
|
project_id=project_id,
|
142
70
|
network_id=external_port.network_id,
|
143
|
-
network_name=network.name,
|
71
|
+
network_name=network.name if network else None,
|
144
72
|
subnet_id=subnet_id,
|
145
73
|
subnet_cidr=subnet_cidr,
|
146
74
|
ip_address=ip_address,
|
@@ -151,27 +79,12 @@ class OpenStackExternalPortImporter(ExternalPortImporter):
|
|
151
79
|
vlan_id=vlan_id
|
152
80
|
)
|
153
81
|
|
154
|
-
return external_port_ret
|
155
|
-
|
156
82
|
def _map_project_id(self, device_owner: str, device_id: str) -> str:
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
def _map_project_id_router(self, device_id: str) -> str:
|
166
|
-
project_id = osi_neutron.get_router_project(
|
167
|
-
self.connection, router_id=device_id
|
168
|
-
)
|
169
|
-
|
170
|
-
return project_id
|
171
|
-
|
172
|
-
def _map_project_id_floating(self, device_id: str) -> str:
|
173
|
-
project_id = osi_neutron.get_floating_ip_project(
|
174
|
-
self.connection, floating_ip_id=device_id
|
175
|
-
)
|
176
|
-
|
177
|
-
return project_id
|
83
|
+
try:
|
84
|
+
if device_owner == "network:router_gateway":
|
85
|
+
return osi_neutron.get_router_project(self.connection, router_id=device_id)
|
86
|
+
elif device_owner == "network:floatingip":
|
87
|
+
return osi_neutron.get_floating_ip_project(self.connection, floating_ip_id=device_id)
|
88
|
+
except Exception as e:
|
89
|
+
logger.warning(f"Could not map project ID for {device_owner}:{device_id}: {e}")
|
90
|
+
return None
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
|
2
|
+
from typing import Generator
|
3
3
|
from osi_dump.model.flavor import Flavor
|
4
4
|
|
5
|
-
|
6
5
|
class FlavorImporter(ABC):
|
7
6
|
@abstractmethod
|
8
|
-
def import_flavors(self) ->
|
7
|
+
def import_flavors(self) -> Generator[Flavor, None, None]:
|
9
8
|
pass
|
9
|
+
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import logging
|
2
|
-
|
3
|
-
import concurrent
|
4
|
-
|
2
|
+
from typing import Generator
|
5
3
|
from openstack.connection import Connection
|
6
4
|
from openstack.compute.v2.flavor import Flavor as OSFlavor
|
7
5
|
|
@@ -10,55 +8,35 @@ from osi_dump.model.flavor import Flavor
|
|
10
8
|
|
11
9
|
logger = logging.getLogger(__name__)
|
12
10
|
|
13
|
-
|
14
11
|
class OpenStackFlavorImporter(FlavorImporter):
|
15
12
|
def __init__(self, connection: Connection):
|
16
13
|
self.connection = connection
|
17
14
|
|
18
|
-
def import_flavors(self) ->
|
19
|
-
"""Import flavors information from Openstack
|
20
|
-
|
21
|
-
Raises:
|
22
|
-
Exception: Raises exception if fetching flavor failed
|
23
|
-
|
24
|
-
Returns:
|
25
|
-
list[Instance]: _description_
|
26
|
-
"""
|
27
|
-
|
15
|
+
def import_flavors(self) -> Generator[Flavor, None, None]:
|
28
16
|
logger.info(f"Importing flavors for {self.connection.auth['auth_url']}")
|
29
|
-
|
30
17
|
try:
|
31
|
-
|
32
|
-
except Exception as e:
|
33
|
-
raise Exception(
|
34
|
-
f"Can not fetch flavors for {self.connection.auth['auth_url']}"
|
35
|
-
) from e
|
36
|
-
|
37
|
-
flavors: list[Flavor] = []
|
18
|
+
flavor_iterator = self.connection.list_flavors()
|
38
19
|
|
39
|
-
|
40
|
-
|
41
|
-
executor.submit(self._get_flavor_info, osflavor)
|
42
|
-
for osflavor in osflavors
|
43
|
-
]
|
44
|
-
for future in concurrent.futures.as_completed(futures):
|
45
|
-
flavors.append(future.result())
|
20
|
+
for osflavor in flavor_iterator:
|
21
|
+
yield self._get_flavor_info(osflavor)
|
46
22
|
|
47
|
-
|
23
|
+
except Exception as e:
|
24
|
+
logger.error(f"Cannot fetch flavors for {self.connection.auth['auth_url']}: {e}")
|
25
|
+
return
|
48
26
|
|
49
|
-
|
27
|
+
logger.info(f"Finished importing flavors for {self.connection.auth['auth_url']}")
|
50
28
|
|
51
29
|
def _get_flavor_info(self, flavor: OSFlavor) -> Flavor:
|
52
30
|
|
53
|
-
|
31
|
+
swap_val = flavor.swap if flavor.swap else None
|
32
|
+
|
33
|
+
return Flavor(
|
54
34
|
flavor_id=flavor.id,
|
55
35
|
flavor_name=flavor.name,
|
56
36
|
ram=flavor.ram,
|
57
37
|
vcpus=flavor.vcpus,
|
58
38
|
disk=flavor.disk,
|
59
|
-
swap=
|
39
|
+
swap=swap_val,
|
60
40
|
public=flavor.is_public,
|
61
41
|
properties=flavor.extra_specs,
|
62
42
|
)
|
63
|
-
|
64
|
-
return ret_flavor
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
|
2
|
+
from typing import Generator
|
3
3
|
from osi_dump.model.floating_ip import FloatingIP
|
4
4
|
|
5
|
-
|
6
5
|
class FloatingIPImporter(ABC):
|
7
6
|
@abstractmethod
|
8
|
-
def import_floating_ips(self) ->
|
7
|
+
def import_floating_ips(self) -> Generator[FloatingIP, None, None]:
|
9
8
|
pass
|
9
|
+
|