osi-dump 0.1.1__py3-none-any.whl → 0.1.2.1__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.
Files changed (48) hide show
  1. osi_dump/api/__init__.py +0 -0
  2. osi_dump/api/octavia.py +17 -0
  3. osi_dump/api/placement.py +17 -0
  4. osi_dump/batch_handler/flavor_batch_handler.py +51 -0
  5. osi_dump/batch_handler/image_batch_handler.py +51 -0
  6. osi_dump/batch_handler/load_balancer_batch_handler.py +61 -0
  7. osi_dump/batch_handler/role_assignment_batch_handler.py +61 -0
  8. osi_dump/cli.py +57 -0
  9. osi_dump/exporter/flavor/__init__.py +0 -0
  10. osi_dump/exporter/flavor/excel_flavor_exporter.py +30 -0
  11. osi_dump/exporter/flavor/flavor_exporter.py +7 -0
  12. osi_dump/exporter/image/__init__.py +0 -0
  13. osi_dump/exporter/image/excel_image_exporter.py +28 -0
  14. osi_dump/exporter/image/image_exporter.py +7 -0
  15. osi_dump/exporter/load_balancer/__init__.py +0 -0
  16. osi_dump/exporter/load_balancer/excel_load_balancer_exporter.py +33 -0
  17. osi_dump/exporter/load_balancer/load_balancer_exporter.py +7 -0
  18. osi_dump/exporter/role_assignment/__init__.py +0 -0
  19. osi_dump/exporter/role_assignment/excel_role_assignment_exporter.py +35 -0
  20. osi_dump/exporter/role_assignment/role_assignment_exporter.py +7 -0
  21. osi_dump/importer/flavor/__init__.py +0 -0
  22. osi_dump/importer/flavor/flavor_importer.py +9 -0
  23. osi_dump/importer/flavor/openstack_flavor_importer.py +64 -0
  24. osi_dump/importer/hypervisor/openstack_hypervisor_importer.py +18 -2
  25. osi_dump/importer/image/__init__.py +0 -0
  26. osi_dump/importer/image/image_importer.py +9 -0
  27. osi_dump/importer/image/openstack_image_importer.py +77 -0
  28. osi_dump/importer/load_balancer/__init__.py +0 -0
  29. osi_dump/importer/load_balancer/load_balancer_importer.py +9 -0
  30. osi_dump/importer/load_balancer/openstack_load_balancer_importer.py +65 -0
  31. osi_dump/importer/project/openstack_project_importer.py +27 -0
  32. osi_dump/importer/role_assignment/__init__.py +0 -0
  33. osi_dump/importer/role_assignment/openstack_role_assignment_importer.py +83 -0
  34. osi_dump/importer/role_assignment/role_assignment_importer.py +9 -0
  35. osi_dump/importer/volume/openstack_volume_importer.py +14 -0
  36. osi_dump/model/flavor.py +20 -0
  37. osi_dump/model/hypervisor.py +10 -2
  38. osi_dump/model/image.py +26 -0
  39. osi_dump/model/load_balancer.py +17 -0
  40. osi_dump/model/project.py +18 -0
  41. osi_dump/model/role_assignment.py +17 -0
  42. osi_dump/model/volume.py +2 -0
  43. osi_dump/os_connection/get_connections.py +0 -1
  44. {osi_dump-0.1.1.dist-info → osi_dump-0.1.2.1.dist-info}/METADATA +1 -1
  45. {osi_dump-0.1.1.dist-info → osi_dump-0.1.2.1.dist-info}/RECORD +48 -13
  46. {osi_dump-0.1.1.dist-info → osi_dump-0.1.2.1.dist-info}/WHEEL +1 -1
  47. {osi_dump-0.1.1.dist-info → osi_dump-0.1.2.1.dist-info}/entry_points.txt +0 -0
  48. {osi_dump-0.1.1.dist-info → osi_dump-0.1.2.1.dist-info}/top_level.txt +0 -0
