Integrate OVN4NFV plugin 51/73751/7
authorVictor Morales <victor.morales@intel.com>
Tue, 27 Nov 2018 13:13:11 +0000 (05:13 -0800)
committerVictor Morales <victor.morales@intel.com>
Fri, 7 Dec 2018 16:13:42 +0000 (08:13 -0800)
This change includes the files to install, configure and test the
OVN4NFV plugin.

Change-Id: I0c431e475bd391e13680c734cff555e4dfc055ae
Signed-off-by: Victor Morales <victor.morales@intel.com>
Issue-ID: MULTICLOUD-304

vagrant/Vagrantfile
vagrant/insecure_keys/key.pub [new file with mode: 0644]
vagrant/installer.sh
vagrant/playbooks/configure-ovn4nfv.yml [new file with mode: 0644]
vagrant/playbooks/krd-vars.yml
vagrant/tests/_common.sh
vagrant/tests/_functions.sh
vagrant/tests/integration_vcFW.sh
vagrant/tests/ovn4nfv.sh [new file with mode: 0755]

index 1b84cb4..3314fe9 100644 (file)
@@ -23,7 +23,7 @@ nodes = YAML.load_file(pdf)
 
 # Inventory file creation
 File.open(File.dirname(__FILE__) + "/inventory/hosts.ini", "w") do |inventory_file|
-  inventory_file.puts("[all:vars]\nansible_connection=ssh\nansible_ssh_user=vagrant\n[all]")
+  inventory_file.puts("[all]")
   nodes.each do |node|
     inventory_file.puts("#{node['name']}\tansible_ssh_host=#{node['ip']} ansible_ssh_port=22")
   end
@@ -119,6 +119,7 @@ Vagrant.configure("2") do |config|
     installer.vm.provision 'shell', privileged: false do |sh|
       sh.env = {'KRD_PLUGIN_ENABLED': 'true'}
       sh.inline = <<-SHELL
+        cp /vagrant/insecure_keys/key.pub /home/vagrant/.ssh/id_rsa.pub
         cp /vagrant/insecure_keys/key /home/vagrant/.ssh/id_rsa
         chown vagrant /home/vagrant/.ssh/id_rsa
         chmod 400 /home/vagrant/.ssh/id_rsa
