Update the HAS specification guide
[optf/has.git] / docs / homingspecification.rst
1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
3
4 Homing Specification Guide
5 ==========================
6
7 *Updated: 10 October 2017*
8
9 This document describes the Homing Template format, used by the Homing
10 service. It is a work in progress and subject to frequent revision.
11
12 Template Structure
13 ------------------
14
15 Homing templates are defined in YAML and follow the structure outlined
16 below.
17
18 .. code:: yaml
19
20     homing_template_version: 2017-10-10
21     parameters:
22       PARAMETER_DICT
23     locations:
24       LOCATION_DICT
25     demands:
26       DEMAND_DICT
27     constraints:
28       CONSTRAINT_DICT
29     reservations:
30       RESERVATION_DICT
31     optimization:
32       OPTIMIZATION
33
34 -  ``homing_template_version``: This key with value 2017-10-10 (or a
35    later date) indicates that the YAML document is a Homing template of
36    the specified version.
37 -  ``parameters``: This section allows for specifying input parameters
38    that have to be provided when instantiating the homing template.
39    Typically, this section is used for providing runtime parameters
40    (like SLA thresholds), which in turn is used in the existing homing
41    policies. The section is optional and can be omitted when no input is
42    required.
43 -  ``locations``: This section contains the declaration of geographic
44    locations. This section is optional and can be omitted when no input
45    is required.
46 -  ``demands``: This section contains the declaration of demands. This
47    section with at least one demand should be defined in any Homing
48    template, or the template would not really do anything when being
49    instantiated.
50 -  ``constraints``: This section contains the declaration of
51    constraints. The section is optional and can be omitted when no input
52    is required.
53 -  ``reservations``: This section contains the declaration of required
54    reservations. This section is optional and can be omitted when
55    reservations are not required.
56 -  ``optimization``: This section allows the declaration of an
57    optimization. This section is optional and can be omitted when no
58    input is required.
59
60 Homing Template Version
61 -----------------------
62
63 The value of ``homing_template_version`` tells HAS not only the format
64 of the template but also features that will be validated and supported.
65 Only one value is supported: ``2017-10-10`` in the initial release of
66 HAS.
67
68 .. code:: yaml
69
70     homing_template_version: 2017-10-10
71
72 Parameters
73 ----------
74
75 The **parameters** section allows for specifying input parameters that
76 have to be provided when instantiating the template. Such parameters are
77 typically used for providing runtime inputs (like SLA thresholds), which
78 in turn is used in the existing homing policies. This also helps build
79 reusable homing constraints where these parameters can be embedded
80 design time, and it corresponding values can be supplied during runtime.
81
82 Each parameter is specified with the name followed by its value. Values
83 can be strings, lists, or dictionaries.
84
85 Example
86 ~~~~~~~
87
88 In this example, ``provider_name`` is a string and ``service_info`` is a
89 dictionary containing both a string and a list (keyed by ``base_url``
90 and ``nod_config``, respectively).
91
92 .. code:: yaml
93
94     parameters:
95       provider_name: multicloud
96       service_info:
97         base_url: http://serviceprovider.sdngc.com/
98         nod_config:
99         - http://nod/config_a.yaml
100         - http://nod/config_b.yaml
101         - http://nod/config_c.yaml
102         - http://nod/config_d.yaml
103
104 A parameter can be referenced in place of any value. See the **Intrinsic
105 Functions** section for more details.
106
107 Locations
108 ---------
109
110 One or more **locations** may be declared. A location may be referenced
111 by one or more ``constraints``. Locations may be defined in any of the
112 following ways:
113
114 Coordinate
115 ~~~~~~~~~~
116
117 A geographic coordinate expressed as a latitude and longitude.
118
119 +---------------+----------------------------+
120 | Key           | Value                      |
121 +===============+============================+
122 | ``latitude``  | Latitude of the location.  |
123 +---------------+----------------------------+
124 | ``longitude`` | Longitude of the location. |
125 +---------------+----------------------------+
126
127 Host Name
128 ~~~~~~~~~
129
130 An opaque host name that can be translated to a coordinate via an
131 inventory provider (e.g., A&AI).
132
133 +---------------+-----------------------------------+
134 | Key           | Value                             |
135 +===============+===================================+
136 | ``host_name`` | Host name identifying a location. |
137 +---------------+-----------------------------------+
138
139 CLLI
140 ~~~~
141
142 Common Language Location Identification (CLLI)
143 code(https://en.wikipedia.org/wiki/CLLI_code).
144
145 +---------------+-------------------+
146 | Key           | Value             |
147 +===============+===================+
148 | ``clli_code`` | 8 character CLLI. |
149 +---------------+-------------------+
150
151 **Questions**
152
153 -  Do we need functions that can convert one of these to the other?
154    E.g., CLLI Codes to a latitude/longitude
155
156 Placemark
157 ~~~~~~~~~
158
159 An address expressed in geographic region-agnostic terms (referred to as
160 a *placemark*).
161
162 *Support for this schema is deferred.*
163
164 +-----------------------------------+----------------------------------+
165 | Key                               | Value                            |
166 +===================================+==================================+
167 | ``iso_country_code``              | The abbreviated country name     |
168 |                                   | associated with the placemark.   |
169 +-----------------------------------+----------------------------------+
170 | ``postal_code``                   | The postal code associated with  |
171 |                                   | the placemark.                   |
172 +-----------------------------------+----------------------------------+
173 | ``administrative_area``           | The state or province associated |
174 |                                   | with the placemark.              |
175 +-----------------------------------+----------------------------------+
176 | ``sub_administrative_area``       | Additional administrative area   |
177 |                                   | information for the placemark.   |
178 +-----------------------------------+----------------------------------+
179 | ``locality``                      | The city associated with the     |
180 |                                   | placemark.                       |
181 +-----------------------------------+----------------------------------+
182 | ``sub_locality``                  | Additional city-level            |
183 |                                   | information for the placemark.   |
184 +-----------------------------------+----------------------------------+
185 | ``thoroughfare``                  | The street address associated    |
186 |                                   | with the placemark.              |
187 +-----------------------------------+----------------------------------+
188 | ``sub_thoroughfare``              | Additional street-level          |
189 |                                   | information for the placemark.   |
190 +-----------------------------------+----------------------------------+
191
192 **Questions**
193
194 -  What geocoder can we use to convert placemarks to a
195    latitude/longitude?
196
197 Examples
198 ~~~~~~~~
199
200 The following examples illustrate a location expressed in coordinate,
201 host_name, CLLI, and placemark, respectively.
202
203 .. code:: yaml
204
205     locations:
206       location_using_coordinates:
207         latitude: 32.897480
208         longitude: -97.040443
209
210       host_location_using_host_name:
211         host_name: USESTCDLLSTX55ANZ123
212
213       location_using_clli:
214         clli_code: DLLSTX55
215
216       location_using_placemark:
217         sub_thoroughfare: 1
218         thoroughfare: ATT Way
219         locality: Bedminster
220         administrative_area: NJ
221         postal_code: 07921-2694
222
223 Demands
224 -------
225
226 A **demand** can be satisfied by using candidates drawn from
227 inventories. Each demand is uniquely named. Inventory is considered to
228 be opaque and can represent anything from which candidates can be drawn.
229
230 A demand’s resource requirements are determined by asking an **inventory
231 provider** for one or more sets of **inventory candidates** against
232 which the demand will be made. An explicit set of candidates may also be
233 declared, for example, if the only candidates for a demand are
234 predetermined.
235
236 Demand criteria is dependent upon the inventory provider in use.
237
238 **Provider-agnostic Schema**
239
240 +---------------------------------+------------------------------------+
241 | Key                             | Value                              |
242 +=================================+====================================+
243 | ``inventory_provider``          | A HAS-supported inventory          |
244 |                                 | provider.                          |
245 +---------------------------------+------------------------------------+
246 | ``inventory_type``              | The reserved word ``cloud`` (for   |
247 |                                 | cloud regions) or the reserved     |
248 |                                 | word ``service`` (for existing     |
249 |                                 | service instances). Exactly one    |
250 |                                 | inventory type may be specified.   |
251 +---------------------------------+------------------------------------+
252 | ``attributes`` (Optional)       | A list of key-value pairs, that is |
253 |                                 | used to select inventory           |
254 |                                 | candidates that match *all* the    |
255 |                                 | specified attributes. The key      |
256 |                                 | should be a uniquely identifiable  |
257 |                                 | attribute at the inventory         |
258 |                                 | provider.                          |
259 +---------------------------------+------------------------------------+
260 | ``service_type`` (Optional)     | If ``inventory_type`` is           |
261 |                                 | ``service``, a list of one or more |
262 |                                 | provider-defined service types. If |
263 |                                 | only one service type is           |
264 |                                 | specified, it may appear without   |
265 |                                 | list markers (``[]``).             |
266 +---------------------------------+------------------------------------+
267 | ``service_id`` (Optional)       | If ``inventory_type`` is           |
268 |                                 | ``service``, a list of one or more |
269 |                                 | provider-defined service ids. If   |
270 |                                 | only one service id is specified,  |
271 |                                 | it may appear without list markers |
272 |                                 | (``[]``).                          |
273 +---------------------------------+------------------------------------+
274 | ``default_cost`` (Optional)     | The default cost of an inventory   |
275 |                                 | candidate, expressed as currency.  |
276 |                                 | This must be specified if the      |
277 |                                 | inventory provider may not always  |
278 |                                 | return a cost.                     |
279 +---------------------------------+------------------------------------+
280 | ``required_candidates``         | A list of one or more candidates   |
281 | (Optional)                      | from which a solution will be      |
282 |                                 | explored. Must be a valid          |
283 |                                 | candidate as described in the      |
284 |                                 | **candidate schema**.              |
285 +---------------------------------+------------------------------------+
286 | ``excluded_candidates``         | A list of one or more candidates   |
287 | (Optional)                      | that should be excluded from the   |
288 |                                 | search space. Must be a valid      |
289 |                                 | candidate as described in the      |
290 |                                 | **candidate schema**.              |
291 +---------------------------------+------------------------------------+
292 | ``existing_placement``          | The current placement for the      |
293 | (Optional)                      | demand. Must be a valid candidate  |
294 |                                 | as described in the **candidate    |
295 |                                 | schema**.                          |
296 +---------------------------------+------------------------------------+
297
298 .. _examples-1:
299
300 Examples
301 ~~~~~~~~
302
303 The following example helps understand a demand specification using
304 Active & Available Inventory (A&AI), the inventory provider-of-record
305 for ONAP.
306
307 **Inventory Provider Criteria**
308
309 +---------------------------------+------------------------------------+
310 | Key                             | Value                              |
311 +=================================+====================================+
312 | ``inventory_provider``          | Examples: ``aai``, ``multicloud``. |
313 +---------------------------------+------------------------------------+
314 | ``inventory_type``              | The reserved word ``cloud`` (for   |
315 |                                 | new inventory) or the reserved     |
316 |                                 | word ``service`` (for existing     |
317 |                                 | inventory). Exactly one inventory  |
318 |                                 | type may be specified.             |
319 +---------------------------------+------------------------------------+
320 | ``attributes`` (Optional)       | A list of key-value pairs to match |
321 |                                 | against inventory when drawing     |
322 |                                 | candidates.                        |
323 +---------------------------------+------------------------------------+
324 | ``service_type`` (Optional)     | Examples may include ``vG``,       |
325 |                                 | ``vG_MuxInfra``, etc.              |
326 +---------------------------------+------------------------------------+
327 | ``service_id`` (Optional)       | Must be a valid service id.        |
328 |                                 | Examples may include ``vCPE``,     |
329 |                                 | ``VoLTE``, etc.                    |
330 +---------------------------------+------------------------------------+
331 | ``default_cost`` (Optional)     | The default cost of an inventory   |
332 |                                 | candidate, expressed as a unitless |
333 |                                 | number.                            |
334 +---------------------------------+------------------------------------+
335 | ``required_candidates``         | A list of one or more valid        |
336 | (Optional)                      | candidates. See **Candidate        |
337 |                                 | Schema** for details.              |
338 +---------------------------------+------------------------------------+
339 | ``excluded_candidates``         | A list of one or more valid        |
340 | (Optional)                      | candidates. See **Candidate        |
341 |                                 | Schema** for details.              |
342 +---------------------------------+------------------------------------+
343 | ``existing_placement``          | A single valid candidate,          |
344 | (Optional)                      | representing the current placement |
345 |                                 | for the demand. See **candidate    |
346 |                                 | schema** for details.              |
347 +---------------------------------+------------------------------------+
348
349 **Candidate Schema**
350
351 The following is the schema for a valid ``candidate``: \*
352 ``candidate_id`` uniquely identifies a candidate. Currently, it is
353 either a Service Instance ID or Cloud Region ID. \* ``candidate_type``
354 identifies the type of the candidate. Currently, it is either ``cloud``
355 or ``service``. \* ``inventory_type`` is defined as described in
356 **Inventory Provider Criteria** (above). \* ``inventory_provider``
357 identifies the inventory from which the candidate was drawn. \*
358 ``host_id`` is an ID of a specific host (used only when referring to
359 service/existing inventory). \* ``cost`` is expressed as a unitless
360 number. \* ``location_id`` is always a location ID of the specified
361 location type (e.g., for a type of ``cloud`` this will be an Cloud
362 Region ID). \* ``location_type`` is an inventory provider supported
363 location type. \* ``latitude`` is a valid latitude corresponding to the
364 *location_id*. \* ``longitude`` is a valid longitude corresponding to
365 the *location_id*. \* ``city`` (Optional) city corresponding to the
366 *location_id*. \* ``state`` (Optional) state corresponding to the
367 *location_id*. \* ``country`` (Optional) country corresponding to the
368 *location_id*. \* ``region`` (Optional) geographic region corresponding
369 to the *location_id*. \* ``complex_name`` (Optional) Name of the complex
370 corresponding to the *location_id*. \* ``cloud_owner`` (Optional) refers
371 to the *cloud owner* (e.g., ``azure``, ``aws``, ``att``, etc.). \*
372 ``cloud_region_version`` (Optional) is an inventory provider supported
373 version of the cloud region. \* ``physical_location_id`` (Optional) is
374 an inventory provider supported CLLI code corresponding to the cloud
375 region.
376
377 **Examples**
378
379 **``Service Candidate``**
380 .. code:: json
381
382     {
383         "candidate_id": "1ac71fb8-ad43-4e16-9459-c3f372b8236d",
384         "candidate_type": "service",
385         "inventory_type": "service",
386         "inventory_provider": "aai",
387         "host_id": "vnf_123456",
388         "cost": "100",
389         "location_id": "DLLSTX9A",
390         "location_type": "azure",
391         "latitude": "32.897480",
392         "longitude": "-97.040443",
393         "city": "Dallas",
394         "state": "TX",
395         "country": "USA",
396         "region": "US",
397         "complex_name": "dalls_one",
398         "cloud_owner": "att-aic",
399         "cloud_region_version": "1.1",
400         "physical_location_id": "DLLSTX9A"
401     }
402
403 **``Cloud Candidate``**
404 .. code:: json
405
406     {
407         "candidate_id": "NYCNY55",
408         "candidate_type": "cloud",
409         "inventory_type": "cloud",
410         "inventory_provider": "aai",
411         "cost": "100",
412         "location_id": "NYCNY55",
413         "location_type": "azure",
414         "latitude": "40.7128",
415         "longitude": "-74.0060",
416         "city": "New York",
417         "state": "NY",
418         "country": "USA",
419         "region": "US",
420         "complex_name": "ny_one",
421         "cloud_owner": "att-aic",
422         "cloud_region_version": "1.1",
423         "physical_location_id": "NYCNY55",
424         "flavors": {
425            "flavor":[
426               {
427                  "flavor-id":"9cf8220b-4d96-4c30-a426-2e9382f3fff2",
428                  "flavor-name":"flavor-numa-cpu-topology-instruction-set",
429                  "flavor-vcpus":64,
430                  "flavor-ram":65536,
431                  "flavor-disk":1048576,
432                  "flavor-ephemeral":128,
433                  "flavor-swap":"0",
434                  "flavor-is-public":false,
435                  "flavor-selflink":"pXtX",
436                  "flavor-disabled":false,
437                  "hpa-capabilities":{
438                     "hpa-capability":[
439                        {
440                           "hpa-capability-id":"01a4bfe1-1993-4fda-bd1c-ef333b4f76a9",
441                           "hpa-feature":"cpuInstructionSetExtensions",
442                           "hpa-version":"v1",
443                           "architecture":"Intel64",
444                           "resource-version":"1521306560982",
445                           "hpa-feature-attributes":[
446                              {
447                                 "hpa-attribute-key":"instructionSetExtensions",
448                                 "hpa-attribute-value":"{\"value\":{['AAA', 'BBB', 'CCC', 'DDD']}}",
449                                 "resource-version":"1521306560989"
450                              }
451                           ]
452                        },
453                        {
454                           "hpa-capability-id":"167ad6a2-7d9c-4bf2-9a1b-30e5311b8c66",
455                           "hpa-feature":"numa",
456                           "hpa-version":"v1",
457                           "architecture":"generic",
458                           "resource-version":"1521306561020",
459                           "hpa-feature-attributes":[
460                              {
461                                 "hpa-attribute-key":"numaCpu-1",
462                                 "hpa-attribute-value":"{\"value\":4}",
463                                 "resource-version":"1521306561060"
464                              },
465                              {
466                                 "hpa-attribute-key":"numaNodes",
467                                 "hpa-attribute-value":"{\"value\":2}",
468                                 "resource-version":"1521306561088"
469                              },
470                              {
471                                 "hpa-attribute-key":"numaCpu-0",
472                                 "hpa-attribute-value":"{\"value\":2}",
473                                 "resource-version":"1521306561028"
474                              },
475                              {
476                                 "hpa-attribute-key":"numaMem-0",
477                                 "hpa-attribute-value":"{\"value\":2, \"unit\":\"GB\" }",
478                                 "resource-version":"1521306561044"
479                              },
480                              {
481                                 "hpa-attribute-key":"numaMem-1",
482                                 "hpa-attribute-value":"{\"value\":4, \"unit\":\"GB\" }",
483                                 "resource-version":"1521306561074"
484                              }
485                           ]
486                        },
487                        {
488                           "hpa-capability-id":"13ec6d4d-7fee-48d8-9e4a-c598feb101ed",
489                           "hpa-feature":"basicCapabilities",
490                           "hpa-version":"v1",
491                           "architecture":"generic",
492                           "resource-version":"1521306560909",
493                           "hpa-feature-attributes":[
494                              {
495                                 "hpa-attribute-key":"numVirtualCpu",
496                                 "hpa-attribute-value":"{\"value\":64}",
497                                 "resource-version":"1521306560932"
498                              },
499                              {
500                                 "hpa-attribute-key":"virtualMemSize",
501                                 "hpa-attribute-value":"{\"value\":65536, \"unit\":\"MB\" }",
502                                 "resource-version":"1521306560954"
503                              }
504                           ]
505                        },
506                        {
507                           "hpa-capability-id":"8fa22e64-41b4-471f-96ad-6c4708635e4c",
508                           "hpa-feature":"cpuTopology",
509                           "hpa-version":"v1",
510                           "architecture":"generic",
511                           "resource-version":"1521306561109",
512                           "hpa-feature-attributes":[
513                              {
514                                 "hpa-attribute-key":"numCpuCores",
515                                 "hpa-attribute-value":"{\"value\":8}",
516                                 "resource-version":"1521306561114"
517                              },
518                              {
519                                 "hpa-attribute-key":"numCpuThreads",
520                                 "hpa-attribute-value":"{\"value\":8}",
521                                 "resource-version":"1521306561138"
522                              },
523                              {
524                                 "hpa-attribute-key":"numCpuSockets",
525                                 "hpa-attribute-value":"{\"value\":6}",
526                                 "resource-version":"1521306561126"
527                              }
528                           ]
529                        }
530                     ]
531                  },
532                  "resource-version":"1521306560203"
533               },
534               {
535                  "flavor-id":"f5aa2b2e-3206-41b6-80d5-cf041b098c43",
536                  "flavor-name":"flavor-cpu-pinning-ovsdpdk-instruction-set",
537                  "flavor-vcpus":32,
538                  "flavor-ram":131072,
539                  "flavor-disk":2097152,
540                  "flavor-ephemeral":128,
541                  "flavor-swap":"0",
542                  "flavor-is-public":false,
543                  "flavor-selflink":"pXtX",
544                  "flavor-disabled":false,
545                  "hpa-capabilities":{
546                     "hpa-capability":[
547                        {
548                           "hpa-capability-id":"4d04f4d8-e257-4442-8417-19a525e56096",
549                           "hpa-feature":"cpuInstructionSetExtensions",
550                           "hpa-version":"v1",
551                           "architecture":"generic",
552                           "resource-version":"1521306561223",
553                           "hpa-feature-attributes":[
554                              {
555                                 "hpa-attribute-key":"instructionSetExtensions",
556                                 "hpa-attribute-value":"{\"value\":{['A11', 'B22']}}",
557                                 "resource-version":"1521306561228"
558                              }
559                           ]
560                        },
561                        {
562                           "hpa-capability-id":"8d36a8fe-bfee-446a-bbcb-881ee66c8f78",
563                           "hpa-feature":"ovsDpdk",
564                           "hpa-version":"v1",
565                           "architecture":"generic",
566                           "resource-version":"1521306561170",
567                           "hpa-feature-attributes":[
568                              {
569                                 "hpa-attribute-key":"dataProcessingAccelerationLibrary",
570                                 "hpa-attribute-value":"{\"value\":\"v18.02\"}",
571                                 "resource-version":"1521306561175"
572                              }
573                           ]
574                        },
575                        {
576                           "hpa-capability-id":"c140c945-1532-4908-86c9-d7f71416f1dd",
577                           "hpa-feature":"cpuPinning",
578                           "hpa-version":"v1",
579                           "architecture":"generic",
580                           "resource-version":"1521306561191",
581                           "hpa-feature-attributes":[
582                              {
583                                 "hpa-attribute-key":"logicalCpuPinningPolicy",
584                                 "hpa-attribute-value":"{\"value\":\"dedicated\"}",
585                                 "resource-version":"1521306561196"
586                              },
587                              {
588                                 "hpa-attribute-key":"logicalCpuThreadPinningPolicy",
589                                 "hpa-attribute-value":"{value:\"prefer\"}",
590                                 "resource-version":"1521306561206"
591                              }
592                           ]
593                        },
594                        {
595                           "hpa-capability-id":"4565615b-1077-4bb5-a340-c5be48db2aaa",
596                           "hpa-feature":"basicCapabilities",
597                           "hpa-version":"v1",
598                           "architecture":"generic",
599                           "resource-version":"1521306561244",
600                           "hpa-feature-attributes":[
601                              {
602                                 "hpa-attribute-key":"numVirtualCpu",
603                                 "hpa-attribute-value":"{\"value\":32}",
604                                 "resource-version":"1521306561259"
605                              },
606                              {
607                                 "hpa-attribute-key":"virtualMemSize",
608                                 "hpa-attribute-value":"{\"value\":131072, \"unit\":\"MB\" }",
609                                 "resource-version":"1521306561248"
610                              }
611                           ]
612                        }
613                     ]
614                  },
615                  "resource-version":"1521306561164"
616               }
617            ]
618         }
619     }
620
621 **Questions** \* Currently, candidates are either service instances or
622 cloud regions. As new services are on-boarded, this can be evolved to
623 represent different types of resources.
624
625 **Examples**
626
627 The following examples illustrate two demands:
628
629 -  ``vGMuxInfra``: A vGMuxInfra service, drawing candidates of type
630    *service* from the inventory. Only candidates that match the
631    customer_id and orchestration-status will be included in the search
632    space.
633 -  ``vG``: A vG, drawing candidates of type *service* and *cloud* from
634    the inventory. Only candidates that match the customer_id and
635    provisioning-status will be included in the search space.
636
637 .. code:: yaml
638
639     demands:
640       vGMuxInfra:
641       - inventory_provider: aai
642         inventory_type: service
643         attributes:
644           equipment_type: vG_Mux
645           customer_id: some_company
646           orchestration-status: Activated
647           model-id: 174e371e-f514-4913-a93d-ed7e7f8fbdca
648           model-version: 2.0
649       vG:
650       - inventory_provider: aai
651         inventory_type: service
652         attributes:
653           equipment_type: vG
654           customer_id: some_company
655           provisioning-status: provisioned
656       - inventory_provider: aai
657         inventory_type: cloud
658
659 **Questions** \* Do we need to support cost as a function ?
660
661 Constraints
662 -----------
663
664 A **Constraint** is used to *eliminate* inventory candidates from one or
665 more demands that do not meet the requirements specified by the
666 constraint. Since reusability is one of the cornerstones of HAS,
667 Constraints are designed to be service-agnostic, and is parameterized
668 such that it can be reused across a wide range of services. Further, HAS
669 is designed with a plug-in architecture that facilitates easy addition
670 of new constraint types.
671
672 Constraints are denoted by a ``constraints`` key. Each constraint is
673 uniquely named and set to a dictionary containing a constraint type, a
674 list of demands to apply the constraint to, and a dictionary of
675 constraint properties.
676
677 **Considerations while using multiple constraints** \* Constraints
678 should be treated as a unordered list, and no assumptions should be made
679 as regards to the order in which the constraints are evaluated for any
680 given demand. \* All constraints are effectively AND-ed together.
681 Constructs such as “Constraint X OR Y” are unsupported. \* Constraints
682 are reducing in nature, and does not increase the available candidates
683 at any point during the constraint evaluations.
684
685 **Schema**
686
687 +-------------------------------------------+--------------------------+
688 | Key                                       | Value                    |
689 +===========================================+==========================+
690 | ``CONSTRAINT_NAME``                       | Key is a unique name.    |
691 +-------------------------------------------+--------------------------+
692 | ``type``                                  | The type of constraint.  |
693 |                                           | See **Constraint Types** |
694 |                                           | for a list of currently  |
695 |                                           | supported values.        |
696 +-------------------------------------------+--------------------------+
697 | ``demands``                               | One or more previously   |
698 |                                           | declared demands. If     |
699 |                                           | only one demand is       |
700 |                                           | specified, it may appear |
701 |                                           | without list markers     |
702 |                                           | (``[]``).                |
703 +-------------------------------------------+--------------------------+
704 | ``properties`` (Optional)                 | Properties particular to |
705 |                                           | the specified constraint |
706 |                                           | type. Use if required by |
707 |                                           | the constraint.          |
708 +-------------------------------------------+--------------------------+
709
710 .. code:: yaml
711
712     constraints:
713       CONSTRAINT_NAME_1:
714         type: CONSTRAINT_TYPE
715         demands: DEMAND_NAME | [DEMAND_NAME_1, DEMAND_NAME_2, ...]
716         properties: PROPERTY_DICT
717
718       CONSTRAINT_NAME_2:
719         type: CONSTRAINT_TYPE
720         demands: DEMAND_NAME | [DEMAND_NAME_1, DEMAND_NAME_2, ...]
721         properties: PROPERTY_DICT
722
723       ...
724
725 Constraint Types
726 ~~~~~~~~~~~~~~~~
727
728 +-------------------------------------------+--------------------------+
729 | Type                                      | Description              |
730 +===========================================+==========================+
731 | ``attribute``                             | Constraint that matches  |
732 |                                           | the specified list of    |
733 |                                           | Attributes.              |
734 +-------------------------------------------+--------------------------+
735 | ``distance_between_demands``              | Geographic distance      |
736 |                                           | constraint between each  |
737 |                                           | pair of a list of        |
738 |                                           | demands.                 |
739 +-------------------------------------------+--------------------------+
740 | ``distance_to_location``                  | Geographic distance      |
741 |                                           | constraint between each  |
742 |                                           | of a list of demands and |
743 |                                           | a specific location.     |
744 +-------------------------------------------+--------------------------+
745 | ``instance_fit``                          | Constraint that ensures  |
746 |                                           | available capacity in an |
747 |                                           | existing service         |
748 |                                           | instance for an incoming |
749 |                                           | demand.                  |
750 +-------------------------------------------+--------------------------+
751 | ``inventory_group``                       | Constraint that enforces |
752 |                                           | two or more demands are  |
753 |                                           | satisfied using          |
754 |                                           | candidates from a        |
755 |                                           | pre-established group in |
756 |                                           | the inventory.           |
757 +-------------------------------------------+--------------------------+
758 | ``region_fit``                            | Constraint that ensures  |
759 |                                           | available capacity in an |
760 |                                           | existing cloud region    |
761 |                                           | for an incoming demand.  |
762 +-------------------------------------------+--------------------------+
763 | ``zone``                                  | Constraint that enforces |
764 |                                           | co-location/diversity at |
765 |                                           | the granularities of     |
766 |                                           | clouds/regions/availabil |
767 |                                           | ity-zones.               |
768 +-------------------------------------------+--------------------------+
769 | ``hpa``                                   | Constraint that          |
770 |                                           | recommends cloud region  |
771 |                                           | with an optimal flavor   |
772 |                                           | based on required HPA    |
773 |                                           | capabilities for an      |
774 |                                           | incoming demand.         |
775 +-------------------------------------------+--------------------------+
776 | ``vim_fit``                               | Constraint that checks if|
777 |                                           | the incoming demand fits |
778 |                                           | the VIM instance.        |         |
779 +-------------------------------------------+--------------------------+
780 | ``license`` (Deferred)                    | License availability     |
781 |                                           | constraint.              |
782 +-------------------------------------------+--------------------------+
783 | ``network_between_demands`` (Deferred)    | Network constraint       |
784 |                                           | between each pair of a   |
785 |                                           | list of demands.         |
786 +-------------------------------------------+--------------------------+
787 | ``network_to_location`` (Deferred)        | Network constraint       |
788 |                                           | between each of a list   |
789 |                                           | of demands and a         |
790 |                                           | specific                 |
791 |                                           | location/address.        |
792 +-------------------------------------------+--------------------------+
793
794 *Note: Constraint names marked “Deferred” **will not** be supported in
795 the initial release of HAS.*
796
797 Threshold Values
798 ~~~~~~~~~~~~~~~~
799
800 Constraint property values representing a threshold may be an integer or
801 floating point number, optionally prefixed with a comparison operator:
802 ``=``, ``<``, ``>``, ``<=``, or ``>=``. The default is ``=`` and
803 optionally suffixed with a unit.
804
805 Whitespace may appear between the comparison operator and value, and
806 between the value and units. When a range values is specified (e.g.,
807 ``10-20 km``), the comparison operator is omitted.
808
809 Each property is documented with a default unit. The following units are
810 supported:
811
812 +------------+------------------------------+----------+
813 | Unit       | Values                       | Default  |
814 +============+==============================+==========+
815 | Currency   | ``USD``                      | ``USD``  |
816 +------------+------------------------------+----------+
817 | Time       | ``ms``, ``sec``              | ``ms``   |
818 +------------+------------------------------+----------+
819 | Distance   | ``km``, ``mi``               | ``km``   |
820 +------------+------------------------------+----------+
821 | Throughput | ``Kbps``, ``Mbps``, ``Gbps`` | ``Mbps`` |
822 +------------+------------------------------+----------+
823
824 Attribute
825 ~~~~~~~~~
826
827 Constrain one or more demands by one or more attributes, expressed as
828 properties. Attributes are mapped to the **inventory provider**
829 specified properties, referenced by the demands. For example, properties
830 could be hardware capabilities provided by the platform (flavor,
831 CPU-Pinning, NUMA), features supported by the services, etc.
832
833 **Schema**
834
835 +------------+---------------------------------------------------------+
836 | Property   | Value                                                   |
837 +============+=========================================================+
838 | ``evaluate | Opaque dictionary of attribute name and value pairs.    |
839 | ``         | Values must be strings or numbers. Encoded and sent to  |
840 |            | the service provider via a plugin.                      |
841 +------------+---------------------------------------------------------+
842
843 *Note: Attribute values are not detected/parsed as thresholds by the
844 Homing framework. Such interpretations and evaluations are inventory
845 provider-specific and delegated to the corresponding plugin*
846
847 .. code:: yaml
848
849     constraints:
850       sriov_nj:
851         type: attribute
852         demands: [my_vnf_demand, my_other_vnf_demand]
853         properties:
854           evaluate:
855             cloud_version: 1.1
856             flavor: SRIOV
857             subdivision: US-TX
858             vcpu_pinning: True
859             numa_topology: numa_spanning
860
861 Proposal: Evaluation Operators
862 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
863
864 To assist in evaluating attributes, the following operators and notation
865 are proposed:
866
867 +-----------+-----------+------------------------------------------------+
868 | Operator  | Name      | Operand                                        |
869 +===========+===========+================================================+
870 | ``eq``    | ``==``    | Any object (string, number, list, dict)        |
871 +-----------+-----------+------------------------------------------------+
872 | ``ne``    | ``!=``    |                                                |
873 +-----------+-----------+------------------------------------------------+
874 | ``lt``    | ``<``     | A number (strings are converted to float)      |
875 +-----------+-----------+------------------------------------------------+
876 | ``gt``    | ``>``     |                                                |
877 +-----------+-----------+------------------------------------------------+
878 | ``lte``   | ``<=``    |                                                |
879 +-----------+-----------+------------------------------------------------+
880 | ``gte``   | ``>=``    |                                                |
881 +-----------+-----------+------------------------------------------------+
882 | ``any``   | ``Any``   | A list of objects (string, number, list, dict) |
883 +-----------+-----------+------------------------------------------------+
884 | ``all``   | ``All``   |                                                |
885 +-----------+-----------+------------------------------------------------+
886 | ``regex`` | ``RegEx`` | A regular expression pattern                   |
887 +-----------+-----------+------------------------------------------------+
888
889 Example usage:
890
891 .. code:: yaml
892
893     constraints:
894       sriov_nj:
895         type: attribute
896         demands: [my_vnf_demand, my_other_vnf_demand]
897         properties:
898           evaluate:
899             cloud_version: {gt: 1.0}
900             flavor: {regex: /^SRIOV$/i}
901             subdivision: {any: [US-TX, US-NY, US-CA]}
902
903 Distance Between Demands
904 ~~~~~~~~~~~~~~~~~~~~~~~~
905
906 Constrain each pairwise combination of two or more demands by distance
907 requirements.
908
909 **Schema**
910
911 +--------------+------------------------------------------------------------+
912 | Name         | Value                                                      |
913 +==============+============================================================+
914 | ``distance`` | Distance between demands, measured by the geographic path. |
915 +--------------+------------------------------------------------------------+
916
917 The constraint is applied between each pairwise combination of demands.
918 For this reason, at least two demands must be specified, implicitly or
919 explicitly.
920
921 .. code:: yaml
922
923     constraints:
924       distance_vnf1_vnf2:
925         type: distance_between_demands
926         demands: [my_vnf_demand, my_other_vnf_demand]
927         properties:
928           distance: < 250 km
929
930 Distance To Location
931 ~~~~~~~~~~~~~~~~~~~~
932
933 Constrain one or more demands by distance requirements relative to a
934 specific location.
935
936 **Schema**
937
938 +--------------+------------------------------------------------------------+
939 | Property     | Value                                                      |
940 +==============+============================================================+
941 | ``distance`` | Distance between demands, measured by the geographic path. |
942 +--------------+------------------------------------------------------------+
943 | ``location`` | A previously declared location.                            |
944 +--------------+------------------------------------------------------------+
945
946 The constraint is applied between each demand and the referenced
947 location, not across all pairwise combinations of Demands.
948
949 .. code:: yaml
950
951     constraints:
952       distance_vnf1_loc:
953         type: distance_to_location
954         demands: [my_vnf_demand, my_other_vnf_demand, another_vnf_demand]
955         properties:
956           distance: < 250 km
957           location: LOCATION_ID
958
959 Instance Fit
960 ~~~~~~~~~~~~
961
962 Constrain each demand by its service requirements.
963
964 Requirements are sent as a request to a **service controller**. Service
965 controllers are defined by plugins in Homing (e.g., ``sdn-c``).
966
967 A service controller plugin knows how to communicate with a particular
968 endpoint (via HTTP/REST, DMaaP, etc.), obtain necessary information, and
969 make a decision. The endpoint and credentials can be configured through
970 plugin settings.
971
972 **Schema**
973
974 +---------------------+------------------------------------------------+
975 | Property            | Description                                    |
976 +=====================+================================================+
977 | ``controller``      | Name of a service controller.                  |
978 +---------------------+------------------------------------------------+
979 | ``request``         | Opaque dictionary of key/value pairs. Values   |
980 |                     | must be strings or numbers. Encoded and sent   |
981 |                     | to the service provider via a plugin.          |
982 +---------------------+------------------------------------------------+
983
984 .. code:: yaml
985
986     constraints:
987       check_for_availability:
988         type: instance_fit
989         demands: [my_vnf_demand, my_other_vnf_demand]
990         properties:
991           controller: sdn-c
992           request: REQUEST_DICT
993
994 Region Fit
995 ~~~~~~~~~~
996
997 Constrain each demand’s inventory candidates based on inventory provider
998 membership.
999
1000 Requirements are sent as a request to a **service controller**. Service
1001 controllers are defined by plugins in Homing (e.g., ``sdn-c``).
1002
1003 A service controller plugin knows how to communicate with a particular
1004 endpoint (via HTTP/REST, DMaaP, etc.), obtain necessary information, and
1005 make a decision. The endpoint and credentials can be configured through
1006 plugin settings.
1007
1008 **Schema**
1009
1010 +---------------------+------------------------------------------------+
1011 | Property            | Description                                    |
1012 +=====================+================================================+
1013 | ``controller``      | Name of a service controller.                  |
1014 +---------------------+------------------------------------------------+
1015 | ``request``         | Opaque dictionary of key/value pairs. Values   |
1016 |                     | must be strings or numbers. Encoded and sent   |
1017 |                     | to the service provider via a plugin.          |
1018 +---------------------+------------------------------------------------+
1019
1020 .. code:: yaml
1021
1022     constraints:
1023       check_for_membership:
1024         type: region_fit
1025         demands: [my_vnf_demand, my_other_vnf_demand]
1026         properties:
1027           controller: sdn-c
1028           request: REQUEST_DICT
1029
1030 Zone
1031 ~~~~
1032
1033 Constrain two or more demands such that each is located in the same or
1034 different zone category.
1035
1036 Zone categories are inventory provider-defined, based on the demands
1037 being constrained.
1038
1039 **Schema**
1040
1041 +-------------+--------------------------------------------------------+
1042 | Property    | Value                                                  |
1043 +=============+========================================================+
1044 | ``qualifier | Zone qualifier. One of ``same`` or ``different``.      |
1045 | ``          |                                                        |
1046 +-------------+--------------------------------------------------------+
1047 | ``category` | Zone category. One of ``disaster``, ``region``,        |
1048 | `           | ``complex``, ``time``, or ``maintenance``.             |
1049 +-------------+--------------------------------------------------------+
1050
1051 For example, to place two demands in different disaster zones:
1052
1053 .. code:: yaml
1054
1055     constraints:
1056       vnf_diversity:
1057         type: zone
1058         demands: [my_vnf_demand, my_other_vnf_demand]
1059         properties:
1060           qualifier: different
1061           category: disaster
1062
1063 Or, to place two demands in the same region:
1064
1065 .. code:: yaml
1066
1067     constraints:
1068       vnf_affinity:
1069         type: zone
1070         demands: [my_vnf_demand, my_other_vnf_demand]
1071         properties:
1072           qualifier: same
1073           category: region
1074
1075 **Notes**
1076
1077 -  These categories could be any of the following: ``disaster_zone``,
1078    ``region``, ``complex``, ``time_zone``, and ``maintenance_zone``.
1079    Really, we are talking affinity/anti-affinity at the level of DCs,
1080    but these terms may cause confusion with affinity/anti-affinity in
1081    OpenStack.
1082
1083 HPA
1084 ~~~~
1085
1086 Constrain each demand's inventory candidates based on cloud regions' Hardware
1087 platform capabilities (HPA)
1088
1089 Requirements mapped to the inventory provider specified properties, referenced
1090 by the demands. For eg, properties could be hardware capabilities provided by
1091 the platform through flavors or cloud-region eg:(CPU-Pinning, NUMA), features
1092 supported by the services, etc.
1093
1094
1095 **Schema**
1096
1097 +-------------+--------------------------------------------------------+
1098 | Property    | Value                                                  |
1099 +=============+========================================================+
1100 | ``evaluate  | List of flavorLabel, flavorProperties of each VM of the|
1101 | ``          | VNF demand.                                            |
1102 +-------------+--------------------------------------------------------+
1103
1104 .. code:: yaml
1105
1106     constraints:
1107       hpa_constraint:
1108         type: hpa
1109         demands: [my_vnf_demand, my_other_vnf_demand]
1110         properties:
1111           evaluate:
1112             - [ List of {flavorLabel : {flavor label name},
1113                         flavorProperties: HPACapability DICT} ]
1114     HPACapability DICT :
1115       hpa-feature: basicCapabilities
1116       hpa-version: v1
1117       architecture: generic
1118       hpa-feature-attributes:
1119         - HPAFEATUREATTRIBUTES LIST
1120
1121     HPAFEATUREATTRIBUTES LIST:
1122       hpa-attribute-key: String
1123       hpa-attribute-value: String
1124       operator: One of OPERATOR
1125       unit: String
1126     OPERATOR : ['=', '<', '>', '<=', '>=', 'ALL']
1127
1128 **Example**
1129
1130 .. code:: json
1131     {
1132         "hpa_constraint":{
1133             "type":"hpa",
1134             "demands":[
1135                "vG"
1136             ],
1137             "properties":{
1138                "evaluate":[
1139                   {
1140                      "flavorLabel":"flavor_label_1",
1141                      "flavorProperties":[
1142                         {
1143                            "hpa-feature":"basicCapabilities",
1144                            "hpa-version":"v1",
1145                            "architecture":"generic",
1146                            "mandatory": "True",
1147                            "hpa-feature-attributes":[
1148                               {
1149                                  "hpa-attribute-key":"numVirtualCpu",
1150                                  "hpa-attribute-value":"32",
1151                                  "operator":"="
1152                               },
1153                               {
1154                                  "hpa-attribute-key":"virtualMemSize",
1155                                  "hpa-attribute-value":"64",
1156                                  "operator":"=",
1157                                  "unit":"GB"
1158                               }
1159                            ]
1160                         },
1161                         {
1162                            "hpa-feature":"ovsDpdk",
1163                            "hpa-version":"v1",
1164                            "architecture":"generic",
1165                            "mandatory": "False",
1166                            "score": "10",
1167                            "hpa-feature-attributes":[
1168                               {
1169                                  "hpa-attribute-key":"dataProcessingAccelerationLibrary",
1170                                  "hpa-attribute-value":"v18.02",
1171                                  "operator":"="
1172                               }
1173                            ]
1174                         }
1175                      ]
1176                   },
1177                   {
1178                      "flavorLabel":"flavor_label_2",
1179                      "flavorProperties":[
1180                         {
1181                            "hpa-feature":"basicCapabilities",
1182                            "hpa-version":"v1",
1183                            "architecture":"generic",
1184                            "mandatory": "False",
1185                            "score": "5",
1186                            "hpa-feature-attributes":[
1187                               {
1188                                  "hpa-attribute-key":"numVirtualCpu",
1189                                  "hpa-attribute-value":"8",
1190                                  "operator":">="
1191                               },
1192                               {
1193                                  "hpa-attribute-key":"virtualMemSize",
1194                                  "hpa-attribute-value":"16",
1195                                  "operator":">=",
1196                                  "unit":"GB"
1197                               }
1198                            ]
1199                         }
1200                      ]
1201                   }
1202                ]
1203             }
1204          }
1205       }
1206
1207 VIM Fit
1208 ~~~~~~~
1209
1210 Constrain each demand's inventory candidates based on capacity check for
1211 available capacity at the VIM instances.
1212
1213 Requirements are sent as an opaque request object understood by the VIM
1214 controllers or MultiCloud. Each controller is defined and implemented as a
1215 plugin in Conductor.
1216
1217 A vim controller plugin knows how to communicate with a particular endpoint
1218 (via HTTP/REST, DMaaP, etc.), obtain necessary information, and make a
1219 decision. The endpoint and credentials can be configured through plugin
1220 settings.
1221
1222
1223 **Schema**
1224
1225 +--------------+--------------------------------------------------------+
1226 | Property     | Value                                                  |
1227 +==============+========================================================+
1228 | ``controller | Name of a vim controller. (e.g., multicloud)           |
1229 +--------------+--------------------------------------------------------+
1230 | ``request``  | Opaque dictionary of key/value pairs. Values           |
1231 |              | must be strings or numbers. Encoded and sent           |
1232 |              | to the vim controller via a plugin.                    |
1233 +--------------+--------------------------------------------------------+
1234
1235 .. code:: yaml
1236
1237     constraints:
1238       check_cloud_capacity:
1239         type: vim_fit
1240         demands: [my_vnf_demand, my_other_vnf_demand]
1241         properties:
1242           controller: multicloud
1243           request: REQUEST_DICT
1244
1245 **Notes**
1246
1247 -  For ONAP Beijing release the REQUEST_DICT is of the following format as
1248    defined by the policy for vim_fit. The REQUEST_DICT is an opaque request
1249    object defined through policy, so it is not restricted to this format. In
1250    ONAP Beijing release MultiCloud supports the check_vim_capacity using the
1251    following grammar.
1252    .. code:: json
1253        {
1254          "request":{
1255            "vCPU":10,
1256            "Memory":{
1257              "quantity":{
1258                "get_param":"REQUIRED_MEM"
1259              },
1260              "unit":"GB"
1261            },
1262            "Storage":{
1263              "quantity":{
1264                "get_param":"REQUIRED_DISK"
1265              },
1266              "unit":"GB"
1267            }
1268          }
1269        }
1270
1271 Inventory Group
1272 ~~~~~~~~~~~~~~~
1273
1274 Constrain demands such that inventory items are grouped across two
1275 demands.
1276
1277 This constraint has no properties.
1278
1279 .. code:: yaml
1280
1281     constraints:
1282       my_group:
1283         type: inventory_group
1284         demands: [demand_1, demand_2]
1285
1286 *Note: Only pair-wise groups are supported at this time. If three or
1287 more demands are specified, only the first two will be used.*
1288
1289 License
1290 ~~~~~~~
1291
1292 Constrain demands according to license availability.
1293
1294 *Support for this constraint is deferred.*
1295
1296 **Schema**
1297
1298 +----------+----------------------------------------------------------+
1299 | Property | Value                                                    |
1300 +==========+==========================================================+
1301 | ``id``   | Unique license identifier                                |
1302 +----------+----------------------------------------------------------+
1303 | ``key``  | Opaque license key, particular to the license identifier |
1304 +----------+----------------------------------------------------------+
1305
1306 .. code:: yaml
1307
1308     constraints:
1309       my_software:
1310         type: license
1311         demands: [demand_1, demand_2, ...]
1312         properties:
1313           id: SOFTWARE_ID
1314           key: LICENSE_KEY
1315
1316 Network Between Demands
1317 ~~~~~~~~~~~~~~~~~~~~~~~
1318
1319 Constrain each pairwise combination of two or more demands by network
1320 requirements.
1321
1322 *Support for this constraint is deferred.*
1323
1324 **Schema**
1325
1326 +-------------------+--------------------------------------------------+
1327 | Property          | Value                                            |
1328 +===================+==================================================+
1329 | ``bandwidth``     | Desired network bandwidth.                       |
1330 | (Optional)        |                                                  |
1331 +-------------------+--------------------------------------------------+
1332 | ``distance``      | Desired distance between demands, measured by    |
1333 | (Optional)        | the network path.                                |
1334 +-------------------+--------------------------------------------------+
1335 | ``latency``       | Desired network latency.                         |
1336 | (Optional)        |                                                  |
1337 +-------------------+--------------------------------------------------+
1338
1339 Any combination of ``bandwidth``, ``distance``, or ``latency`` must be
1340 specified. If none of these properties are used, it is treated as a
1341 malformed request.
1342
1343 The constraint is applied between each pairwise combination of demands.
1344 For this reason, at least two demands must be specified, implicitly or
1345 explicitly.
1346
1347 .. code:: yaml
1348
1349     constraints:
1350       network_requirements:
1351         type: network_between_demands
1352         demands: [my_vnf_demand, my_other_vnf_demand]
1353         properties:
1354           bandwidth: >= 1000 Mbps
1355           distance: < 250 km
1356           latency: < 50 ms
1357
1358 Network To Location
1359 ~~~~~~~~~~~~~~~~~~~
1360
1361 Constrain one or more demands by network requirements relative to a
1362 specific location.
1363
1364 *Support for this constraint is deferred.*
1365
1366 **Schema**
1367
1368 +-----------------------------------+-----------------------------------+
1369 | Property                          | Value                             |
1370 +===================================+===================================+
1371 | ``bandwidth``                     | Desired network bandwidth.        |
1372 +-----------------------------------+-----------------------------------+
1373 | ``distance``                      | Desired distance between demands, |
1374 |                                   | measured by the network path.     |
1375 +-----------------------------------+-----------------------------------+
1376 | ``latency``                       | Desired network latency.          |
1377 +-----------------------------------+-----------------------------------+
1378 | ``location``                      | A previously declared location.   |
1379 +-----------------------------------+-----------------------------------+
1380
1381 Any combination of ``bandwidth``, ``distance``, or ``latency`` must be
1382 specified. If none of these properties are used, it is treated as a
1383 malformed request.
1384
1385 The constraint is applied between each demand and the referenced
1386 location, not across all pairwise combinations of Demands.
1387
1388 .. code:: yaml
1389
1390     constraints:
1391       my_access_network_constraint:
1392         type: network_to_location
1393         demands: [my_vnf_demand, my_other_vnf_demand]
1394         properties:
1395           bandwidth: >= 1000 Mbps
1396           distance: < 250 km
1397           latency: < 50 ms
1398           location: LOCATION_ID
1399
1400 Capabilities
1401 ~~~~~~~~~~~~
1402
1403 Constrain each demand by its cluster capability requirements. For
1404 example, as described by an OpenStack Heat template and operational
1405 environment.
1406
1407 *Support for this constraint is deferred.*
1408
1409 **Schema**
1410
1411 +------------+---------------------------------------------------------+
1412 | Property   | Value                                                   |
1413 +============+=========================================================+
1414 | ``specific | Indicates the kind of specification being provided in   |
1415 | ation``    | the properties. Must be ``heat``. Future values may     |
1416 |            | include ``tosca``, ``Homing``, etc.                     |
1417 +------------+---------------------------------------------------------+
1418 | ``template | For specifications of type ``heat``, a single stack in  |
1419 | ``         | OpenStack Heat Orchestration Template (HOT) format.     |
1420 |            | Stacks may be expressed as a URI reference or a string  |
1421 |            | of well-formed YAML/JSON. Templates are validated by    |
1422 |            | the Heat service configured for use by HAS. Nested      |
1423 |            | stack references are unsupported.                       |
1424 +------------+---------------------------------------------------------+
1425 | ``environm | For specifications of type ``heat``, an optional Heat   |
1426 | ent``      | environment. Environments may be expressed as a URI     |
1427 | (Optional) | reference or a string of well-formed YAML/JSON.         |
1428 |            | Environments are validated by the Heat service          |
1429 |            | configured for use by Homing.                           |
1430 +------------+---------------------------------------------------------+
1431
1432 .. code:: yaml
1433
1434     constraints:
1435       check_for_fit:
1436         type: capability
1437         demands: [my_vnf_demand, my_other_vnf_demand]
1438         properties:
1439           specification: heat
1440           template: http://repository/my/stack_template
1441           environment: http://repository/my/stack_environment
1442
1443 Reservations
1444 ------------
1445
1446 A **Reservation** allows reservation of resources associated with
1447 candidate that satisfies one or more demands.
1448
1449 Similar to the *instance_fit* constraint, requirements are sent as a
1450 request to a **service controller** that handles the reservation.
1451 Service controllers are defined by plugins in Homing (e.g., ``sdn-c``).
1452
1453 The service controller plugin knows how to make a reservation (and
1454 initiate rollback on a failure) with a particular endpoint (via
1455 HTTP/REST, DMaaP, etc.) of the service controller. The endpoint and
1456 credentials can be configured through plugin settings.
1457
1458 **Schema**
1459
1460 +---------------------+------------------------------------------------+
1461 | Property            | Description                                    |
1462 +=====================+================================================+
1463 | ``controller``      | Name of a service controller.                  |
1464 +---------------------+------------------------------------------------+
1465 | ``request``         | Opaque dictionary of key/value pairs. Values   |
1466 |                     | must be strings or numbers. Encoded and sent   |
1467 |                     | to the service provider via a plugin.          |
1468 +---------------------+------------------------------------------------+
1469
1470 .. code:: yaml
1471
1472     resource_reservation:
1473       type: instance_reservation
1474       demands: [my_vnf_demand, my_other_vnf_demand]
1475       properties:
1476         controller: sdn-c
1477         request: REQUEST_DICT
1478
1479 Optimizations
1480 -------------
1481
1482 An **Optimization** allows specification of a objective function, which
1483 aims to maximize or minimize a certain value that varies based on the
1484 choice of candidates for one or more demands that are a part of the
1485 objective function. For example, an objective function may be to find
1486 the *closest* cloud-region to a customer to home a demand.
1487
1488 Optimization Components
1489 ~~~~~~~~~~~~~~~~~~~~~~~
1490
1491 Optimization definitions can be broken down into three components:
1492
1493 +-------+----------------+--------------------------------------------+
1494 | Compo | Key            | Value                                      |
1495 | nent  |                |                                            |
1496 +=======+================+============================================+
1497 | Goal  | ``minimize``   | A single Operand (usually ``sum``) or      |
1498 |       |                | Function                                   |
1499 +-------+----------------+--------------------------------------------+
1500 | Opera | ``sum``,       | Two or more Operands (Numbers, Operators,  |
1501 | tor   | ``product``    | Functions)                                 |
1502 +-------+----------------+--------------------------------------------+
1503 | Funct | ``distance_bet | A two-element list consisting of a         |
1504 | ion   | ween``         | location and demand.                       |
1505 +-------+----------------+--------------------------------------------+
1506
1507 .. _example-1:
1508
1509 Example
1510 ~~~~~~~
1511
1512 Given a customer location ``cl``, two demands ``vG1`` and ``vG2``, and
1513 weights ``w1`` and ``w2``, the optimization criteria can be expressed
1514 as:
1515
1516 ``minimize(weight1 * distance_between(cl, vG1) + weight2 * distance_between(cl, vG2))``
1517
1518 This can be read as: “Minimize the sum of weighted distances from cl to
1519 vG1 and from cl to vG2.”
1520
1521 Such optimizations may be expressed in a template as follows:
1522
1523 .. code:: yaml
1524
1525     parameters:
1526       w1: 10
1527       w2: 20
1528
1529     optimization:
1530       minimize:
1531         sum:
1532         - product:
1533           - {get_param: w1}
1534           - {distance_between: [cl, vG1]}
1535         - product:
1536           - {get_param: w2}
1537           - {distance_between: [cl, vG2]}
1538
1539 Or without the weights as:
1540
1541 .. code:: yaml
1542
1543     optimization:
1544       minimize:
1545         sum:
1546         - {distance_between: [cl, vG1]}
1547         - {distance_between: [cl, vG2]}
1548
1549 **Template Restriction**
1550
1551 While the template format supports any number of arrangements of
1552 numbers, operators, and functions, HAS’s solver presently expects a very
1553 specific arrangement.
1554
1555 Until further notice:
1556
1557 -  Optimizations must conform to a single goal of ``minimize`` followed
1558    by a ``sum`` operator.
1559 -  The sum can consist of two ``distance_between`` function calls, or
1560    two ``product`` operators.
1561 -  If a ``product`` operator is present, it must contain at least a
1562    ``distance_between`` function call, plus one optional number to be
1563    used for weighting.
1564 -  Numbers may be referenced via ``get_param``.
1565 -  The objective function has to be written in the sum-of-product
1566    format. In the future, HAS can convert product-of-sum into
1567    sum-of-product automatically.
1568
1569 The first two examples in this section illustrate both of these use
1570 cases.
1571
1572 **Inline Operations**
1573
1574 If desired, operations can be rewritten inline. For example, the two
1575 ``product`` operations from the previous example can also be expressed
1576 as:
1577
1578 .. code:: yaml
1579
1580     parameters:
1581       w1: 10
1582       w2: 20
1583
1584     optimization:
1585       minimize:
1586         sum:
1587         - {product: [{get_param: w1}, {distance_between: [cl, vG1]}]}
1588         - {product: [{get_param: w2}, {distance_between: [cl, vG2]}]}
1589
1590 In turn, even the ``sum`` operation can be rewritten inline, however
1591 there is a point of diminishing returns in terms of readability!
1592
1593 **Notes**
1594
1595 -  In the first version, we do not support more than one dimension in
1596    the optimization (e.g., Minimize distance and cost). For supporting
1597    multiple dimensions we would need a function the normalize the unit
1598    across dimensions.
1599
1600 Intrinsic Functions
1601 -------------------
1602
1603 Homing provides a set of intrinsic functions that can be used inside
1604 templates to perform specific tasks. The following section describes the
1605 role and syntax of the intrinsic functions.
1606
1607 Functions are written as a dictionary with one key/value pair. The key
1608 is the function name. The value is a list of arguments. If only one
1609 argument is provided, a string may be used instead.
1610
1611 .. code:: yaml
1612
1613     a_property: {FUNCTION_NAME: [ARGUMENT_LIST]}
1614
1615     a_property: {FUNCTION_NAME: ARGUMENT_STRING}
1616
1617 *Note: These functions can only be used within “properties” sections.*
1618
1619 get_file
1620 ~~~~~~~~
1621
1622 The ``get_file`` function inserts the content of a file into the
1623 template. It is generally used as a file inclusion mechanism for files
1624 containing templates from other services (e.g., Heat).
1625
1626 The syntax of the ``get_file`` function is:
1627
1628 .. code:: yaml
1629
1630     {get_file: <content key>}
1631
1632 The ``content`` key is used to look up the ``files`` dictionary that is
1633 provided in the REST API call. The Homing client command (``Homing``) is
1634 ``get_file`` aware and populates the ``files`` dictionary with the
1635 actual content of fetched paths and URLs. The Homing client command
1636 supports relative paths and transforms these to the absolute URLs
1637 required by the Homing API.
1638
1639 **Note**: The ``get_file`` argument must be a static path or URL and not
1640 rely on intrinsic functions like ``get_param``. The Homing client does
1641 not process intrinsic functions. They are only processed by the Homing
1642 engine.
1643
1644 The example below demonstrates the ``get_file`` function usage with both
1645 relative and absolute URLs:
1646
1647 .. code:: yaml
1648
1649     constraints:
1650       check_for_fit:
1651         type: capacity
1652         demands: [my_vnf_demand, my_other_vnf_demand]
1653         properties:
1654           template: {get_file: stack_template.yaml}
1655           environment: {get_file: http://hostname/environment.yaml}
1656
1657 The ``files`` dictionary generated by the Homing client during
1658 instantiation of the plan would contain the following keys. Each value
1659 would be of that file’s contents.
1660
1661 -  ``file:///path/to/stack_template.yaml``
1662 -  ``http://hostname/environment.yaml``
1663
1664 **Questions**
1665
1666 -  If Homing will only be accessed over DMaaP, files will need to be
1667    embedded using the Homing API request format.
1668
1669 get_param
1670 ~~~~~~~~~
1671
1672 The ``get_param`` function references an input parameter of a template.
1673 It resolves to the value provided for this input parameter at runtime.
1674
1675 The syntax of the ``get_param`` function is:
1676
1677 .. code:: yaml
1678
1679     {get_param: <parameter name>}
1680
1681     {get_param: [<parameter name>, <key/index1> (optional), <key/index2> (optional), ...]}
1682
1683 **parameter name** is the parameter name to be resolved. If the
1684 parameters returns a complex data structure such as a list or a dict,
1685 then subsequent keys or indices can be specified. These additional
1686 parameters are used to navigate the data structure to return the desired
1687 value. Indices are zero-based.
1688
1689 The following example demonstrates how the ``get_param`` function is
1690 used:
1691
1692 .. code:: yaml
1693
1694     parameters:
1695       software_id: SOFTWARE_ID
1696       license_key: LICENSE_KEY
1697       service_info:
1698         provider: dmaap:///full.topic.name
1699         costs: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
1700
1701     constraints:
1702       my_software:
1703         type: license
1704         demands: [demand_1, demand_2, ...]
1705         properties:
1706           id: {get_param: software_id}
1707           key: {get_param: license_key}
1708
1709       check_for_availability:
1710         type: service
1711         demands: [my_vnf_demand, my_other_vnf_demand]
1712         properties:
1713           provider_url: {get_param: [service_info, provider]}
1714           request: REQUEST_DICT
1715           cost: {get_param: [service_info, costs, 4]}
1716
1717 In this example, properties would be set as follows:
1718
1719 +------------------+--------------------------+
1720 | Key              | Value                    |
1721 +==================+==========================+
1722 | ``id``           | SOFTWARE_ID              |
1723 +------------------+--------------------------+
1724 | ``key``          | LICENSE_KEY              |
1725 +------------------+--------------------------+
1726 | ``provider_url`` | dmaap:///full.topic.name |
1727 +------------------+--------------------------+
1728 | ``cost``         | 50                       |
1729 +------------------+--------------------------+
1730
1731 Contact
1732 -------
1733
1734 Shankar Narayanan shankarpnsn@gmail.com