File without changes
@@ -0,0 +1,17 @@
1
+ from openstack.connection import Connection
2
+ from openstack.identity.v3.service import Service
3
+
4
+
5
+ def get_amphorae(connection: Connection, load_balancer_id: str) -> str | None:
6
+
7
+ octavia_endpoint = connection.endpoint_for(
8
+ service_type="octavia", interface="public"
9
+ )
10
+
11
+ url = f"{octavia_endpoint}/v2/octavia/amphorae"
12
+
13
+ response = connection.session.get(url)
14
+
15
+ data = response.json()
16
+
17
+ return data["usages"]
@@ -0,0 +1,17 @@
1
+ from openstack.connection import Connection
2
+ from openstack.identity.v3.service import Service
3
+
4
+
5
+ def get_usage(connection: Connection, resource_provider_id: str):
6
+
7
+ placement_endpoint = connection.endpoint_for(
8
+ service_type="placement", interface="public"
9
+ )
10
+
11
+ url = f"{placement_endpoint}/resource_providers/{resource_provider_id}/usages"
12
+
13
+ response = connection.session.get(url)
14
+
15
+ data = response.json()
16
+
17
+ return data["usages"]
@@ -0,0 +1,51 @@
1
+ import logging
2
+
3
+ from openstack.connection import Connection
4
+
5
+ from osi_dump.exporter.flavor.flavor_exporter import FlavorExporter
6
+ from osi_dump.exporter.flavor.excel_flavor_exporter import (
7
+ ExcelFlavorExporter,
8
+ )
9
+
10
+ from osi_dump.importer.flavor.flavor_importer import FlavorImporter
11
+ from osi_dump.importer.flavor.openstack_flavor_importer import (
12
+ OpenStackFlavorImporter,
13
+ )
14
+
15
+
16
+ from osi_dump import util
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class FlavorBatchHandler:
22
+ def __init__(self):
23
+ self._importer_exporter_list: list[tuple[FlavorImporter, FlavorExporter]] = []
24
+
25
+ def add_importer_exporter_from_openstack_connections(
26
+ self, connections: list[Connection], output_file: str
27
+ ):
28
+ for connection in connections:
29
+ importer = OpenStackFlavorImporter(connection)
30
+
31
+ sheet_name = f"{util.extract_hostname(connection.auth['auth_url'])}-flavor"
32
+ exporter = ExcelFlavorExporter(
33
+ sheet_name=sheet_name, output_file=output_file
34
+ )
35
+
36
+ self.add_importer_exporter(importer=importer, exporter=exporter)
37
+
38
+ def add_importer_exporter(self, importer: FlavorImporter, exporter: FlavorExporter):
39
+ self._importer_exporter_list.append((importer, exporter))
40
+
41
+ def process(self):
42
+
43
+ for importer, exporter in self._importer_exporter_list:
44
+ try:
45
+
46
+ flavors = importer.import_flavors()
47
+
48
+ exporter.export_flavors(flavors=flavors)
49
+ except Exception as e:
50
+ logger.warning(e)
51
+ logger.warning("Skipping...")
@@ -0,0 +1,51 @@
1
+ import logging
2
+
3
+ from openstack.connection import Connection
4
+
5
+ from osi_dump.exporter.image.image_exporter import ImageExporter
6
+ from osi_dump.exporter.image.excel_image_exporter import (
7
+ ExcelImageExporter,
8
+ )
9
+
10
+ from osi_dump.importer.image.image_importer import ImageImporter
11
+ from osi_dump.importer.image.openstack_image_importer import (
12
+ OpenStackImageImporter,
13
+ )
14
+
15
+
16
+ from osi_dump import util
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class ImageBatchHandler:
22
+ def __init__(self):
23
+ self._importer_exporter_list: list[tuple[ImageImporter, ImageExporter]] = []
24
+
25
+ def add_importer_exporter_from_openstack_connections(
26
+ self, connections: list[Connection], output_file: str
27
+ ):
28
+ for connection in connections:
29
+ importer = OpenStackImageImporter(connection)
30
+
31
+ sheet_name = f"{util.extract_hostname(connection.auth['auth_url'])}-image"
32
+ exporter = ExcelImageExporter(
33
+ sheet_name=sheet_name, output_file=output_file
34
+ )
35
+
36
+ self.add_importer_exporter(importer=importer, exporter=exporter)
37
+
38
+ def add_importer_exporter(self, importer: ImageImporter, exporter: ImageExporter):
39
+ self._importer_exporter_list.append((importer, exporter))
40
+
41
+ def process(self):
42
+
43
+ for importer, exporter in self._importer_exporter_list:
44
+ try:
45
+
46
+ images = importer.import_images()
47
+
48
+ exporter.export_images(images=images)
49
+ except Exception as e:
50
+ logger.warning(e)
51
+ logger.warning("Skipping...")
@@ -0,0 +1,61 @@
1
+ import logging
2
+
3
+ from openstack.connection import Connection
4
+
5
+ from osi_dump.exporter.load_balancer.load_balancer_exporter import (
6
+ LoadBalancerExporter,
7
+ )
8
+ from osi_dump.exporter.load_balancer.excel_load_balancer_exporter import (
9
+ ExcelLoadBalancerExporter,
10
+ )
11
+
12
+ from osi_dump.importer.load_balancer.load_balancer_importer import (
13
+ LoadBalancerImporter,
14
+ )
15
+ from osi_dump.importer.load_balancer.openstack_load_balancer_importer import (
16
+ OpenStackLoadBalancerImporter,
17
+ )
18
+
19
+
20
+ from osi_dump import util
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class LoadBalancerBatchHandler:
26
+ def __init__(self):
27
+ self._importer_exporter_list: list[
28
+ tuple[LoadBalancerImporter, LoadBalancerExporter]
29
+ ] = []
30
+
31
+ def add_importer_exporter_from_openstack_connections(
32
+ self, connections: list[Connection], output_file: str
33
+ ):
34
+ for connection in connections:
35
+ importer = OpenStackLoadBalancerImporter(connection)
36
+
37
+ sheet_name = (
38
+ f"{util.extract_hostname(connection.auth['auth_url'])}-load_balancer"
39
+ )
40
+ exporter = ExcelLoadBalancerExporter(
41
+ sheet_name=sheet_name, output_file=output_file
42
+ )
43
+
44
+ self.add_importer_exporter(importer=importer, exporter=exporter)
45
+
46
+ def add_importer_exporter(
47
+ self, importer: LoadBalancerImporter, exporter: LoadBalancerExporter
48
+ ):
49
+ self._importer_exporter_list.append((importer, exporter))
50
+
51
+ def process(self):
52
+
53
+ for importer, exporter in self._importer_exporter_list:
54
+ try:
55
+
56
+ load_balancers = importer.import_load_balancers()
57
+
58
+ exporter.export_load_balancers(load_balancers=load_balancers)
59
+ except Exception as e:
60
+ logger.warning(e)
61
+ logger.warning("Skipping...")
@@ -0,0 +1,61 @@
1
+ import logging
2
+
3
+ from openstack.connection import Connection
4
+
5
+ from osi_dump.exporter.role_assignment.role_assignment_exporter import (
6
+ RoleAssignmentExporter,
7
+ )
8
+ from osi_dump.exporter.role_assignment.excel_role_assignment_exporter import (
9
+ ExcelRoleAssignmentExporter,
10
+ )
11
+
12
+ from osi_dump.importer.role_assignment.role_assignment_importer import (
13
+ RoleAssignmentImporter,
14
+ )
15
+ from osi_dump.importer.role_assignment.openstack_role_assignment_importer import (
16
+ OpenStackRoleAssignmentImporter,
17
+ )
18
+
19
+
20
+ from osi_dump import util
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class RoleAssignmentBatchHandler:
26
+ def __init__(self):
27
+ self._importer_exporter_list: list[
28
+ tuple[RoleAssignmentImporter, RoleAssignmentExporter]
29
+ ] = []
30
+
31
+ def add_importer_exporter_from_openstack_connections(
32
+ self, connections: list[Connection], output_file: str
33
+ ):
34
+ for connection in connections:
35
+ importer = OpenStackRoleAssignmentImporter(connection)
36
+
37
+ sheet_name = (
38
+ f"{util.extract_hostname(connection.auth['auth_url'])}-role_assignment"
39
+ )
40
+ exporter = ExcelRoleAssignmentExporter(
41
+ sheet_name=sheet_name, output_file=output_file
42
+ )
43
+
44
+ self.add_importer_exporter(importer=importer, exporter=exporter)
45
+
46
+ def add_importer_exporter(
47
+ self, importer: RoleAssignmentImporter, exporter: RoleAssignmentExporter
48
+ ):
49
+ self._importer_exporter_list.append((importer, exporter))
50
+
51
+ def process(self):
52
+
53
+ for importer, exporter in self._importer_exporter_list:
54
+ try:
55
+
56
+ role_assignments = importer.import_role_assignments()
57
+
58
+ exporter.export_role_assignments(role_assignments=role_assignments)
59
+ except Exception as e:
60
+ logger.warning(e)
61
+ logger.warning("Skipping...")
osi_dump/cli.py CHANGED
@@ -8,9 +8,16 @@ import typer
8
8
 
9
9
  from typing_extensions import Annotated
10
10
 
11
+ from osi_dump.batch_handler.load_balancer_batch_handler import LoadBalancerBatchHandler
12
+ from osi_dump.batch_handler.role_assignment_batch_handler import (
13
+ RoleAssignmentBatchHandler,
14
+ )
15
+
11
16
  app = typer.Typer()
12
17
 
13
18
 
19
+ from osi_dump.batch_handler.flavor_batch_handler import FlavorBatchHandler
20
+ from osi_dump.batch_handler.image_batch_handler import ImageBatchHandler
14
21
  from osi_dump.batch_handler.volume_batch_handler import VolumeBatchHandler
15
22
  from osi_dump.os_connection.get_connections import get_connections
16
23
 
@@ -76,6 +83,46 @@ def _hypervisor(connections, output_path: str):
76
83
  hypervisor_batch_handler.process()
77
84
 
78
85
 
