aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com>2020-03-17 05:32:22 +0000
committerKuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com>2020-09-17 16:24:55 -0700
commit62079e3b34f2f7ce7f04dc42e305c32bb719bd57 (patch)
treed1b39c0dccaf863fee4052c3bd4ae4e02836a0c4
parent342d8470b54ca175756d0216c9f5294fd69746ec (diff)
adding primary network features
- adding docker build bugfixes - Removing the dependence on Multus - ovn4nfv-k8s CNI will be default or cluster networking - ovn4nfv-k8s creates ovn overlay mutli-networking using pod annotations itself - remove the outdated unit test Based on the Ritu(ovn4nfv-k8s-plugin committer) patches Change-Id: Ic48bd11d746e6339075fb3ba33f12463bb3f218d Co-authored-by: Ritu Sood <ritu.sood@intel.com> Signed-off-by: Kuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com> Change-Id: I9702bbd2d4aa23157052258ef6b363bc7b472a63
-rw-r--r--cmd/ovn4nfvk8s-cni/app/helper_linux.go23
-rw-r--r--cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go5
-rw-r--r--cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go126
-rw-r--r--deploy/ovn4nfv-k8s-plugin-daemonset.yml571
-rw-r--r--go.sum2
-rw-r--r--internal/pkg/ovn/common.go53
-rw-r--r--internal/pkg/ovn/ovn.go146
-rw-r--r--internal/pkg/ovn/ovn_test.go180
-rw-r--r--internal/pkg/ovn/utils.go8
-rw-r--r--pkg/controller/pod/pod_controller.go31
10 files changed, 740 insertions, 405 deletions
diff --git a/cmd/ovn4nfvk8s-cni/app/helper_linux.go b/cmd/ovn4nfvk8s-cni/app/helper_linux.go
index 676901e..2dba628 100644
--- a/cmd/ovn4nfvk8s-cni/app/helper_linux.go
+++ b/cmd/ovn4nfvk8s-cni/app/helper_linux.go
@@ -6,7 +6,7 @@ import (
"fmt"
"net"
"os/exec"
- "regexp"
+ "strconv"
"strings"
"github.com/sirupsen/logrus"
@@ -37,7 +37,7 @@ func renameLink(curName, newName string) error {
return nil
}
-func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress, gatewayIP, defaultGateway string, mtu int) (*current.Interface, *current.Interface, error) {
+func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress, gatewayIP, defaultGateway string, idx, mtu int) (*current.Interface, *current.Interface, error) {
hostIface := &current.Interface{}
contIface := &current.Interface{}
@@ -97,9 +97,7 @@ func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress,
}
// rename the host end of veth pair
- re := regexp.MustCompile("(\\d+)\\D*\\z")
- index := re.FindAllString(ifName, -1)
- hostIface.Name = containerID[:14] + index[0]
+ hostIface.Name = containerID[:14] + strconv.Itoa(idx)
if err := renameLink(oldHostVethName, hostIface.Name); err != nil {
return nil, nil, fmt.Errorf("failed to rename %s to %s: %v", oldHostVethName, hostIface.Name, err)
}
@@ -108,21 +106,24 @@ func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress,
}
// ConfigureInterface sets up the container interface
-var ConfigureInterface = func(args *skel.CmdArgs, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway string, mtu int) ([]*current.Interface, error) {
+var ConfigureInterface = func(args *skel.CmdArgs, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway string, idx, mtu int) ([]*current.Interface, error) {
netns, err := ns.GetNS(args.Netns)
if err != nil {
return nil, fmt.Errorf("failed to open netns %q: %v", args.Netns, err)
}
defer netns.Close()
- hostIface, contIface, err := setupInterface(netns, args.ContainerID, interfaceName, macAddress, ipAddress, gatewayIP, defaultGateway, mtu)
- if err != nil {
- return nil, err
- }
+
var ifaceID string
- if interfaceName != "" {
+ if interfaceName != "*" {
ifaceID = fmt.Sprintf("%s_%s_%s", namespace, podName, interfaceName)
} else {
ifaceID = fmt.Sprintf("%s_%s", namespace, podName)
+ interfaceName = args.IfName
+ defaultGateway = "true"
+ }
+ hostIface, contIface, err := setupInterface(netns, args.ContainerID, interfaceName, macAddress, ipAddress, gatewayIP, defaultGateway, idx, mtu)
+ if err != nil {
+ return nil, err
}
ovsArgs := []string{
diff --git a/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go b/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go
index 2585fcf..c176700 100644
--- a/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go
+++ b/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni.go
@@ -142,8 +142,7 @@ func addMultipleInterfaces(args *skel.CmdArgs, ovnAnnotation, namespace, podName
logrus.Errorf("addMultipleInterfaces: interface can't be null")
return nil
}
- logrus.Debugf("addMultipleInterfaces: ipAddress %v %v", ipAddress, interfaceName)
- interfacesArray, err = app.ConfigureInterface(args, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway, config.Default.MTU)
+ interfacesArray, err = app.ConfigureInterface(args, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway, index, config.Default.MTU)
if err != nil {
logrus.Errorf("Failed to configure interface in pod: %v", err)
return nil
@@ -318,7 +317,7 @@ func cmdDel(args *skel.CmdArgs) error {
}
func main() {
- logrus.Infof("ovn4nfvk8s-cni CNI Invoked by Multus")
+ logrus.Infof("ovn4nfvk8s-cni invoked")
c := cli.NewApp()
c.Name = "ovn4nfvk8s-cni"
c.Usage = "a CNI plugin to set up or tear down a additional interfaces with OVN"
diff --git a/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go b/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go
deleted file mode 100644
index 16296e3..0000000
--- a/cmd/ovn4nfvk8s-cni/ovn4nfvk8s-cni_test.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// +build linux
-
-package main
-
-import (
- "encoding/json"
-
- "github.com/containernetworking/cni/pkg/skel"
- "github.com/containernetworking/cni/pkg/types"
- "github.com/containernetworking/cni/pkg/types/current"
- "net"
- "ovn4nfv-k8s-plugin/cmd/ovn4nfvk8s-cni/app"
- "reflect"
- "testing"
-)
-
-func TestAddMultipleInterfaces(t *testing.T) {
- oldConfigureInterface := app.ConfigureInterface
- // as we are exiting, revert ConfigureInterface back at end of function
- defer func() { app.ConfigureInterface = oldConfigureInterface }()
- app.ConfigureInterface = func(args *skel.CmdArgs, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway string, mtu int) ([]*current.Interface, error) {
- return []*current.Interface{
- {
- Name: "pod",
- Mac: "0a:00:00:00:00:0c",
- Sandbox: "102103104",
- }}, nil
- }
- oldConfigureRoute := app.ConfigureRoute
- defer func() { app.ConfigureRoute = oldConfigureRoute }()
- app.ConfigureRoute = func(args *skel.CmdArgs, dst, gw, dev string) error {
- return nil
- }
-
- args := &skel.CmdArgs{"102103104", "default", "eth0", "", "", nil}
- ovnAnnotation := "[{\"ip_address\":\"172.16.24.2/24\", \"mac_address\":\"0a:00:00:00:00:0c\", \"gateway_ip\": \"172.16.24.1\",\"interface\":\"net0\"}] "
- result := addMultipleInterfaces(args, ovnAnnotation, "default", "pod")
- if result == nil {
- t.Errorf("Failed addMultipleInterfaces %+v", ovnAnnotation)
- }
- resultSave := result
- ovnAnnotation = "[{\"ip_address\":\"172.16.24.2/24\", \"mac_address\":\"0a:00:00:00:00:0c\", \"gateway_ip\": \"172.16.24.1\",\"defaultGateway\":\"true\",\"interface\":\"net0\"}] "
- result = addMultipleInterfaces(args, ovnAnnotation, "default", "pod")
- if result == nil {
- t.Errorf("Failed addMultipleInterfaces %+v", ovnAnnotation)
- }
- ovnAnnotation = "[{\"ip_address\":\"172.16.24.2/24\", \"mac_address\":\"0a:00:00:00:00:0c\", \"gateway_ip\": \"172.16.24.1\"}] "
- result = addMultipleInterfaces(args, ovnAnnotation, "default", "pod")
- if result != nil {
- t.Errorf("Failed addMultipleInterfaces %+v", ovnAnnotation)
- }
- ovnAnnotation = "[{\"mac_address\":\"0a:00:00:00:00:0c\", \"gateway_ip\": \"172.16.24.1\",\"interface\":\"net0\"}] "
- result = addMultipleInterfaces(args, ovnAnnotation, "default", "pod")
- if result != nil {
- t.Errorf("Failed addMultipleInterfaces %+v", ovnAnnotation)
- }
- ovnAnnotation = "[{\"ip_address\":\"172.16.24.2/24\", \"mac_address\":\"0a:00:00:00:00:0c\", \"gateway_ip\": \"172.16.24.1\",\"interface\":\"net0\"}, {\"ip_address\":\"172.16.25.2/24\", \"mac_address\":\"0a:00:00:00:00:0d\", \"gateway_ip\": \"172.16.25.1\",\"interface\":\"net1\"}]"
- result = addMultipleInterfaces(args, ovnAnnotation, "default", "pod")
- if result == nil {
- t.Errorf("Failed addMultipleInterfaces %+v", ovnAnnotation)
- }
- ovnAnnotation = "[{\"ip_address\":\"172.16.24.2/24\", \"mac_address\":\"0a:00:00:00:00:0c\", \"gateway_ip\": \"172.16.24.1\",\"interface\":\"net0\", \"defaultGateway\":\"true\"}, {\"ip_address\":\"172.16.25.2/24\", \"mac_address\":\"0a:00:00:00:00:0d\", \"gateway_ip\": \"172.16.25.1\",\"interface\":\"net1\"}]"
- result = addMultipleInterfaces(args, ovnAnnotation, "default", "pod")
- if result == nil {
- t.Errorf("Failed addMultipleInterfaces %+v", ovnAnnotation)
- }
- // Test add route feature
- ovnRoutesAnnotation := "[{ \"dst\": \"172.16.29.0/24\", \"gw\": \"172.16.24.1\", \"dev\": \"eth0\" }]"
- result = addRoutes(args, ovnRoutesAnnotation, resultSave)
- if result == nil {
- t.Errorf("Failed addRoutes %+v", ovnRoutesAnnotation)
- }
-
- ovnRoutesAnnotation = "[{ \"dst\": \"172.16.30.0/24\", \"gw\": \"172.16.25.1\", \"dev\": \"eth0\"}, { \"dst\": \"172.16.31.0/24\", \"gw\": \"172.16.26.1\", \"dev\": \"eth1\" }]"
- result = addRoutes(args, ovnRoutesAnnotation, resultSave)
- if result == nil {
- t.Errorf("Failed addRoutes %+v", ovnRoutesAnnotation)
- }
- newResult, err := current.NewResultFromResult(result)
- if err != nil {
- t.Errorf("Failed addMultipleInterfaces %+v", newResult)
- }
- addr1, addrNet1, _ := net.ParseCIDR("172.16.24.2/24")
- addr2, addrNet2, _ := net.ParseCIDR("172.16.29.0/24")
- addr3, addrNet3, _ := net.ParseCIDR("172.16.30.0/24")
- addr4, addrNet4, _ := net.ParseCIDR("172.16.31.0/24")
- expectedResult := &current.Result{
- CNIVersion: "0.3.1",
- Interfaces: []*current.Interface{
- {
- Name: "pod",
- Mac: "0a:00:00:00:00:0c",
- Sandbox: "102103104",
- },
- },
- IPs: []*current.IPConfig{
- {
- Version: "4",
- Interface: current.Int(1),
- Address: net.IPNet{IP: addr1, Mask: addrNet1.Mask},
- Gateway: net.ParseIP("172.16.24.1"),
- },
- },
- Routes: []*types.Route{
- {
- Dst: net.IPNet{IP: addr2, Mask: addrNet2.Mask},
- GW: net.ParseIP("172.16.24.1"),
- },
- {
- Dst: net.IPNet{IP: addr3, Mask: addrNet3.Mask},
- GW: net.ParseIP("172.16.25.1"),
- },
- {
- Dst: net.IPNet{IP: addr4, Mask: addrNet4.Mask},
- GW: net.ParseIP("172.16.26.1"),
- },
- },
- DNS: types.DNS{},
- }
- jsonBytes1, err := json.Marshal(newResult.Routes)
- jsonBytes2, err := json.Marshal(expectedResult.Routes)
- if !reflect.DeepEqual(jsonBytes1, jsonBytes2) {
- t.Errorf("Routes are not correct")
- }
-
-}
diff --git a/deploy/ovn4nfv-k8s-plugin-daemonset.yml b/deploy/ovn4nfv-k8s-plugin-daemonset.yml
new file mode 100644
index 0000000..13e749f
--- /dev/null
+++ b/deploy/ovn4nfv-k8s-plugin-daemonset.yml
@@ -0,0 +1,571 @@
+
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: networks.k8s.plugin.opnfv.org
+spec:
+ group: k8s.plugin.opnfv.org
+ names:
+ kind: Network
+ listKind: NetworkList
+ plural: networks
+ singular: network
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ cniType:
+ description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ Important: Run "operator-sdk generate k8s" to regenerate code after
+ modifying this file Add custom validation using kubebuilder tags:
+ https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
+ type: string
+ dns:
+ properties:
+ domain:
+ type: string
+ nameservers:
+ items:
+ type: string
+ type: array
+ options:
+ items:
+ type: string
+ type: array
+ search:
+ items:
+ type: string
+ type: array
+ type: object
+ ipv4Subnets:
+ items:
+ properties:
+ excludeIps:
+ type: string
+ gateway:
+ type: string
+ name:
+ type: string
+ subnet:
+ type: string
+ required:
+ - name
+ - subnet
+ type: object
+ type: array
+ ipv6Subnets:
+ items:
+ properties:
+ excludeIps:
+ type: string
+ gateway:
+ type: string
+ name:
+ type: string
+ subnet:
+ type: string
+ required:
+ - name
+ - subnet
+ type: object
+ type: array
+ routes:
+ items:
+ properties:
+ dst:
+ type: string
+ gw:
+ type: string
+ required:
+ - dst
+ type: object
+ type: array
+ required:
+ - cniType
+ - ipv4Subnets
+ type: object
+ status:
+ properties:
+ state:
+ description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
+ of cluster Important: Run "operator-sdk generate k8s" to regenerate
+ code after modifying this file Add custom validation using kubebuilder
+ tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
+ type: string
+ required:
+ - state
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: providernetworks.k8s.plugin.opnfv.org
+spec:
+ group: k8s.plugin.opnfv.org
+ names:
+ kind: ProviderNetwork
+ listKind: ProviderNetworkList
+ plural: providernetworks
+ singular: providernetwork
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ description: ProviderNetwork is the Schema for the providernetworks API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: ProviderNetworkSpec defines the desired state of ProviderNetwork
+ properties:
+ cniType:
+ description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ Important: Run "operator-sdk generate k8s" to regenerate code after
+ modifying this file Add custom validation using kubebuilder tags:
+ https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
+ type: string
+ direct:
+ properties:
+ directNodeSelector:
+ type: string
+ nodeLabelList:
+ items:
+ type: string
+ type: array
+ providerInterfaceName:
+ type: string
+ required:
+ - directNodeSelector
+ - providerInterfaceName
+ type: object
+ dns:
+ properties:
+ domain:
+ type: string
+ nameservers:
+ items:
+ type: string
+ type: array
+ options:
+ items:
+ type: string
+ type: array
+ search:
+ items:
+ type: string
+ type: array
+ type: object
+ ipv4Subnets:
+ items:
+ properties:
+ excludeIps:
+ type: string
+ gateway:
+ type: string
+ name:
+ type: string
+ subnet:
+ type: string
+ required:
+ - name
+ - subnet
+ type: object
+ type: array
+ ipv6Subnets:
+ items:
+ properties:
+ excludeIps:
+ type: string
+ gateway:
+ type: string
+ name:
+ type: string
+ subnet:
+ type: string
+ required:
+ - name
+ - subnet
+ type: object
+ type: array
+ providerNetType:
+ type: string
+ routes:
+ items:
+ properties:
+ dst:
+ type: string
+ gw:
+ type: string
+ required:
+ - dst
+ type: object
+ type: array
+ vlan:
+ properties:
+ logicalInterfaceName:
+ type: string
+ nodeLabelList:
+ items:
+ type: string
+ type: array
+ providerInterfaceName:
+ type: string
+ vlanId:
+ type: string
+ vlanNodeSelector:
+ type: string
+ required:
+ - providerInterfaceName
+ - vlanId
+ - vlanNodeSelector
+ type: object
+ required:
+ - cniType
+ - ipv4Subnets
+ - providerNetType
+ type: object
+ status:
+ description: ProviderNetworkStatus defines the observed state of ProviderNetwork
+ properties:
+ state:
+ description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
+ of cluster Important: Run "operator-sdk generate k8s" to regenerate
+ code after modifying this file Add custom validation using kubebuilder
+ tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
+ type: string
+ required:
+ - state
+ type: object
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+---
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: k8s-nfn-sa
+ namespace: operator
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ creationTimestamp: null
+ name: k8s-nfn-cr
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - pods
+ - services
+ - endpoints
+ - persistentvolumeclaims
+ - events
+ - configmaps
+ - secrets
+ - nodes
+ verbs:
+ - '*'
+- apiGroups:
+ - apps
+ resources:
+ - deployments
+ - daemonsets
+ - replicasets
+ - statefulsets
+ verbs:
+ - '*'
+- apiGroups:
+ - monitoring.coreos.com
+ resources:
+ - servicemonitors
+ verbs:
+ - get
+ - create
+- apiGroups:
+ - apps
+ resourceNames:
+ - nfn-operator
+ resources:
+ - deployments/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - k8s.plugin.opnfv.org
+ resources:
+ - '*'
+ - providernetworks
+ verbs:
+ - '*'
+
+---
+
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: k8s-nfn-crb
+subjects:
+- kind: Group
+ name: system:serviceaccounts
+ apiGroup: rbac.authorization.k8s.io
+roleRef:
+ kind: ClusterRole
+ name: k8s-nfn-cr
+ apiGroup: rbac.authorization.k8s.io
+
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: nfn-operator
+ namespace: operator
+spec:
+ type: NodePort
+ ports:
+ - port: 50000
+ protocol: TCP
+ targetPort: 50000
+ selector:
+ name: nfn-operator
+
+
+---
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: ovn-controller-network
+ namespace: operator
+data:
+ OVN_SUBNET: "10.244.64.0/18"
+ OVN_GATEWAYIP: "10.244.64.20/18"
+ OVN_EXCLUDEIPS: "10.244.64.0..10.244.64.16"
+
+
+---
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: nfn-operator
+ namespace: operator
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ name: nfn-operator
+ template:
+ metadata:
+ labels:
+ name: nfn-operator
+ spec:
+ hostNetwork: true
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: nfnType
+ operator: In
+ values:
+ - operator
+ tolerations:
+ - key: "node-role.kubernetes.io/master"
+ effect: "NoSchedule"
+ operator: "Exists"
+ serviceAccountName: k8s-nfn-sa
+ containers:
+ - name: nfn-operator
+ image: integratedcloudnative/ovn4nfv-k8s-plugin:master
+ command: ["/usr/local/bin/entrypoint", "operator"]
+ imagePullPolicy: IfNotPresent
+ envFrom:
+ - configMapRef:
+ name: ovn-controller-network
+ ports:
+ - containerPort: 50000
+ protocol: TCP
+ env:
+ - name: HOST_IP
+ valueFrom:
+ fieldRef:
+ fieldPath: status.hostIP
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: OPERATOR_NAME
+ value: "nfn-operator"
+
+---
+kind: ConfigMap
+apiVersion: v1
+metadata:
+ name: ovn4nfv-cni-config
+ namespace: operator
+ labels:
+ app: ovn4nfv
+data:
+ ovn4nfv_k8s.conf: |
+ [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
+
+---
+apiVersion: extensions/v1beta1
+kind: DaemonSet
+metadata:
+ name: ovn4nfv-cni
+ namespace: operator
+ labels:
+ app: ovn4nfv
+spec:
+ updateStrategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: ovn4nfv
+ spec:
+ hostNetwork: true
+ nodeSelector:
+ beta.kubernetes.io/arch: amd64
+ tolerations:
+ - operator: Exists
+ effect: NoSchedule
+ containers:
+ - name: ovn4nfv
+ image: integratedcloudnative/ovn4nfv-k8s-plugin:master
+ command: ["/usr/local/bin/entrypoint", "cni"]
+ resources:
+ requests:
+ cpu: "100m"
+ memory: "50Mi"
+ limits:
+ cpu: "100m"
+ memory: "50Mi"
+ securityContext:
+ privileged: true
+ volumeMounts:
+ - name: cnibin
+ mountPath: /host/opt/cni/bin
+ - name: cniconf
+ mountPath: /host/etc/openvswitch
+ - name: ovn4nfv-cfg
+ mountPath: /tmp/ovn4nfv-conf
+ volumes:
+ - name: cnibin
+ hostPath:
+ path: /opt/cni/bin
+ - name: cniconf
+ hostPath:
+ path: /etc/openvswitch
+ - name: ovn4nfv-cfg
+ configMap:
+ name: ovn4nfv-cni-config
+ items:
+ - key: ovn4nfv_k8s.conf
+ path: ovn4nfv_k8s.conf
+
+---
+apiVersion: extensions/v1beta1
+kind: DaemonSet
+metadata:
+ name: nfn-agent
+ namespace: operator
+ labels:
+ app: nfn-agent
+spec:
+ updateStrategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: nfn-agent
+ spec:
+ hostNetwork: true
+ nodeSelector:
+ beta.kubernetes.io/arch: amd64
+ tolerations:
+ - operator: Exists
+ effect: NoSchedule
+ containers:
+ - name: nfn-agent
+ image: integratedcloudnative/ovn4nfv-k8s-plugin:master
+ command: ["/usr/local/bin/entrypoint", "agent"]
+ resources:
+ requests:
+ cpu: "100m"
+ memory: "50Mi"
+ limits:
+ cpu: "100m"
+ memory: "50Mi"
+ env:
+ - name: NFN_NODE_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
+ securityContext:
+ privileged: true
+ volumeMounts:
+ - mountPath: /run/openvswitch
+ name: host-run-ovs
+ - mountPath: /var/run/openvswitch
+ name: host-var-run-ovs
+ volumes:
+ - name: host-run-ovs
+ hostPath:
+ path: /run/openvswitch
+ - name: host-var-run-ovs
+ hostPath:
+ path: /var/run/openvswitch
diff --git a/go.sum b/go.sum
index ee74113..fd474b6 100644
--- a/go.sum
+++ b/go.sum
@@ -786,7 +786,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.0.0 h1:OyHbl+7IOECpPKfVK42oFr6N7+Y2dR+Jsb/IiDV3hOo=
+gomodules.xyz/jsonpatch/v2 v2.0.0 h1:lHNQverf0+Gm1TbSbVIDWVXOhZ2FpZopxRqpr2uIjs4=
gomodules.xyz/jsonpatch/v2 v2.0.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
diff --git a/internal/pkg/ovn/common.go b/internal/pkg/ovn/common.go
index a294004..e38c440 100644
--- a/internal/pkg/ovn/common.go
+++ b/internal/pkg/ovn/common.go
@@ -246,6 +246,59 @@ func setupDistributedRouter(name string) error {
return nil
}
+// CreateNetwork in OVN controller
+func createOvnLS(name, subnet, gatewayIP, excludeIps string) (gatewayIPMask string, err error) {
+ var stdout, stderr string
+
+ output, stderr, err := RunOVNNbctl("--data=bare", "--no-heading",
+ "--columns=name", "find", "logical_switch", "name="+name)
+ if err != nil {
+ log.Error(err, "Error in reading logical switch", "stderr", stderr)
+ return
+ }
+
+ if strings.Compare(name, output) == 0 {
+ log.V(1).Info("Logical Switch already exists, delete first to update/recreate", "name", name)
+ return "", fmt.Errorf("LS exists")
+ }
+
+ _, cidr, err := net.ParseCIDR(subnet)
+ if err != nil {
+ log.Error(err, "ovnNetwork '%s' invalid subnet CIDR", "name", name)
+ return
+
+ }
+ firstIP := NextIP(cidr.IP)
+ n, _ := cidr.Mask.Size()
+
+ var gwIP net.IP
+ if gatewayIP != "" {
+ gwIP, _, err = net.ParseCIDR(gatewayIP)
+ if err != nil {
+ // Check if this is a valid IP address
+ gwIP = net.ParseIP(gatewayIP)
+ }
+ }
+ // If no valid Gateway use the first IP address for GatewayIP
+ if gwIP == nil {
+ gatewayIPMask = fmt.Sprintf("%s/%d", firstIP.String(), n)
+ } else {
+ gatewayIPMask = fmt.Sprintf("%s/%d", gwIP.String(), n)
+ }
+
+ // Create a logical switch and set its subnet.
+ if excludeIps != "" {
+ stdout, stderr, err = RunOVNNbctl("--wait=hv", "--", "--may-exist", "ls-add", name, "--", "set", "logical_switch", name, "other-config:subnet="+subnet, "external-ids:gateway_ip="+gatewayIPMask, "other-config:exclude_ips="+excludeIps)
+ } else {
+ stdout, stderr, err = RunOVNNbctl("--wait=hv", "--", "--may-exist", "ls-add", name, "--", "set", "logical_switch", name, "other-config:subnet="+subnet, "external-ids:gateway_ip="+gatewayIPMask)
+ }
+ if err != nil {
+ log.Error(err, "Failed to create a logical switch", "name", name, "stdout", stdout, "stderr", stderr)
+ return
+ }
+ return
+}
+
// generateMac generates mac address.
func generateMac() string {
prefix := "00:00:00"
diff --git a/internal/pkg/ovn/ovn.go b/internal/pkg/ovn/ovn.go
index 6e9cd79..6f7951a 100644
--- a/internal/pkg/ovn/ovn.go
+++ b/internal/pkg/ovn/ovn.go
@@ -6,7 +6,7 @@ import (
kapi "k8s.io/api/core/v1"
kexec "k8s.io/utils/exec"
"math/rand"
- "net"
+ "os"
k8sv1alpha1 "ovn4nfv-k8s-plugin/pkg/apis/k8s/v1alpha1"
"strings"
"time"
@@ -16,12 +16,43 @@ type Controller struct {
gatewayCache map[string]string
}
+type OVNNetworkConf struct {
+ Subnet string
+ GatewayIP string
+ ExcludeIPs string
+}
+
const (
ovn4nfvRouterName = "ovn4nfv-master"
// Ovn4nfvAnnotationTag tag on already processed Pods
Ovn4nfvAnnotationTag = "k8s.plugin.opnfv.org/ovnInterfaces"
+ // OVN Default Network name
+ Ovn4nfvDefaultNw = "ovn4nfvk8s-default-nw"
)
+var ovnConf *OVNNetworkConf
+
+func GetOvnNetConf() error {
+ ovnConf = &OVNNetworkConf{}
+
+ ovnConf.Subnet = os.Getenv("OVN_SUBNET")
+ if ovnConf.Subnet == "" {
+ fmt.Errorf("OVN subnet is not set in nfn-operator configmap env")
+ }
+
+ ovnConf.GatewayIP = os.Getenv("OVN_GATEWAYIP")
+ if ovnConf.GatewayIP == "" {
+ fmt.Errorf("OVN gatewayIP is not set in nfn-operator configmap env")
+ }
+
+ ovnConf.ExcludeIPs = os.Getenv("OVN_EXCLUDEIPS")
+ if ovnConf.ExcludeIPs == "" {
+ fmt.Errorf("OVN excludeIPs is not set in nfn-operator configmap env")
+ }
+
+ return nil
+}
+
type netInterface struct {
Name string
Interface string
@@ -43,10 +74,16 @@ func NewOvnController(exec kexec.Interface) (*Controller, error) {
log.Error(err, "Failed to initialize exec helper")
return nil, err
}
+
+ if err := GetOvnNetConf(); err != nil {
+ log.Error(err, "nfn-operator OVN Network configmap is not set")
+ return nil, err
+ }
if err := SetupOvnUtils(); err != nil {
log.Error(err, "Failed to initialize OVN State")
return nil, err
}
+
ovnCtl = &Controller{
gatewayCache: make(map[string]string),
}
@@ -64,10 +101,6 @@ func GetOvnController() (*Controller, error) {
// AddLogicalPorts adds ports to the Pod
func (oc *Controller) AddLogicalPorts(pod *kapi.Pod, ovnNetObjs []map[string]interface{}) (key, value string) {
- if ovnNetObjs == nil {
- return
- }
-
if pod.Spec.HostNetwork {
return
}
@@ -78,28 +111,38 @@ func (oc *Controller) AddLogicalPorts(pod *kapi.Pod, ovnNetObjs []map[string]int
}
var ovnString, outStr string
+ var defaultInterface bool
+
ovnString = "["
var ns netInterface
for _, net := range ovnNetObjs {
-
err := mapstructure.Decode(net, &ns)
if err != nil {
log.Error(err, "mapstruct error", "network", net)
return
}
-
if !oc.FindLogicalSwitch(ns.Name) {
log.Info("Logical Switch not found")
return
}
- if ns.Interface == "" {
+ if ns.Name == Ovn4nfvDefaultNw {
+ defaultInterface = true
+ }
+ if ns.Interface == "" && ns.Name != Ovn4nfvDefaultNw {
log.Info("Interface name must be provided")
return
}
if ns.DefaultGateway == "" {
ns.DefaultGateway = "false"
}
- outStr = oc.addLogicalPortWithSwitch(pod, ns.Name, ns.IPAddress, ns.MacAddress, ns.Interface, ns.NetType)
+ var portName string
+ if ns.Interface != "" {
+ portName = fmt.Sprintf("%s_%s_%s", pod.Namespace, pod.Name, ns.Interface)
+ } else {
+ portName = fmt.Sprintf("%s_%s", pod.Namespace, pod.Name)
+ ns.Interface = "*"
+ }
+ outStr = oc.addLogicalPortWithSwitch(pod, ns.Name, ns.IPAddress, ns.MacAddress, portName)
if outStr == "" {
return
}
@@ -110,7 +153,21 @@ func (oc *Controller) AddLogicalPorts(pod *kapi.Pod, ovnNetObjs []map[string]int
ovnString += tmpString
ovnString += ","
}
- last := len(ovnString) - 1
+ var last int
+ if defaultInterface == false {
+ // Add Default interface
+ portName := fmt.Sprintf("%s_%s", pod.Namespace, pod.Name)
+ outStr = oc.addLogicalPortWithSwitch(pod, Ovn4nfvDefaultNw, "", "", portName)
+ if outStr == "" {
+ return
+ }
+ last := len(outStr) - 1
+ tmpString := outStr[:last]
+ tmpString += "," + "\\\"interface\\\":" + "\\\"" + "*" + "\\\"}"
+ ovnString += tmpString
+ ovnString += ","
+ }
+ last = len(ovnString) - 1
ovnString = ovnString[:last]
ovnString += "]"
key = Ovn4nfvAnnotationTag
@@ -121,6 +178,7 @@ func (oc *Controller) AddLogicalPorts(pod *kapi.Pod, ovnNetObjs []map[string]int
// DeleteLogicalPorts deletes the OVN ports for the pod
func (oc *Controller) DeleteLogicalPorts(name, namespace string) {
+ log.Info("DeleteLogicalPorts")
logicalPort := fmt.Sprintf("%s_%s", namespace, name)
// get the list of logical ports from OVN
@@ -134,7 +192,7 @@ func (oc *Controller) DeleteLogicalPorts(name, namespace string) {
for _, existingPort := range existingLogicalPorts {
if strings.Contains(existingPort, logicalPort) {
// found, delete this logical port
- log.V(1).Info("Deleting", "Port", existingPort)
+ log.Info("Deleting", "Port", existingPort)
stdout, stderr, err := RunOVNNbctl("--if-exists", "lsp-del",
existingPort)
if err != nil {
@@ -146,59 +204,6 @@ func (oc *Controller) DeleteLogicalPorts(name, namespace string) {
}
// CreateNetwork in OVN controller
-func (oc *Controller) createOvnLS(name, subnet, gatewayIP, excludeIps string) (gatewayIPMask string, err error) {
- var stdout, stderr string
-
- output, stderr, err := RunOVNNbctl("--data=bare", "--no-heading",
- "--columns=name", "find", "logical_switch", "name="+name)
- if err != nil {
- log.Error(err, "Error in reading logical switch", "stderr", stderr)
- return
- }
-
- if strings.Compare(name, output) == 0 {
- log.V(1).Info("Logical Switch already exists, delete first to update/recreate", "name", name)
- return "", fmt.Errorf("LS exists")
- }
-
- _, cidr, err := net.ParseCIDR(subnet)
- if err != nil {
- log.Error(err, "ovnNetwork '%s' invalid subnet CIDR", "name", name)
- return
-
- }
- firstIP := NextIP(cidr.IP)
- n, _ := cidr.Mask.Size()
-
- var gwIP net.IP
- if gatewayIP != "" {
- gwIP, _, err = net.ParseCIDR(gatewayIP)
- if err != nil {
- // Check if this is a valid IP address
- gwIP = net.ParseIP(gatewayIP)
- }
- }
- // If no valid Gateway use the first IP address for GatewayIP
- if gwIP == nil {
- gatewayIPMask = fmt.Sprintf("%s/%d", firstIP.String(), n)
- } else {
- gatewayIPMask = fmt.Sprintf("%s/%d", gwIP.String(), n)
- }
-
- // Create a logical switch and set its subnet.
- if excludeIps != "" {
- stdout, stderr, err = RunOVNNbctl("--wait=hv", "--", "--may-exist", "ls-add", name, "--", "set", "logical_switch", name, "other-config:subnet="+subnet, "external-ids:gateway_ip="+gatewayIPMask, "other-config:exclude_ips="+excludeIps)
- } else {
- stdout, stderr, err = RunOVNNbctl("--wait=hv", "--", "--may-exist", "ls-add", name, "--", "set", "logical_switch", name, "other-config:subnet="+subnet, "external-ids:gateway_ip="+gatewayIPMask)
- }
- if err != nil {
- log.Error(err, "Failed to create a logical switch", "name", name, "stdout", stdout, "stderr", stderr)
- return
- }
- return
-}
-
-// CreateNetwork in OVN controller
func (oc *Controller) CreateNetwork(cr *k8sv1alpha1.Network) error {
var stdout, stderr string
@@ -208,7 +213,7 @@ func (oc *Controller) CreateNetwork(cr *k8sv1alpha1.Network) error {
gatewayIP := cr.Spec.Ipv4Subnets[0].Gateway
excludeIps := cr.Spec.Ipv4Subnets[0].ExcludeIps
- gatewayIPMask, err := oc.createOvnLS(name, subnet, gatewayIP, excludeIps)
+ gatewayIPMask, err := createOvnLS(name, subnet, gatewayIP, excludeIps)
if err != nil {
return err
}
@@ -266,7 +271,7 @@ func (oc *Controller) CreateProviderNetwork(cr *k8sv1alpha1.ProviderNetwork) err
subnet := cr.Spec.Ipv4Subnets[0].Subnet
gatewayIP := cr.Spec.Ipv4Subnets[0].Gateway
excludeIps := cr.Spec.Ipv4Subnets[0].ExcludeIps
- _, err := oc.createOvnLS(name, subnet, gatewayIP, excludeIps)
+ _, err := createOvnLS(name, subnet, gatewayIP, excludeIps)
if err != nil {
return err
}
@@ -339,7 +344,7 @@ func (oc *Controller) getGatewayFromSwitch(logicalSwitch string) (string, string
return gatewayIP, mask, nil
}
-func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipAddress, macAddress, interfaceName, netType string) (annotation string) {
+func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipAddress, macAddress, portName string) (annotation string) {
var out, stderr string
var err error
var isStaticIP bool
@@ -347,13 +352,6 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
return
}
- var portName string
- if interfaceName != "" {
- portName = fmt.Sprintf("%s_%s_%s", pod.Namespace, pod.Name, interfaceName)
- } else {
- return
- }
-
log.V(1).Info("Creating logical port for on switch", "portName", portName, "logicalSwitch", logicalSwitch)
if ipAddress != "" && macAddress != "" {
diff --git a/internal/pkg/ovn/ovn_test.go b/internal/pkg/ovn/ovn_test.go
deleted file mode 100644
index 5ea01d1..0000000
--- a/internal/pkg/ovn/ovn_test.go
+++ /dev/null
@@ -1,180 +0,0 @@
-package ovn
-
-import (
- "fmt"
- "testing"
-
- "github.com/urfave/cli"
- fakeexec "k8s.io/utils/exec/testing"
-
- "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "ovn4nfv-k8s-plugin/internal/pkg/config"
- ovntest "ovn4nfv-k8s-plugin/internal/pkg/testing"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-func TestOvn(t *testing.T) {
- RegisterFailHandler(Fail)
- RunSpecs(t, "OVN/Pod Test Suite")
-}
-
-var _ = AfterSuite(func() {
-})
-
-var _ = Describe("Add logical Port", func() {
- var app *cli.App
-
- BeforeEach(func() {
- app = cli.NewApp()
- app.Name = "test"
- app.Flags = config.Flags
-
- })
-
- It("tests Pod", func() {
- app.Action = func(ctx *cli.Context) error {
- const (
- gwIP string = "10.1.1.1"
- gwCIDR string = gwIP + "/24"
- netName string = "ovn-prot-net"
- portName string = "_ok_net0"
- macIPAddress string = "0a:00:00:00:00:01 192.168.1.3"
- )
- fakeCmds := ovntest.AddFakeCmd(nil, &ovntest.ExpectedCmd{
- Cmd: "ovn-nbctl --timeout=15 --data=bare --no-heading --columns=name find logical_switch " + "name=" + netName,
- Output: netName,
- })
- fakeCmds = ovntest.AddFakeCmdsNoOutputNoError(fakeCmds, []string{
- "ovn-nbctl --timeout=15 --wait=sb -- --may-exist lsp-add " + netName + " " + portName + " -- lsp-set-addresses " + portName + " dynamic -- set logical_switch_port " + portName + " external-ids:namespace= external-ids:logical_switch=" + netName + " external-ids:pod=true",
- })
-
- fakeCmds = ovntest.AddFakeCmd(fakeCmds, &ovntest.ExpectedCmd{
- Cmd: "ovn-nbctl --timeout=15 get logical_switch_port " + portName + " dynamic_addresses",
- Output: macIPAddress,
- })
- fakeCmds = ovntest.AddFakeCmd(fakeCmds, &ovntest.ExpectedCmd{
- Cmd: "ovn-nbctl --timeout=15 --if-exists get logical_switch " + netName + " external_ids:gateway_ip",
- Output: gwCIDR,
- })
-
- fexec := &fakeexec.FakeExec{
- CommandScript: fakeCmds,
- LookPathFunc: func(file string) (string, error) {
- return fmt.Sprintf("/fake-bin/%s", file), nil
- },
- }
- oldSetupOvnUtils := SetupOvnUtils
- // as we are exiting, revert ConfigureInterface back at end of function
- defer func() { SetupOvnUtils = oldSetupOvnUtils }()
- SetupOvnUtils = func() error {
- return nil
- }
- ovnController, err := NewOvnController(fexec)
- Expect(err).NotTo(HaveOccurred())
-
- var (
- okPod = v1.Pod{
- TypeMeta: metav1.TypeMeta{
- Kind: "Pod",
- APIVersion: "v1",
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: "ok",
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Name: "by-name",
- },
- {},
- },
- },
- }
- )
- a := []map[string]interface{}{{"name": "ovn-prot-net", "interface": "net0"}}
- ovnController.AddLogicalPorts(&okPod, a)
- Expect(fexec.CommandCalls).To(Equal(len(fakeCmds)))
-
- return nil
- }
-
- err := app.Run([]string{app.Name})
- Expect(err).NotTo(HaveOccurred())
- })
-
- It("tests Pod provider", func() {
- app.Action = func(ctx *cli.Context) error {
- const (
- gwIP string = "10.1.1.1"
- gwCIDR string = gwIP + "/24"
- netName string = "ovn-prot-net"
- portName string = "_ok_net0"
- macIPAddress string = "0a:00:00:00:00:01 192.168.1.3/24"
- )
- fakeCmds := ovntest.AddFakeCmd(nil, &ovntest.ExpectedCmd{
- Cmd: "ovn-nbctl --timeout=15 --data=bare --no-heading --columns=name find logical_switch " + "name=" + netName,
- Output: netName,
- })
-
- fakeCmds = ovntest.AddFakeCmdsNoOutputNoError(fakeCmds, []string{
- "ovn-nbctl --timeout=15 --may-exist lsp-add " + netName + " " + portName + " -- lsp-set-addresses " + portName + " " + macIPAddress + " -- --if-exists clear logical_switch_port " + portName + " dynamic_addresses" + " -- set logical_switch_port " + portName + " external-ids:namespace= external-ids:logical_switch=" + netName + " external-ids:pod=true",
- })
-
- fakeCmds = ovntest.AddFakeCmd(fakeCmds, &ovntest.ExpectedCmd{
- Cmd: "ovn-nbctl --timeout=15 get logical_switch_port " + portName + " addresses",
- Output: macIPAddress,
- })
-
- fakeCmds = ovntest.AddFakeCmd(fakeCmds, &ovntest.ExpectedCmd{
- Cmd: "ovn-nbctl --timeout=15 --if-exists get logical_switch " + netName + " external_ids:gateway_ip",
- Output: gwCIDR,
- })
-
- fexec := &fakeexec.FakeExec{
- CommandScript: fakeCmds,
- LookPathFunc: func(file string) (string, error) {
- return fmt.Sprintf("/fake-bin/%s", file), nil
- },
- }
- oldSetupOvnUtils := SetupOvnUtils
- // as we are exiting, revert ConfigureInterface back at end of function
- defer func() { SetupOvnUtils = oldSetupOvnUtils }()
- SetupOvnUtils = func() error {
- return nil
- }
- ovnController, err := NewOvnController(fexec)
- Expect(err).NotTo(HaveOccurred())
- var (
- okPod = v1.Pod{
- TypeMeta: metav1.TypeMeta{
- Kind: "Pod",
- APIVersion: "v1",
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: "ok",
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Name: "by-name",
- },
- {},
- },
- },
- }
- )
- a := []map[string]interface{}{{"name": "ovn-prot-net", "interface": "net0", "netType": "provider", "ipAddress": "192.168.1.3/24", "macAddress": "0a:00:00:00:00:01"}}
- ovnController.AddLogicalPorts(&okPod, a)
- Expect(fexec.CommandCalls).To(Equal(len(fakeCmds)))
-
- return nil
- }
-
- err := app.Run([]string{app.Name})
- Expect(err).NotTo(HaveOccurred())
- })
-
-})
diff --git a/internal/pkg/ovn/utils.go b/internal/pkg/ovn/utils.go
index 3b3b53b..9b388b7 100644
--- a/internal/pkg/ovn/utils.go
+++ b/internal/pkg/ovn/utils.go
@@ -5,6 +5,7 @@ import (
"fmt"
kexec "k8s.io/utils/exec"
"os"
+ "reflect"
"strings"
"time"
)
@@ -36,6 +37,13 @@ var SetupOvnUtils = func() error {
log.Error(err, "Failed to initialize OVN Distributed Router")
return err
}
+
+ log.Info("OVN Network", "OVN Default NW", Ovn4nfvDefaultNw, "OVN Subnet", ovnConf.Subnet, "OVN Gateway IP", ovnConf.GatewayIP, "OVN ExcludeIPs", ovnConf.ExcludeIPs)
+ _, err = createOvnLS(Ovn4nfvDefaultNw, ovnConf.Subnet, ovnConf.GatewayIP, ovnConf.ExcludeIPs)
+ if err != nil && !reflect.DeepEqual(err, fmt.Errorf("LS exists")) {
+ log.Error(err, "Failed to create ovn4nfvk8s default nw")
+ return err
+ }
return nil
}
diff --git a/pkg/controller/pod/pod_controller.go b/pkg/controller/pod/pod_controller.go
index 23a847e..75ed731 100644
--- a/pkg/controller/pod/pod_controller.go
+++ b/pkg/controller/pod/pod_controller.go
@@ -31,6 +31,7 @@ type nfnNetwork struct {
Interface []map[string]interface{} "json:\"interface\""
}
+var enableOvnDefaultIntf bool = true
// Add creates a new Pod Controller and adds it to the Manager. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager) error {
@@ -69,19 +70,19 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
CreateFunc: func(e event.CreateEvent) bool {
// The object doesn't contain annotation ,nfnNetworkAnnotation so the event will be
// ignored.
- annotaion := e.Meta.GetAnnotations()
+ /*annotaion := e.Meta.GetAnnotations()
if _, ok := annotaion[nfnNetworkAnnotation]; !ok {
return false
- }
+ }*/
return true
},
DeleteFunc: func(e event.DeleteEvent) bool {
// The object doesn't contain annotation ,nfnNetworkAnnotation so the event will be
// ignored.
- annotaion := e.Meta.GetAnnotations()
+ /*annotaion := e.Meta.GetAnnotations()
if _, ok := annotaion[nfnNetworkAnnotation]; !ok {
return false
- }
+ }*/
return true
},
}
@@ -121,10 +122,9 @@ func (r *ReconcilePod) Reconcile(request reconcile.Request) (reconcile.Result, e
// Request object not found, could have been deleted after reconcile request.
// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
// Return and don't requeue
- if instance.Name == "" || instance.Namespace == "" {
- return reconcile.Result{}, nil
- }
+ reqLogger.Info("Delete Pod", "request", request)
r.deleteLogicalPorts(request.Name, request.Namespace)
+ reqLogger.Info("Exit Reconciling Pod")
return reconcile.Result{}, nil
}
// Error reading the object - requeue the request.
@@ -133,6 +133,10 @@ func (r *ReconcilePod) Reconcile(request reconcile.Request) (reconcile.Result, e
if instance.Name == "" || instance.Namespace == "" {
return reconcile.Result{}, nil
}
+ if instance.Spec.HostNetwork {
+ return reconcile.Result{}, nil
+ }
+
err = r.addLogicalPorts(instance)
if err != nil && err.Error() == "Failed to add ports" {
// Requeue the object
@@ -158,16 +162,22 @@ func (r *ReconcilePod) addLogicalPorts(pod *corev1.Pod) error {
nfn, err := r.readPodAnnotation(pod)
if err != nil {
- return err
+ // No annotation for multiple interfaces
+ nfn = &nfnNetwork {Interface: nil}
+ if enableOvnDefaultIntf == true {
+ nfn.Type = "ovn4nfv"
+ } else {
+ return err
+ }
}
-
+
switch {
case nfn.Type == "ovn4nfv":
ovnCtl, err := ovn.GetOvnController()
if err != nil {
return err
}
- if _, ok := pod.Annotations[ovn.Ovn4nfvAnnotationTag]; ok {
+ if _, ok := pod.Annotations[ovn.Ovn4nfvAnnotationTag]; ok {
return fmt.Errorf("Pod annotation found")
}
key, value := ovnCtl.AddLogicalPorts(pod, nfn.Interface)
@@ -188,6 +198,7 @@ func (r *ReconcilePod) deleteLogicalPorts(name, namesapce string) error {
if err != nil {
return err
}
+ log.Info("Calling DeleteLogicalPorts")
ovnCtl.DeleteLogicalPorts(name, namesapce)
return nil
// Add other types here