forked from openstack/openstacksdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprint-services.py
131 lines (111 loc) · 4.62 KB
/
print-services.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# Copyright 2018 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import importlib
import warnings
import os_service_types
from openstack import _log
from openstack import service_description
_logger = _log.setup_logging('openstack')
_service_type_manager = os_service_types.ServiceTypes()
def make_names():
imports = ['from openstack import service_description']
services = []
for service in _service_type_manager.services:
service_type = service['service_type']
if service_type == 'ec2-api':
# NOTE(mordred) It doesn't make any sense to use ec2-api
# from openstacksdk. The credentials API calls are all calls
# on identity endpoints.
continue
desc_class = _find_service_description_class(service_type)
st = service_type.replace('-', '_')
if desc_class.__module__ != 'openstack.service_description':
base_mod, dm = desc_class.__module__.rsplit('.', 1)
imports.append(f'from {base_mod} import {dm}')
else:
dm = 'service_description'
dc = desc_class.__name__
services.append(
"{st} = {dm}.{dc}(service_type='{service_type}')".format(
st=st, dm=dm, dc=dc, service_type=service_type
),
)
# Register the descriptor class with every known alias. Don't
# add doc strings though - although they are supported, we don't
# want to give anybody any bad ideas. Making a second descriptor
# does not introduce runtime cost as the descriptors all use
# the same _proxies dict on the instance.
for alias_name in _get_aliases(st):
if alias_name[-1].isdigit():
continue
services.append(f'{alias_name} = {st}')
services.append('')
print("# Generated file, to change, run tools/print-services.py")
for imp in sorted(imports):
print(imp)
print('\n')
print("class ServicesMixin:\n")
for service in services:
if service:
print(f" {service}")
else:
print()
def _get_aliases(service_type, aliases=None):
# We make connection attributes for all official real type names
# and aliases. Three services have names they were called by in
# openstacksdk that are not covered by Service Types Authority aliases.
# Include them here - but take heed, no additional values should ever
# be added to this list.
# that were only used in openstacksdk resource naming.
LOCAL_ALIASES = {
'baremetal': 'bare_metal',
'block_storage': 'block_store',
'clustering': 'cluster',
}
all_types = set(_service_type_manager.get_aliases(service_type))
if aliases:
all_types.update(aliases)
if service_type in LOCAL_ALIASES:
all_types.add(LOCAL_ALIASES[service_type])
all_aliases = set()
for alias in all_types:
all_aliases.add(alias.replace('-', '_'))
return all_aliases
def _find_service_description_class(service_type):
package_name = f'openstack.{service_type}'.replace('-', '_')
module_name = service_type.replace('-', '_') + '_service'
class_name = ''.join(
[part.capitalize() for part in module_name.split('_')]
)
# We have some exceptions :(
# This should have been called 'shared-filesystem'
if service_type == 'shared-file-system':
class_name = 'SharedFilesystemService'
try:
import_name = '.'.join([package_name, module_name])
service_description_module = importlib.import_module(import_name)
except ImportError as e:
# ImportWarning is ignored by default. This warning is here
# as an opt-in for people trying to figure out why something
# didn't work.
warnings.warn(
f"Could not import {service_type} service description: {str(e)}",
ImportWarning,
)
return service_description.ServiceDescription
# There are no cases in which we should have a module but not the class
# inside it.
service_description_class = getattr(service_description_module, class_name)
return service_description_class
make_names()