aboutsummaryrefslogtreecommitdiffstats
path: root/ice_validator/preload/data.py
blob: 721608fcfd7b6854091d63c2f426011c34e87237 (plain)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
from abc import ABC, abstractmethod
from pathlib import Path
from typing import Iterable, Any, Optional, Mapping

from preload.model import VnfModule


class AbstractPreloadInstance(ABC):
    """
    Represents the data source for a single instance of a preload for
    any format.  The implementation of AbstractPreloadGenerator will
    call the methods of this class to retrieve the necessary data
    to populate the preload.  If a data element is not available,
    then simply return ``None`` and a suitable placeholder will be
    placed in the preload.
    """

    @property
    @abstractmethod
    def output_dir(self) -> Path:
        """
        Base output directory where the preload will be generated.  Please
        note, that the generator may create nested directories under this
        directory for the preload.

        :return: Path to the desired output directory.  This directory
                 and its parents will be created by the generator if
                 it is not already present.
        """
        raise NotImplementedError()

    @property
    @abstractmethod
    def module_label(self) -> str:
        """
        Identifier of the module.  This must match the base name of the
        heat module (ex: if the Heat file name is base.yaml, then the label
        is 'base'.

        :return: string name of the module
        """
        raise NotImplementedError()

    @property
    @abstractmethod
    def vf_module_name(self) -> Optional[str]:
        """
        :return: module name to populate in the preload if available
        """
        raise NotImplementedError()

    @property
    @abstractmethod
    def flag_incompletes(self) -> bool:
        """
        If True, then the generator will modify the file name of any
        generated preload to end with _incomplete.<ext> if any preload
        value was not satisfied by the data source.  If False, then
        the file name will be the same regardless of the completeness
        of the preload.

        :return: True if file names should denote preload incompleteness
        """
        raise NotImplementedError()

    @property
    @abstractmethod
    def preload_basename(self) -> str:
        """
        Base name of the preload that will be used by the generator to create
        the file name.
        """
        raise NotImplementedError()

    @property
    @abstractmethod
    def vnf_name(self) -> Optional[str]:
        """
        :return: the VNF name to populate in the prelad if available
        """
        raise NotImplementedError()

    @property
    @abstractmethod
    def vnf_type(self) -> Optional[str]:
        """
        The VNF Type must be match the values in SDC.  It is a concatenation
        of <Service Instance Name>/<Resource Instance Name>.

        :return: VNF Type to populate in the preload if available
        """
        raise NotImplementedError()

    @property
    @abstractmethod
    def vf_module_model_name(self) -> Optional[str]:
        """
        :return: Module model name if available
        """
        raise NotImplementedError()

    @abstractmethod
    def get_availability_zone(self, index: int, param_name: str) -> Optional[str]:
        """
        Retrieve the value for the availability zone at requested zero-based
        index (i.e. 0, 1, 2, etc.)

        :param index:       index of availability zone (0, 1, etc.)
        :param param_name:  Name of the parameter from Heat
        :return:            value for the AZ if available
        """
        raise NotImplementedError()

    @abstractmethod
    def get_network_name(self, network_role: str, name_param: str) -> Optional[str]:
        """
        Retrieve the OpenStack name of the network for the given network role.

        :param network_role:    Network role from Heat template
        :param name_param:      Network name parameter from Heat
        :return:                Name of the network if available
        """
        raise NotImplementedError()

    @abstractmethod
    def get_subnet_id(
        self, network_role: str, ip_version: int, param_name: str
    ) -> Optional[str]:
        """
        Retrieve the subnet's UUID for the given network and IP version (4 or 6).

        :param network_role:    Network role from Heat template
        :param ip_version:      IP Version (4 or 6)
        :param param_name:      Parameter name from Heat
        :return:                UUID of the subnet if available
        """
        raise NotImplementedError()

    @abstractmethod
    def get_subnet_name(
        self, network_role: str, ip_version: int, param_name: str
    ) -> Optional[str]:
        """
        Retrieve the OpenStack Subnet name for the given network role and IP version

        :param network_role:    Network role from Heat template
        :param ip_version:      IP Version (4 or 6)
        :param param_name:      Parameter name from Heat
        :return:                Name of the subnet if available
        """
        raise NotImplementedError()

    @abstractmethod
    def get_vm_name(self, vm_type: str, index: int, param_name: str) -> Optional[str]:
        """
        Retrieve the vm name for the given VM type and index.

        :param vm_type:         VM Type from Heat template
        :param index:           Zero-based index of the VM for the vm-type
        :param param_name:      Parameter name from Heat
        :return:                VM Name if available
        """
        raise NotImplementedError()

    @abstractmethod
    def get_floating_ip(
        self, vm_type: str, network_role: str, ip_version: int, param_name: str
    ) -> Optional[str]:
        """
        Retreive the floating IP for the VM and Port identified by VM Type,
        Network Role, and IP Version.

        :param vm_type:         VM Type from Heat template
        :param network_role:    Network Role from Heat template
        :param ip_version:      IP Version (4 or 6)
        :param param_name:      Parameter name from Heat
        :return: floating IP address if available
        """
        raise NotImplementedError()

    @abstractmethod
    def get_fixed_ip(
        self, vm_type: str, network_role: str, ip_version: int, index: int, param: str
    ) -> Optional[str]:
        """
        Retreive the fixed IP for the VM and Port identified by VM Type,
        Network Role, IP Version, and index.

        :param vm_type:         VM Type from Heat template
        :param network_role:    Network Role from Heat template
        :param ip_version:      IP Version (4 or 6)
        :param index:           zero-based index for the IP for the given
                                VM Type, Network Role, IP Version combo
        :param param_name:      Parameter name from Heat
        :return: floating IP address if available
        """
        raise NotImplementedError()

    @abstractmethod
    def get_vnf_parameter(self, key: str, value: Any) -> Optional[Any]:
        """
        Retrieve the value for the given key.  These will be placed in the
        tag-values/vnf parameters in the preload.  If a value was specified in
        the environment packaged in the Heat for for the VNF module, then
        that value will be  passed in ``value``.  This class can return
        the value or ``None`` if it does not have a value for the given key.

        :param key:     parameter name from Heat
        :param value:   Value from Heat env file if it was assigned there;
                        None otherwise
        :return:        Returns the value for the object.  This should
                        be a str, dict, or list.  The generator will
                        format it properly based on the selected output format
        """
        raise NotImplementedError()

    @abstractmethod
    def get_additional_parameters(self) -> Mapping[str, Any]:
        """
        Return any additional parameters that should be added to the VNF parameters.

        This can be useful if you want to duplicate paramters in tag values that are
        also in the other sections (ex: VM names).

        :return: dict of str to object mappings that the generator must add to
                 the vnf_parameters/tag values
        """
        raise NotImplementedError()


