Skip to content

Commit 044f2f7

Browse files
committed
decouple Interfaces from Implementation
1 parent fc9e669 commit 044f2f7

12 files changed

+194
-185
lines changed

cmd/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"time"
1313

1414
"github.com/prometheus/client_golang/prometheus/promhttp"
15+
"sigs.k8s.io/kube-network-policies/pkg/api"
1516
"sigs.k8s.io/kube-network-policies/pkg/dataplane"
1617
"sigs.k8s.io/kube-network-policies/pkg/dns"
1718
"sigs.k8s.io/kube-network-policies/pkg/networkpolicy"
@@ -193,7 +194,7 @@ func run() int {
193194
// Create the evaluators for the Pipeline to process the packets
194195
// and take a network policy action. The evaluators are processed
195196
// by the order in the array.
196-
evaluators := []networkpolicy.PolicyEvaluator{}
197+
evaluators := []api.PolicyEvaluator{}
197198

198199
// Logging evaluator must go first if enabled.
199200
if klog.V(2).Enabled() {

pkg/api/interfaces.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package api
2+
3+
import (
4+
"context"
5+
"net"
6+
"net/netip"
7+
8+
"sigs.k8s.io/kube-network-policies/pkg/network"
9+
)
10+
11+
// PodInfoProvider defines an interface for components that can provide PodInfo.
12+
type PodInfoProvider interface {
13+
GetPodInfoByIP(podIP string) (*PodInfo, bool)
14+
}
15+
16+
// DomainResolver provides an interface for resolving domain names to IP addresses.
17+
type DomainResolver interface {
18+
ContainsIP(domain string, ip net.IP) bool
19+
}
20+
21+
// SyncFunc is a callback function that an evaluator can invoke to trigger
22+
// a dataplane reconciliation.
23+
type SyncFunc func()
24+
25+
// Verdict represents the outcome of a packet evaluation.
26+
type Verdict int
27+
28+
const (
29+
// VerdictAccept allows the packet. In a directional pipeline, this means
30+
// the packet is allowed for that stage.
31+
VerdictAccept Verdict = iota
32+
// VerdictDeny denies the packet. This is a final decision for that direction.
33+
VerdictDeny
34+
// VerdictNext continues to the next evaluator in the pipeline.
35+
VerdictNext
36+
)
37+
38+
// PolicyEvaluator is the complete interface for a policy plugin.
39+
// It is responsible for both evaluating packets against its policies and
40+
// providing the necessary configuration to the dataplane.
41+
type PolicyEvaluator interface {
42+
// Name returns the identifier for this evaluator.
43+
Name() string
44+
// Ready returns true if the evaluator is initialized and ready to work.
45+
Ready() bool
46+
47+
// EvaluateIngress/EvaluateEgress perform the runtime packet evaluation.
48+
EvaluateIngress(ctx context.Context, p *network.Packet, srcPod, dstPod *PodInfo) (Verdict, error)
49+
EvaluateEgress(ctx context.Context, p *network.Packet, srcPod, dstPod *PodInfo) (Verdict, error)
50+
51+
// SetDataplaneSyncCallback allows the dataplane to provide a callback function.
52+
// The evaluator MUST call this function whenever its state changes in a way
53+
// that requires the dataplane rules to be re-synced.
54+
SetDataplaneSyncCallback(syncFn SyncFunc)
55+
56+
// ManagedIPs returns the set of Pod IPs that this policy evaluator manages.
57+
// The dataplane uses this to build optimized nftables sets.
58+
// It can also return 'divertAll = true' to signal that all traffic
59+
// must be sent to the nfqueue, disabling the IP set optimization.
60+
ManagedIPs(ctx context.Context) (ips []netip.Addr, divertAll bool, err error)
61+
}

pkg/dataplane/controller_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,17 @@ type mockPolicyEvaluator struct {
3535
ips []netip.Addr
3636
divertAll bool
3737
isReady bool
38-
sync networkpolicy.SyncFunc
38+
sync api.SyncFunc
3939
}
4040

4141
func (m *mockPolicyEvaluator) Name() string { return m.name }
42-
func (m *mockPolicyEvaluator) EvaluateIngress(context.Context, *network.Packet, *api.PodInfo, *api.PodInfo) (networkpolicy.Verdict, error) {
43-
return networkpolicy.VerdictNext, nil
42+
func (m *mockPolicyEvaluator) EvaluateIngress(context.Context, *network.Packet, *api.PodInfo, *api.PodInfo) (api.Verdict, error) {
43+
return api.VerdictNext, nil
4444
}
45-
func (m *mockPolicyEvaluator) EvaluateEgress(context.Context, *network.Packet, *api.PodInfo, *api.PodInfo) (networkpolicy.Verdict, error) {
46-
return networkpolicy.VerdictNext, nil
45+
func (m *mockPolicyEvaluator) EvaluateEgress(context.Context, *network.Packet, *api.PodInfo, *api.PodInfo) (api.Verdict, error) {
46+
return api.VerdictNext, nil
4747
}
48-
func (m *mockPolicyEvaluator) SetDataplaneSyncCallback(syncFn networkpolicy.SyncFunc) {
48+
func (m *mockPolicyEvaluator) SetDataplaneSyncCallback(syncFn api.SyncFunc) {
4949
m.sync = syncFn
5050
}
5151
func (m *mockPolicyEvaluator) Ready() bool { return m.isReady }
@@ -54,7 +54,7 @@ func (m *mockPolicyEvaluator) ManagedIPs(context.Context) ([]netip.Addr, bool, e
5454
}
5555

5656
// newTestController creates a controller instance for testing with mock evaluators.
57-
func newTestController(config Config, evaluators []networkpolicy.PolicyEvaluator) *Controller {
57+
func newTestController(config Config, evaluators []api.PolicyEvaluator) *Controller {
5858
client := fake.NewSimpleClientset()
5959
informersFactory := informers.NewSharedInformerFactory(client, 0)
6060
podInformer := informersFactory.Core().V1().Pods()
@@ -219,7 +219,7 @@ func testNetworkPolicies_SyncRules(t *testing.T) {
219219
tests := []struct {
220220
name string
221221
config Config
222-
evaluators []networkpolicy.PolicyEvaluator
222+
evaluators []api.PolicyEvaluator
223223
expectedNftables string
224224
}{
225225
{
@@ -230,7 +230,7 @@ func testNetworkPolicies_SyncRules(t *testing.T) {
230230
FailOpen: true,
231231
NFTableName: "kube-network-policies",
232232
},
233-
evaluators: []networkpolicy.PolicyEvaluator{
233+
evaluators: []api.PolicyEvaluator{
234234
&mockPolicyEvaluator{
235235
name: "test-evaluator",
236236
ips: []netip.Addr{
@@ -285,7 +285,7 @@ table inet kube-network-policies {
285285
NFTableName: "kube-network-policies",
286286
FailOpen: false,
287287
},
288-
evaluators: []networkpolicy.PolicyEvaluator{
288+
evaluators: []api.PolicyEvaluator{
289289
&mockPolicyEvaluator{
290290
name: "divert-all-evaluator",
291291
divertAll: true,
@@ -321,7 +321,7 @@ table inet kube-network-policies {
321321
QueueID: 102,
322322
NFTableName: "kube-network-policies",
323323
},
324-
evaluators: []networkpolicy.PolicyEvaluator{
324+
evaluators: []api.PolicyEvaluator{
325325
&mockPolicyEvaluator{
326326
name: "ip-evaluator",
327327
ips: []netip.Addr{netip.MustParseAddr("10.0.0.1")},

pkg/networkpolicy/adminnetworkpolicy.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ import (
2222
type AdminNetworkPolicy struct {
2323
anpLister anplisters.AdminNetworkPolicyLister
2424
anpSynced cache.InformerSynced
25-
domainResolver DomainResolver
25+
domainResolver api.DomainResolver
2626
}
2727

28-
var _ PolicyEvaluator = &AdminNetworkPolicy{}
28+
var _ api.PolicyEvaluator = &AdminNetworkPolicy{}
2929

3030
// NewAdminNetworkPolicy creates a new ANP implementation.
31-
func NewAdminNetworkPolicy(anpInformer anpinformers.AdminNetworkPolicyInformer, domainResolver DomainResolver) *AdminNetworkPolicy {
31+
func NewAdminNetworkPolicy(anpInformer anpinformers.AdminNetworkPolicyInformer, domainResolver api.DomainResolver) *AdminNetworkPolicy {
3232
return &AdminNetworkPolicy{
3333
anpLister: anpInformer.Lister(),
3434
anpSynced: anpInformer.Informer().HasSynced,
@@ -44,7 +44,7 @@ func (a *AdminNetworkPolicy) Ready() bool {
4444
return a.anpSynced()
4545
}
4646

47-
func (a *AdminNetworkPolicy) SetDataplaneSyncCallback(syncFn SyncFunc) {
47+
func (a *AdminNetworkPolicy) SetDataplaneSyncCallback(syncFn api.SyncFunc) {
4848
// No-op for AdminNetworkPolicy as it doesn't directly control dataplane rules.
4949
// The controller will handle syncing based on policy changes.
5050
}
@@ -55,59 +55,59 @@ func (a *AdminNetworkPolicy) ManagedIPs(ctx context.Context) ([]netip.Addr, bool
5555
return nil, true, nil
5656
}
5757

58-
func (a *AdminNetworkPolicy) EvaluateIngress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (Verdict, error) {
58+
func (a *AdminNetworkPolicy) EvaluateIngress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (api.Verdict, error) {
5959
logger := klog.FromContext(ctx)
6060

6161
allPolicies, err := a.anpLister.List(labels.Everything())
6262
if err != nil || len(allPolicies) == 0 {
63-
return VerdictNext, err
63+
return api.VerdictNext, err
6464
}
6565

6666
dstPodAdminNetworkPolicies := getAdminNetworkPoliciesForPod(dstPod, allPolicies)
6767
if len(dstPodAdminNetworkPolicies) == 0 {
6868
logger.V(2).Info("Ingress AdminNetworkPolicies does not apply")
69-
return VerdictNext, nil
69+
return api.VerdictNext, nil
7070
}
7171
ingressAction := a.evaluateAdminIngress(dstPodAdminNetworkPolicies, srcPod, dstPod, p.DstPort, p.Proto)
7272
logger.V(2).Info("Ingress AdminNetworkPolicies", "npolicies", len(dstPodAdminNetworkPolicies), "action", ingressAction)
7373

7474
switch ingressAction {
7575
case npav1alpha1.AdminNetworkPolicyRuleActionAllow:
76-
return VerdictAccept, nil
76+
return api.VerdictAccept, nil
7777
case npav1alpha1.AdminNetworkPolicyRuleActionDeny:
78-
return VerdictDeny, nil
78+
return api.VerdictDeny, nil
7979
case npav1alpha1.AdminNetworkPolicyRuleActionPass:
80-
return VerdictNext, nil
80+
return api.VerdictNext, nil
8181
default: // Pass
82-
return VerdictNext, nil
82+
return api.VerdictNext, nil
8383
}
8484
}
8585

86-
func (a *AdminNetworkPolicy) EvaluateEgress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (Verdict, error) {
86+
func (a *AdminNetworkPolicy) EvaluateEgress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (api.Verdict, error) {
8787
logger := klog.FromContext(ctx)
8888

8989
allPolicies, err := a.anpLister.List(labels.Everything())
9090
if err != nil || len(allPolicies) == 0 {
91-
return VerdictNext, err
91+
return api.VerdictNext, err
9292
}
9393

9494
srcPodAdminNetworkPolicies := getAdminNetworkPoliciesForPod(srcPod, allPolicies)
9595
if len(srcPodAdminNetworkPolicies) == 0 {
9696
logger.V(2).Info("Egress AdminNetworkPolicies does not apply")
97-
return VerdictNext, nil
97+
return api.VerdictNext, nil
9898
}
9999
egressAction := a.evaluateAdminEgress(srcPodAdminNetworkPolicies, dstPod, p.DstIP, p.DstPort, p.Proto)
100100
logger.V(2).Info("Egress AdminNetworkPolicies", "npolicies", len(srcPodAdminNetworkPolicies), "action", egressAction)
101101

102102
switch egressAction {
103103
case npav1alpha1.AdminNetworkPolicyRuleActionAllow:
104-
return VerdictAccept, nil
104+
return api.VerdictAccept, nil
105105
case npav1alpha1.AdminNetworkPolicyRuleActionDeny:
106-
return VerdictDeny, nil
106+
return api.VerdictDeny, nil
107107
case npav1alpha1.AdminNetworkPolicyRuleActionPass:
108-
return VerdictNext, nil
108+
return api.VerdictNext, nil
109109
default: // Pass
110-
return VerdictNext, nil
110+
return api.VerdictNext, nil
111111
}
112112
}
113113

pkg/networkpolicy/adminnetworkpolicy_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ func Test_adminNetworkPolicyAction(t *testing.T) {
495495
}
496496

497497
evaluator := NewAdminNetworkPolicy(npaInformerFactory.Policy().V1alpha1().AdminNetworkPolicies(), nil)
498-
engine := NewPolicyEngine(podInfoProvider, []PolicyEvaluator{evaluator})
498+
engine := NewPolicyEngine(podInfoProvider, []api.PolicyEvaluator{evaluator})
499499

500500
verdict, err := engine.EvaluatePacket(context.TODO(), &tt.p)
501501
if err != nil {
@@ -1009,7 +1009,7 @@ func TestController_evaluateAdminEgress_DomainNames(t *testing.T) {
10091009
}
10101010

10111011
evaluator := NewAdminNetworkPolicy(npaInformerFactory.Policy().V1alpha1().AdminNetworkPolicies(), domainResolver)
1012-
engine := NewPolicyEngine(podInfoProvider, []PolicyEvaluator{evaluator})
1012+
engine := NewPolicyEngine(podInfoProvider, []api.PolicyEvaluator{evaluator})
10131013

10141014
packet := network.Packet{
10151015
SrcIP: net.ParseIP("192.168.1.11"),

pkg/networkpolicy/baselineadminnetworkpolicy.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type BaselineAdminNetworkPolicy struct {
2222
banpSynced cache.InformerSynced
2323
}
2424

25-
var _ PolicyEvaluator = &BaselineAdminNetworkPolicy{}
25+
var _ api.PolicyEvaluator = &BaselineAdminNetworkPolicy{}
2626

2727
// NewAdminNetworkPolicy creates a new ANP implementation.
2828
func NewBaselineAdminNetworkPolicy(banpInformer banpinformers.BaselineAdminNetworkPolicyInformer) *BaselineAdminNetworkPolicy {
@@ -40,7 +40,7 @@ func (b *BaselineAdminNetworkPolicy) Ready() bool {
4040
return b.banpSynced()
4141
}
4242

43-
func (b *BaselineAdminNetworkPolicy) SetDataplaneSyncCallback(syncFn SyncFunc) {
43+
func (b *BaselineAdminNetworkPolicy) SetDataplaneSyncCallback(syncFn api.SyncFunc) {
4444
// No-op for AdminNetworkPolicy as it doesn't directly control dataplane rules.
4545
// The controller will handle syncing based on policy changes.
4646
}
@@ -51,39 +51,39 @@ func (b *BaselineAdminNetworkPolicy) ManagedIPs(ctx context.Context) ([]netip.Ad
5151
return nil, true, nil
5252
}
5353

54-
func (b *BaselineAdminNetworkPolicy) EvaluateIngress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (Verdict, error) {
54+
func (b *BaselineAdminNetworkPolicy) EvaluateIngress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (api.Verdict, error) {
5555
logger := klog.FromContext(ctx)
5656

5757
allPolicies, err := b.banpLister.List(labels.Everything())
5858
if err != nil || len(allPolicies) == 0 {
59-
return VerdictNext, err
59+
return api.VerdictNext, err
6060
}
6161

6262
dstPodBaselineAdminNetworkPolices := getBaselineAdminNetworkPoliciesForPod(dstPod, allPolicies)
6363
if len(dstPodBaselineAdminNetworkPolices) == 0 {
6464
logger.V(2).Info("Ingress BaselineAdminNetworkPolicies does not apply")
65-
return VerdictNext, nil
65+
return api.VerdictNext, nil
6666
}
6767
ingressAction := b.evaluateBaselineAdminIngress(dstPodBaselineAdminNetworkPolices, srcPod, dstPod, p.DstPort, p.Proto)
6868
logger.V(2).Info("Ingress BaselineAdminNetworkPolicies", "npolicies", len(dstPodBaselineAdminNetworkPolices), "action", ingressAction)
6969

7070
switch ingressAction {
7171
case npav1alpha1.BaselineAdminNetworkPolicyRuleActionAllow:
72-
return VerdictAccept, nil
72+
return api.VerdictAccept, nil
7373
case npav1alpha1.BaselineAdminNetworkPolicyRuleActionDeny:
74-
return VerdictDeny, nil
74+
return api.VerdictDeny, nil
7575
default: // Pass
76-
return VerdictNext, nil
76+
return api.VerdictNext, nil
7777
}
7878
}
7979

80-
func (b *BaselineAdminNetworkPolicy) EvaluateEgress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (Verdict, error) {
80+
func (b *BaselineAdminNetworkPolicy) EvaluateEgress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (api.Verdict, error) {
8181
logger := klog.FromContext(ctx)
8282

8383
allPolicies, err := b.banpLister.List(labels.Everything())
8484
if err != nil || len(allPolicies) == 0 {
8585
logger.V(2).Info("Egress BaselineAdminNetworkPolicies does not apply")
86-
return VerdictNext, err
86+
return api.VerdictNext, err
8787
}
8888

8989
srcPodBaselineAdminNetworkPolices := getBaselineAdminNetworkPoliciesForPod(srcPod, allPolicies)
@@ -92,11 +92,11 @@ func (b *BaselineAdminNetworkPolicy) EvaluateEgress(ctx context.Context, p *netw
9292

9393
switch egressAction {
9494
case npav1alpha1.BaselineAdminNetworkPolicyRuleActionAllow:
95-
return VerdictAccept, nil
95+
return api.VerdictAccept, nil
9696
case npav1alpha1.BaselineAdminNetworkPolicyRuleActionDeny:
97-
return VerdictDeny, nil
97+
return api.VerdictDeny, nil
9898
default: // Pass
99-
return VerdictNext, nil
99+
return api.VerdictNext, nil
100100
}
101101
}
102102

pkg/networkpolicy/baselineadminnetworkpolicy_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func Test_baselineAdminNetworkPolicyAction(t *testing.T) {
168168
}
169169

170170
evaluator := NewBaselineAdminNetworkPolicy(banpInformer)
171-
engine := NewPolicyEngine(podInfoProvider, []PolicyEvaluator{evaluator})
171+
engine := NewPolicyEngine(podInfoProvider, []api.PolicyEvaluator{evaluator})
172172

173173
verdict, err := engine.EvaluatePacket(context.TODO(), &tt.packet)
174174
if err != nil {

0 commit comments

Comments
 (0)