func ArePodsConnectedToNetwork(client danmclientset.Interface, dnet *danmtypes.DanmNet)(bool, danmtypes.DanmEp, error) {
  result, err := client.DanmV1().DanmEps("").List(context.TODO(), meta_v1.ListOptions{})
  if err != nil {
    return false, danmtypes.DanmEp{}, errors.New("cannot list DanmEps because:" + err.Error())
  }
  if result == nil {
    return false, danmtypes.DanmEp{}, nil
  }
  eplist := result.Items
  for _, ep := range eplist {
    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
    }
  }
  return false, danmtypes.DanmEp{}, nil
}
ArePodsConnectedToNetwork checks if there are any Pods currently in the system using the particular network.
If there is at least, it returns true, and the spec of the first matching DanmEp.
package danmep
import (
  "context"
  "errors"
  "fmt"
  "net"
  "os"
  "log"
  "runtime"
  "strconv"
  "time"
  "github.com/containernetworking/plugins/pkg/ns"
  "github.com/containernetworking/plugins/pkg/utils/sysctl"
  meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  sriov_utils "github.com/intel/sriov-cni/pkg/utils"
  danmtypes "github.com/nokia/danm/crd/apis/danm/v1"
  danmclientset "github.com/nokia/danm/crd/client/clientset/versioned"
  "github.com/nokia/danm/pkg/datastructs"
  "github.com/nokia/danm/pkg/ipam"
  "github.com/nokia/danm/pkg/netcontrol"
  "github.com/satori/go.uuid"
  "github.com/vishvananda/netlink"
)
type sysctlFunction func(*danmtypes.DanmEp) bool
type sysctlObject struct {
  sysctlName  string
  sysctlValue string
}
type sysctlTask struct {
  sysctlFunc sysctlFunction
  sysctlData []sysctlObject
}
var sysctls = []sysctlTask {
  {
    sysctlFunc: isIPv6Needed,
    sysctlData: []sysctlObject {
      {"net.ipv6.conf.%s.disable_ipv6", "0"},
      {"net.ipv6.conf.%s.autoconf", "0"},
      {"net.ipv6.conf.%s.accept_ra", "0"},
      {"net.ipv6.conf.%s.ndisc_notify", "1"},
    },
  },
  {
    sysctlFunc: isIPv6NotNeeded,
    sysctlData: []sysctlObject {
      {"net.ipv6.conf.%s.disable_ipv6", "1"},
    },
  },
}
const (
  MaxRetryCount = 10
  RetryInterval = 100
)
func DeleteIpvlanInterface(ep *danmtypes.DanmEp) (error) {
  return deleteEp(ep)
}
func FindByCid(client danmclientset.Interface, cid string)([]danmtypes.DanmEp, error) {
  var err error
  var result *danmtypes.DanmEpList
  for i := 0; i < MaxRetryCount; i++ {
    result, err = client.DanmV1().DanmEps("").List(context.TODO(), meta_v1.ListOptions{})
    if err == nil {
      break
    }
    time.Sleep(RetryInterval * time.Millisecond)
  }
  if err != nil {
    return nil, errors.New("cannot list DanmEps because:" + err.Error())
  }
  ret := make([]danmtypes.DanmEp, 0)
  if result == nil {
    return ret, nil
  }
  eplist := result.Items
  for _, ep := range eplist {
    if ep.Spec.CID == cid {
      ret = append(ret, ep)
    }
  }
  return ret, nil
}
func CidsByHost(client danmclientset.Interface, host string)(map[string]danmtypes.DanmEp, error) {
  result, err := client.DanmV1().DanmEps("").List(context.TODO(), meta_v1.ListOptions{})
  if err != nil {
    return nil, errors.New("cannot list DanmEps because:" + err.Error())
  }
  ret := make(map[string]danmtypes.DanmEp, 0)
  if result == nil {
    return ret, nil
  }
  eplist := result.Items
  for _, ep := range eplist {
    if ep.Spec.Host == host {
      ret[ep.Spec.CID] = ep
    }
  }
  return ret, nil
}
func FindByPodName(client danmclientset.Interface, podName, ns string) ([]danmtypes.DanmEp, error) {
  result, err := client.DanmV1().DanmEps(ns).List(context.TODO(), meta_v1.ListOptions{})
  if err != nil {
    return nil, errors.New("cannot list DanmEps because:" + err.Error())
  }
  ret := make([]danmtypes.DanmEp, 0)
  if result == nil {
    return ret, nil
  }
  eplist := result.Items
  for _, ep := range eplist {
    if podName != "" && ep.Spec.Pod != podName {
      continue
    }
    ret = append(ret, ep)
  }
  return ret, nil
}
func FindByPodUid(client danmclientset.Interface, podUid, ns string) ([]danmtypes.DanmEp, error) {
  result, err := client.DanmV1().DanmEps(ns).List(context.TODO(), meta_v1.ListOptions{})
  if err != nil {
    return nil, errors.New("cannot list DanmEps because:" + err.Error())
  }
  ret := make([]danmtypes.DanmEp, 0)
  if result == nil {
    return ret, nil
  }
  eplist := result.Items
  for _, ep := range eplist {
    if podUid != "" && string(ep.Spec.PodUID) != podUid {
      continue
    }
    ret = append(ret, ep)
  }
  return ret, nil
}
func AddIpvlanInterface(dnet *danmtypes.DanmNet, ep *danmtypes.DanmEp) error {
  if ep.Spec.NetworkType != "ipvlan" {
    return nil
  }
  return createIpvlanInterface(dnet, ep)
}
func PostProcessInterface(ep *danmtypes.DanmEp, dnet *danmtypes.DanmNet) error {
  runtime.LockOSThread()
  defer runtime.UnlockOSThread()
  origNs, err := ns.GetCurrentNS()
  if err != nil {
    return errors.New("getting current namespace failed")
  }
  hns, err := ns.GetNS(ep.Spec.Netns)
  if err != nil {
    return errors.New("cannot open network namespace:" + ep.Spec.Netns)
  }
  defer func() {
    hns.Close()
    err = origNs.Set()
    if err != nil {
      log.Println("Could not switch back to default ns during IP route provisioning operation:" + err.Error())
    }
  }()
  err = hns.Set()
  if err != nil {
    return errors.New("failed to enter network namespace of CID:" + ep.Spec.Netns + " with error:" + err.Error())
  }
  isVfAttachedToDpdkDriver,_ := sriov_utils.HasDpdkDriver(ep.Spec.Iface.DeviceID)
  if isVfAttachedToDpdkDriver {
    err = createDummyInterface(ep, dnet)
    if err != nil {
      return errors.New("failed to create dummy kernel interface for " + ep.Spec.Iface.Name + " because:" + err.Error())
    }
  }
  link, err := netlink.LinkByName(ep.Spec.Iface.Name)
  if err != nil {
    log.Println("WARNING: Interface post-processing was skipped for Pod:" + ep.Spec.Pod + " and link:" + ep.Spec.Iface.Name + " because it does not exist in the kernel. If it is not a user space interface, you should investigate!!!")
    return nil
  }
  err = setDanmEpSysctls(ep)
  if err != nil {
    return errors.New("failed to set kernel configs for interface" + ep.Spec.Iface.Name + " because:" + err.Error())
  }
  err = disableDadOnIface(link, ep)
  if err != nil {
    return errors.New("failed to disable DAD for address" + ep.Spec.Iface.AddressIPv6 + " because:" + err.Error())
  }
  return addIpRoutes(link, ep, dnet)
}
func setDanmEpSysctls(ep *danmtypes.DanmEp) error {
  var err error
  for _, s := range sysctls {
    if s.sysctlFunc(ep) {
      for _, ss := range s.sysctlData {
        sss := fmt.Sprintf(ss.sysctlName, ep.Spec.Iface.Name)
        _, err = sysctl.Sysctl(sss, ss.sysctlValue)
        if err != nil {
          return errors.New("failed to set sysctl due to:" + err.Error())
        }
      }
    }
  }
  return nil
}
func isIPv6Needed(ep *danmtypes.DanmEp) bool {
  if ep.Spec.Iface.AddressIPv6 != "" {
    return true
  }
  return false
}
func isIPv6NotNeeded(ep *danmtypes.DanmEp) bool {
  if ep.Spec.Iface.AddressIPv6 == "" {
    return true
  }
  return false
}