86
+ def _image(connections, output_path: str):
87
+ image_batch_handler = ImageBatchHandler()
88
+
89
+ image_batch_handler.add_importer_exporter_from_openstack_connections(
90
+ connections, output_file=output_path
91
+ )
92
+
93
+ image_batch_handler.process()
94
+
95
+
96
+ def _flavor(connections, output_path: str):
97
+ flavor_batch_handler = FlavorBatchHandler()
98
+
99
+ flavor_batch_handler.add_importer_exporter_from_openstack_connections(
100
+ connections, output_file=output_path
101
+ )
102
+
103
+ flavor_batch_handler.process()
104
+
105
+
106
+ def _role_assignment(connections, output_path: str):
107
+ _role_assignment_batch_handler = RoleAssignmentBatchHandler()
108
+
109
+ _role_assignment_batch_handler.add_importer_exporter_from_openstack_connections(
110
+ connections, output_file=output_path
111
+ )
112
+
113
+ _role_assignment_batch_handler.process()
114
+
115
+
116
+ def _load_balancer(connections, output_path: str):
117
+ _load_balancer_batch_handler = LoadBalancerBatchHandler()
118
+
119
+ _load_balancer_batch_handler.add_importer_exporter_from_openstack_connections(
120
+ connections, output_file=output_path
121
+ )
122
+
123
+ _load_balancer_batch_handler.process()
124
+
125
+
79
126
  def inner_main(file_path: str, output_path: str):
80
127
 
81
128
  logger = logging.getLogger(__name__)
@@ -92,6 +139,13 @@ def inner_main(file_path: str, output_path: str):
92
139
 
93
140
  _project(connections=connections, output_path=output_path)
94
141
 
142
+ _image(connections=connections, output_path=output_path)
143
+
144
+ _flavor(connections=connections, output_path=output_path)
145
+
146
+ _role_assignment(connections=connections, output_path=output_path)
147
+
148
+ _load_balancer(connections=connections, output_path=output_path)
95
149
  util.excel_autosize_column(output_path)
96
150
 
97
151
  util.excel_sort_sheet(output_path)
@@ -141,6 +195,9 @@ Path of the output file, will override if file already exists
141
195
  level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
142
196
  )
143
197
 
198
+ # Suppress pool limit warning will investigate later
199
+ logging.getLogger("urllib3").propagate = False
200
+
144
201
  logger = logging.getLogger(__name__)
145
202
 
146
203
  if util.validate_dir_path(file_path=output_path) is False:
File without changes
@@ -0,0 +1,30 @@
1
+ import logging
2
+
3
+
4
+ import pandas as pd
5
+
6
+
7
+ from osi_dump.exporter.flavor.flavor_exporter import FlavorExporter
8
+
9
+ from osi_dump.model.flavor import Flavor
10
+
11
+ from osi_dump import util
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class ExcelFlavorExporter(FlavorExporter):
17
+ def __init__(self, sheet_name: str, output_file: str):
18
+ self.sheet_name = sheet_name
19
+ self.output_file = output_file
20
+
21
+ def export_flavors(self, flavors: list[Flavor]):
22
+ df = pd.json_normalize([flavor.model_dump() for flavor in flavors])
23
+
24
+ logger.info(f"Exporting flavors for {self.sheet_name}")
25
+ try:
26
+ util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
27
+
28
+ logger.info(f"Exported flavors for {self.sheet_name}")
29
+ except Exception as e:
30
+ logger.warning(f"Exporting floating ips for {self.sheet_name} error: {e}")
@@ -0,0 +1,7 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class FlavorExporter(ABC):
5
+ @abstractmethod
6
+ def export_flavors(self, flavors, output_file: str):
7
+ pass
File without changes
@@ -0,0 +1,28 @@
1
+ import pandas as pd
2
+
3
+ import logging
4
+
5
+
6
+ from osi_dump import util
7
+ from osi_dump.exporter.image.image_exporter import ImageExporter
8
+
9
+ from osi_dump.model.image import Image
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class ExcelImageExporter(ImageExporter):
15
+ def __init__(self, sheet_name: str, output_file: str):
16
+ self.sheet_name = sheet_name
17
+ self.output_file = output_file
18
+
19
+ def export_images(self, images: list[Image]):
20
+ df = pd.json_normalize([image.model_dump() for image in images])
21
+
22
+ logger.info(f"Exporting images for {self.sheet_name}")
23
+ try:
24
+ util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
25
+
26
+ logger.info(f"Exported images for {self.sheet_name}")
27
+ except Exception as e:
28
+ logger.warning(f"Exporting images for {self.sheet_name} error: {e}")
@@ -0,0 +1,7 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class ImageExporter(ABC):
5
+ @abstractmethod
6
+ def export_images(self, images, output_file: str):
7
+ pass
File without changes
@@ -0,0 +1,33 @@
1
+ import pandas as pd
2
+
3
+ import logging
4
+
5
+
6
+ from osi_dump import util
7
+
8
+ from osi_dump.exporter.load_balancer.load_balancer_exporter import (
9
+ LoadBalancerExporter,
10
+ )
11
+
12
+ from osi_dump.model.load_balancer import LoadBalancer
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class ExcelLoadBalancerExporter(LoadBalancerExporter):
18
+ def __init__(self, sheet_name: str, output_file: str):
19
+ self.sheet_name = sheet_name
20
+ self.output_file = output_file
21
+
22
+ def export_load_balancers(self, load_balancers: list[LoadBalancer]):
23
+ df = pd.json_normalize(
24
+ [load_balancer.model_dump() for load_balancer in load_balancers]
25
+ )
26
+
27
+ logger.info(f"Exporting load_balancers for {self.sheet_name}")
28
+ try:
29
+ util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
30
+
31
+ logger.info(f"Exported load_balancers for {self.sheet_name}")
32
+ except Exception as e:
33
+ logger.warning(f"Exporting load_balancers for {self.sheet_name} error: {e}")
@@ -0,0 +1,7 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class LoadBalancerExporter(ABC):
5
+ @abstractmethod
6
+ def export_load_balancers(self, load_balancers, output_file: str):
7
+ pass
File without changes
@@ -0,0 +1,35 @@
1
+ import pandas as pd
2
+
3
+ import logging
4
+
5
+
6
+ from osi_dump import util
7
+
8
+ from osi_dump.exporter.role_assignment.role_assignment_exporter import (
9
+ RoleAssignmentExporter,
10
+ )
11
+
12
+ from osi_dump.model.role_assignment import RoleAssignment
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class ExcelRoleAssignmentExporter(RoleAssignmentExporter):
18
+ def __init__(self, sheet_name: str, output_file: str):
19
+ self.sheet_name = sheet_name
20
+ self.output_file = output_file
21
+
22
+ def export_role_assignments(self, role_assignments: list[RoleAssignment]):
23
+ df = pd.json_normalize(
24
+ [role_assignment.model_dump() for role_assignment in role_assignments]
25
+ )
26
+
27
+ logger.info(f"Exporting role_assignments for {self.sheet_name}")
28
+ try:
29
+ util.export_data_excel(self.output_file, sheet_name=self.sheet_name, df=df)
30
+
31
+ logger.info(f"Exported role_assignments for {self.sheet_name}")
32
+ except Exception as e:
33
+ logger.warning(
34
+ f"Exporting role_assignments for {self.sheet_name} error: {e}"
35
+ )
@@ -0,0 +1,7 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class RoleAssignmentExporter(ABC):
5
+ @abstractmethod
6
+ def export_role_assignments(self, role_assignments, output_file: str):
7
+ pass
File without changes
@@ -0,0 +1,9 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from osi_dump.model.flavor import Flavor
4
+
5
+
6
+ class FlavorImporter(ABC):
7
+ @abstractmethod
8
+ def import_flavors(self) -> list[Flavor]:
9
+ pass
@@ -0,0 +1,64 @@
1
+ import logging
2
+
3
+ import concurrent
4
+
5
+ from openstack.connection import Connection
6
+ from openstack.compute.v2.flavor import Flavor as OSFlavor
7
+
8
+ from osi_dump.importer.flavor.flavor_importer import FlavorImporter
9
+ from osi_dump.model.flavor import Flavor
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class OpenStackFlavorImporter(FlavorImporter):
15
+ def __init__(self, connection: Connection):
16
+ self.connection = connection
17
+
18
+ def import_flavors(self) -> list[Flavor]:
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
+
28
+ logger.info(f"Importing flavors for {self.connection.auth['auth_url']}")
29
+
30
+ try:
31
+ osflavors: list[OSFlavor] = list(self.connection.list_flavors())
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] = []
38
+
39
+ with concurrent.futures.ThreadPoolExecutor() as executor:
40
+ futures = [
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())
46
+
47
+ logger.info(f"Imported flavors for {self.connection.auth['auth_url']}")
48
+
49
+ return flavors
50
+
51
+ def _get_flavor_info(self, flavor: OSFlavor) -> Flavor:
52
+
53
+ ret_flavor = Flavor(
54
+ flavor_id=flavor.id,
55
+ flavor_name=flavor.name,
56
+ ram=flavor.ram,
57
+ vcpus=flavor.vcpus,
58
+ disk=flavor.disk,
59
+ swap=flavor.swap,
60
+ public=flavor.is_public,
61
+ properties=flavor.extra_specs,
62
+ )
63
+
64
+ return ret_flavor
@@ -11,6 +11,8 @@ from openstack.placement.v1.resource_provider_inventory import ResourceProviderI
11
11
  from osi_dump.importer.hypervisor.hypervisor_importer import HypervisorImporter
