From 46b8f569c09571e95abeabcf5df4f4e526a804a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=A5=96=E5=BB=BA?= Date: Wed, 21 Aug 2024 10:38:40 +0800 Subject: [PATCH] netpol: add allow acl rules for u2o logical gateway (#4420) Signed-off-by: zhangzujian --- mocks/pkg/ovs/interface.go | 72 ++++++++++++++++---------------- pkg/controller/network_policy.go | 5 +-- pkg/controller/subnet.go | 12 ++++++ pkg/ovs/interface.go | 2 +- pkg/ovs/ovn-nb-acl.go | 10 ++++- pkg/ovs/ovn-nb-acl_test.go | 10 ++--- 6 files changed, 64 insertions(+), 47 deletions(-) diff --git a/mocks/pkg/ovs/interface.go b/mocks/pkg/ovs/interface.go index c0fa401a17b..46645ecc1d7 100644 --- a/mocks/pkg/ovs/interface.go +++ b/mocks/pkg/ovs/interface.go @@ -103,20 +103,6 @@ func (mr *MockNBGlobalMockRecorder) SetLsCtSkipDstLportIPs(enabled any) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLsCtSkipDstLportIPs", reflect.TypeOf((*MockNBGlobal)(nil).SetLsCtSkipDstLportIPs), enabled) } -// SetOVNIPSec mocks base method. -func (m *MockNBGlobal) SetOVNIPSec(enabled bool) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetOVNIPSec", enabled) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetOVNIPSec indicates an expected call of SetOVNIPSec. -func (mr *MockNBGlobalMockRecorder) SetOVNIPSec(enabled any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOVNIPSec", reflect.TypeOf((*MockNBGlobal)(nil).SetOVNIPSec), enabled) -} - // SetLsDnatModDlDst mocks base method. func (m *MockNBGlobal) SetLsDnatModDlDst(enabled bool) error { m.ctrl.T.Helper() @@ -145,6 +131,20 @@ func (mr *MockNBGlobalMockRecorder) SetNodeLocalDNSIP(nodeLocalDNSIP any) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNodeLocalDNSIP", reflect.TypeOf((*MockNBGlobal)(nil).SetNodeLocalDNSIP), nodeLocalDNSIP) } +// SetOVNIPSec mocks base method. +func (m *MockNBGlobal) SetOVNIPSec(enabled bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetOVNIPSec", enabled) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetOVNIPSec indicates an expected call of SetOVNIPSec. +func (mr *MockNBGlobalMockRecorder) SetOVNIPSec(enabled any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOVNIPSec", reflect.TypeOf((*MockNBGlobal)(nil).SetOVNIPSec), enabled) +} + // SetUseCtInvMatch mocks base method. func (m *MockNBGlobal) SetUseCtInvMatch() error { m.ctrl.T.Helper() @@ -1657,17 +1657,17 @@ func (m *MockACL) EXPECT() *MockACLMockRecorder { } // CreateGatewayACL mocks base method. -func (m *MockACL) CreateGatewayACL(lsName, pgName, gateway string) error { +func (m *MockACL) CreateGatewayACL(lsName, pgName, gateway, u2oInterconnectionIP string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateGatewayACL", lsName, pgName, gateway) + ret := m.ctrl.Call(m, "CreateGatewayACL", lsName, pgName, gateway, u2oInterconnectionIP) ret0, _ := ret[0].(error) return ret0 } // CreateGatewayACL indicates an expected call of CreateGatewayACL. -func (mr *MockACLMockRecorder) CreateGatewayACL(lsName, pgName, gateway any) *gomock.Call { +func (mr *MockACLMockRecorder) CreateGatewayACL(lsName, pgName, gateway, u2oInterconnectionIP any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGatewayACL", reflect.TypeOf((*MockACL)(nil).CreateGatewayACL), lsName, pgName, gateway) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGatewayACL", reflect.TypeOf((*MockACL)(nil).CreateGatewayACL), lsName, pgName, gateway, u2oInterconnectionIP) } // CreateNodeACL mocks base method. @@ -2649,17 +2649,17 @@ func (mr *MockNbClientMockRecorder) CreateBareLogicalSwitchPort(lsName, lspName, } // CreateGatewayACL mocks base method. -func (m *MockNbClient) CreateGatewayACL(lsName, pgName, gateway string) error { +func (m *MockNbClient) CreateGatewayACL(lsName, pgName, gateway, u2oInterconnectionIP string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateGatewayACL", lsName, pgName, gateway) + ret := m.ctrl.Call(m, "CreateGatewayACL", lsName, pgName, gateway, u2oInterconnectionIP) ret0, _ := ret[0].(error) return ret0 } // CreateGatewayACL indicates an expected call of CreateGatewayACL. -func (mr *MockNbClientMockRecorder) CreateGatewayACL(lsName, pgName, gateway any) *gomock.Call { +func (mr *MockNbClientMockRecorder) CreateGatewayACL(lsName, pgName, gateway, u2oInterconnectionIP any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGatewayACL", reflect.TypeOf((*MockNbClient)(nil).CreateGatewayACL), lsName, pgName, gateway) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGatewayACL", reflect.TypeOf((*MockNbClient)(nil).CreateGatewayACL), lsName, pgName, gateway, u2oInterconnectionIP) } // CreateGatewayLogicalSwitch mocks base method. @@ -4347,20 +4347,6 @@ func (mr *MockNbClientMockRecorder) SetLsCtSkipDstLportIPs(enabled any) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLsCtSkipDstLportIPs", reflect.TypeOf((*MockNbClient)(nil).SetLsCtSkipDstLportIPs), enabled) } -// SetOVNIPSec mocks base method. -func (m *MockNbClient) SetOVNIPSec(enabled bool) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetOVNIPSec", enabled) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetOVNIPSec indicates an expected call of SetOVNIPSec. -func (mr *MockNbClientMockRecorder) SetOVNIPSec(enabled any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOVNIPSec", reflect.TypeOf((*MockNbClient)(nil).SetOVNIPSec), enabled) -} - // SetLsDnatModDlDst mocks base method. func (m *MockNbClient) SetLsDnatModDlDst(enabled bool) error { m.ctrl.T.Helper() @@ -4389,6 +4375,20 @@ func (mr *MockNbClientMockRecorder) SetNodeLocalDNSIP(nodeLocalDNSIP any) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNodeLocalDNSIP", reflect.TypeOf((*MockNbClient)(nil).SetNodeLocalDNSIP), nodeLocalDNSIP) } +// SetOVNIPSec mocks base method. +func (m *MockNbClient) SetOVNIPSec(enabled bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetOVNIPSec", enabled) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetOVNIPSec indicates an expected call of SetOVNIPSec. +func (mr *MockNbClientMockRecorder) SetOVNIPSec(enabled any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOVNIPSec", reflect.TypeOf((*MockNbClient)(nil).SetOVNIPSec), enabled) +} + // SetUseCtInvMatch mocks base method. func (m *MockNbClient) SetUseCtInvMatch() error { m.ctrl.T.Helper() diff --git a/pkg/controller/network_policy.go b/pkg/controller/network_policy.go index 7a935a618a2..af749ae3b18 100644 --- a/pkg/controller/network_policy.go +++ b/pkg/controller/network_policy.go @@ -8,6 +8,7 @@ import ( "strings" "unicode" + "github.com/scylladb/go-set/strset" corev1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -17,8 +18,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" - "github.com/scylladb/go-set/strset" - kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" "github.com/kubeovn/kube-ovn/pkg/ovs" "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb" @@ -423,7 +422,7 @@ func (c *Controller) handleUpdateNp(key string) error { } for _, subnet := range subnets { - if err = c.OVNNbClient.CreateGatewayACL("", pgName, subnet.Spec.Gateway); err != nil { + if err = c.OVNNbClient.CreateGatewayACL("", pgName, subnet.Spec.Gateway, subnet.Status.U2OInterconnectionIP); err != nil { klog.Errorf("create gateway acl: %v", err) return err } diff --git a/pkg/controller/subnet.go b/pkg/controller/subnet.go index 48c303c300e..0a8cd2fd4ee 100644 --- a/pkg/controller/subnet.go +++ b/pkg/controller/subnet.go @@ -67,6 +67,18 @@ func (c *Controller) enqueueUpdateSubnet(oldObj, newObj interface{}) { return } + if newSubnet.Spec.Gateway != oldSubnet.Spec.Gateway || + newSubnet.Status.U2OInterconnectionIP != oldSubnet.Status.U2OInterconnectionIP { + policies, err := c.npsLister.List(labels.Everything()) + if err != nil { + klog.Errorf("failed to list network policies: %v", err) + } else { + for _, np := range policies { + c.enqueueAddNp(np) + } + } + } + if newSubnet.Spec.Protocol == kubeovnv1.ProtocolIPv6 { usingIPs = newSubnet.Status.V6UsingIPs } else { diff --git a/pkg/ovs/interface.go b/pkg/ovs/interface.go index d16f25a0f8e..b8ad0e8579e 100644 --- a/pkg/ovs/interface.go +++ b/pkg/ovs/interface.go @@ -142,7 +142,7 @@ type PortGroup interface { type ACL interface { UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName string, npp []netv1.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName string, npp []netv1.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) - CreateGatewayACL(lsName, pgName, gateway string) error + CreateGatewayACL(lsName, pgName, gateway, u2oInterconnectionIP string) error CreateNodeACL(pgName, nodeIPStr, joinIPStr string) error CreateSgDenyAllACL(sgName string) error CreateSgBaseACL(sgName, direction string) error diff --git a/pkg/ovs/ovn-nb-acl.go b/pkg/ovs/ovn-nb-acl.go index 8d504ce3e2d..853172a4d3d 100644 --- a/pkg/ovs/ovn-nb-acl.go +++ b/pkg/ovs/ovn-nb-acl.go @@ -13,6 +13,7 @@ import ( netv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/klog/v2" + "k8s.io/utils/set" v1alpha1 "sigs.k8s.io/network-policy-api/apis/v1alpha1" @@ -138,7 +139,7 @@ func (c *OVNNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, pro } // CreateGatewayACL create allow acl for subnet gateway -func (c *OVNNbClient) CreateGatewayACL(lsName, pgName, gateway string) error { +func (c *OVNNbClient) CreateGatewayACL(lsName, pgName, gateway, u2oInterconnectionIP string) error { acls := make([]*ovnnb.ACL, 0) var parentName, parentType string @@ -151,7 +152,12 @@ func (c *OVNNbClient) CreateGatewayACL(lsName, pgName, gateway string) error { return errors.New("one of port group name and logical switch name must be specified") } - for _, gw := range strings.Split(gateway, ",") { + gateways := set.New(strings.Split(gateway, ",")...) + if u2oInterconnectionIP != "" { + gateways = gateways.Insert(strings.Split(u2oInterconnectionIP, ",")...) + } + + for gw := range gateways { protocol := util.CheckProtocol(gw) ipSuffix := "ip4" if protocol == kubeovnv1.ProtocolIPv6 { diff --git a/pkg/ovs/ovn-nb-acl_test.go b/pkg/ovs/ovn-nb-acl_test.go index cbf24948be6..5d113cb1fd8 100644 --- a/pkg/ovs/ovn-nb-acl_test.go +++ b/pkg/ovs/ovn-nb-acl_test.go @@ -275,7 +275,7 @@ func (suite *OvnClientTestSuite) testCreateGatewayACL() { err := ovnClient.CreatePortGroup(pgName, nil) require.NoError(t, err) - err = ovnClient.CreateGatewayACL("", pgName, gateway) + err = ovnClient.CreateGatewayACL("", pgName, gateway, "") require.NoError(t, err) pg, err := ovnClient.GetPortGroup(pgName, false) @@ -294,7 +294,7 @@ func (suite *OvnClientTestSuite) testCreateGatewayACL() { err := ovnClient.CreatePortGroup(pgName, nil) require.NoError(t, err) - err = ovnClient.CreateGatewayACL("", pgName, gateway) + err = ovnClient.CreateGatewayACL("", pgName, gateway, "") require.NoError(t, err) pg, err := ovnClient.GetPortGroup(pgName, false) @@ -313,7 +313,7 @@ func (suite *OvnClientTestSuite) testCreateGatewayACL() { err := ovnClient.CreatePortGroup(pgName, nil) require.NoError(t, err) - err = ovnClient.CreateGatewayACL("", pgName, gateway) + err = ovnClient.CreateGatewayACL("", pgName, gateway, "") require.NoError(t, err) pg, err := ovnClient.GetPortGroup(pgName, false) @@ -336,7 +336,7 @@ func (suite *OvnClientTestSuite) testCreateGatewayACL() { err := ovnClient.CreateBareLogicalSwitch(lsName) require.NoError(t, err) - err = ovnClient.CreateGatewayACL(lsName, "", gateway) + err = ovnClient.CreateGatewayACL(lsName, "", gateway, "") require.NoError(t, err) ls, err := ovnClient.GetLogicalSwitch(lsName, false) @@ -349,7 +349,7 @@ func (suite *OvnClientTestSuite) testCreateGatewayACL() { t.Run("has no pg name and ls name", func(t *testing.T) { t.Parallel() - err := ovnClient.CreateGatewayACL("", "", "") + err := ovnClient.CreateGatewayACL("", "", "", "") require.EqualError(t, err, "one of port group name and logical switch name must be specified") }) }