class AbstractPreloadDataSource(ABC):
    """
    Represents a data source for a VNF preload data.  Implementations of this
    class can be dynamically discovered if they are in a preload plugin module.
    A module is considered a preload plugin module if it starts with
    prelaod_ and is available as a top level module on Python's sys.path.

    The ``get_module_preloads`` will be invoked for each module in
    the VNF.  An instance of AbstractPreloadInstance must be returned for
    each instance of the preload module that is to be created.

    Parameters:
        :param path:    The path to the configuration source selected
                        in either the VVP GUI or command-line.  This
                        may be a file or directory depending upon
                        the source_type defined by this data source
    """

    def __init__(self, path: Path):
        self.path = path

    @classmethod
    @abstractmethod
    def get_source_type(cls) -> str:
        """
        If 'FILE' returned, then the config source will be a specific
        file; If 'DIR', then the config source will be a directory
        :return:
        """
        raise NotImplementedError()

    @classmethod
    @abstractmethod
    def get_identifier(cls) -> str:
        """
        Identifier for the given data source. This is the value that
        can be passed via --preload-source-type.

        :return: short identifier for this data source type
        """

    @classmethod
    @abstractmethod
    def get_name(self) -> str:
        """
        Human readable name to describe the preload data source. It is
        recommended not to exceed 50 characters.

        :return: human readable name of the preload data source (ex: Environment Files)
        """
        raise NotImplementedError()

    @abstractmethod
    def get_module_preloads(
        self, module: VnfModule
    ) -> Iterable[AbstractPreloadInstance]:
        """
        For the  requested module, return an instance of AbstractPreloadInstance
        for every preload module you wish to be created.

        :param module:  Module of the VNF
        :return:        iterable of preloads to create for the given module
        """
        raise NotImplementedError()


class BlankPreloadInstance(AbstractPreloadInstance):
    """
    Used to create blank preload templates.  VVP will always create
    a template of a preload in the requested format with no data provided.
    """

    def __init__(self, output_dir: Path, module_name: str):
        self._output_dir = output_dir
        self._module_name = module_name

    @property
    def flag_incompletes(self) -> bool:
        return False

    @property
    def preload_basename(self) -> str:
        return self._module_name

    @property
    def vf_module_name(self) -> Optional[str]:
        return None

    def get_vm_name(self, vm_type: str, index: int, param_name: str) -> Optional[str]:
        return None

    def get_availability_zone(self, index: int, param_name: str) -> Optional[str]:
        return None

    @property
    def output_dir(self) -> Path:
        return self._output_dir

    @property
    def module_label(self) -> str:
        return self._module_name

    @property
    def vnf_name(self) -> Optional[str]:
        return None

    @property
    def vnf_type(self) -> Optional[str]:
        return None

    @property
    def vf_module_model_name(self) -> Optional[str]:
        return None

    def get_network_name(self, network_role: str, name_param: str) -> Optional[str]:
        return None

    def get_subnet_id(
        self, network_role: str, ip_version: int, param_name: str
    ) -> Optional[str]:
        return None

    def get_subnet_name(
        self, network_role: str, ip_version: int, param_name: str
    ) -> Optional[str]:
        return None

    def get_floating_ip(
        self, vm_type: str, network_role: str, ip_version: int, param_name: str
    ) -> Optional[str]:
        return None

    def get_fixed_ip(
        self, vm_type: str, network_role: str, ip_version: int, index: int, param: str
    ) -> Optional[str]:
        return None

    def get_vnf_parameter(self, key: str, value: Any) -> Optional[Any]:
        return None

    def get_additional_parameters(self) -> Mapping[str, Any]:
        return {}