Upgrade dependent version: github.com/open-policy-agent/opa (#5315)

Upgrade dependent version: github.com/open-policy-agent/opa v0.18.0 -> v0.45.0

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
hongzhouzi
2022-10-31 10:58:55 +08:00
committed by GitHub
parent 668fca1773
commit ef03b1e3df
363 changed files with 277341 additions and 13544 deletions

View File

@@ -1,11 +1,15 @@
package topdown
import (
"bytes"
"errors"
"fmt"
"math/big"
"net"
"sort"
"github.com/open-policy-agent/opa/ast"
cidrMerge "github.com/open-policy-agent/opa/internal/cidr/merge"
"github.com/open-policy-agent/opa/topdown/builtins"
)
@@ -69,7 +73,7 @@ func builtinNetCIDRIntersects(a, b ast.Value) (ast.Value, error) {
}
// If either net contains the others starting IP they are overlapping
cidrsOverlap := (cidrnetA.Contains(cidrnetB.IP) || cidrnetB.Contains(cidrnetA.IP))
cidrsOverlap := cidrnetA.Contains(cidrnetB.IP) || cidrnetB.Contains(cidrnetA.IP)
return ast.Boolean(cidrsOverlap), nil
}
@@ -97,7 +101,8 @@ func builtinNetCIDRContains(a, b ast.Value) (ast.Value, error) {
return nil, fmt.Errorf("not a valid textual representation of an IP address or CIDR: %s", string(bStr))
}
// We can determine if cidr A contains cidr B iff A contains the starting address of B and the last address in B.
// We can determine if cidr A contains cidr B if and only if A contains
// the starting address of B and the last address in B.
cidrContained := false
if cidrnetA.Contains(cidrnetB.IP) {
// Only spend time calculating the last IP if the starting IP is already verified to be in cidr A
@@ -111,6 +116,75 @@ func builtinNetCIDRContains(a, b ast.Value) (ast.Value, error) {
return ast.Boolean(cidrContained), nil
}
var errNetCIDRContainsMatchElementType = errors.New("element must be string or non-empty array")
func getCIDRMatchTerm(a *ast.Term) (*ast.Term, error) {
switch v := a.Value.(type) {
case ast.String:
return a, nil
case *ast.Array:
if v.Len() == 0 {
return nil, errNetCIDRContainsMatchElementType
}
return v.Elem(0), nil
default:
return nil, errNetCIDRContainsMatchElementType
}
}
func evalNetCIDRContainsMatchesOperand(operand int, a *ast.Term, iter func(cidr, index *ast.Term) error) error {
switch v := a.Value.(type) {
case ast.String:
return iter(a, a)
case *ast.Array:
for i := 0; i < v.Len(); i++ {
cidr, err := getCIDRMatchTerm(v.Elem(i))
if err != nil {
return fmt.Errorf("operand %v: %v", operand, err)
}
if err := iter(cidr, ast.IntNumberTerm(i)); err != nil {
return err
}
}
return nil
case ast.Set:
return v.Iter(func(x *ast.Term) error {
cidr, err := getCIDRMatchTerm(x)
if err != nil {
return fmt.Errorf("operand %v: %v", operand, err)
}
return iter(cidr, x)
})
case ast.Object:
return v.Iter(func(k, v *ast.Term) error {
cidr, err := getCIDRMatchTerm(v)
if err != nil {
return fmt.Errorf("operand %v: %v", operand, err)
}
return iter(cidr, k)
})
}
return nil
}
func builtinNetCIDRContainsMatches(bctx BuiltinContext, args []*ast.Term, iter func(*ast.Term) error) error {
result := ast.NewSet()
err := evalNetCIDRContainsMatchesOperand(1, args[0], func(cidr1 *ast.Term, index1 *ast.Term) error {
return evalNetCIDRContainsMatchesOperand(2, args[1], func(cidr2 *ast.Term, index2 *ast.Term) error {
if v, err := builtinNetCIDRContains(cidr1.Value, cidr2.Value); err != nil {
return err
} else if vb, ok := v.(ast.Boolean); ok && bool(vb) {
result.Add(ast.ArrayTerm(index1, index2))
}
return nil
})
})
if err == nil {
return iter(ast.NewTerm(result))
}
return err
}
func builtinNetCIDRExpand(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
s, err := builtins.StringOperand(operands[0].Value, 1)
@@ -128,9 +202,11 @@ func builtinNetCIDRExpand(bctx BuiltinContext, operands []*ast.Term, iter func(*
for ip := ip.Mask(ipNet.Mask); ipNet.Contains(ip); incIP(ip) {
if bctx.Cancel != nil && bctx.Cancel.Cancelled() {
return &Error{
Code: CancelErr,
Message: "net.cidr_expand: timed out before generating all IP addresses",
return Halt{
Err: &Error{
Code: CancelErr,
Message: "net.cidr_expand: timed out before generating all IP addresses",
},
}
}
@@ -140,6 +216,176 @@ func builtinNetCIDRExpand(bctx BuiltinContext, operands []*ast.Term, iter func(*
return iter(ast.NewTerm(result))
}
type cidrBlockRange struct {
First *net.IP
Last *net.IP
Network *net.IPNet
}
type cidrBlockRanges []*cidrBlockRange
// Implement Sort interface
func (c cidrBlockRanges) Len() int {
return len(c)
}
func (c cidrBlockRanges) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}
func (c cidrBlockRanges) Less(i, j int) bool {
// Compare last IP.
cmp := bytes.Compare(*c[i].Last, *c[j].Last)
if cmp < 0 {
return true
} else if cmp > 0 {
return false
}
// Then compare first IP.
cmp = bytes.Compare(*c[i].First, *c[i].First)
if cmp < 0 {
return true
} else if cmp > 0 {
return false
}
// Ranges are Equal.
return false
}
// builtinNetCIDRMerge merges the provided list of IP addresses and subnets into the smallest possible list of CIDRs.
// It merges adjacent subnets where possible, those contained within others and also removes any duplicates.
// Original Algorithm: https://github.com/netaddr/netaddr.
func builtinNetCIDRMerge(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
networks := []*net.IPNet{}
switch v := operands[0].Value.(type) {
case *ast.Array:
for i := 0; i < v.Len(); i++ {
network, err := generateIPNet(v.Elem(i))
if err != nil {
return err
}
networks = append(networks, network)
}
case ast.Set:
err := v.Iter(func(x *ast.Term) error {
network, err := generateIPNet(x)
if err != nil {
return err
}
networks = append(networks, network)
return nil
})
if err != nil {
return err
}
default:
return errors.New("operand must be an array")
}
merged := evalNetCIDRMerge(networks)
result := ast.NewSet()
for _, network := range merged {
result.Add(ast.StringTerm(network.String()))
}
return iter(ast.NewTerm(result))
}
func evalNetCIDRMerge(networks []*net.IPNet) []*net.IPNet {
if len(networks) == 0 {
return nil
}
ranges := make(cidrBlockRanges, 0, len(networks))
// For each CIDR, create an IP range. Sort them and merge when possible.
for _, network := range networks {
firstIP, lastIP := cidrMerge.GetAddressRange(*network)
ranges = append(ranges, &cidrBlockRange{
First: &firstIP,
Last: &lastIP,
Network: network,
})
}
// merge CIDRs.
merged := mergeCIDRs(ranges)
// convert ranges into an equivalent list of net.IPNet.
result := []*net.IPNet{}
for _, r := range merged {
// Not merged with any other CIDR.
if r.Network != nil {
result = append(result, r.Network)
} else {
// Find new network that represents the merged range.
rangeCIDRs := cidrMerge.RangeToCIDRs(*r.First, *r.Last)
result = append(result, rangeCIDRs...)
}
}
return result
}
func generateIPNet(term *ast.Term) (*net.IPNet, error) {
e, ok := term.Value.(ast.String)
if !ok {
return nil, errors.New("element must be string")
}
// try to parse element as an IP first, fall back to CIDR
ip := net.ParseIP(string(e))
if ip == nil {
_, network, err := net.ParseCIDR(string(e))
return network, err
}
if ip.To4() != nil {
return &net.IPNet{
IP: ip,
Mask: ip.DefaultMask(),
}, nil
}
return nil, errors.New("IPv6 invalid: needs prefix length")
}
func mergeCIDRs(ranges cidrBlockRanges) cidrBlockRanges {
sort.Sort(ranges)
// Merge adjacent CIDRs if possible.
for i := len(ranges) - 1; i > 0; i-- {
previousIP := cidrMerge.GetPreviousIP(*ranges[i].First)
// If the previous IP of the current network overlaps
// with the last IP of the previous network in the
// list, then merge the two ranges together.
if bytes.Compare(previousIP, *ranges[i-1].Last) <= 0 {
var firstIP *net.IP
if bytes.Compare(*ranges[i-1].First, *ranges[i].First) < 0 {
firstIP = ranges[i-1].First
} else {
firstIP = ranges[i].First
}
lastIPRange := make(net.IP, len(*ranges[i].Last))
copy(lastIPRange, *ranges[i].Last)
firstIPRange := make(net.IP, len(*firstIP))
copy(firstIPRange, *firstIP)
ranges[i-1] = &cidrBlockRange{First: &firstIPRange, Last: &lastIPRange, Network: nil}
// Delete ranges[i] since merged with the previous.
ranges = append(ranges[:i], ranges[i+1:]...)
}
}
return ranges
}
func incIP(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
@@ -153,5 +399,7 @@ func init() {
RegisterFunctionalBuiltin2(ast.NetCIDROverlap.Name, builtinNetCIDRContains)
RegisterFunctionalBuiltin2(ast.NetCIDRIntersects.Name, builtinNetCIDRIntersects)
RegisterFunctionalBuiltin2(ast.NetCIDRContains.Name, builtinNetCIDRContains)
RegisterBuiltinFunc(ast.NetCIDRContainsMatches.Name, builtinNetCIDRContainsMatches)
RegisterBuiltinFunc(ast.NetCIDRExpand.Name, builtinNetCIDRExpand)
RegisterBuiltinFunc(ast.NetCIDRMerge.Name, builtinNetCIDRMerge)
}