12
12
  from osi_dump.model.hypervisor import Hypervisor
13
13
 
14
+ from osi_dump.api.placement import get_usage
15
+
14
16
  logger = logging.getLogger(__name__)
15
17
 
16
18
 
@@ -31,7 +33,9 @@ class OpenStackHypervisorImporter(HypervisorImporter):
31
33
  logger.info(f"Importing hypervisors for {self.connection.auth['auth_url']}")
32
34
 
33
35
  try:
34
- oshypervisors: list[OSHypervisor] = list(self.connection.list_hypervisors())
36
+ oshypervisors: list[OSHypervisor] = list(
37
+ self.connection.compute.hypervisors(details=True)
38
+ )
35
39
  except Exception as e:
36
40
  raise Exception(
37
41
  f"Can not fetch hypervisor for {self.connection.auth['auth_url']}"
@@ -61,6 +65,14 @@ class OpenStackHypervisorImporter(HypervisorImporter):
61
65
  )
62
66
  )
63
67
 
68
+ servers = list(
69
+ self.connection.compute.servers(
70
+ details=False, all_project=True, hypervisor=hypervisor.id
71
+ )
72
+ )
73
+
74
+ usage_data = get_usage(self.connection, resource_provider_id=hypervisor.id)
75
+
64
76
  vcpu = rpi[0]
65
77
  memory = rpi[1]
66
78
  disk = rpi[2]
@@ -73,7 +85,11 @@ class OpenStackHypervisorImporter(HypervisorImporter):
73
85
  status=hypervisor.status,
74
86
  local_disk_size=disk["max_unit"],
75
87
  memory_size=memory["max_unit"] + memory["reserved"],
76
- vpus=vcpu["max_unit"],
88
+ vcpus=vcpu["max_unit"],
89
+ vcpus_usage=usage_data["VCPU"],
90
+ memory_usage=usage_data["MEMORY_MB"],
91
+ local_disk_usage=usage_data["DISK_GB"],
92
+ vm_count=len(servers),
77
93
  )
78
94
 
79
95
  return ret_hypervisor
File without changes
@@ -0,0 +1,9 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from osi_dump.model.image import Image
4
+
5
+
6
+ class ImageImporter(ABC):
7
+ @abstractmethod
8
+ def import_images(self) -> list[Image]:
9
+ pass
@@ -0,0 +1,77 @@
1
+ import logging
2
+
3
+ import concurrent
4
+
5
+ from openstack.connection import Connection
6
+ from openstack.image.v2.image import Image as OSImage
7
+
8
+ from osi_dump.importer.image.image_importer import ImageImporter
9
+ from osi_dump.model.image import Image
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class OpenStackImageImporter(ImageImporter):
15
+ def __init__(self, connection: Connection):
16
+ self.connection = connection
17
+
18
+ def import_images(self) -> list[Image]:
19
+ """Import instances information from Openstack
20
+
21
+ Raises:
22
+ Exception: Raises exception if fetching server failed
23
+
24
+ Returns:
25
+ list[Instance]: _description_
26
+ """
27
+
28
+ logger.info(f"Importing images for {self.connection.auth['auth_url']}")
29
+
30
+ try:
31
+
32
+ os_images: list[OSImage] = list(self.connection.list_images(show_all=True))
33
+ except Exception as e:
34
+ raise Exception(
35
+ f"Can not fetch images for {self.connection.auth['auth_url']}"
36
+ ) from e
37
+
38
+ images: list[OSImage] = []
39
+
40
+ with concurrent.futures.ThreadPoolExecutor() as executor:
41
+ futures = [
42
+ executor.submit(self._get_image_info, image) for image in os_images
43
+ ]
44
+ for future in concurrent.futures.as_completed(futures):
45
+ images.append(future.result())
46
+
47
+ logger.info(f"Imported images for {self.connection.auth['auth_url']}")
48
+
49
+ return images
50
+
51
+ def _get_image_info(self, os_image: OSImage) -> Image:
52
+
53
+ properties: dict = os_image.properties
54
+
55
+ properties.pop("owner_specified.openstack.md5", None)
56
+ properties.pop("owner_specified.openstack.sha256", None)
57
+ properties.pop("owner_specified.openstack.object", None)
58
+ properties.pop("stores", None)
59
+
60
+ image = Image(
61
+ image_id=os_image.id,
62
+ disk_format=os_image.disk_format,
63
+ min_disk=os_image.min_disk,
64
+ min_ram=os_image.min_ram,
65
+ image_name=os_image.name,
66
+ owner=os_image.owner,
67
+ properties=os_image.properties,
68
+ protected=os_image.is_protected,
69
+ status=os_image.status,
70
+ size=os_image.size,
71
+ virtual_size=os_image.virtual_size,
72
+ visibility=os_image.visibility,
73
+ created_at=os_image.created_at,
74
+ updated_at=os_image.updated_at,
75
+ )
76
+
77
+ return image
File without changes
@@ -0,0 +1,9 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from osi_dump.model.load_balancer import LoadBalancer
4
+
5
+
6
+ class LoadBalancerImporter(ABC):
7
+ @abstractmethod
8
+ def import_load_balancers(self) -> list[LoadBalancer]:
9
+ pass
@@ -0,0 +1,65 @@
1
+ import logging
2
+
3
+ import concurrent
4
+
5
+ from openstack.connection import Connection
6
+
7
+ from openstack.load_balancer.v2.load_balancer import LoadBalancer as OSLoadBalancer
8
+
9
+ from osi_dump.importer.load_balancer.load_balancer_importer import (
10
+ LoadBalancerImporter,
11
+ )
12
+ from osi_dump.model.load_balancer import LoadBalancer
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class OpenStackLoadBalancerImporter(LoadBalancerImporter):
18
+ def __init__(self, connection: Connection):
19
+ self.connection = connection
20
+
21
+ def import_load_balancers(self) -> list[LoadBalancer]:
22
+ """Import load_balancers information from Openstack
23
+
24
+ Raises:
25
+ Exception: Raises exception if fetching load_balancer failed
26
+
27
+ Returns:
28
+ list[LoadBalancer]: _description_
29
+ """
30
+
31
+ logger.info(f"Importing load_balancers for {self.connection.auth['auth_url']}")
32
+
33
+ try:
34
+ osload_balancers: list[OSLoadBalancer] = list(
35
+ self.connection.network.load_balancers()
36
+ )
37
+ except Exception as e:
38
+ raise Exception(
39
+ f"Can not fetch load_balancers for {self.connection.auth['auth_url']}"
40
+ ) from e
41
+
42
+ load_balancers: list[LoadBalancer] = []
43
+
44
+ with concurrent.futures.ThreadPoolExecutor() as executor:
45
+ futures = [
46
+ executor.submit(self._get_load_balancer_info, load_balancer)
47
+ for load_balancer in osload_balancers
48
+ ]
49
+ for future in concurrent.futures.as_completed(futures):
50
+ load_balancers.append(future.result())
51
+
52
+ logger.info(f"Imported load_balancers for {self.connection.auth['auth_url']}")
53
+
54
+ return load_balancers
55
+
56
+ def _get_load_balancer_info(self, load_balancer: OSLoadBalancer) -> LoadBalancer:
57
+
58
+ load_balancer_ret = LoadBalancer(
59
+ id=load_balancer.id,
60
+ load_balancer_name=load_balancer.name,
61
+ status=load_balancer.operating_status,
62
+ project_id=load_balancer.project_id,
63
+ )
64
+
65
+ return load_balancer_ret
@@ -49,12 +49,39 @@ class OpenStackProjectImporter(ProjectImporter):
49
49
  return projects