diff --git a/vagrant/insecure_keys/key.pub b/vagrant/insecure_keys/key.pub
new file mode 100644 (file)
index 0000000..18a9c00
--- /dev/null
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
index e251170..271f44f 100755 (executable)
@@ -131,7 +131,7 @@ function install_addons {
     sudo ansible-galaxy install $verbose -r $krd_folder/galaxy-requirements.yml --ignore-errors
 
     ansible-playbook $verbose -i $krd_inventory $krd_playbooks/configure-krd.yml | sudo tee $log_folder/setup-krd.log
-    for addon in ${KRD_ADDONS:-virtlet ovn-kubernetes multus}; do
+    for addon in ${KRD_ADDONS:-virtlet ovn4nfv}; do
         echo "Deploying $addon using configure-$addon.yml playbook.."
         ansible-playbook $verbose -i $krd_inventory $krd_playbooks/configure-${addon}.yml | sudo tee $log_folder/setup-${addon}.log
         if [[ "${testing_enabled}" == "true" ]]; then
@@ -212,6 +212,7 @@ testing_enabled=${KRD_ENABLE_TESTS:-false}
 
 sudo mkdir -p $log_folder
 sudo mkdir -p /opt/csar
+sudo chown -R $USER /opt/csar
 export CSAR_DIR=/opt/csar
 echo "export CSAR_DIR=${CSAR_DIR}" | sudo tee --append /etc/environment
 
diff --git a/vagrant/playbooks/configure-ovn4nfv.yml b/vagrant/playbooks/configure-ovn4nfv.yml
new file mode 100644 (file)
index 0000000..c864b8c
--- /dev/null
@@ -0,0 +1,98 @@
+---
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2018
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+- import_playbook: configure-ovn.yml
+- import_playbook: configure-multus.yml
+
+- hosts: kube-master:kube-node
+  environment:
+    PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin/"
+  roles:
+    - role: andrewrothstein.go
+  tasks:
+    - name: Load krd variables
+      include_vars:
+        file: krd-vars.yml
+    - name: clone ovn4nfv-k8s-plugin repo
+      git:
+        repo: "{{ ovn4nfv_url }}"
+        dest: "{{ ovn4nfv_dest }}"
+        version: "{{ ovn4nfv_version }}"
+        force: yes
+      when: ovn4nfv_source_type == "source"
+    - name: clean ovn4nfvk8s left over files
+      make:
+        chdir: "{{ ovn4nfv_dest }}"
+        target: clean
+    - name: build ovn4nfvk8s-cni
+      make:
+        chdir: "{{ ovn4nfv_dest }}"
+        target: ovn4nfvk8s-cni
+      become: yes
+      environment:
+        GOPATH: "{{ go_path }}"
+    - name: copy ovn4nfvk8s-cni to cni folder
+      command: "mv {{ ovn4nfv_dest }}/ovn4nfvk8s-cni /opt/cni/bin/ovn4nfvk8s-cni"
+      become: yes
+    - name: create ovn4k8s config file
+      become: yes
+      blockinfile:
+        path: /etc/openvswitch/ovn4nfv_k8s.conf
+        create: yes
+        block: |
+          [logging]
+          loglevel=5
+          logfile=/var/log/openvswitch/ovn4k8s.log
+
+          [cni]
+          conf-dir=/etc/cni/net.d
+          plugin=ovn4nfvk8s-cni
+
+          [kubernetes]
+          kubeconfig=/etc/kubernetes/admin.conf
+    - name: create ovnkube logging directory
+      file:
+        path: /var/log/openvswitch
+        state: directory
+
+- hosts: kube-master
+  environment:
+    PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin/"
+  become: yes
+  tasks:
+    - name: Load krd variables
+      include_vars:
+        file: krd-vars.yml
+    - name: build ovn4nfvk8s
+      make:
+        chdir: "{{ ovn4nfv_dest }}"
+        target: ovn4nfvk8s
+      environment:
+        GOPATH: "{{ go_path }}"
+    - name: copy ovn4nfvk8s to /usr/bin folder
+      command: "mv {{ ovn4nfv_dest }}/ovn4nfvk8s /usr/bin/ovn4nfvk8s"
+    - name: create ovn4nfvk8s systemd service
+      blockinfile:
+        path: /etc/systemd/system/ovn4nfvk8s.service
+        create: yes
+        block: |
+          [Unit]
+          Description=OVN4NFV Kubernetes Daemon
+
+          [Service]
+          ExecStart=/usr/bin/ovn4nfvk8s \
+                -k8s-kubeconfig=/etc/kubernetes/admin.conf
+
+          [Install]
+          WantedBy=multi-user.target
+    - name: start ovn4nfvk8s systemd service
+      service:
+        name: ovn4nfvk8s
+        state: started
+        enabled: yes
index 0269b9b..15b7a1a 100644 (file)
@@ -51,6 +51,12 @@ istio_source_type: "tarball"
 istio_version: 1.0.3
 istio_url: "https://github.com/istio/istio/releases/download/{{ istio_version }}/istio-{{ istio_version }}-linux.tar.gz"
 
+go_path: "{{ base_dest }}/go"
+ovn4nfv_dest: "{{ go_path }}/src/ovn4nfv-k8s-plugin"
+ovn4nfv_source_type: "source"
+ovn4nfv_version: 5026d1d89b05eac5e004279b742df6745a73d93a
+ovn4nfv_url: "https://git.opnfv.org/ovn4nfv-k8s-plugin/"
+
 go_version: '1.11'
 kubespray_version: 2.8.0
 kubectl_version: 1.11.2
index e5134fd..620c00a 100755 (executable)
@@ -21,9 +21,11 @@ virtlet_image=virtlet.cloud/fedora
 virtlet_deployment_name=virtlet-deployment
 plugin_deployment_name=plugin-deployment
 plugin_service_name=plugin-service
+ovn4nfv_deployment_name=ovn4nfv-deployment
 onap_private_net=onap-private-net
 unprotected_private_net=unprotected-private-net
 protected_private_net=protected-private-net
+ovn_multus_network_name=ovn-networkobj
 
 # vFirewall vars
 demo_artifacts_version=1.3.0
@@ -229,6 +231,8 @@ function populate_CSAR_vms_containers_vFW {
     cat << META > metadata.yaml
 resources:
   network:
+    - onap-ovn4nfvk8s-network.yaml
+  onapNetwork:
     - $unprotected_private_net.yaml
     - $protected_private_net.yaml
     - $onap_private_net.yaml
@@ -255,52 +259,53 @@ spec:
     context: darkstat
 SERVICE
 
-    cat << NET > $unprotected_private_net.yaml
+    cat << MULTUS_NET > onap-ovn4nfvk8s-network.yaml
 apiVersion: "k8s.cni.cncf.io/v1"
 kind: NetworkAttachmentDefinition
 metadata:
-  name: $unprotected_private_net
+  name: $ovn_multus_network_name
 spec:
   config: '{
-    "name": "unprotected",
-    "type": "bridge",
-    "ipam": {
-        "type": "host-local",
-        "subnet": "$protected_private_net_cidr"
-    }
-}'
+      "cniVersion": "0.3.1",
+      "name": "ovn4nfv-k8s-plugin",
+      "type": "ovn4nfvk8s-cni"
+    }'
+MULTUS_NET
+
+    cat << NET > $unprotected_private_net.yaml
+apiVersion: v1
+kind: onapNetwork
+metadata:
+  name: $unprotected_private_net
+  cnitype : ovn4nfvk8s
+spec:
+  name: $unprotected_private_net
+  subnet: $protected_private_net_cidr
+  gateway: 192.168.10.1/24
 NET
 
     cat << NET > $protected_private_net.yaml
