Skip to content

Commit

Permalink
Adding unit tests, updating documentation.
Browse files Browse the repository at this point in the history
Added checks for namespace when deciding if a Pod is connected to the network.
For TNs and DNs the EP needs to be in the same namespace as the network to consider it "connected".
For CNs name match is enough, as it is a non-namespaced API.
  • Loading branch information
Levovar committed Aug 6, 2019
1 parent fe5bdbd commit 062bac2
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 110 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,10 @@ Every CREATE, and PUT DanmNet operation is subject to the following validation r
11. spec.NetworkID cannot be longer than 11 characters for dynamic backends
12. spec.AllowedTenants is not a valid parameter for this API type
13. spec.Options.Device_pool must be, and spec.Options.Host_device mustn't be provided for K8s Devices based networks (such as SR-IOV)
14. Any of spec.Options.Device, spec.Options.Vlan, or spec.Options.Vxlan attributes cannot be changed if there are any Pods currently connected to the network

Every DELETE DanmNet operation is subject to the following validation rules:
15. the network cannot be deleted if there are any Pods currently connected to the network

Not complying with any of these rules results in the denial of the provisioning operation.
##### TenantNetwork
Expand All @@ -612,9 +616,14 @@ In addition TenantNetwork provisioning has the following extra rules:
5. spec.Options.Host_device cannot be modified
6. spec.Options.Device_pool cannot be modified

Every DELETE TenantNetwork operation is subject to the DanmNet validation rule no.15.

Not complying with any of these rules results in the denial of the provisioning operation.
##### ClusterNetwork
Every CREATE, and PUT ClusterNetwork operation is subject to the DanmNet validation rules no. 1-11, 13.
Every CREATE, and PUT ClusterNetwork operation is subject to the DanmNet validation rules no. 1-11, 13-14.

Every DELETE ClusterNetwork operation is subject to the DanmNet validation rule no.15.

Not complying with any of these rules results in the denial of the provisioning operation.
##### TenantConfig
Every CREATE, and PUT TenantConfig operation is subject to the following validation rules:
Expand All @@ -631,8 +640,9 @@ It shall be running on all hosts where DANM CNI is the configured CNI plugin.

The netwatcher component is responsible for dynamically managing (i.e. creation and deletion) VxLAN and VLAN interfaces on all the hosts based on the dynamic network management APIs.

Whenever a network is created or deleted -any network, belonging to any of the supported API types- within the Kubernetes cluster, netwatcher will be triggered.
Whenever a network is created, modified, or deleted -any network, belonging to any of the supported API types- within the Kubernetes cluster, netwatcher will be triggered.
If the network in question contained either the "vxlan", or the "vlan" attributes; then netwatcher immediately creates, or deletes the VLAN or VxLAN host interface with the matching VID.
If the Spec.Options.host_device, .vlan, or .vxlan attributes are modified netwatcher first deletes the old, and then creates the new host interface.

This feature is the most beneficial when used together with a dynamic network provisioning backend supporting connecting Pod interfaces to virtual host devices (IPVLAN, MACVLAN, SR-IOV for VLANs). Whenever a Pod is connected to such a network containing a virtual network identifier, the CNI component automatically connects the created interface to the VxLAN or VLAN host interface created by the netwatcher; instead of directly connecting it to the configured host device.
### Usage of DANM's Svcwatcher component
Expand Down
2 changes: 1 addition & 1 deletion pkg/admit/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func validateVniChange(oldManifest, newManifest *danmtypes.DanmNet, opType admis
if opType != admissionv1.Update {
return nil
}
isAnyPodConnectedToNetwork, connectedEp, err := danmep.ArePodsConnectedToNetwork(client, newManifest)
isAnyPodConnectedToNetwork, connectedEp, err := danmep.ArePodsConnectedToNetwork(client, oldManifest)
if err != nil {
return errors.New("no way to tell if Pods are still using the network due to:" + err.Error())
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/danmep/danmep.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ func ArePodsConnectedToNetwork(client danmclientset.Interface, dnet *danmtypes.D
}
eplist := result.Items
for _, ep := range eplist {
if ep.Spec.ApiType == dnet.TypeMeta.Kind && ep.Spec.NetworkName == dnet.ObjectMeta.Name {
if (ep.Spec.ApiType == dnet.TypeMeta.Kind && ep.Spec.NetworkName == dnet.ObjectMeta.Name) &&
(dnet.TypeMeta.Kind == "ClusterNetwork" || ep.ObjectMeta.Namespace == dnet.ObjectMeta.Namespace ) {
return true, ep, nil
}
}
Expand Down
19 changes: 15 additions & 4 deletions test/stubs/danm/epclient_stub.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package danm

import (
"errors"
"strings"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
danmtypes "github.com/nokia/danm/crd/apis/danm/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
)

type EpClientStub struct{
testEps []danmtypes.DanmEp
TestEps []danmtypes.DanmEp
}

func newEpClientStub(eps []danmtypes.DanmEp) EpClientStub {
return EpClientStub{testEps: eps}
return EpClientStub{TestEps: eps}
}

func (epClient EpClientStub) Create(obj *danmtypes.DanmEp) (*danmtypes.DanmEp, error) {
Expand All @@ -32,7 +34,7 @@ func (epClient EpClientStub) DeleteCollection(options *meta_v1.DeleteOptions, li
}

func (epClient EpClientStub) Get(epName string, options meta_v1.GetOptions) (*danmtypes.DanmEp, error) {
for _, testNet := range epClient.testEps {
for _, testNet := range epClient.TestEps {
if testNet.Spec.NetworkName == epName {
return &testNet, nil
}
Expand All @@ -46,7 +48,16 @@ func (epClient EpClientStub) Watch(opts meta_v1.ListOptions) (watch.Interface, e
}

func (epClient EpClientStub) List(opts meta_v1.ListOptions) (*danmtypes.DanmEpList, error) {
return nil, nil
if epClient.TestEps == nil {
return nil, nil
}
for _, ep := range epClient.TestEps {
if strings.HasPrefix(ep.ObjectMeta.Name,"error") {
return nil, errors.New("error happened")
}
}
epList := danmtypes.DanmEpList{Items: epClient.TestEps}
return &epList, nil
}

func (epClient EpClientStub) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *danmtypes.DanmEp, err error) {
Expand Down
Loading

0 comments on commit 062bac2

Please sign in to comment.