Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix webhook for virtual workers #198

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions api/v1/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ func IsSupportedModel(vendorId, deviceId string) bool {
return false
}

func IsVfSupportedModel(vendorId, deviceId string) bool {
for _, n := range NicIdMap {
ids := strings.Split(n, " ")
if vendorId == ids[0] && deviceId == ids[2] {
return true
}
}
return false
}

func IsEnabledUnsupportedVendor(vendorId string, unsupportedNicIdMap map[string]string) bool {
for _, n := range unsupportedNicIdMap {
if IsValidPciString(n) {
Expand Down
7 changes: 1 addition & 6 deletions cmd/sriov-network-config-daemon/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ var (
kubeconfig string
nodeName string
}

// PlatformMap contains supported platforms for virtual VF
platformMap = map[string]utils.PlatformType{
"openstack": utils.VirtualOpenStack,
}
)

func init() {
Expand Down Expand Up @@ -147,7 +142,7 @@ func runStartCmd(cmd *cobra.Command, args []string) {

nodeInfo, err := kubeclient.CoreV1().Nodes().Get(context.Background(), startOpts.nodeName, v1.GetOptions{})
if err == nil {
for key, pType := range platformMap {
for key, pType := range utils.PlatformMap {
if strings.Contains(strings.ToLower(nodeInfo.Spec.ProviderID), strings.ToLower(key)) {
platformType = pType
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/utils/utils_virtual.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ func (e PlatformType) String() string {
}
}

var (
// PlatformMap contains supported platforms for virtual VF
PlatformMap = map[string]PlatformType{
"openstack": VirtualOpenStack,
}
)

const (
ospMetaDataDir = "/host/var/config/openstack/latest/"
ospNetworkData = ospMetaDataDir + "/network_data.json"
Expand Down
17 changes: 13 additions & 4 deletions pkg/webhook/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package webhook
import (
"context"
"fmt"
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils"
"os"
"regexp"
"strconv"
"strings"

"github.com/golang/glog"
"k8s.io/api/admission/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"

Expand Down Expand Up @@ -169,7 +171,7 @@ func dynamicValidateSriovNetworkNodePolicy(cr *sriovnetworkv1.SriovNetworkNodePo
nodesSelected = true
for _, ns := range nsList.Items {
if ns.GetName() == node.GetName() {
if ok, err := validatePolicyForNodeState(cr, &ns); err != nil || !ok {
if ok, err := validatePolicyForNodeState(cr, &ns, &node); err != nil || !ok {
return false, err
}
}
Expand All @@ -195,10 +197,10 @@ func dynamicValidateSriovNetworkNodePolicy(cr *sriovnetworkv1.SriovNetworkNodePo
return true, nil
}

func validatePolicyForNodeState(policy *sriovnetworkv1.SriovNetworkNodePolicy, state *sriovnetworkv1.SriovNetworkNodeState) (bool, error) {
func validatePolicyForNodeState(policy *sriovnetworkv1.SriovNetworkNodePolicy, state *sriovnetworkv1.SriovNetworkNodeState, node *corev1.Node) (bool, error) {
glog.V(2).Infof("validatePolicyForNodeState(): validate policy %s for node %s.", policy.GetName(), state.GetName())
for _, iface := range state.Status.Interfaces {
if validateNicModel(&policy.Spec.NicSelector, &iface, state.GetName()) {
if validateNicModel(&policy.Spec.NicSelector, &iface, node) {
interfaceSelected = true
if policy.GetName() != "default" && policy.Spec.NumVfs == 0 {
return false, fmt.Errorf("numVfs(%d) in CR %s is not allowed", policy.Spec.NumVfs, policy.GetName())
Expand Down Expand Up @@ -256,7 +258,7 @@ func keys(m map[string]([]string)) []string {
return keys
}

func validateNicModel(selector *sriovnetworkv1.SriovNetworkNicSelector, iface *sriovnetworkv1.InterfaceExt, nodeName string) bool {
func validateNicModel(selector *sriovnetworkv1.SriovNetworkNicSelector, iface *sriovnetworkv1.InterfaceExt, node *corev1.Node) bool {
if selector.Vendor != "" && selector.Vendor != iface.Vendor {
return false
}
Expand Down Expand Up @@ -285,5 +287,12 @@ func validateNicModel(selector *sriovnetworkv1.SriovNetworkNicSelector, iface *s
if sriovnetworkv1.IsSupportedModel(iface.Vendor, iface.DeviceID) {
return true
}

for key := range utils.PlatformMap {
if strings.Contains(strings.ToLower(node.Spec.ProviderID), strings.ToLower(key)) && sriovnetworkv1.IsVfSupportedModel(iface.Vendor, iface.DeviceID) {
return true
}
}

return false
}
80 changes: 75 additions & 5 deletions pkg/webhook/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package webhook

import (
"fmt"
corev1 "k8s.io/api/core/v1"
"os"
"testing"

Expand Down Expand Up @@ -121,6 +122,10 @@ func newNodePolicy() *SriovNetworkNodePolicy {
}
}

func NewNode() *corev1.Node {
return &corev1.Node{Spec: corev1.NodeSpec{ProviderID: "openstack"}}
}

func TestValidateSriovOperatorConfigWithDefaultOperatorConfig(t *testing.T) {
var err error
var ok bool
Expand Down Expand Up @@ -205,7 +210,7 @@ func TestValidatePolicyForNodeStateWithValidPolicy(t *testing.T) {
},
}
g := NewGomegaWithT(t)
ok, err := validatePolicyForNodeState(policy, state)
ok, err := validatePolicyForNodeState(policy, state, NewNode())
g.Expect(err).NotTo(HaveOccurred())
g.Expect(ok).To(Equal(true))
}
Expand All @@ -232,7 +237,7 @@ func TestValidatePolicyForNodeStateWithInvalidNumVfsPolicy(t *testing.T) {
},
}
g := NewGomegaWithT(t)
ok, err := validatePolicyForNodeState(policy, state)
ok, err := validatePolicyForNodeState(policy, state, NewNode())
g.Expect(err).To(MatchError(ContainSubstring(fmt.Sprintf("numVfs(%d) in CR %s exceed the maximum allowed value(%d)", policy.Spec.NumVfs, policy.GetName(), state.Status.Interfaces[0].TotalVfs))))
g.Expect(ok).To(Equal(false))
}
Expand Down Expand Up @@ -423,7 +428,7 @@ func TestValidatePolicyForNodeStateWithInvalidDevice(t *testing.T) {
g.Expect(err).ToNot(HaveOccurred())
g.Expect(cfg).ToNot(BeNil())
kubeclient = kubernetes.NewForConfigOrDie(cfg)
ok, err := validatePolicyForNodeState(policy, state)
ok, err := validatePolicyForNodeState(policy, state, NewNode())
g.Expect(err).NotTo(HaveOccurred())
g.Expect(ok).To(Equal(true))
}
Expand All @@ -446,7 +451,7 @@ func TestValidatePolicyForNodeStateWithInvalidPfName(t *testing.T) {
},
}
g := NewGomegaWithT(t)
ok, err := validatePolicyForNodeState(policy, state)
ok, err := validatePolicyForNodeState(policy, state, NewNode())
g.Expect(err).NotTo(HaveOccurred())
g.Expect(ok).To(Equal(true))
g.Expect(interfaceSelected).To(Equal(false))
Expand All @@ -470,7 +475,7 @@ func TestValidatePolicyForNodeStateWithValidPfName(t *testing.T) {
},
}
g := NewGomegaWithT(t)
ok, err := validatePolicyForNodeState(policy, state)
ok, err := validatePolicyForNodeState(policy, state, NewNode())
g.Expect(err).NotTo(HaveOccurred())
g.Expect(ok).To(Equal(true))
g.Expect(interfaceSelected).To(Equal(true))
Expand All @@ -492,3 +497,68 @@ func TestStaticValidateSriovNetworkNodePolicyWithInvalidNicSelector(t *testing.T
g.Expect(err).To(HaveOccurred())
g.Expect(ok).To(Equal(false))
}

func TestValidatePolicyForNodeStateWithValidVFAndNetFilter(t *testing.T) {
interfaceSelected = false
state := &SriovNetworkNodeState{
Spec: SriovNetworkNodeStateSpec{
Interfaces: []Interface{
{
Name: "ens803f1",
NumVfs: 1,
PciAddress: "0000:86:00.1",
VfGroups: []VfGroup{
{
DeviceType: "netdevice",
ResourceName: "nic1",
},
},
},
},
},
Status: SriovNetworkNodeStateStatus{
Interfaces: []InterfaceExt{
{
VFs: []VirtualFunction{
{
DeviceID: "154c",
Driver: "iavf",
PciAddress: "0000:86:00.1",
Mtu: 1500,
VfID: 0,
},
},
DeviceID: "154c",
Driver: "iavf",
Mtu: 1500,
Name: "ens803f0",
PciAddress: "0000:86:00.0",
Vendor: "8086",
NumVfs: 1,
TotalVfs: 64,
NetFilter: "openstack/NetworkID:e48c7670-bcb4-4f9c-8038-012b6571501d",
},
},
},
}
policy := &SriovNetworkNodePolicy{
Spec: SriovNetworkNodePolicySpec{
DeviceType: "netdevice",
NicSelector: SriovNetworkNicSelector{
PfNames: []string{"ens803f0"},
NetFilter: "openstack/NetworkID:e48c7670-bcb4-4f9c-8038-012b6571501d",
},
NodeSelector: map[string]string{
"feature.node.kubernetes.io/network-sriov.capable": "true",
},
NumVfs: 1,
Priority: 99,
ResourceName: "p0",
},
}
g := NewGomegaWithT(t)
ok, err := validatePolicyForNodeState(policy, state, NewNode())
g.Expect(err).NotTo(HaveOccurred())
g.Expect(ok).To(Equal(true))
g.Expect(interfaceSelected).To(Equal(true))
}