Adding document for vfw/edgex use case
[integration.git] / docs / docs_vfw_edgex_k8s.rst
1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. http://creativecommons.org/licenses/by/4.0
3 .. Copyright 2018 ONAP
4
5 .. _docs_vfw_edgex_multicloud_k8s:
6
7 vFW/Edgex with Multicloud Kubernetes Plugin: Setting Up and Configuration
8 -------------------------------------------------------------------------
9
10 Description
11 ~~~~~~~~~~~
12 This use case covers the deployment of vFW and Edgex HELM Charts in a Kubernetes based cloud region via the multicloud-k8s plugin.
13 The multicloud-k8s plugin provides APIs to upload self-contained HELM Charts that can be customized via the profile API and later installed in a particular cloud region.
14
15 When the installation is complete (all the pods are either in running or completed state)
16
17 vFW Helm Chart link:
18 --------------------
19
20 https://github.com/onap/multicloud-k8s/tree/master/kud/demo/firewall
21
22 EdgeXFoundry Helm Chart link:
23 -----------------------------
24
25 https://github.com/onap/multicloud-k8s/tree/master/kud/tests/vnfs/edgex/helm/edgex
26
27
28 **Create CSAR with Helm chart as an artifact**
29 ----------------------------------------------
30
31 The CSAR is a heat template package with Helm chart in it. The basic package
32 consists of an **environment file**, **base_dummy.yaml file** (example),
33 **MANIFEST.json** and the **tar.gz** file (of Helm chart).
34 We need to zip all of these files before onboarding.
35 One thing to pay much attention to is the naming convention which must
36 be followed while making the tgz.
37 **NOTE: The Naming convention is for the helm chart tgz file.**
38
39 **Naming convention follows the format:**
40
41 <free format string>\_\ ***cloudtech***\ \_<technology>\_<subtype>.extension
42
43 1. *Cloudtech:* is a fixed pattern and should not be changed if not
44    necessary
45 2. *Technology:* k8s, azure, aws
46 3. *Subtype*: charts, day0, config template
47 4. *Extension*: zip, tgz, csar
48
49 NOTE: The .tgz file must be a tgz created from the top level helm chart
50 folder. I.e. a folder that contains a Chart.yaml file in it.
51
52
53 Listed below is an example of the contents inside a heat template
54 package
55 ::
56
57      $ vfw-k8s/package$ ls
58       MANIFEST.json base_dummy.env base_dummy.yaml
59       vfw_cloudtech_k8s_charts.tgz vfw_k8s_demo.zip
60
61
62
63
64 **MANIFEST.json**
65 ~~~~~~~~~~~~~~~~~
66
67 Key thing is note the addition of cloud artifact
68 ::
69
70   type: "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACTS"
71
72   {
73     "name": "",
74     "description": "",
75     "data": [
76         {
77             "file": "base_dummy.yaml",
78             "type": "HEAT",
79             "isBase": "true",
80             "data": [
81                 {
82                     "file": "base_dummy.env",
83                     "type": "HEAT_ENV"
84                 }
85             ]
86         },
87         {
88             "file": "vfw_cloudtech_k8s_charts.tgz",
89             "type": "CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACTS"
90         }
91         ]
92   }
93
94 **Base\_dummy.yaml**
95 ~~~~~~~~~~~~~~~~~~~~~
96 Designed to be minimal HEAT template
97
98 ::
99
100  ##==================LICENSE_START========================================
101   ##
102   ## Copyright (C) 2019 Intel Corporation
103   ## SPDX-License-Identifier: Apache-2.0
104   ##
105   ##==================LICENSE_END===========================================
106
107   heat_template_version: 2016-10-14
108   description: Heat template to deploy dummy VNF
109
110   parameters:
111     dummy_name_0:
112       type: string
113       label: name of vm
114       description: Dummy name
115
116     vnf_id:
117       type: string
118             label: id of vnf
119       description: Provided by ONAP
120
121     vnf_name:
122       type: string
123       label: name of vnf
124       description: Provided by ONAP
125
126     vf_module_id:
127       type: string
128       label: vnf module id
129       description: Provided by ONAP
130
131     dummy_image_name:
132           type: string
133       label: Image name or ID
134       description: Dummy image name
135
136     dummy_flavor_name:
137       type: string
138       label: flavor
139       description: Dummy flavor
140
141   resources:
142     dummy_0:
143       type: OS::Nova::Server
144       properties:
145         name: { get_param: dummy_name_0 }
146         image: { get_param: dummy_image_name }
147         flavor: { get_param: dummy_flavor_name } metadata: { vnf_name: { get_param: vnf_name }, vnf_id: { get_param: vnf_id }, vf_module_id: { get_param: vf_module_id }}
148
149
150
151
152
153
154 **Base\_dummy.env**
155
156 ::
157
158   parameters:
159     vnf_id: PROVIDED_BY_ONAP
160     vnf_name: PROVIDED_BY_ONAP
161     vf_module_id: PROVIDED_BY_ONAP
162     dummy_name_0: dummy_1_0
163     dummy_image_name: dummy
164     dummy_flavor_name: dummy.default
165
166 **Onboard the CSAR**
167 --------------------
168
169 For onboarding instructions please refer to steps 4-9 from the document
170 `here <https://wiki.onap.org/display/DW/vFWCL+instantiation%2C+testing%2C+and+debuging>`__.
171
172 **Steps for installing KUD Cloud**
173 ----------------------------------
174
175 Follow the link to install KUD Kubernetes Deployment. KUD contains all
176 the packages required for running vfw use case.
177
178 Kubernetes Baremetal deployment instructions here_
179
180 .. _here: https://wiki.onap.org/display/DW/Kubernetes+Baremetal+deployment+setup+instructions/
181
182 **REGISTER KUD CLOUD REGION with K8s-Plugin**
183 ---------------------------------------------
184
185 API to support Reachability for Kubernetes Cloud
186
187 **The command to POST connectivity info**
188 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189 ::
190
191   {
192     "cloud-region" : "<name>",   // Must be unique across
193     "cloud-owner" :  "<owner>",
194     "other-connectivity-list" : {
195            }
196
197 This is a multipart upload and here is how you do the POST for this.
198
199 #Using a json file (eg: post.json) containing content as above
200 ::
201
202  curl -i -F "metadata=<post.json;type=application/json" -F file=@
203   /home/ad_kkkamine/.kube/config -X POST http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/connectivity-info
204
205 **Command to GET Connectivity Info**
206 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207
208 ::
209
210   curl -i -X GET http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/connectivity-info/{name}
211
212
213 **Command to DELETE Connectivity Info**
214 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
215
216 ::
217
218   curl -i -X GET http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/connectivity-info/{name}
219
220
221 **Command to UPDATE/PUT Connectivity Info**
222 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
223
224 ::
225
226   curl -i -X GET http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/connectivity-info/{name}
227
228 **Register KUD Cloud region with AAI**
229 --------------------------------------
230
231 With k8s cloud region, we need to add a tenant to the k8s cloud region.
232 The 'easy' way is to have the ESR information (in step 1 of cloud
233 registration) point to a real OpenStack tenant (e.g. the OOF tenant in
234 the lab where we tested).
235
236 This will cause multicloud to add the tenant to the k8s cloud region and
237 then, similar to #10 in the documentation
238 `here <https://onap.readthedocs.io/en/casablanca/submodules/integration.git/docs/docs_vfwHPA.html#docs-vfw-hpa>`__,
239 the service-subscription can be added to that object.
240
241 NOTE: use same name cloud-region and cloud-owner name
242
243 An example is shown below for K8s cloud but following the steps 1,2,3
244 from
245 `here <https://onap.readthedocs.io/en/latest/submodules/multicloud/framework.git/docs/multicloud-plugin-windriver/UserGuide-MultiCloud-WindRiver-TitaniumCloud.html#tutorial-onboard-instance-of-wind-river-titanium-cloud>`__.
246 The sample input below is for k8s cloud type.
247
248 **Step 1 - Cloud Registration/ Create a cloud region to represent the instance.**
249
250
251 Note: highlighted part of the body refers to an existing OpenStack
252 tenant (OOF in this case). Has nothing to do with the K8s cloud region
253 we are adding.
254
255 ::
256
257  PUT https://{{AAI1_PUB_IP}}:{{AAI1_PUB_PORT}}/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/k8scloudowner4/k8sregionfour
258   {
259         "cloud-owner": "k8scloudowner4",
260         "cloud-region-id": "k8sregionfour",
261         "cloud-type": "k8s",
262         "owner-defined-type": "t1",
263         "cloud-region-version": "1.0",
264         "complex-name": "clli1",
265         "cloud-zone": "CloudZone",
266         "sriov-automation": false,
267     "cloud-extra-info":"{\"openstack-region-id\":\"k8sregionthree\"}",
268         "esr-system-info-list": {
269                "esr-system-info": [
270                               {
271                                                 "esr-system-info-id": "55f97d59-6cc3-49df-8e69-926565f00066",
272                                                 "service-url": "http://10.12.25.2:5000/v3",
273                                                 "user-name": "demo",
274                                                 "password": "onapdemo",
275                                                 "system-type": "VIM",
276                                                 "ssl-insecure": true,
277                                                 "cloud-domain": "Default",
278                                                 "default-tenant": "OOF",
279                                                 "tenant-id": "6bbd2981b210461dbc8fe846df1a7808",
280                                                 "system-status": "active"
281                                              }
282                               ]
283         }
284   }
285
286 **Step 2  add a complex to the cloud**
287
288 Note: just adding one that exists already
289
290 ::
291
292  PUT https://{{AAI1_PUB_IP}}:{{AAI1_PUB_PORT}}/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/k8scloudowner4/k8sregionfour/relationship-list/relationship
293   {
294   "related-to": "complex",
295   "related-link": "/aai/v13/cloud-infrastructure/complexes/complex/clli1",
296   "relationship-data": [
297     {
298        "relationship-key": "complex.physical-location-id",
299        "relationship-value": "clli1"
300     }
301   ]
302   }
303
304 **Step 3 - Trigger the Multicloud plugin registration process**
305
306
307 ::
308
309   POST http://{{MSB_IP}}:{{MSB_PORT}}/api/multicloud-titaniumcloud/v1/k8scloudowner4/k8sregionfour/registry
310
311
312 This registers the K8S cloud with Multicloud  it also reaches out and
313 adds tenant information to the cloud (see example below  you'll see all
314 kinds of flavor, image information that is associated with the OOF
315 tenant).
316
317 If we had not done it this way, then wed have to go in to AAI at this
318 point and manually add a tenant to the cloud region. The first time I
319 tried this (k8s region one), I just made up some random tenant id and
320 put it in.)
321
322 The tenant is there so you can add the service-subscription to it:
323
324 **Making a Service Type:**
325
326 ::
327
328  PUT https://{{AAI1_PUB_IP}}:{{AAI1_PUB_PORT}}/aai/v13/service-design-and-creation/services/service/vfw-k8s
329   {
330               "service-description": "vfw-k8s",
331               "service-id": "vfw-k8s"
332   }
333
334 Add subscription to service type to the customer (Demonstration in this
335 case  which was already created by running the robot demo scripts)
336
337 ::
338
339  PUT https://{{AAI1_PUB_IP}}:{{AAI1_PUB_PORT}}/aai/v16/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vfw-k8s
340   {
341            "service-type": "vfw-k8s"
342   }
343
344 Add Service-Subscription to the tenant (resource-version changes based
345 on actual value at the time):
346
347 ::
348
349  PUT https://{{AAI1_PUB_IP}}:{{AAI1_PUB_PORT}}/aai/v16/cloud-infrastructure/cloud-regions/cloud-region/k8scloudowner4/k8sregionfour/tenants/tenant/6bbd2981b210461dbc8fe846df1a7808?resource-version=1559345527327
350   {
351   "tenant-id": "6bbd2981b210461dbc8fe846df1a7808",
352   "tenant-name": "OOF",
353   "resource-version": "1559345527327",
354   "relationship-list": {
355        "relationship": [
356            {
357                "related-to": "service-subscription",
358                "relationship-label": "org.onap.relationships.inventory.Uses",
359                "related-link": "/aai/v13/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vfw-k8s",
360                "relationship-data": [
361                    {
362                        "relationship-key": "customer.global-customer-id",
363                        "relationship-value": "Demonstration"
364                    },
365                    {
366                        "relationship-key": "service-subscription.service-type",
367                        "relationship-value": "vfw-k8s"
368                    }
369                ]
370            }
371     ]
372   }
373   }
374
375 **Distribute the CSAR**
376 -----------------------
377 Onboard a service it gets stored in SDC final action is distributed. SO
378 and other services are notified sdc listener in the multicloud sidecar.
379 When distribution happens it takes tar.gz file and uploads to k8s
380 plugin.
381
382 **Create Profile Manually**
383 ---------------------------
384
385 K8s-plugin artifacts start in the form of Definitions. These are nothing
386 but Helm Charts wrapped with some metadata about the chart itself. Once
387 the Definitions are created, we are ready to create some profiles so
388 that we can customize that definition and instantiate it in Kubernetes.
389
390 NOTE: Refer this link_ for complete API lists and
391 documentation:
392
393 .. _link : https://wiki.onap.org/display/DW/MultiCloud+K8s-Plugin-service+API
394
395 A profile consists of the following:
396
397 **manifest.yaml**
398
399 - Contains the details for the profile and everything contained within
400
401 A **HELM** values override yaml file.
402
403 - It can have any name as long as it matches the corresponding entry in the **manifest.yaml**
404
405 Any number of files organized in a folder structure
406
407 - All these files should have a corresponding entry in **manifest.yaml** file
408
409 **Creating a Profile Artifact**
410 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
411
412 ::
413
414  > cd multicloud-k8s/kud/tests/vnfs/testrb/helm/profile
415   > find .
416   manifest.yaml
417   override_values.yaml
418   testfol
419   testfol/subdir
420   testfol/subdir/deployment.yaml
421
422   #Create profile tar.gz
423   > cd profile
424   > tar -cf profile.tar *
425   > gzip profile.tar
426   > mv profile.tar.gz ../
427
428 The manifest file contains the following
429
430 ::
431
432  ---
433  version: v1
434  type:
435  values: "values_override.yaml"
436  configresource:
437    - filepath: testfol/subdir/deployment.yaml
438      chartpath: vault-consul-dev/templates/deployment.yaml
439
440 Note: values: "values\_override.yaml" can **be** empty **file** **if**
441 you are creating **a** dummy **profile**
442
443 Note: A dummy profile does not need any customization. The following is
444 optional in the manifest file.
445
446 ::
447
448  configresource:
449    - filepath: testfol/subdir/deployment.yaml
450      chartpath: vault-consul-dev/templates/deployment.yaml
451
452
453 With this information, we are ready to upload the profile with the
454 following JSON data
455
456 ::
457
458  {
459    "rb-name": "test-rbdef",
460    "rb-version": "v1",
461    "profile-name": "p1",
462    "release-name": "r1", //If release-name is not provided, profile-name will be used
463    "namespace": "testnamespace1",
464    "kubernetes-version": "1.12.3"
465  }
466
467
468 **Command to create (POST) Profile**
469 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
470
471 ::
472
473  curl -i -d @create_rbprofile.json -X POST http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/rb/definition/test-rbdef/v1/profile
474
475
476
477 **Command to UPLOAD artifact for Profile**
478
479 ::
480
481  curl -i --data-binary @profile.tar.gz -X POST http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/rb/definition/test-rbdef/v1/profile/p1/content
482
483
484
485 **Command to GET Profiles**
486
487 ::
488
489  curl -i http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/rb/definition/test-rbdef/v1/profile
490   # Get one Profile
491   curl -i http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/rb/definition/test-rbdef/v1/profile/p1
492
493
494
495 **Command to DELETE Profile**
496 ::
497
498  curl -i -X DELETE http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/rb/definition/test-rbdef/v1/profile/p1
499
500
501 **Instantiation**
502 -----------------
503
504 Instantiation is done by SO. SO then talks to Multi Cloud-broker via MSB
505 and that in turn looks up the cloud region in AAI to find the endpoint.
506 If k8sregion one is registered with AAI and SO makes a call with that,
507 then the broker will know that it needs to talk to k8s-plugin based on
508 the type of the registration.
509
510 **Instantiate the created Profile via the following REST API**
511
512 ::
513
514  Using the following JSON:
515   {
516    "cloud-region": "kud",
517    "profile-name": "p1",
518    "rb-name":"test-rbdef",
519    "rb-version":"v1",
520    "labels": {
521    }
522   }
523
524 **NOTE**: Make sure that the namespace is already created before
525 instantiation.
526
527 Instantiate the profile with the ID provided above
528
529 **Command to Instantiate a Profile**
530
531 ::
532
533  curl -d @create_rbinstance.json http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/instance
534
535
536 The command returns the following JSON
537
538 ::
539
540  {
541  "id": "ZKMTSaxv",
542  "rb-name": "mongo",
543  "rb-version": "v1",
544  "profile-name": "profile1",
545  "cloud-region": "kud",
546  "namespace": "testns",
547  "resources": [
548    {
549      "GVK": {
550        "Group": "",
551        "Version": "v1",
552        "Kind": "Service"
553      },
554      "Name": "mongo"
555    },
556    {
557      "GVK": {
558        "Group": "",
559        "Version": "v1",
560        "Kind": "Service"
561      },
562      "Name": "mongo-read"
563    },
564    {
565      "GVK": {
566        "Group": "apps",
567        "Version": "v1beta1",
568        "Kind": "StatefulSet"
569      },
570      "Name": "profile1-mongo"
571    }
572  ]
573  }
574
575 **Delete Instantiated Kubernetes resources**
576
577 The **id** field from the returned JSON can be used to **DELETE** the
578 resources created in the previous step. This executes a Delete operation
579 using the Kubernetes API.
580
581 ::
582
583  curl -X DELETE http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/instance/ZKMTSaxv
584
585
586 **GET Instantiated Kubernetes resources**
587
588
589 The **id field** from the returned JSON can be used to **GET** the
590 resources created in the previous step. This executes a get operation
591 using the Kubernetes API.
592
593 ::
594
595  curl -X GET http://MSB_NODE_IP:30280/api/multicloud-k8s/v1/v1/instance/ZKMTSaxv
596
597
598 `*\ https://github.com/onap/oom/blob/master/kubernetes/multicloud/resources/config/provider-plugin.json <https://github.com/onap/oom/blob/master/kubernetes/multicloud/resources/config/provider-plugin.json>`__
599
600 **Create User parameters**
601
602 We need to create parameters that ultimately get translated as:
603
604 ::
605
606  "user_directives": {
607  "attributes": [
608  {
609  "attribute_name": "definition-name",
610  "attribute_value": "edgex"
611  },
612  {
613  "attribute_name": "definition-version",
614  "attribute_value": "v1"
615  },
616  {
617  "attribute_name": "profile-name",
618  "attribute_value": "profile1"
619  }
620  ]
621  }