Skip to content

Commit

Permalink
fix(diagnosis): fix calico host interface auto detection & use cr ins…
Browse files Browse the repository at this point in the history
…tead when projectcalico.org/v3 not found

Signed-off-by: xiayu.lyt <[email protected]>
  • Loading branch information
Lyt99 committed Feb 1, 2024
1 parent 8592df0 commit 19c612f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 19 deletions.
2 changes: 1 addition & 1 deletion pkg/skoop/assertions/netstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (na *NetstackAssertion) AssertNetDevice(s string, expect netstack.Interface
}

na.AddSuspicion(model.SuspicionLevelCritical,
fmt.Sprintf("cannot found interface: %s to assert", s),
fmt.Sprintf("cannot find interface: %s to assert", s),
)
}

Expand Down
73 changes: 55 additions & 18 deletions pkg/skoop/plugin/calico.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"context"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"

Check failure on line 9 in pkg/skoop/plugin/calico.go

View workflow job for this annotation

GitHub Actions / lint

File is not `goimports`-ed (goimports)
"k8s.io/client-go/dynamic"
"net"
"strings"

Expand Down Expand Up @@ -76,7 +79,6 @@ type CalicoPluginOptions struct {
}

type calicoPlugin struct {
calicoClient *clientset.Clientset
serviceProcessor service.Processor
podMTU int
ipipPodMTU int
Expand Down Expand Up @@ -114,6 +116,45 @@ func getIPPool(ipPools []calicov3.IPPool, ip net.IP) *calicov3.IPPool {
return &matchedPool
}

func listIPPools(ctx *ctx.Context) ([]calicov3.IPPool, error) {
client, err := clientset.NewForConfig(ctx.KubernetesRestClient())
if err != nil {
return nil, err
}

ippools, err := client.ProjectcalicoV3().IPPools().List(context.TODO(), metav1.ListOptions{})
if err == nil {
return ippools.Items, nil
}

klog.V(5).Infof("not able to list projectcalico.org/v3 ippools, error %s, fallback to list crd.", err)
dynClient, err := dynamic.NewForConfig(ctx.KubernetesRestClient())
if err != nil {
return nil, err
}

gvr := schema.GroupVersionResource{
Group: "crd.projectcalico.org",
Version: "v1",
Resource: "ippools",
}
list, err := dynClient.Resource(gvr).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
str, err := list.MarshalJSON()
if err != nil {
return nil, err
}
var ippoolList calicov3.IPPoolList
err = json.Unmarshal(str, &ippoolList)
if err != nil {
return nil, err
}

return ippools.Items, err
}

func (c *calicoPlugin) CreatePod(pod *k8s.Pod) (model.NetNodeAction, error) {
mtu := c.podMTU

Expand Down Expand Up @@ -246,30 +287,24 @@ func (r *calicoRoute) Assert(pkt *model.Packet) error {
}

func NewCalicoPluginWithOptions(ctx *ctx.Context, options *CalicoPluginOptions) (Plugin, error) {
client, err := clientset.NewForConfig(ctx.KubernetesRestClient())
if err != nil {
return nil, err
}

if options.ServiceProcessor == nil {
return nil, fmt.Errorf("service processor must be provided")
}

ippools, err := client.ProjectcalicoV3().IPPools().List(context.TODO(), metav1.ListOptions{})
ippools, err := listIPPools(ctx)
if err != nil {
return nil, err
}

return &calicoPlugin{
calicoClient: client,
infraShim: options.InfraShim,
podMTU: options.PodMTU,
ipipPodMTU: options.IPIPPodMTU,
ipCache: ctx.ClusterConfig().IPCache,
serviceProcessor: options.ServiceProcessor,
hostOptions: &calicoHostOptions{
Interface: options.Interface,
IPPools: ippools.Items,
IPPools: ippools,
MTU: options.HostMTU,
},
}, nil
Expand Down Expand Up @@ -321,35 +356,37 @@ func newCalicoHost(ipCache *k8s.IPCache, nodeInfo *k8s.NodeInfo, infraShim netwo
assertion := assertions.NewNetstackAssertion(netNode, &nodeInfo.NetNS)
k8sAssertion := assertions.NewKubernetesAssertion(netNode)

iface, ok := lo.Find(nodeInfo.Interfaces, func(i netstack.Interface) bool { return i.Name == options.Interface })
if !ok {
return nil, fmt.Errorf("cannot find interface %s", options.Interface)
}
ip, mask := netstack.GetDefaultIPv4(&iface)
ipNet := &net.IPNet{IP: ip, Mask: mask}

host := &calicoHost{
netNode: netNode,
nodeInfo: nodeInfo,
iface: options.Interface,
mtu: options.MTU,
ipCache: ipCache,
serviceProcessor: serviceProcessor,
network: ipNet,
gateway: options.Gateway,
ipPools: options.IPPools,
net: assertion,
k8s: k8sAssertion,
infraShim: infraShim,
}

if host.iface == "" {
host.iface = netstack.LookupDefaultIfaceName(nodeInfo.NetNSInfo.Interfaces)
if host.iface == "" {
return nil, fmt.Errorf("cannot lookup default host interface, please manually specify it via --calico-host-interface")
}
klog.V(5).Infof("detected host interface %s on node %s", host.iface, host.nodeInfo.NodeName)
klog.V(5).Infof("detected host interface %s on node %s", host.iface, nodeInfo.NodeName)
}

iface, ok := lo.Find(nodeInfo.Interfaces, func(i netstack.Interface) bool { return i.Name == host.iface })
if !ok {
return nil, fmt.Errorf("cannot find interface %s", options.Interface)
}

ip, mask := netstack.GetDefaultIPv4(&iface)
ipNet := &net.IPNet{IP: ip, Mask: mask}
host.network = ipNet

err := host.initRoute()
if err != nil {
return nil, err
Expand Down

0 comments on commit 19c612f

Please sign in to comment.