/
nft-processor-abstact.go
145 lines (125 loc) · 3.4 KB
/
nft-processor-abstact.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package nft
import (
"context"
"fmt"
"net"
"sync"
"github.com/H-BF/sgroups/cmd/to-nft/internal/nft/cases"
"github.com/H-BF/sgroups/internal/config"
"github.com/H-BF/sgroups/internal/dict"
model "github.com/H-BF/sgroups/internal/models/sgroups"
nftlib "github.com/google/nftables"
"github.com/pkg/errors"
"github.com/c-robinson/iplib"
uuid "github.com/satori/go.uuid"
)
type (
// AppliedRules -
AppliedRules struct {
ID uuid.UUID
NetNS string
TargetTable string
BaseRules BaseRules
LocalData cases.LocalData
}
// Patch -
Patch interface {
String() string
Apply(context.Context, *AppliedRules) error
isAppliedRulesPatch()
}
// UpdateFqdnNetsets - is kind of Patch
UpdateFqdnNetsets struct {
IPVersion int
FQDN model.FQDN
Addresses []net.IP
}
// NfTablesProcessorOpt constructor option(s)
NfTablesProcessorOpt interface {
isNfTablesProcessorOpt()
}
// NfTablesProcessor abstract interface
NfTablesProcessor interface {
ApplyConf(ctx context.Context, data cases.LocalData) (AppliedRules, error)
Close() error
}
// WithNetNS use network namespace
WithNetNS struct {
NetNS string
}
// BaseRules -
BaseRules struct {
Nets []config.NetCIDR
}
)
// LastAppliedRules -
func LastAppliedRules(netNS string) *AppliedRules {
lastAppliedRulesMx.RLock()
defer lastAppliedRulesMx.RUnlock()
return lastAppliedRules.At(netNS)
}
// LastAppliedRulesUpd -
func LastAppliedRulesUpd(netNS string, data *AppliedRules) {
lastAppliedRulesMx.Lock()
defer lastAppliedRulesMx.Unlock()
lastAppliedRules.Put(netNS, data)
}
var (
lastAppliedRules dict.HDict[string, *AppliedRules]
lastAppliedRulesMx sync.RWMutex
_ Patch = (*UpdateFqdnNetsets)(nil)
)
func (UpdateFqdnNetsets) isAppliedRulesPatch() {}
// String impl Stringer interface
func (p UpdateFqdnNetsets) String() string {
return fmt.Sprintf("patch/fqdn-netset(IPv: %v; domain: '%s'; addrs: %s)",
p.IPVersion, p.FQDN, slice2stringer(p.Addresses...))
}
// NetSet -
func (ns UpdateFqdnNetsets) NetSet() []net.IPNet {
isV6 := ns.IPVersion == iplib.IP6Version
bits := tern(isV6, net.IPv6len, net.IPv4len) * 8
mask := net.CIDRMask(bits, bits)
ret := make([]net.IPNet, len(ns.Addresses))
for i, ip := range ns.Addresses {
ret[i] = net.IPNet{IP: ip, Mask: mask}
}
return ret
}
// Apply -
func (ns UpdateFqdnNetsets) Apply(ctx context.Context, rules *AppliedRules) error {
const api = "apply"
if !isIn(ns.IPVersion, sli(iplib.IP4Version, iplib.IP6Version)) {
return errors.WithMessagef(ErrPatchNotApplicable,
"%s/%s failed cause it has bad IPv(%v)", ns, api, ns.IPVersion)
}
tx, err := NewTx(rules.NetNS)
if err != nil {
return err
}
defer tx.Close()
var nftConf NFTablesConf
if err = nftConf.Load(tx.Conn); err != nil {
return err
}
targetTable := NfTableKey{
TableFamily: nftlib.TableFamilyINet,
Name: rules.TargetTable,
}
netSets := nftConf.Sets.At(targetTable)
netsetName := nameUtils{}.
nameOfFqdnNetSet(ns.IPVersion, ns.FQDN)
set := netSets.At(netsetName)
if set.Set == nil {
return errors.WithMessagef(ErrPatchNotApplicable,
"%s/%s failed cause targed netset '%s' does not exist", ns, api, netsetName)
}
elements := setsUtils{}.nets2SetElements(ns.NetSet(), ns.IPVersion)
if err = tx.SetAddElements(set.Set, elements); err != nil {
panic(err)
}
err = tx.FlushAndClose()
return err
}
func (WithNetNS) isNfTablesProcessorOpt() {}
func (BaseRules) isNfTablesProcessorOpt() {}