add python compatibility module
[optf/has.git] / conductor / doc / template / README.md
1 ###### Apache License, Version 2.0
2
3 ===========================
4
5 ``Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.``
6
7 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
8
9     http://www.apache.org/licenses/LICENSE-2.0
10
11 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.
12
13 # Homing Specification Guide
14
15 *Updated: 10 October 2017*
16
17 This document describes the Homing Template format, used by the Homing service. It is a work in progress and subject to frequent revision.
18
19 ## Template Structure
20
21 Homing templates are defined in YAML and follow the structure outlined below.
22
23 ```yaml
24 homing_template_version: 2017-10-10
25 parameters:
26   PARAMETER_DICT
27 locations:
28   LOCATION_DICT
29 demands:
30   DEMAND_DICT
31 constraints:
32   CONSTRAINT_DICT
33 reservations:
34   RESERVATION_DICT
35 optimization:
36   OPTIMIZATION
37 ```
38
39 * ``homing_template_version``: This key with value 2017-10-10 (or a later date) indicates that the YAML document is a Homing template of the specified version.
40 * ``parameters``: This section allows for specifying input parameters that have to be provided when instantiating the homing template. Typically, this section is used for providing runtime parameters (like SLA thresholds), which in turn is used in the existing homing policies. The section is optional and can be omitted when no input is required.
41 * ``locations``: This section contains the declaration of geographic locations. This section is optional and can be omitted when no input is required.
42 * ``demands``: This section contains the declaration of demands. This section with at least one demand should be defined in any Homing template, or the template would not really do anything when being instantiated.
43 * ``constraints``: This section contains the declaration of constraints. The section is optional and can be omitted when no input is required.
44 * ``reservations``: This section contains the declaration of required reservations. This section is optional and can be omitted when reservations are not required.
45 * ``optimization``: This section allows the declaration of an optimization. This section is optional and can be omitted when no input is required.
46
47 ## Homing Template Version
48
49 The value of ``homing_template_version`` tells HAS not only the format of the template but also features that will be validated and supported. Only one value is supported: ``2017-10-10`` in the initial release of HAS.
50
51 ```yaml
52 homing_template_version: 2017-10-10
53 ```
54
55 ## Parameters
56
57 The **parameters** section allows for specifying input parameters that have to be provided when instantiating the template. Such parameters are typically used for providing runtime inputs (like SLA thresholds), which in turn is used in the existing homing policies. This also helps build reusable homing constraints where these parameters can be embedded design time, and it corresponding values can be supplied during runtime.
58
59 Each parameter is specified with the name followed by its value. Values can be strings, lists, or dictionaries.
60
61 ### Example
62
63 In this example, ``provider_name`` is a string and ``service_info`` is a dictionary containing both a string and a list (keyed by ``base_url`` and ``nod_config``, respectively).
64
65 ```yaml
66 parameters:
67   provider_name: multicloud
68   service_info:
69     base_url: http://serviceprovider.sdngc.com/
70     nod_config:
71     - http://nod/config_a.yaml
72     - http://nod/config_b.yaml
73     - http://nod/config_c.yaml
74     - http://nod/config_d.yaml
75 ```
76
77 A parameter can be referenced in place of any value. See the **Intrinsic Functions** section for more details.
78
79 ## Locations
80
81 One or more **locations** may be declared. A location may be referenced by one or more ``constraints``. Locations may be defined in any of the following ways:
82
83 ### Coordinate
84
85 A geographic coordinate expressed as a latitude and longitude.
86
87 | Key                         | Value                      |
88 |-----------------------------|----------------------------|
89 | ``latitude``                | Latitude of the location.  |
90 | ``longitude``               | Longitude of the location. |
91
92 ### Host Name
93
94 An opaque host name that can be translated to a coordinate via an inventory provider (e.g., A&AI).
95
96 | Key                         | Value                      |
97 |-----------------------------|----------------------------|
98 | ``host_name``               | Host name identifying a location. |
99
100 ### CLLI
101
102 Common Language Location Identification (CLLI) code(https://en.wikipedia.org/wiki/CLLI_code).
103
104 | Key                         | Value                      |
105 |-----------------------------|----------------------------|
106 | ``clli_code``               | 8 character CLLI. |
107
108 **Questions**
109
110 * Do we need functions that can convert one of these to the other? E.g., CLLI Codes to a latitude/longitude
111
112 ### Placemark
113
114 An address expressed in geographic region-agnostic terms (referred to as a *placemark*).
115
116 *Support for this schema is deferred.*
117
118 | Key                         | Value                      |
119 |-----------------------------|----------------------------|
120 | ``iso_country_code``        | The abbreviated country name associated with the placemark. |
121 | ``postal_code``             | The postal code associated with the placemark. |
122 | ``administrative_area``     | The state or province associated with the placemark. |
123 | ``sub_administrative_area`` | Additional administrative area information for the placemark. |
124 | ``locality``                | The city associated with the placemark. |
125 | ``sub_locality``            | Additional city-level information for the placemark. |
126 | ``thoroughfare``            | The street address associated with the placemark. |
127 | ``sub_thoroughfare``        | Additional street-level information for the placemark. |
128
129 **Questions**
130
131 * What geocoder can we use to convert placemarks to a latitude/longitude?
132
133 ### Examples
134
135 The following examples illustrate a location expressed in coordinate, host_name, CLLI, and placemark, respectively.
136
137 ```yaml
138 locations:
139   location_using_coordinates:
140     latitude: 32.897480
141     longitude: -97.040443
142
143   host_location_using_host_name:
144     host_name: USESTCDLLSTX55ANZ123
145
146   location_using_clli:
147     clli_code: DLLSTX55
148
149   location_using_placemark:
150     sub_thoroughfare: 1
151     thoroughfare: ATT Way
152     locality: Bedminster
153     administrative_area: NJ
154     postal_code: 07921-2694
155 ```
156
157 ## Demands
158
159 A **demand** can be satisfied by using candidates drawn from inventories. Each demand is uniquely named. Inventory is considered to be opaque and can represent anything from which candidates can be drawn.
160
161 A demand's resource requirements are determined by asking an **inventory provider** for one or more sets of **inventory candidates** against which the demand will be made. An explicit set of candidates may also be declared, for example, if the only candidates for a demand are predetermined.
162
163 Demand criteria is dependent upon the inventory provider in use.
164
165 **Provider-agnostic Schema**
166
167 | Key                    | Value                    |
168 |------------------------|--------------------------|
169 | ``inventory_provider`` | A HAS-supported inventory provider. |
170 | ``inventory_type`` | The reserved word ``cloud`` (for cloud regions) or the reserved word ``service`` (for existing service instances). Exactly one inventory type may be specified. |
171 | ``attributes`` (Optional) | A list of key-value pairs, that is used to select inventory candidates that match *all* the specified attributes. The key should be a uniquely identifiable attribute at the inventory provider. |
172 | ``service_type`` (Optional) | If ``inventory_type`` is ``service``, a list of one or more provider-defined service types. If only one service type is specified, it may appear without list markers (``[]``). |
173 | ``service_id`` (Optional) | If ``inventory_type`` is ``service``, a list of one or more provider-defined service ids. If only one service id is specified, it may appear without list markers (``[]``). |
174 | ``default_cost`` (Optional) | The default cost of an inventory candidate, expressed as currency. This must be specified if the inventory provider may not always return a cost. |
175 | ``required_candidates`` (Optional) | A list of one or more candidates from which a solution will be explored. Must be a valid candidate as described in the **candidate schema**. |
176 | ``excluded_candidates`` (Optional) | A list of one or more candidates that should be excluded from the search space. Must be a valid candidate as described in the **candidate schema**. |
177 | ``existing_placement`` (Optional) | The current placement for the demand. Must be a valid candidate as described in the **candidate schema**. |
178
179
180 ### Examples
181
182 The following example helps understand a demand specification using Active & Available Inventory (A&AI), the inventory provider-of-record for ONAP.
183
184 **Inventory Provider Criteria**
185
186 | Key                    | Value                    |
187 |------------------------|--------------------------|
188 | ``inventory_provider`` | Examples: ``aai``, ``multicloud``. |
189 | ``inventory_type`` | The reserved word ``cloud`` (for new inventory) or the reserved word ``service`` (for existing inventory). Exactly one inventory type may be specified. |
190 | ``attributes`` (Optional) | A list of key-value pairs to match against inventory when drawing candidates. |
191 | ``service_type`` (Optional) | Examples may include ``vG``, ``vG_MuxInfra``, etc. |
192 | ``service_id`` (Optional) | Must be a valid service id. Examples may include ``vCPE``, ``VoLTE``, etc. |
193 | ``default_cost`` (Optional) | The default cost of an inventory candidate, expressed as a unitless number. |
194 | ``required_candidates`` (Optional) | A list of one or more valid candidates. See **Candidate Schema** for details. |
195 | ``excluded_candidates`` (Optional) | A list of one or more valid candidates. See **Candidate Schema** for details. |
196 | ``existing_placement`` (Optional) | A single valid candidate, representing the current placement for the demand. See **candidate schema** for details. |
197
198 **Candidate Schema**
199
200 The following is the schema for a valid ``candidate``:
201 * ``candidate_id`` uniquely identifies a candidate. Currently, it is either a Service Instance ID or Cloud Region ID.
202 * ``candidate_type`` identifies the type of the candidate. Currently, it is either ``cloud`` or ``service``.
203 * ``inventory_type`` is defined as described in **Inventory Provider Criteria** (above).
204 * ``inventory_provider`` identifies the inventory from which the candidate was drawn.
205 * ``host_id`` is an ID of a specific host (used only when referring to service/existing inventory).
206 * ``cost`` is expressed as a unitless number.
207 * ``location_id`` is always a location ID of the specified location type (e.g., for a type of ``cloud`` this will be an Cloud Region ID).
208 * ``location_type`` is an inventory provider supported location type.
209 * ``latitude`` is a valid latitude corresponding to the *location_id*.
210 * ``longitude`` is a valid longitude corresponding to the *location_id*.
211 * ``city`` (Optional) city corresponding to the *location_id*.
212 * ``state`` (Optional) state corresponding to the *location_id*.
213 * ``country`` (Optional) country corresponding to the *location_id*.
214 * ``region`` (Optional) geographic region corresponding to the *location_id*.
215 * ``complex_name`` (Optional) Name of the complex corresponding to the *location_id*.
216 * ``cloud_owner`` (Optional) refers to the *cloud owner* (e.g., ``azure``, ``aws``, ``att``, etc.).
217 * ``cloud_region_version`` (Optional) is an inventory provider supported version of the cloud region.
218 * ``physical_location_id`` (Optional) is an inventory provider supported CLLI code corresponding to the cloud region.
219
220 **Examples**
221
222 ```json
223 {
224         "candidate_id": "1ac71fb8-ad43-4e16-9459-c3f372b8236d",
225         "candidate_type": "service",
226         "inventory_type": "service",
227         "inventory_provider": "aai",
228         "host_id": "vnf_123456",
229         "cost": "100",
230         "location_id": "DLLSTX9A",
231         "location_type": "azure",
232         "latitude": "32.897480",
233         "longitude": "-97.040443",
234         "city": "Dallas",
235         "state": "TX",
236         "country": "USA",
237         "region": "US",
238         "complex_name": "dalls_one",
239         "cloud_owner": "att-aic",
240         "cloud_region_version": "1.1",
241         "physical_location_id": "DLLSTX9A",
242 }
243 ```
244
245 **Questions**
246 * Currently, candidates are either service instances or cloud regions. As new services are on-boarded, this can be evolved to represent different types of resources.
247
248 **Examples**
249
250 The following examples illustrate two demands:
251
252 * ``vGMuxInfra``: A vGMuxInfra service, drawing candidates of type *service* from the inventory. Only candidates that match the customer_id and orchestration-status will be included in the search space.
253 * ``vG``: A vG, drawing candidates of type *service* and *cloud* from the inventory. Only candidates that match the customer_id and provisioning-status will be included in the search space.
254
255
256 ```yaml
257 demands:
258   vGMuxInfra:
259   - inventory_provider: aai
260     inventory_type: service
261     attributes:
262       equipment_type: vG_Mux
263       customer_id: some_company
264       orchestration-status: Activated
265       model-id: 174e371e-f514-4913-a93d-ed7e7f8fbdca
266       model-version: 2.0
267   vG:
268   - inventory_provider: aai
269     inventory_type: service
270     attributes:
271       equipment_type: vG
272       customer_id: some_company
273       provisioning-status: provisioned
274   - inventory_provider: aai
275     inventory_type: cloud
276 ```
277
278 **Questions**
279 * Do we need to support cost as a function ?
280
281 ## Constraints
282
283 A **Constraint** is used to *eliminate* inventory candidates from one or more demands that do not meet the requirements specified by the constraint. Since reusability is one of the cornerstones of HAS, Constraints are designed to be service-agnostic, and is parameterized such that it can be reused across a wide range of services. Further, HAS is designed with a plug-in architecture that facilitates easy addition of new constraint types.
284
285 Constraints are denoted by a ``constraints`` key. Each constraint is uniquely named and set to a dictionary containing a constraint type, a list of demands to apply the constraint to, and a dictionary of constraint properties.
286
287 **Considerations while using multiple constraints**
288 * Constraints should be treated as a unordered list, and no assumptions should be made as regards to the order in which the constraints are evaluated for any given demand.
289 * All constraints are effectively AND-ed together. Constructs such as "Constraint X OR Y" are unsupported.
290 * Constraints are reducing in nature, and does not increase the available candidates at any point during the constraint evaluations.
291
292
293 **Schema**
294
295 | Key                 | Value       |
296 |---------------------|-------------|
297 | ``CONSTRAINT_NAME`` | Key is a unique name. |
298 | ``type`` | The type of constraint. See **Constraint Types** for a list of currently supported values. |
299 | ``demands`` | One or more previously declared demands. If only one demand is specified, it may appear without list markers (``[]``). |
300 | ``properties`` (Optional) | Properties particular to the specified constraint type. Use if required by the constraint. |
301
302 ```yaml
303 constraints:
304   CONSTRAINT_NAME_1:
305     type: CONSTRAINT_TYPE
306     demands: DEMAND_NAME | [DEMAND_NAME_1, DEMAND_NAME_2, ...]
307     properties: PROPERTY_DICT
308
309   CONSTRAINT_NAME_2:
310     type: CONSTRAINT_TYPE
311     demands: DEMAND_NAME | [DEMAND_NAME_1, DEMAND_NAME_2, ...]
312     properties: PROPERTY_DICT
313
314   ...
315 ```
316
317 #### Constraint Types
318
319 | Type                | Description |
320 |---------------------|-------------|
321 | ``attribute`` | Constraint that matches the specified list of Attributes. |
322 | ``distance_between_demands`` | Geographic distance constraint between each pair of a list of demands. |
323 | ``distance_to_location`` | Geographic distance constraint between each of a list of demands and a specific location.  |
324 | ``instance_fit`` | Constraint that ensures available capacity in an existing service instance for an incoming demand. |
325 | ``inventory_group`` | Constraint that enforces two or more demands are satisfied using candidates from a pre-established group in the inventory. |
326 | ``region_fit`` | Constraint that ensures available capacity in an existing cloud region for an incoming demand. |
327 | ``zone`` | Constraint that enforces co-location/diversity at the granularities of clouds/regions/availability-zones. |
328 | ``license`` (Deferred) | License availability constraint. |
329 | ``network_between_demands`` (Deferred) | Network constraint between each pair of a list of demands. |
330 | ``network_to_location`` (Deferred) | Network constraint between each of a list of demands and a specific location/address. |
331
332 *Note: Constraint names marked "Deferred" **will not** be supported in the initial release of HAS.*
333
334 #### Threshold Values
335
336 Constraint property values representing a threshold may be an integer or floating point number, optionally prefixed with a comparison operator: ``=``, ``<``, ``>``, ``<=``, or ``>=``. The default is ``=`` and optionally suffixed with a unit.
337
338 Whitespace may appear between the comparison operator and value, and between the value and units. When a range values is specified (e.g., ``10-20 km``), the comparison operator is omitted.
339
340 Each property is documented with a default unit. The following units are supported:
341
342 | Unit       | Values                       | Default  |
343 |------------|------------------------------|----------|
344 | Currency   | ``USD``                      | ``USD``  |
345 | Time       | ``ms``, ``sec``              | ``ms``   |
346 | Distance   | ``km``, ``mi``               | ``km``   |
347 | Throughput | ``Kbps``, ``Mbps``, ``Gbps`` | ``Mbps`` |
348
349 ### Attribute
350
351 Constrain one or more demands by one or more attributes, expressed as properties. Attributes are mapped to the **inventory provider** specified properties, referenced by the demands. For example, properties could be hardware capabilities provided by the platform (flavor, CPU-Pinning, NUMA), features supported by the services, etc.  
352
353 **Schema**
354
355 | Property     | Value                                                       |
356 |--------------|-------------------------------------------------------------|
357 | ``evaluate`` | Opaque dictionary of attribute name and value pairs. Values must be strings or numbers. Encoded and sent to the service provider via a plugin. |
358
359 *Note: Attribute values are not detected/parsed as thresholds by the Homing framework. Such interpretations and evaluations are inventory provider-specific and delegated to the corresponding plugin*
360
361 ```yaml
362 constraints:
363   sriov_nj:
364     type: attribute
365     demands: [my_vnf_demand, my_other_vnf_demand]
366     properties:
367       evaluate:
368         cloud_version: 1.1
369         flavor: SRIOV
370         subdivision: US-TX
371         vcpu_pinning: True
372         numa_topology: numa_spanning
373 ```
374
375 #### Proposal: Evaluation Operators
376
377 To assist in evaluating attributes, the following operators and notation are proposed:
378
379 | Operator     | Name      | Operand                                        |
380 |--------------|-----------|------------------------------------------------|
381 | ``eq``       | ``==``    | Any object (string, number, list, dict)        |
382 | ``ne``       | ``!=``    |                                                |
383 | ``lt``       | ``<``     | A number (strings are converted to float)      |
384 | ``gt``       | ``>``     |                                                |
385 | ``lte``      | ``<=``    |                                                |
386 | ``gte``      | ``>=``    |                                                |
387 | ``any``      | ``Any``   | A list of objects (string, number, list, dict) |
388 | ``all``      | ``All``   |                                                |
389 | ``regex``    | ``RegEx`` | A regular expression pattern                   |
390
391 Example usage:
392
393 ```yaml
394 constraints:
395   sriov_nj:
396     type: attribute
397     demands: [my_vnf_demand, my_other_vnf_demand]
398     properties:
399       evaluate:
400         cloud_version: {gt: 1.0}
401         flavor: {regex: /^SRIOV$/i}
402         subdivision: {any: [US-TX, US-NY, US-CA]}
403 ```
404
405 ### Distance Between Demands
406
407 Constrain each pairwise combination of two or more demands by distance requirements.
408
409 **Schema**
410
411 | Name         | Value                                                       |
412 |--------------|-------------------------------------------------------------|
413 | ``distance`` | Distance between demands, measured by the geographic path.  |
414
415 The constraint is applied between each pairwise combination of demands. For this reason, at least two demands must be specified, implicitly or explicitly.
416
417 ```yaml
418 constraints:
419   distance_vnf1_vnf2:
420     type: distance_between_demands
421     demands: [my_vnf_demand, my_other_vnf_demand]
422     properties:
423       distance: < 250 km
424 ```
425
426 ### Distance To Location
427
428 Constrain one or more demands by distance requirements relative to a specific location.
429
430 **Schema**
431
432 | Property     | Value                                                      |
433 |--------------|------------------------------------------------------------|
434 | ``distance`` | Distance between demands, measured by the geographic path. |
435 | ``location`` | A previously declared location.                            |
436
437 The constraint is applied between each demand and the referenced location, not across all pairwise combinations of Demands.
438
439 ```yaml
440 constraints:
441   distance_vnf1_loc:
442     type: distance_to_location
443     demands: [my_vnf_demand, my_other_vnf_demand, another_vnf_demand]
444     properties:
445       distance: < 250 km
446       location: LOCATION_ID
447 ```
448
449 ### Instance Fit
450
451 Constrain each demand by its service requirements.
452
453 Requirements are sent as a request to a **service controller**. Service controllers are defined by plugins in Homing (e.g., ``sdn-c``).
454
455 A service controller plugin knows how to communicate with a particular endpoint (via HTTP/REST, DMaaP, etc.), obtain necessary information, and make a decision. The endpoint and credentials can be configured through plugin settings.
456
457 **Schema**
458
459 | Property       | Description                       |
460 |----------------|-----------------------------------|
461 | ``controller`` | Name of a service controller.     |
462 | ``request``    | Opaque dictionary of key/value pairs. Values must be strings or numbers. Encoded and sent to the service provider via a plugin. |
463
464 ```yaml
465 constraints:
466   check_for_availability:
467     type: instance_fit
468     demands: [my_vnf_demand, my_other_vnf_demand]
469     properties:
470       controller: sdn-c
471       request: REQUEST_DICT
472 ```
473
474 ### Region Fit
475
476 Constrain each demand's inventory candidates based on inventory provider membership.
477
478 Requirements are sent as a request to a **service controller**. Service controllers are defined by plugins in Homing (e.g., ``sdn-c``).
479
480 A service controller plugin knows how to communicate with a particular endpoint (via HTTP/REST, DMaaP, etc.), obtain necessary information, and make a decision. The endpoint and credentials can be configured through plugin settings.
481
482 **Schema**
483
484 | Property       | Description                       |
485 |----------------|-----------------------------------|
486 | ``controller`` | Name of a service controller.     |
487 | ``request``    | Opaque dictionary of key/value pairs. Values must be strings or numbers. Encoded and sent to the service provider via a plugin. |
488
489 ```yaml
490 constraints:
491   check_for_membership:
492     type: region_fit
493     demands: [my_vnf_demand, my_other_vnf_demand]
494     properties:
495       controller: sdn-c
496       request: REQUEST_DICT
497 ```
498 ### Zone
499
500 Constrain two or more demands such that each is located in the same or different zone category.
501
502 Zone categories are inventory provider-defined, based on the demands being constrained.
503
504 **Schema**
505
506 | Property      | Value                                                       |
507 |---------------|-------------------------------------------------------------|
508 | ``qualifier`` | Zone qualifier. One of ``same`` or ``different``.     |
509 | ``category``  | Zone category. One of ``disaster``, ``region``, ``complex``, ``time``, or ``maintenance``. |
510
511 For example, to place two demands in different disaster zones:
512
513 ```yaml
514 constraints:
515   vnf_diversity:
516     type: zone
517     demands: [my_vnf_demand, my_other_vnf_demand]
518     properties:
519       qualifier: different
520       category: disaster
521 ```
522
523 Or, to place two demands in the same region:
524
525 ```yaml
526 constraints:
527   vnf_affinity:
528     type: zone
529     demands: [my_vnf_demand, my_other_vnf_demand]
530     properties:
531       qualifier: same
532       category: region
533 ```
534
535 **Notes**
536
537 * These categories could be any of the following: ``disaster_zone``, ``region``, ``complex``, ``time_zone``, and ``maintenance_zone``. Really, we are talking affinity/anti-affinity at the level of DCs, but these terms may cause confusion with affinity/anti-affinity in OpenStack.
538
539 ### Inventory Group
540
541 Constrain demands such that inventory items are grouped across two demands.
542
543 This constraint has no properties.
544
545 ```yaml
546 constraints:
547   my_group:
548     type: inventory_group
549     demands: [demand_1, demand_2]
550 ```
551
552 *Note: Only pair-wise groups are supported at this time. If three or more demands are specified, only the first two will be used.*
553
554 ### License
555
556 Constrain demands according to license availability.
557
558 *Support for this constraint is deferred.*
559
560 **Schema**
561
562 | Property | Value                                                    |
563 |----------|----------------------------------------------------------|
564 | ``id``   | Unique license identifier                                |
565 | ``key``  | Opaque license key, particular to the license identifier |
566
567 ```yaml
568 constraints:
569   my_software:
570     type: license
571     demands: [demand_1, demand_2, ...]
572     properties:
573       id: SOFTWARE_ID
574       key: LICENSE_KEY
575 ```
576
577 ### Network Between Demands
578
579 Constrain each pairwise combination of two or more demands by network requirements.
580
581 *Support for this constraint is deferred.*
582
583 **Schema**
584
585 | Property                 | Value                                                           |
586 |--------------------------|-----------------------------------------------------------------|
587 | ``bandwidth`` (Optional) | Desired network bandwidth.                                      |
588 | ``distance`` (Optional)  | Desired distance between demands, measured by the network path. |
589 | ``latency`` (Optional)   | Desired network latency.                                        |
590
591 Any combination of ``bandwidth``, ``distance``, or ``latency`` must be specified. If none of these properties are used, it is treated as a malformed request.
592
593 The constraint is applied between each pairwise combination of demands. For this reason, at least two demands must be specified, implicitly or explicitly.
594
595 ```yaml
596 constraints:
597   network_requirements:
598     type: network_between_demands
599     demands: [my_vnf_demand, my_other_vnf_demand]
600     properties:
601       bandwidth: >= 1000 Mbps
602       distance: < 250 km
603       latency: < 50 ms
604 ```
605
606 ### Network To Location
607
608 Constrain one or more demands by network requirements relative to a specific location.
609
610 *Support for this constraint is deferred.*
611
612 **Schema**
613
614 | Property      | Value                                                           |
615 |---------------|-----------------------------------------------------------------|
616 | ``bandwidth`` | Desired network bandwidth.                                      |
617 | ``distance``  | Desired distance between demands, measured by the network path. |
618 | ``latency``   | Desired network latency.                                        |
619 | ``location``  | A previously declared location.                                 |
620
621 Any combination of ``bandwidth``, ``distance``, or ``latency`` must be specified. If none of these properties are used, it is treated as a malformed request.
622
623 The constraint is applied between each demand and the referenced location, not across all pairwise combinations of Demands.
624
625 ```yaml
626 constraints:
627   my_access_network_constraint:
628     type: network_to_location
629     demands: [my_vnf_demand, my_other_vnf_demand]
630     properties:
631       bandwidth: >= 1000 Mbps
632       distance: < 250 km
633       latency: < 50 ms
634       location: LOCATION_ID
635 ```
636 ### Capabilities
637
638 Constrain each demand by its cluster capability requirements. For example, as described by an OpenStack Heat template and operational environment.
639
640 *Support for this constraint is deferred.*
641
642 **Schema**
643
644 | Property     | Value                                                       |
645 |--------------|-------------------------------------------------------------|
646 | ``specification`` | Indicates the kind of specification being provided in the properties. Must be ``heat``. Future values may include ``tosca``, ``Homing``, etc. |
647 | ``template`` | For specifications of type ``heat``, a single stack in OpenStack Heat Orchestration Template (HOT) format. Stacks may be expressed as a URI reference or a string of well-formed YAML/JSON. Templates are validated by the Heat service configured for use by HAS. Nested stack references are unsupported. |
648 | ``environment`` (Optional) | For specifications of type ``heat``, an optional Heat environment. Environments may be expressed as a URI reference or a string of well-formed YAML/JSON. Environments are validated by the Heat service configured for use by Homing. |
649
650 ```yaml
651 constraints:
652   check_for_fit:
653     type: capability
654     demands: [my_vnf_demand, my_other_vnf_demand]
655     properties:
656       specification: heat
657       template: http://repository/my/stack_template
658       environment: http://repository/my/stack_environment
659 ```
660
661
662 ## Reservations
663
664 A **Reservation** allows reservation of resources associated with candidate that satisfies one or more demands.
665
666 Similar to the *instance_fit* constraint, requirements are sent as a request to a **service controller** that handles the reservation. Service controllers are defined by plugins in Homing (e.g., ``sdn-c``).
667
668 The service controller plugin knows how to make a reservation (and initiate rollback on a failure) with a particular endpoint (via HTTP/REST, DMaaP, etc.) of the service controller. The endpoint and credentials can be configured through plugin settings.
669
670 **Schema**
671
672 | Property       | Description                       |
673 |----------------|-----------------------------------|
674 | ``controller`` | Name of a service controller.     |
675 | ``request``    | Opaque dictionary of key/value pairs. Values must be strings or numbers. Encoded and sent to the service provider via a plugin. |
676
677
678 ```yaml
679 resource_reservation:
680   type: instance_reservation
681   demands: [my_vnf_demand, my_other_vnf_demand]
682   properties:
683     controller: sdn-c
684     request: REQUEST_DICT
685 ```    
686
687 ## Optimizations
688
689 An **Optimization** allows specification of a objective function, which aims to maximize or minimize a certain value that varies based on the choice of candidates for one or more demands that are a part of the objective function. For example, an objective function may be to find the *closest* cloud-region to a customer to home a demand.
690
691 ### Optimization Components
692
693 Optimization definitions can be broken down into three components:
694
695 | Component | Key                  | Value                                                   |
696 |-----------|----------------------|---------------------------------------------------------|
697 | Goal      | ``minimize``         | A single Operand (usually ``sum``) or Function          |
698 | Operator  | ``sum``, ``product`` | Two or more Operands (Numbers, Operators, Functions)    |
699 | Function  | ``distance_between`` | A two-element list consisting of a location and demand. |
700
701
702 ### Example
703
704 Given a customer location ``cl``, two demands ``vG1`` and ``vG2``, and weights ``w1`` and ``w2``, the optimization criteria can be expressed as:
705
706 ``minimize(weight1 * distance_between(cl, vG1) + weight2 * distance_between(cl, vG2))``
707
708 This can be read as: "Minimize the sum of weighted distances from cl to vG1 and from cl to vG2."
709
710 Such optimizations may be expressed in a template as follows:
711
712 ```yaml
713 parameters:
714   w1: 10
715   w2: 20
716
717 optimization:
718   minimize:
719     sum:
720     - product:
721       - {get_param: w1}
722       - {distance_between: [cl, vG1]}
723     - product:
724       - {get_param: w2}
725       - {distance_between: [cl, vG2]}
726 ```
727
728 Or without the weights as:
729
730 ```yaml
731 optimization:
732   minimize:
733     sum:
734     - {distance_between: [cl, vG1]}
735     - {distance_between: [cl, vG2]}
736 ```
737
738 **Template Restriction**
739
740 While the template format supports any number of arrangements of numbers, operators, and functions, HAS's solver presently expects a very specific arrangement.
741
742 Until further notice:
743
744 * Optimizations must conform to a single goal of ``minimize`` followed by a ``sum`` operator.
745 * The sum can consist of two ``distance_between`` function calls, or two ``product`` operators.
746 * If a ``product`` operator is present, it must contain at least a ``distance_between`` function call, plus one optional number to be used for weighting.
747 * Numbers may be referenced via ``get_param``.
748 * The objective function has to be written in the sum-of-product format. In the future, HAS can convert product-of-sum into sum-of-product automatically.
749
750 The first two examples in this section illustrate both of these use cases.
751
752 **Inline Operations**
753
754 If desired, operations can be rewritten inline. For example, the two ``product`` operations from the previous example can also be expressed as:
755
756 ```yaml
757 parameters:
758   w1: 10
759   w2: 20
760
761 optimization:
762   minimize:
763     sum:
764     - {product: [{get_param: w1}, {distance_between: [cl, vG1]}]}
765     - {product: [{get_param: w2}, {distance_between: [cl, vG2]}]}
766 ```
767
768 In turn, even the ``sum`` operation can be rewritten inline, however there is a point of diminishing returns in terms of readability!
769
770 **Notes**
771
772 * In the first version, we do not support more than one dimension in the optimization (e.g., Minimize distance and cost). For supporting multiple dimensions we would need a function the normalize the unit across dimensions.
773
774 ## Intrinsic Functions
775
776 Homing provides a set of intrinsic functions that can be used inside templates to perform specific tasks. The following section describes the role and syntax of the intrinsic functions.
777
778 Functions are written as a dictionary with one key/value pair. The key is the function name. The value is a list of arguments. If only one argument is provided, a string may be used instead.
779
780 ```yaml
781 a_property: {FUNCTION_NAME: [ARGUMENT_LIST]}
782
783 a_property: {FUNCTION_NAME: ARGUMENT_STRING}
784 ```
785
786 *Note: These functions can only be used within "properties" sections.*
787
788 ### get_file
789
790 The ``get_file`` function inserts the content of a file into the template. It is generally used as a file inclusion mechanism for files containing templates from other services (e.g., Heat).
791
792 The syntax of the ``get_file`` function is:
793
794 ```yaml
795 {get_file: <content key>}
796 ```
797
798 The ``content`` key is used to look up the ``files`` dictionary that is provided in the REST API call. The Homing client command (``Homing``) is ``get_file`` aware and populates the ``files`` dictionary with the actual content of fetched paths and URLs. The Homing client command supports relative paths and transforms these to the absolute URLs required by the Homing API.
799
800 **Note**: The ``get_file`` argument must be a static path or URL and not rely on intrinsic functions like ``get_param``. The Homing client does not process intrinsic functions. They are only processed by the Homing engine.
801
802 The example below demonstrates the ``get_file`` function usage with both relative and absolute URLs:
803
804 ```yaml
805 constraints:
806   check_for_fit:
807     type: capacity
808     demands: [my_vnf_demand, my_other_vnf_demand]
809     properties:
810       template: {get_file: stack_template.yaml}
811       environment: {get_file: http://hostname/environment.yaml}
812 ```
813
814 The ``files`` dictionary generated by the Homing client during instantiation of the plan would contain the following keys. Each value would be of that file's contents.
815
816 * ``file:///path/to/stack_template.yaml``
817 * ``http://hostname/environment.yaml``
818
819 **Questions**
820
821 * If Homing will only be accessed over DMaaP, files will need to be embedded using the Homing API request format.
822
823 ### get_param
824
825 The ``get_param`` function references an input parameter of a template. It resolves to the value provided for this input parameter at runtime.
826
827 The syntax of the ``get_param`` function is:
828
829 ```yaml
830 {get_param: <parameter name>}
831
832 {get_param: [<parameter name>, <key/index1> (optional), <key/index2> (optional), ...]}
833 ```
834
835 **parameter name** is the parameter name to be resolved. If the parameters returns a complex data structure such as a list or a dict, then subsequent keys or indices can be specified. These additional parameters are used to navigate the data structure to return the desired value. Indices are zero-based.
836
837 The following example demonstrates how the ``get_param`` function is used:
838
839 ```yaml
840 parameters:
841   software_id: SOFTWARE_ID
842   license_key: LICENSE_KEY
843   service_info:
844     provider: dmaap:///full.topic.name
845     costs: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
846
847 constraints:
848   my_software:
849     type: license
850     demands: [demand_1, demand_2, ...]
851     properties:
852       id: {get_param: software_id}
853       key: {get_param: license_key}
854
855   check_for_availability:
856     type: service
857     demands: [my_vnf_demand, my_other_vnf_demand]
858     properties:
859       provider_url: {get_param: [service_info, provider]}
860       request: REQUEST_DICT
861       cost: {get_param: [service_info, costs, 4]}
862 ```
863
864 In this example, properties would be set as follows:
865
866 | Key              | Value                    |
867 |------------------|--------------------------|
868 | ``id``           | SOFTWARE_ID              |
869 | ``key``          | LICENSE_KEY              |
870 | ``provider_url`` | dmaap:///full.topic.name |
871 | ``cost``         | 50                       |
872
873 ## Contact ##
874
875 Shankar Narayanan <shankarpnsn@gmail.com>