50
50
 
51
51
  def _get_project_info(self, project: OSProject) -> Project:
52
+
53
+ try:
54
+ compute_quotas = self.connection.compute.get_quota_set(
55
+ project.id, usage=True
56
+ )
57
+ except Exception as e:
58
+ logger.warning(f"Get compute quotas failed for {project.id} error: {e}")
59
+
60
+ try:
61
+ storage_quotas = self.connection.block_storage.get_quota_set(
62
+ project.id, usage=True
63
+ )
64
+ except Exception as e:
65
+ logger.warning(f"Get storage quotas failed for {project.id} error: {e}")
66
+
52
67
  project_ret = Project(
53
68
  project_id=project.id,
54
69
  project_name=project.name,
55
70
  domain_id=project.domain_id,
56
71
  enabled=project.is_enabled,
57
72
  parent_id=project.parent_id,
73
+ usage_instance=compute_quotas.usage["instances"],
74
+ quota_instance=compute_quotas.instances,
75
+ usage_ram=compute_quotas.usage["ram"],
76
+ quota_ram=compute_quotas.ram,
77
+ usage_vcpu=compute_quotas.usage["cores"],
78
+ quota_vcpu=compute_quotas.cores,
79
+ usage_volume=storage_quotas.usage["volumes"],
80
+ quota_volume=storage_quotas.volumes,
81
+ usage_snapshot=storage_quotas.usage["snapshots"],
82
+ quota_snapshot=storage_quotas.snapshots,
83
+ usage_storage=storage_quotas.usage["gigabytes"],
84
+ quota_storage=storage_quotas.gigabytes,
58
85
  )
59
86
 
60
87
  return project_ret
File without changes
@@ -0,0 +1,83 @@
1
+ import logging
2
+
3
+ import concurrent
4
+
5
+ from openstack.connection import Connection
6
+ from openstack.identity.v3.role_assignment import RoleAssignment as OSRoleAssignment
7
+
8
+ from osi_dump.importer.role_assignment.role_assignment_importer import (
9
+ RoleAssignmentImporter,
10
+ )
11
+ from osi_dump.model.role_assignment import RoleAssignment
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class OpenStackRoleAssignmentImporter(RoleAssignmentImporter):
17
+ def __init__(self, connection: Connection):
18
+ self.connection = connection
19
+
20
+ def import_role_assignments(self) -> list[RoleAssignment]:
21
+ """Import role_assignments information from Openstack
22
+
23
+ Raises:
24
+ Exception: Raises exception if fetching role_assignment failed
25
+
26
+ Returns:
27
+ list[RoleAssignment]: _description_
28
+ """
29
+
30
+ logger.info(
31
+ f"Importing role_assignments for {self.connection.auth['auth_url']}"
32
+ )
33
+
34
+ try:
35
+ osrole_assignments: list[OSRoleAssignment] = list(
36
+ self.connection.identity.role_assignments()
37
+ )
38
+ except Exception as e:
39
+ raise Exception(
40
+ f"Can not fetch role_assignments for {self.connection.auth['auth_url']}"
41
+ ) from e
42
+
43
+ role_assignments: list[RoleAssignment] = []
44
+
45
+ with concurrent.futures.ThreadPoolExecutor() as executor:
46
+ futures = [
47
+ executor.submit(self._get_role_assignment_info, role_assignment)
48
+ for role_assignment in osrole_assignments
49
+ ]
50
+ for future in concurrent.futures.as_completed(futures):
51
+ role_assignments.append(future.result())
52
+
53
+ logger.info(f"Imported role_assignments for {self.connection.auth['auth_url']}")
54
+
55
+ return role_assignments
56
+
57
+ def _get_role_assignment_info(
58
+ self, role_assignment: OSRoleAssignment
59
+ ) -> RoleAssignment:
60
+
61
+ user_name = None
62
+ role_name = None
63
+
64
+ try:
65
+ role_name = self.connection.identity.get_role(
66
+ role_assignment.role["id"]
67
+ ).name
68
+ user_name = self.connection.identity.get_user(
69
+ role_assignment.user["id"]
70
+ ).name
71
+
72
+ except Exception as e:
73
+ logger.warning("Can not get role name or user name")
74
+
75
+ role_assignment_ret = RoleAssignment(
76
+ user_id=role_assignment.user["id"],
77
+ user_name=user_name,
78
+ role_id=role_assignment.role["id"],
79
+ role_name=role_name,
80
+ scope=role_assignment.scope,
81
+ )
82
+
83
+ return role_assignment_ret
@@ -0,0 +1,9 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from osi_dump.model.role_assignment import RoleAssignment
4
+
5
+
6
+ class RoleAssignmentImporter(ABC):
7
+ @abstractmethod
8
+ def import_role_assignments(self) -> list[RoleAssignment]:
9
+ pass
@@ -52,6 +52,19 @@ class OpenStackVolumeImporter(VolumeImporter):
52
52
 
