{"id":1825,"date":"2023-09-05T15:57:09","date_gmt":"2023-09-05T15:57:09","guid":{"rendered":"https:\/\/community.5gasp.eu\/?page_id=1825"},"modified":"2023-09-26T14:20:28","modified_gmt":"2023-09-26T14:20:28","slug":"how-to-manage-your-vnf-with-an-helm-chart-based-execution-environment-ee","status":"publish","type":"page","link":"https:\/\/community.5gasp.eu\/index.php\/how-to-manage-your-vnf-with-an-helm-chart-based-execution-environment-ee\/","title":{"rendered":"How to manage your VNF with an Helm Chart-based Execution Environment (EE) tutorial"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction to Execution Environments in OSM<\/h2>\n\n\n\n<p>OSM&#8217;s Execution Environments (EE) provide a runtime framework to run day-1 and day-2 primitives. These EE provide the means for NF-specific management code to run it into a dedicated helm chart, which is deployed into OSM&#8217;s system cluster. From there, the EE interacts with the managed NF (e.g. via SSH), providing a NF-agnostic mean to manage NFs by OSM.<\/p>\n\n\n\n<p>OSM communicates with its EE to trigger actions via gRPC calls, which are handled by a frontend component (running in a pod) in its constituent helm chart. In order to ease the NF onboarding tasks, there is already a helm chart template available including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>a frontend element which implements the gRPC interface required by OSM (exposed via a Kubernetes service). **However the OSM&#8217;s current frontend element is outdated ( due to GRPC), thus a custom one will be used **<\/li>\n\n\n\n<li>and an optional back-end, in charge of the interaction with the NF.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Software Installation<\/h2>\n\n\n\n<p>Installation of Helm<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ curl https:\/\/get.helm.sh\/helm-v3.11.2-linux-amd64.tar.gz\n$ tar -zxvf helm-v3.11.2-linux-amd64.tar.gz\n$ mv linux-amd64\/helm \/usr\/local\/bin\/helm<\/code><\/pre>\n\n\n\n<p>Installation of Ansible<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip3 install ansible<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Code Structure<\/h2>\n\n\n\n<p>Inside this directory you may find three core subdirectories:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>grpc<\/code>(Includes the underlying code of the frontend element which implements the gRPC interface)<\/li>\n\n\n\n<li><code>simple_ee_vnf<\/code> (Includes the VNFD and Helm Chart)<\/li>\n\n\n\n<li><code>simple_ee_ns<\/code> (Includes the NSD) The <code>completed<\/code> folder, contains the resolution of the tutorial.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">gRPC image<\/h2>\n\n\n\n<p>The code used has been adapted from OSM&#8217;S. Thus, you should build the Docker image and push it to your Images Registry.<\/p>\n\n\n\n<p>If the OSM&#8217;s gRPC code is not up to date with Protoc Buffers, to regenerate the protocol buffers do the following:<\/p>\n\n\n\n<p>Download and install the python compiler from <a href=\"https:\/\/github.com\/protocolbuffers\/protobuf\/releases\">ProtoBuf<\/a> following the instructions in the README file.<\/p>\n\n\n\n<p>Delete <code>frontend_pb2.py<\/code> and <code>frontend_grpc.py<\/code>.<\/p>\n\n\n\n<p>Run the compiler:<\/p>\n\n\n\n<p><code>protoc -I=\/path\/to\/grpc\/osm_ee\/ --python\\_out=\/path\/to\/grpc\/osm_ee\/ \/path\/to\/grpc\/osm_ee\/frontend.proto<\/code><\/p>\n\n\n\n<p>Once, this is done you may build the Docker image and upload it to your registry using the following commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker build -t  &lt;your_registry_domain_name&gt;\/&lt;the_grpc_image_name&gt; .\ndocker push  &lt;your_registry_domain_name&gt;\/&lt;the_grpc_image_name&gt;<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Creating day-1\/day-2 primitives via Ansible<\/h1>\n\n\n\n<p>All your Ansible playbooks must be present in your Helm chart inside the <code>source<\/code> folder (<code>\/simple_ee_vnf\/helm-charts\/eechart\/source<\/code>). In the <code>source<\/code> folder there are already two empty files called <code>playbook.yaml<\/code> and <code>update_file.yaml<\/code>.<\/p>\n\n\n\n<p>Inside the <code>playbook.yaml<\/code> file on the source <code>directory<\/code> introduce the following code, which perform a day1 operation responsible for creating an empty file on the VNF&#8217;s VM.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>- hosts: all\n  name: Create an empty file on the remote machine\n  become: true\n  tasks:\n  - name: Create an empty file on the remote machine\n    file:\n      path: \"\/home\/ubuntu\/myfile.txt\"\n      state: touch<\/code><\/pre>\n\n\n\n<p>Then, introduce the following code block to the empty playbook <code>update_file,yaml<\/code> on the source <code>directory<\/code>. This is the playbook to be invoked on the day-2 primitive. This primitive will update the file&#8217;s content with the user input. The workflow will be explained with further detail.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>- hosts: all\n  vars:\n    content: \"{{ params.content }}\"\n  tasks:\n  - name: Update the content of the file\n    blockinfile:\n      path: \"\/home\/ubuntu\/myfile.txt\"\n      block: |\n       \"{{content}}\"<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Change the Helm Chart Content<\/h3>\n\n\n\n<p>Inside the Helm Chart you may find the file <code>values.yaml<\/code> which will be used to change variable names, such as the image names used. You should change to include the GRPC image that OSM needs to interact.<br>For instance:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>name: ansible-grpc\nrepository: atnog-harbor.av.it.pt\/5gasp\/ansible-grpc-keyauth@sha256\ntag: 28e4a0a5cb210cabbc39d4b4fb597e786975d65e7a3a54365b1915b30fd72bbf\npullPolicy: Always<\/code><\/pre>\n\n\n\n<p>In OSM 14, the Helm-Charts are deployed in a namespace created on-the-fly. However, we cannot share Secrets across namespaces, thus one solution can be to include the Image Pull Secret inside the Helm Chart.<br>To that end, on the same file, <code>values.yaml<\/code>, make sure to edit the key <code>dockerConfig<\/code>&#8216;s value to access your Images Registry<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Change the VNFD<\/h2>\n\n\n\n<p>A pre-requirement to define EE-based primitives is including the appropriate reference in the descriptor to the own EE, and then a reference to the corresponding day-1 and day-2 primitives that are hosted in the EE. You may find the VNFD in the root of the VNF artifact folder (<code>simple_ee_vnf\/sample_ee_vnfd.yaml<\/code>)<br>The first is achieved by adding an execution-environment-list block, where one or more EEs (there might be more than one) are indicated. Inside the <code>df<\/code> element put the following excerpt of code, aligned with the same identation level as <code>vdu-profile<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lcm-operations-configuration:\n      operate-vnf-op-config:\n        day1-2:\n        - execution-environment-list:\n          - external-connection-point-ref: vnf-mgmt-ext\n            helm-chart: eechart\n            helm-version: v3\n            id: sample\n          id: simple\n          config-access:\n            ssh-access:\n              default-user: ubuntu\n              required: true\n          initial-config-primitive:\n          - execution-environment-ref: sample\n            name: config\n            parameter:\n            - name: ssh-hostname\n              value: &lt;rw_mgmt_ip&gt;\n            - name: ssh-username\n              value: ubuntu\n            - name: ssh-password\n              value: password\n            seq: 1<\/code><\/pre>\n\n\n\n<p>The next step is to include the day1-primitive block referencing the <code>playbook.yaml<\/code> file, inside the <code>initial-config-primitive block<\/code>. The parameter&#8217;s value must match the playbook&#8217;s file name.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>- execution-environment-ref: sample\n  name: ansible_playbook\n  parameter:\n    - name: playbook-name\n      value: playbook\n  seq: 2<\/code><\/pre>\n\n\n\n<p>In this tutorial, as mentioned, we will create a day-2 primitive. The primitive requires two parameters: the playbook file name (in the provided example, playbook-name) as well as the content to add to the file created on day-1 operation (content). Make sure to add the following block code bellow <code>initial-config-primitive<\/code>directive :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>config-primitive:\n- execution-environment-primitive: ansible_playbook\n  execution-environment-ref: sample\n  name: ansible_playbook\n  parameter:\n    - data-type: STRING\n      name: playbook-name\n    - data-type: STRING\n      name: content\n      default-value: &lt;content&gt;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Change the NSD<\/h2>\n\n\n\n<p>Regarding the NSD ( <code>simple_ee_ns\/nsd.yaml<\/code>) you should change the <code>vim-network-name<\/code> to the name of your VIM Network<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> virtual-link-desc:\n    - id: mgmtnet\n      mgmt-network: true\n      vim-network-name: XXXXX<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Upload the NFV Artifacts<\/h2>\n\n\n\n<p>To upload the NS and VNF packages you may run the following commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osm nfpkg-create simple_ee_vnf\nosm nspkg-create simple_ee_ns<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Instantiate the NS<\/h2>\n\n\n\n<p>Now, we are ready to deploy the VNF. Using the OSM CLI you may use the following command:<\/p>\n\n\n\n<p><code>osm ns-create --ns_name 5gasp_ee_tutorial --nsd_name simple_ee-ns --vim_account &lt;your_vim_account&gt;<\/code><\/p>\n\n\n\n<p>To check if the day-1 operations has succeeded, in another terminal tab, we can now enter into the machine via SSH:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh ubuntu@&lt;your_vm_ip&gt;<\/code><\/pre>\n\n\n\n<p>By doing a simple <code>ls<\/code> command we can verify that the file has been created:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ ls\nmyfile.txt<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Performing the day-2 operation<\/h2>\n\n\n\n<p>To perform the day-2 operation we have can run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> osm ns-action  --vnf_name simple --vdu_id mgmtVM  --action_name ansible_playbook --params \"{\\\"playbook-name\\\": \\\"update_file\\\", \\\"content\\\": \\\"Hello World!\\\"}\"   5gasp_ee_tutorial<\/code><\/pre>\n\n\n\n<p><br>In the VNF&#8217;s VM we can verify that the content of the file has been updated:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cat myfile.txt\n\n# BEGIN ANSIBLE MANAGED BLOCK\n\"Hello\"\n# END ANSIBLE MANAGED BLOCK<\/code><\/pre>\n\n\n\n<p>Tutorial materials<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/5gasp\/tutorials\/tree\/master\/5-manage_your_vnf_with_an_helm_chart_based_execution_environment\">GitHub repository<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction to Execution Environments in OSM OSM&#8217;s Execution Environments (EE) provide a runtime framework to run day-1 and day-2 primitives. These EE provide the means for NF-specific management code to run it into a dedicated helm chart, which is deployed into OSM&#8217;s system cluster. From there, the EE interacts with [\u2026]<\/p>\n","protected":false},"author":30,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"pg_page_styles":[],"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"ngg_post_thumbnail":0,"footnotes":""},"class_list":["post-1825","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/community.5gasp.eu\/index.php\/wp-json\/wp\/v2\/pages\/1825","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/community.5gasp.eu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/community.5gasp.eu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/community.5gasp.eu\/index.php\/wp-json\/wp\/v2\/users\/30"}],"replies":[{"embeddable":true,"href":"https:\/\/community.5gasp.eu\/index.php\/wp-json\/wp\/v2\/comments?post=1825"}],"version-history":[{"count":3,"href":"https:\/\/community.5gasp.eu\/index.php\/wp-json\/wp\/v2\/pages\/1825\/revisions"}],"predecessor-version":[{"id":1853,"href":"https:\/\/community.5gasp.eu\/index.php\/wp-json\/wp\/v2\/pages\/1825\/revisions\/1853"}],"wp:attachment":[{"href":"https:\/\/community.5gasp.eu\/index.php\/wp-json\/wp\/v2\/media?parent=1825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}