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