53
53
  def _get_volume_info(self, volume: OSVolume) -> Volume:
54
54
 
55
+ snapshots = []
56
+ try:
57
+ snapshots = list(
58
+ self.connection.block_storage.snapshots(
59
+ details=False, all_projects=True, volume_id=volume.id
60
+ )
61
+ )
62
+
63
+ snapshots = [snapshot["id"] for snapshot in snapshots]
64
+
65
+ except Exception as e:
66
+ logger.warning(f"Fetching snapshots failed for {volume.id} error: {e}")
67
+
55
68
  ret_volume = Volume(
56
69
  volume_id=volume.id,
57
70
  project_id=volume.project_id,
@@ -59,6 +72,7 @@ class OpenStackVolumeImporter(VolumeImporter):
59
72
  attachments=[att["server_id"] for att in volume.attachments],
60
73
  type=volume.volume_type,
61
74
  size=volume.size,
75
+ snapshots=snapshots,
62
76
  updated_at=volume.updated_at,
63
77
  created_at=volume.created_at,
64
78
  )
@@ -0,0 +1,20 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict, ValidationError
4
+
5
+
6
+ class Flavor(BaseModel):
7
+ model_config = ConfigDict(strict=True)
8
+
9
+ flavor_id: str
10
+
11
+ flavor_name: str
12
+
13
+ properties: Optional[dict]
14
+
15
+ ram: int
16
+ vcpus: int
17
+ disk: int
18
+ swap: Optional[int]
19
+
20
+ public: bool
@@ -7,6 +7,14 @@ class Hypervisor(BaseModel):
7
7
  name: str
8
8
  state: str
9
9
  status: str
10
- local_disk_size: int
10
+
11
+ vcpus: int
12
+ vcpus_usage: int
13
+
11
14
  memory_size: int
12
- vpus: int
15
+ memory_usage: int
16
+
17
+ local_disk_usage: int
18
+ local_disk_size: int
19
+
20
+ vm_count: int
@@ -0,0 +1,26 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict, ValidationError
4
+
5
+
6
+ class Image(BaseModel):
7
+ model_config = ConfigDict(strict=True)
8
+
9
+ image_id: str
10
+
11
+ disk_format: str
12
+ min_disk: int
13
+ min_ram: int
14
+ image_name: Optional[str]
15
+ owner: str
16
+
17
+ properties: Optional[dict]
18
+
19
+ protected: bool
20
+ status: str
21
+ size: int
22
+ virtual_size: int
23
+ visibility: str
24
+
25
+ created_at: str
26
+ updated_at: str
@@ -0,0 +1,17 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict, ValidationError
4
+
5
+
6
+ class LoadBalancer(BaseModel):
7
+ model_config = ConfigDict(strict=True)
8
+
9
+ id: str
10
+
11
+ load_balancer_name: Optional[str]
12
+
13
+ status: str
14
+
15
+ # amphora_id: Optional[str]
16
+
17
+ project_id: Optional[str]
osi_dump/model/project.py CHANGED
@@ -11,3 +11,21 @@ class Project(BaseModel):
11
11
  domain_id: Optional[str]
12
12
  enabled: bool
13
13
  parent_id: Optional[str]
14
+
15
+ usage_instance: Optional[int]
16
+ quota_instance: Optional[int]
17
+
18
+ usage_vcpu: Optional[int]
19
+ quota_vcpu: Optional[int]
20
+
21
+ usage_ram: Optional[int]
22
+ quota_ram: Optional[int]
23
+
24
+ usage_volume: Optional[int]
25
+ quota_volume: Optional[int]
26
+
27
+ usage_snapshot: Optional[int]
28
+ quota_snapshot: Optional[int]
29
+
30
+ usage_storage: Optional[int]
31
+ quota_storage: Optional[int]
@@ -0,0 +1,17 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict, ValidationError
4
+
5
+
6
+ class RoleAssignment(BaseModel):
7
+ model_config = ConfigDict(strict=True)
8
+
9
+ user_id: str
10
+
11
+ user_name: Optional[str]
12
+
13
+ role_id: str
14
+
15
+ role_name: Optional[str]
16
+
17
+ scope: Optional[dict]
osi_dump/model/volume.py CHANGED
@@ -17,5 +17,7 @@ class Volume(BaseModel):
17
17
  type: str
18
18
  size: int
19
19
 
20
+ snapshots: Optional[list[str]]
21
+
20
22
  updated_at: str
21
23
  created_at: str
@@ -33,7 +33,6 @@ def get_connections(file_path) -> list[Connection]:
33
33
  password=auth.password,
34
34
  project_domain_name=auth.project_domain_name,
35
35
  user_domain_name=auth.user_domain_name,
36
- timeout=TIMEOUT_SECOND,
37
36
  )
38
37
 
39
38
  connections.append(connection)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: osi-dump
3
- Version: 0.1.1
3
+ Version: 0.1.2.1
4
4
  Summary: OpenStack instances information dump tool
5
5
  Author: TVKain
6
6
  License: Apache-2.0
@@ -1,52 +1,87 @@
1
1
  osi_dump/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  osi_dump/__main__.py,sha256=fCVTLFipB-P0872_4j7iOJNNosOMBj3YdHr8TH_fhRY,71
3
- osi_dump/cli.py,sha256=cTOQA_thCt1ON5eQ-gTA_hFUSN5uPgFPDoOttpyuTNg,3605
3
+ osi_dump/cli.py,sha256=5sFtsS91Em26PmziWybKFW7bxnfRompH-1UTnWIKGkc,5425
4
+ osi_dump/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ osi_dump/api/octavia.py,sha256=rT6d10OCQRdMnqvZTlW1gRMe1vOk8Rgct58oUIvDoyg,433
6
+ osi_dump/api/placement.py,sha256=9yADLulo1HfUnPLE7IJt4ZY8e2jRTaoeV4J4MMiKCew,455
4
7
  osi_dump/batch_handler/__init__.py,sha256=wsiE42GCjbKgXBzpiahWEDF_-IXCKzr6PyrLn0oEKSc,288
8
+ osi_dump/batch_handler/flavor_batch_handler.py,sha256=Cxf-rkuW5MrrOyiKi9N3InsdDGku7Bf0CAaPNhhM0hE,1589
5
9
  osi_dump/batch_handler/floating_ip_batch_handler.py,sha256=bEkT4BRi85qir-a1i7eEI_arA0LENq1gD6xHj8IdXu0,1771
6
10
  osi_dump/batch_handler/hypervisor_batch_handler.py,sha256=vkv6SAx1arPNVvFJ6RyvbJjC2F2Hes9km7dwhL4NJDY,1755
11
+ osi_dump/batch_handler/image_batch_handler.py,sha256=aGF_jnHXuBc7IRFoLLCrSFD8h4TP0g98T_NtBXkZjd4,1564
7
12
  osi_dump/batch_handler/instance_batch_handler.py,sha256=tiHAdhH76BT9-ymnTmTr962cMUTqpPpAQyPSePKEgSM,1761
