package netacl import ( "encoding/json" "errors" "fmt" "net/netip" "sigs.k8s.io/yaml" ) type NetACL struct { enabledAddresses []netip.Addr enabledNetworks []netip.Prefix disabledAddresses []netip.Addr disabledNetworks []netip.Prefix } func NewNetACL() *NetACL { return &NetACL{ enabledAddresses: make([]netip.Addr, 0), enabledNetworks: make([]netip.Prefix, 0), disabledAddresses: make([]netip.Addr, 0), disabledNetworks: make([]netip.Prefix, 0), } } type netACL struct { EnabledAddresses []string `json:"enabledAddresses" yaml:"enabledAddresses"` EnabledNetworks []string `json:"enabledNetworks" yaml:"enabledNetworks"` DisabledAddresses []string `json:"disabledAddresses" yaml:"disabledAddresses"` DisabledNetworks []string `json:"disabledNetworks" yaml:"disabledNetworks"` } func newNetACL() *netACL { return &netACL{ EnabledAddresses: make([]string, 0), EnabledNetworks: make([]string, 0), DisabledAddresses: make([]string, 0), DisabledNetworks: make([]string, 0), } } func (al *NetACL) MarshalJSON() ([]byte, error) { alDescr := newNetACL() for _, disabledAddress := range al.disabledAddresses { alDescr.DisabledAddresses = append(alDescr.DisabledAddresses, disabledAddress.String()) } for _, disabledNetwork := range al.disabledNetworks { alDescr.DisabledNetworks = append(alDescr.DisabledNetworks, disabledNetwork.String()) } for _, enabledAddress := range al.enabledAddresses { alDescr.EnabledAddresses = append(alDescr.EnabledAddresses, enabledAddress.String()) } for _, enabledNetwork := range al.enabledNetworks { alDescr.EnabledNetworks = append(alDescr.EnabledNetworks, enabledNetwork.String()) } return json.Marshal(alDescr) } func (al *NetACL) UnmarshalJSON(data []byte) error { var err error return err } func (al *NetACL) MarshalYAML() ([]byte, error) { alDescr := newNetACL() for _, disabledAddress := range al.disabledAddresses { alDescr.DisabledAddresses = append(alDescr.DisabledAddresses, disabledAddress.String()) } for _, disabledNetwork := range al.disabledNetworks { alDescr.DisabledNetworks = append(alDescr.DisabledNetworks, disabledNetwork.String()) } for _, enabledAddress := range al.enabledAddresses { alDescr.EnabledAddresses = append(alDescr.EnabledAddresses, enabledAddress.String()) } for _, enabledNetwork := range al.enabledNetworks { alDescr.EnabledNetworks = append(alDescr.EnabledNetworks, enabledNetwork.String()) } return yaml.Marshal(alDescr) } func (al *NetACL) UnmarshalYAML(data []byte) error { var err error return err } func (al *NetACL) AddressIsEnabled(address string) (bool, error) { var err error var res bool addr, err := netip.ParseAddr(address) if err != nil { return res, err } for _, disabledAddr := range al.disabledAddresses { if disabledAddr.Compare(addr) == 0 { res = false return res, err } } for _, disabledNetwork := range al.disabledNetworks { if disabledNetwork.Contains(addr) { res = false return res, err } } for _, enabledAddr := range al.enabledAddresses { if enabledAddr.Compare(addr) == 0 { res = true return res, err } } for _, enabledNetwork := range al.enabledNetworks { if enabledNetwork.Contains(addr) { res = true return res, err } } return res, err } func (al *NetACL) AddrIsEnabled(addr netip.Addr) (bool, error) { var err error var res bool for _, disabledAddr := range al.disabledAddresses { if disabledAddr.Compare(addr) == 0 { res = false return res, err } } for _, disabledNetwork := range al.disabledNetworks { if disabledNetwork.Contains(addr) { res = false return res, err } } for _, enabledAddr := range al.enabledAddresses { if enabledAddr.Compare(addr) == 0 { res = true return res, err } } for _, enabledNetwork := range al.enabledNetworks { if enabledNetwork.Contains(addr) { res = true return res, err } } return res, err } func (al *NetACL) AddEnabledAddresses(addresses ...string) error { var err error for _, address := range addresses { addr, addrParseErr := netip.ParseAddr(address) if addrParseErr == nil { al.enabledAddresses = append(al.enabledAddresses, addr) continue } prefix, prefixParseErr := netip.ParsePrefix(address) if prefixParseErr == nil { al.enabledNetworks = append(al.enabledNetworks, prefix) continue } err = errors.Join(addrParseErr, prefixParseErr) err = fmt.Errorf("Address %s is not correct, error: %v", address, err) break } return err } func (al *NetACL) AddDisabledAddresses(addresses ...string) error { var err error for _, address := range addresses { addr, addrParseErr := netip.ParseAddr(address) if addrParseErr == nil { al.disabledAddresses = append(al.disabledAddresses, addr) continue } prefix, prefixParseErr := netip.ParsePrefix(address) if prefixParseErr == nil { al.disabledNetworks = append(al.disabledNetworks, prefix) continue } err = errors.Join(addrParseErr, prefixParseErr) err = fmt.Errorf("Address %s is not correct, error: %v", address, err) break } return err }