-apiVersion: "k8s.cni.cncf.io/v1"
-kind: NetworkAttachmentDefinition
+apiVersion: v1
+kind: onapNetwork
 metadata:
   name: $protected_private_net
+  cnitype : ovn4nfvk8s
 spec:
-  config: '{
-    "name": "protected",
-    "type": "bridge",
-    "ipam": {
-        "type": "host-local",
-        "subnet": "$protected_net_cidr"
-    }
-}'
+  name: $protected_private_net
+  subnet: $protected_net_cidr
+  gateway: $protected_net_gw/24
 NET
 
     cat << NET > $onap_private_net.yaml
-apiVersion: "k8s.cni.cncf.io/v1"
-kind: NetworkAttachmentDefinition
+apiVersion: v1
+kind: onapNetwork
 metadata:
   name: $onap_private_net
+  cnitype : ovn4nfvk8s
 spec:
-  config: '{
-    "name": "onap",
-    "type": "bridge",
-    "ipam": {
-        "type": "host-local",
-        "subnet": "$onap_private_net_cidr"
-    }
-}'
+  name: $onap_private_net
+  subnet: $onap_private_net_cidr
+  gateway: 10.10.0.1/16
 NET
 
     proxy="apt:"
@@ -370,9 +375,10 @@ spec:
         VirtletSSHKeys: |
           $ssh_key
         VirtletRootVolumeSize: 5Gi
-        k8s.v1.cni.cncf.io/networks: '[
-            { "name": "$unprotected_private_net", "interfaceRequest": "eth1" },
-            { "name": "$onap_private_net", "interfaceRequest": "eth2" }
+        k8s.v1.cni.cncf.io/networks: '[{ "name": "$ovn_multus_network_name"}]'
+        ovnNetwork: '[
+            { "name": "$unprotected_private_net", "ipAddress": "$vpg_private_ip_0", "interface": "eth1" , "defaultGateway": "false"},
+            { "name": "$onap_private_net", "ipAddress": "$vpg_private_ip_1", "interface": "eth2" , "defaultGateway": "false"}
         ]'
         kubernetes.io/target-runtime: virtlet.cloud
     spec:
@@ -437,10 +443,11 @@ spec:
         VirtletSSHKeys: |
           $ssh_key
         VirtletRootVolumeSize: 5Gi
-        k8s.v1.cni.cncf.io/networks: '[
-            { "name": "$unprotected_private_net", "interfaceRequest": "eth1" },
-            { "name": "$protected_private_net", "interfaceRequest": "eth2" },
-            { "name": "$onap_private_net", "interfaceRequest": "eth3" }
+        k8s.v1.cni.cncf.io/networks: '[{ "name": "$ovn_multus_network_name"}]'
+        ovnNetwork: '[
+            { "name": "$unprotected_private_net", "ipAddress": "$vfw_private_ip_0", "interface": "eth1" , "defaultGateway": "false"},
+            { "name": "$protected_private_net", "ipAddress": "$vfw_private_ip_1", "interface": "eth2", "defaultGateway": "false" },
+            { "name": "$onap_private_net", "ipAddress": "$vfw_private_ip_2", "interface": "eth3" , "defaultGateway": "false"}
         ]'
         kubernetes.io/target-runtime: virtlet.cloud
     spec:
@@ -483,9 +490,10 @@ spec:
         app: vFirewall
         context: darkstat
       annotations:
-        k8s.v1.cni.cncf.io/networks: '[
-            { "name": "$protected_private_net", "interfaceRequest": "eth1" },
-            { "name": "$onap_private_net", "interfaceRequest": "eth2" }
+        k8s.v1.cni.cncf.io/networks: '[{ "name": "$ovn_multus_network_name"}]'
+        ovnNetwork: '[
+            { "name": "$protected_private_net", "ipAddress": "$vsn_private_ip_0", "interface": "eth1", "defaultGateway": "false" },
+            { "name": "$onap_private_net", "ipAddress": "$vsn_private_ip_1", "interface": "eth2" , "defaultGateway": "false"}
         ]'
     spec:
       containers:
@@ -1001,3 +1009,88 @@ SERVICE
     popd
 }
 
+# populate_CSAR_ovn4nfv() - Create content used for OVN4NFV functional test
+function populate_CSAR_ovn4nfv {
+    local csar_id=$1
+
+    _checks_args $csar_id
+    pushd ${CSAR_DIR}/${csar_id}
+
+    cat << META > metadata.yaml
+resources:
+  onap_network:
+    - ovn-port-net.yaml
+    - ovn-priv-net.yaml
+  network:
+    - onap-ovn4nfvk8s-network.yaml
+  deployment:
+    - $ovn4nfv_deployment_name.yaml
+META
+
+    cat << MULTUS_NET > onap-ovn4nfvk8s-network.yaml
+apiVersion: "k8s.cni.cncf.io/v1"
+kind: NetworkAttachmentDefinition
+metadata:
+  name: $ovn_multus_network_name
+spec:
+  config: '{
+      "cniVersion": "0.3.1",
+      "name": "ovn4nfv-k8s-plugin",
+      "type": "ovn4nfvk8s-cni"
+    }'
+MULTUS_NET
+
+    cat << NETWORK > ovn-port-net.yaml
+apiVersion: v1
+kind: onapNetwork
+metadata:
+  name: ovn-port-net
+  cnitype : ovn4nfvk8s
+spec:
+  name: ovn-port-net
+  subnet: 172.16.33.0/24
+  gateway: 172.16.33.1/24
+NETWORK
+
+    cat << NETWORK > ovn-priv-net.yaml
+apiVersion: v1
+kind: onapNetwork
+metadata:
+  name: ovn-priv-net
+  cnitype : ovn4nfvk8s
+spec:
+  name: ovn-priv-net
+  subnet: 172.16.44.0/24
+  gateway: 172.16.44.1/24
+NETWORK
+
+    cat << DEPLOYMENT > $ovn4nfv_deployment_name.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: $ovn4nfv_deployment_name
+  labels:
+    app: ovn4nfv
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: ovn4nfv
+  template:
+    metadata:
+      labels:
+        app: ovn4nfv
+      annotations:
+        k8s.v1.cni.cncf.io/networks: '[{ "name": "$ovn_multus_network_name"}]'
+        ovnNetwork: '[{ "name": "ovn-port-net", "interface": "net0" , "defaultGateway": "false"},
+                      { "name": "ovn-priv-net", "interface": "net1" , "defaultGateway": "false"}]'
+    spec:
+      containers:
+      - name: $ovn4nfv_deployment_name
+        image: "busybox"
+        command: ["top"]
+        stdin: true
+        tty: true
+DEPLOYMENT
+    popd
+}
index e3d88eb..fe69b07 100755 (executable)
@@ -12,6 +12,66 @@ set -o errexit
 set -o nounset
 set -o pipefail
 