13
+ osi_dump/batch_handler/load_balancer_batch_handler.py,sha256=Y8K5raUPX-ZtIRE9G0rgVBP9WsxKpqN3wv6eDYmXau4,1839
8
14
  osi_dump/batch_handler/project_batch_handler.py,sha256=uMHx_s-Z4tO1MBah5X-T5d6tLr0qUJuPIR_7RHJ64ck,1626
15
+ osi_dump/batch_handler/role_assignment_batch_handler.py,sha256=x0LuRIyaBQq17aDznXqLxtZOPj79ufGz7TKFSM63vMA,1889
9
16
  osi_dump/batch_handler/volume_batch_handler.py,sha256=UAU34FZD8XkJkmlr4Idk4NgFBzjD52PxekJDgV1ekG0,1569
10
17
  osi_dump/exporter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ osi_dump/exporter/flavor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ osi_dump/exporter/flavor/excel_flavor_exporter.py,sha256=_wNVToj0FsIkaLbqn7-TWETrtUftBM1Pjr-0WaBJtBI,876
20
+ osi_dump/exporter/flavor/flavor_exporter.py,sha256=-zQ8776yk7vHpiZUOcX61V8KxA40AAq8foV7fD0i1g0,155
11
21
  osi_dump/exporter/floating_ip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
22
  osi_dump/exporter/floating_ip/excel_floating_ip_exporter.py,sha256=Bn1yZTvZ8dP3EhVHW-Pr4O9TC2Cz2RbJaz_vRE66xTQ,975
13
23
  osi_dump/exporter/floating_ip/floating_ip_exporter.py,sha256=5qh4xS6m1Gfu2N3WcfkEu6U38qtc6oLWAsnNhSwXTCo,169
14
24
  osi_dump/exporter/hypervisor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
25
  osi_dump/exporter/hypervisor/excel_hypervisor_exporter.py,sha256=VhZoVjqCky5Sxvx0R9kxj-7O4tLTaPZKVqxyvqe1YLY,964
16
26
  osi_dump/exporter/hypervisor/hypervisor_exporter.py,sha256=HS3U-M-iv-ixNLfkGoaGdjdgHXXTBAjgtWQ_OhVY2xQ,167
27
+ osi_dump/exporter/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ osi_dump/exporter/image/excel_image_exporter.py,sha256=S_9UScZKI4N8xe8oXjNfnV2Eh7_llg7tOPR7H0hGVnA,853
29
+ osi_dump/exporter/image/image_exporter.py,sha256=7sNugBJDIDHjW_J9DCPgonIIGvD7xrjb5ofK195xNfM,152
17
30
  osi_dump/exporter/instance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
31
  osi_dump/exporter/instance/excel_instance_exporter.py,sha256=8WTv3RDOdUkumyWzwUK4KAZCnnq9P2yKi5TC091I9fs,931
19
32
  osi_dump/exporter/instance/instance_exporter.py,sha256=5CuKKvTa5S2_Ds7fap6tle4go9pOFmQ5VEf6O7tjwBo,161
33
+ osi_dump/exporter/load_balancer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ osi_dump/exporter/load_balancer/excel_load_balancer_exporter.py,sha256=BM3dzGL7UAug1v3Re04RBowOLGvHwc6mc0gsTfRJJwo,1008
35
+ osi_dump/exporter/load_balancer/load_balancer_exporter.py,sha256=Z5uvEKz1UG_dpAw5KVh-IX5PWLzlPt7pV9773bkgjXs,175
20
36
  osi_dump/exporter/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
37
  osi_dump/exporter/project/excel_project_exporter.py,sha256=2U3Tvn_Bk4xEQk3Tmh-oj5WXAG1bfxI6m7WVPF1upQw,916
22
38
  osi_dump/exporter/project/project_exporter.py,sha256=q3VAmtmBP4iq9YEW9Eescm3vjAVM4Ev3BDjzkGz9Pgo,158
39
+ osi_dump/exporter/role_assignment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ osi_dump/exporter/role_assignment/excel_role_assignment_exporter.py,sha256=CvMmueVclc22A7BPx8qR2-zXyr6FptI31bMHtyih2CA,1070
41
+ osi_dump/exporter/role_assignment/role_assignment_exporter.py,sha256=MmqFhhF7HWFoULNdDPt8yuW0GZmDxV262iEnLkLKw1s,181
23
42
  osi_dump/exporter/volume/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
43
  osi_dump/exporter/volume/excel_volume_exporter.py,sha256=BhesTGXMQF3BAwHgJMYfnxFgHxZo7TKPePG8q9T8ONI,865
25
44
  osi_dump/exporter/volume/volume_exporter.py,sha256=YoPvytC0ctWeWwVcG6pb0XwkF4N0QcGAoUHa3QldkEg,155
45
+ osi_dump/importer/flavor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ osi_dump/importer/flavor/flavor_importer.py,sha256=IfU2L8N8EO4eESnEDirwe9U-GXSTuTcsdrlDxD95tcQ,186
47
+ osi_dump/importer/flavor/openstack_flavor_importer.py,sha256=y3uFCls7H-l1tu11T_PaEoWghhdxINsf7baRAShXC1w,1876
26
48
  osi_dump/importer/floating_ip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
49
  osi_dump/importer/floating_ip/floating_ip_importer.py,sha256=2_lCZYF-r2dgdL4YzwsJPudDLbRBsSPi7Wt4jS0INiI,208
28
50
  osi_dump/importer/floating_ip/openstack_floating_ip_importer.py,sha256=xuALHyiyb4LdRgFN0hZvOx0pImKpGsLUtPWW_1q52gc,2286
29
51
  osi_dump/importer/hypervisor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
52
  osi_dump/importer/hypervisor/hypervisor_importer.py,sha256=JuoJBltqFYhH-Ql9TLUPHX2YurS0JFV7Augrc6bDJ5Q,206
31
- osi_dump/importer/hypervisor/openstack_hypervisor_importer.py,sha256=9Y-OsjfOzCKi_DijlHeMv9sgsD_oWB_YXW_lDtVeahM,2567
53
+ osi_dump/importer/hypervisor/openstack_hypervisor_importer.py,sha256=8EP99VPMrm4RUSHDbMmiuZeDOnwY17RLtJGotHd6ETs,3093
54
+ osi_dump/importer/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
+ osi_dump/importer/image/image_importer.py,sha256=6zwAMnS58S2HGwARwebqf4VE9IBQBv5Ot6nmcn9H4fY,181
56
+ osi_dump/importer/image/openstack_image_importer.py,sha256=Tc2eZ4fU_2S-fp_vuDWutqPcyV6Erz17nDLjzjusihY,2413
32
57
  osi_dump/importer/instance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
58
  osi_dump/importer/instance/instance_importer.py,sha256=TaaPgEFVVMRT3mSXrzQkSaSIBPBwwANpEaWCgRsgImc,196
34
59
  osi_dump/importer/instance/openstack_instance_importer.py,sha256=b1OB-8_7DlwvOo7TX5zUG64XXtUufKhgCc3lhgNqxaY,3394
