vFW and vDNS support added to azure-plugin
[multicloud/azure.git] / azure / aria / aria-extension-cloudify / src / aria / aria / extension.py
1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements.  See the NOTICE file distributed with
3 # this work for additional information regarding copyright ownership.
4 # The ASF licenses this file to You under the Apache License, Version 2.0
5 # (the "License"); you may not use this file except in compliance with
6 # the License.  You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 """
17 Mechanism for registering and loading ARIA extensions.
18 """
19
20 # pylint: disable=no-self-use
21
22 from .utils import collections
23
24
25 class _Registrar(object):
26
27     def __init__(self, registry):
28         if not isinstance(registry, (dict, list)):
29             raise RuntimeError('Unsupported registry type')
30         self._registry = registry
31
32     def register(self, function):
33         result = function()
34         if isinstance(self._registry, dict):
35             for key in result:
36                 if key in self._registry:
37                     raise RuntimeError('Re-definition of {0} in {1}'.format(key, function.__name__))
38             self._registry.update(result)
39         elif isinstance(self._registry, list):
40             if not isinstance(result, (list, tuple, set)):
41                 result = [result]
42             self._registry += list(result)
43         else:
44             raise RuntimeError('Illegal state')
45
46     def __call__(self):
47         return self._registry
48
49
50 def _registrar(function):
51     function._registrar_function = True
52     return function
53
54
55 class _ExtensionRegistration(object):
56     """
57     Base class for extension class decorators.
58     """
59
60     def __init__(self):
61         self._registrars = {}
62         self._registered_classes = []
63         for attr, value in vars(self.__class__).items():
64             try:
65                 is_registrar_function = value._registrar_function
66             except AttributeError:
67                 is_registrar_function = False
68             if is_registrar_function:
69                 registrar = _Registrar(registry=getattr(self, attr)())
70                 setattr(self, attr, registrar)
71                 self._registrars[attr] = registrar
72
73     def __call__(self, cls):
74         self._registered_classes.append(cls)
75         return cls
76
77     def init(self):
78         """
79         Initialize all registrars by calling all registered functions.
80         """
81         registered_instances = [cls() for cls in self._registered_classes]
82         for name, registrar in self._registrars.items():
83             for instance in registered_instances:
84                 registrating_function = getattr(instance, name, None)
85                 if registrating_function:
86                     registrar.register(registrating_function)
87
88
89 class _ParserExtensionRegistration(_ExtensionRegistration):
90     """
91     Parser extensions class decorator.
92     """
93
94     @_registrar
95     def presenter_class(self):
96         """
97         Presentation class registration.
98
99         Implementing functions can return a single class or a list/tuple of classes.
100         """
101         return []
102
103     @_registrar
104     def specification_package(self):
105         """
106         Specification package registration.
107
108         Implementing functions can return a package name or a list/tuple of names.
109         """
110         return []
111
112     @_registrar
113     def specification_url(self):
114         """
115         Specification URL registration.
116
117         Implementing functions should return a dictionary from names to URLs.
118         """
119         return {}
120
121     @_registrar
122     def uri_loader_prefix(self):
123         """
124         URI loader prefix registration.
125
126         Implementing functions can return a single prefix or a list/tuple of prefixes.
127         """
128         return collections.StrictList(value_class=basestring)
129
130 parser = _ParserExtensionRegistration()
131
132
133 class _ProcessExecutorExtensionRegistration(_ExtensionRegistration):
134     """
135     Process executor extension class decorator.
136     """
137
138     @_registrar
139     def decorate(self):
140         """
141         The operation function executed by the process executor will be decorated with the function
142         returned from ``decorate()``.
143         """
144         return []
145
146 process_executor = _ProcessExecutorExtensionRegistration()
147
148
149 def init():
150     """
151     Initialize all registrars by calling all registered functions.
152     """
153     parser.init()
154     process_executor.init()