+function _get_ovn_central_address {
+    ansible_ifconfig=$(ansible ovn-central[0] -i $test_folder/../inventory/hosts.ini -m shell -a "ifconfig eth1 |grep \"inet addr\" |awk '{print \$2}' |awk -F: '{print \$2}'")
+    if [[ $ansible_ifconfig != *CHANGED* ]]; then
+        echo "Fail to get the OVN central IP address from eth1 nic"
+        exit
+    fi
+    echo "$(echo ${ansible_ifconfig#*>>} | tr '\n' ':')6641"
+}
+
+# install_ovn_deps() - Install dependencies required for tests that require OVN
+function install_ovn_deps {
+    if ! $(yq --version &>/dev/null); then
+        sudo -E pip install yq
+    fi
+    if ! $(ovn-nbctl --version &>/dev/null); then
+        source /etc/os-release || source /usr/lib/os-release
+        case ${ID,,} in
+            *suse)
+            ;;
+            ubuntu|debian)
+                sudo apt-get install -y apt-transport-https
+                echo "deb https://packages.wand.net.nz $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/wand.list
+                sudo curl https://packages.wand.net.nz/keyring.gpg -o /etc/apt/trusted.gpg.d/wand.gpg
+                sudo apt-get update
+                sudo apt install -y ovn-common
+            ;;
+            rhel|centos|fedora)
+            ;;
+        esac
+    fi
+}
+
+# init_network() - This function creates the OVN resouces required by the test
+function init_network {
+    local fname=$1
+    local router_name="ovn4nfv-master"
+
+    name=$(cat $fname | yq '.spec.name' | xargs)
+    subnet=$(cat $fname  | yq '.spec.subnet' | xargs)
+    gateway=$(cat $fname  | yq '.spec.gateway' | xargs)
+    ovn_central_address=$(_get_ovn_central_address)
+
+    router_mac=$(printf '00:00:00:%02X:%02X:%02X' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))
+    ovn-nbctl --may-exist --db tcp:$ovn_central_address ls-add $name -- set logical_switch $name other-config:subnet=$subnet external-ids:gateway_ip=$gateway
+    ovn-nbctl --may-exist --db tcp:$ovn_central_address lrp-add $router_name rtos-$name $router_mac $gateway
+    ovn-nbctl --may-exist --db tcp:$ovn_central_address lsp-add $name stor-$name -- set logical_switch_port stor-$name type=router options:router-port=rtos-$name addresses=\"$router_mac\"
+}
+
+# cleanup_network() - This function removes the OVN resources created for the test
+function cleanup_network {
+    local fname=$1
+
+    name=$(cat $fname | yq '.spec.name' | xargs)
+    ovn_central_address=$(_get_ovn_central_address)
+
+    for cmd in "ls-del $name" "lrp-del rtos-$name" "lsp-del stor-$name"; do
+        ovn-nbctl --if-exist --db tcp:$ovn_central_address $cmd
+    done
+}
+
 function _checks_args {
     if [[ -z $1 ]]; then
         echo "Missing CSAR ID argument"
index 93e7596..15cffcb 100755 (executable)
@@ -18,13 +18,19 @@ source _functions.sh
 csar_id=aa443e7e-c8ba-11e8-8877-525400b164ff
 
 # Setup
+install_ovn_deps
 if [[ ! -f $HOME/.ssh/id_rsa.pub ]]; then
     echo -e "\n\n\n" | ssh-keygen -t rsa -N ""
 fi
 populate_CSAR_vms_containers_vFW $csar_id
 
 pushd ${CSAR_DIR}/${csar_id}
-for resource in $unprotected_private_net $protected_private_net $onap_private_net sink-service; do
+for net in $unprotected_private_net $protected_private_net $onap_private_net; do
+    cleanup_network $net.yaml
+    echo "Create OVN Network $net network"
+    init_network $net.yaml
+done
+for resource in onap-ovn4nfvk8s-network sink-service; do
     kubectl apply -f $resource.yaml
 done
 setup $packetgen_deployment_name $firewall_deployment_name $sink_deployment_name
@@ -43,4 +49,7 @@ done
 
 # Teardown
 #teardown $packetgen_deployment_name $firewall_deployment_name $sink_deployment_name
+#for net in $unprotected_private_net $protected_private_net $onap_private_net; do
+#    cleanup_network $net.yaml
+#done
 popd
diff --git a/vagrant/tests/ovn4nfv.sh b/vagrant/tests/ovn4nfv.sh
new file mode 100755 (executable)
index 0000000..37fddfd
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2018
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+source _common.sh
+source _functions.sh
+
+csar_id=a1c5b53e-d7ab-11e8-85b7-525400e8c29a
+
+# Setup
+install_ovn_deps
+populate_CSAR_ovn4nfv $csar_id
+
+pushd ${CSAR_DIR}/${csar_id}
+for net in ovn-priv-net ovn-port-net; do
+    cleanup_network $net.yaml
+    echo "Create OVN Network $net network"
+    init_network $net.yaml
+done
+kubectl apply -f onap-ovn4nfvk8s-network.yaml
+setup $ovn4nfv_deployment_name
+
+# Test
+deployment_pod=$(kubectl get pods | grep  $ovn4nfv_deployment_name | awk '{print $1}')
+echo "===== $deployment_pod details ====="
+kubectl exec -it $deployment_pod -- ip a
+multus_nic=$(kubectl exec -it $deployment_pod -- ifconfig | grep "net1")
+if [ -z "$multus_nic" ]; then
+    echo "The $deployment_pod pod doesn't contain the net1 nic"
+    exit 1
+fi
+
+# Teardown
+teardown $ovn4nfv_deployment_name
+cleanup_network ovn-priv-net.yaml
+cleanup_network ovn-port-net.yaml
+popd