60
+ osi_dump/importer/load_balancer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
+ osi_dump/importer/load_balancer/load_balancer_importer.py,sha256=fzInBlkscqlbhCATeQYXvufc-WHq2pbofTJJifN0zaY,218
62
+ osi_dump/importer/load_balancer/openstack_load_balancer_importer.py,sha256=Uh94UJLeKCSmDAuPORf-TJbl3nVYzkB4lDxt2J6-d88,2072
35
63
  osi_dump/importer/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
- osi_dump/importer/project/openstack_project_importer.py,sha256=wdNJTTEhsvhnW6Wn0xLx8nAoJOhtiG9-6jGB0WnnYVU,1837
64
+ osi_dump/importer/project/openstack_project_importer.py,sha256=K8Si2uaC88L2CxXi68A4ML9mlWKwnZp1ABDiufFUZ8g,2988
37
65
  osi_dump/importer/project/project_importer.py,sha256=jwEvxteFbSwyWMV8hKAtf5Lo2bZysWkQ1L_NVUE8XOQ,191
66
+ osi_dump/importer/role_assignment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ osi_dump/importer/role_assignment/openstack_role_assignment_importer.py,sha256=nESax2gka0BpKUA2phmk1-wx0IjFLA1xGf-mORHZgFg,2598
68
+ osi_dump/importer/role_assignment/role_assignment_importer.py,sha256=Faorx0qsgdXjv5y2t-7obpV3wFfbmByx_-8b9yBr7L8,228
38
69
  osi_dump/importer/volume/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- osi_dump/importer/volume/openstack_volume_importer.py,sha256=dKIOezidH3IZhlp6745XruJbxdzeMzXE-q4x0SYAe74,2007
70
+ osi_dump/importer/volume/openstack_volume_importer.py,sha256=Tte9fX91oxEoRcUZPJd7g6oH6izcWy8WwFCapg_ZY1M,2454
40
71
  osi_dump/importer/volume/volume_importer.py,sha256=tmDTE9L9vtl75GR79blSxa_MVsRU6LDCbR0yJk0xKwo,186
41
72
  osi_dump/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
73
  osi_dump/model/authentication_info.py,sha256=02kXxtILfjh8t45_-bPM8rtyRk2cQcJK6l2d1bPih7k,257
74
+ osi_dump/model/flavor.py,sha256=-G8FaH_qiVrgtRxAWhdpC1c9FRdXLRroG-WJ03-DRZ4,318
43
75
  osi_dump/model/floating_ip.py,sha256=CRJufC5ZaxxcbGvdot7Af-sO8uyKbyQK9zHljfBnyFA,427
44
- osi_dump/model/hypervisor.py,sha256=L3FKY57HiI55-AgxNPXVT55BgkJUDwPFYIfzLprJ2VE,244
76
+ osi_dump/model/hypervisor.py,sha256=pToa-rg7LldKd-h3aNZDJQPy5dhYDIXehq-tr8_xv1I,336
77
+ osi_dump/model/image.py,sha256=ahW0rRb2mgqoPqYhRzn_qnyShKvCvNZPlcDs_bnyt6g,445
45
78
  osi_dump/model/instance.py,sha256=flNywojuBj7ZyFTnWvl2rpvzL3Ju-QtuUY69DSPfPs8,464
46
- osi_dump/model/project.py,sha256=vh3qhR5JpQ6yxvGK9CXiJ9-HoyyYGAggKF56AEEg-tE,289
47
- osi_dump/model/volume.py,sha256=unb2dy7dIDi3-D6WKJAhmnPsn_DI27GZJsZCrDBh89M,335
79
+ osi_dump/model/load_balancer.py,sha256=ve0vEbIAZLR7RBCbEk_MGR8wrfKQ9dI21Jx6V7nFoR4,298
80
+ osi_dump/model/project.py,sha256=3fNsDcWxuRVBS96W98C_Fia82qt14InjUM7n7rBCX6E,679
81
+ osi_dump/model/role_assignment.py,sha256=dwuXVxgHJ8pIu8_i_w9kZ0r0uaQQXAMDTYnLrDY3O9U,290
82
+ osi_dump/model/volume.py,sha256=1p5Xw0LPxfroJwSYtE-n_Gv4MsRDA_sSvc7SQY_Uo8I,371
48
83
  osi_dump/os_connection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
- osi_dump/os_connection/get_connections.py,sha256=_CiKot2GgQDOAJ33goN9mcwaGYQCqzCOitntz9cf3-c,1793
84
+ osi_dump/os_connection/get_connections.py,sha256=1zeir4cEtzJOUOn53zUmlD9lWMvYXhuRr0IhI5U1DAw,1753
50
85
  osi_dump/util/__init__.py,sha256=GvhYTETVePJAsp0LfseMGtuRFWbbCc2xox-QSGQA3Us,286
51
86
  osi_dump/util/create_file.py,sha256=hcEspFD0VZDtXCaG5QtMkV37GsbAHATdxYlClTszVK8,242
52
87
  osi_dump/util/excel_autosize_column.py,sha256=zzQ6uXkQhHAqVn9fUAgNjoCH_HiNEC9Dcj4OBqHd6rw,1102
@@ -54,8 +89,8 @@ osi_dump/util/excel_sort_sheet.py,sha256=o4jXtP1ZFYtAGzkAP5S8Tym4h-SEoFBAI3j24y-
54
89
  osi_dump/util/export_data_excel.py,sha256=VYSxDBZ7dgSbTj3n_8RRPqe183tILNh6wJW-UnFvJUU,882
55
90
  osi_dump/util/extract_hostname.py,sha256=IpdklGHevmtRu67xeSRE_5n2mvWGI1sDsnJwExo_AR0,111
56
91
  osi_dump/util/validate_dir_path.py,sha256=pL_OrY8JnNwk3vj6Zp6bsZtgHXhszSGRoqIt-1G5S90,507
57
- osi_dump-0.1.1.dist-info/METADATA,sha256=z48w2kSB9iL1CiVn2E3jP3FzExf4R1P5dIZ_Xu51vxU,662
58
- osi_dump-0.1.1.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
59
- osi_dump-0.1.1.dist-info/entry_points.txt,sha256=ozm5sIBtXzLv6_FiUe26v1BgA3_xUReGLPhKQKZ56wQ,46
60
- osi_dump-0.1.1.dist-info/top_level.txt,sha256=OtAAwmJfcoPvlw_Cemo_H1aXIGV_7w0O2941KQt6faQ,9
61
- osi_dump-0.1.1.dist-info/RECORD,,
92
+ osi_dump-0.1.2.1.dist-info/METADATA,sha256=DCMaAo3uYHiZeiyqjcWStEokaKxFKuzgYH-_-JIDBnE,664
93
+ osi_dump-0.1.2.1.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
94
+ osi_dump-0.1.2.1.dist-info/entry_points.txt,sha256=ozm5sIBtXzLv6_FiUe26v1BgA3_xUReGLPhKQKZ56wQ,46
95
+ osi_dump-0.1.2.1.dist-info/top_level.txt,sha256=OtAAwmJfcoPvlw_Cemo_H1aXIGV_7w0O2941KQt6faQ,9
96
+ osi_dump-0.1.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: setuptools (72.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5