Skip to content

Commit

Permalink
Merge pull request #1913 from JoelSpeed/backport-cel-ip-cidr-4.14
Browse files Browse the repository at this point in the history
OCPBUGS-30964: Set up CEL IP/CIDR library from 4.14 onwards
  • Loading branch information
openshift-merge-bot[bot] committed Mar 15, 2024
2 parents d8e449a + 61ca2c7 commit 749fe1d
Show file tree
Hide file tree
Showing 10 changed files with 1,786 additions and 1 deletion.
88 changes: 88 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/cel/cidr.go
@@ -0,0 +1,88 @@
/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cel

import (
"fmt"
"math"
"net/netip"
"reflect"

"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
)

// CIDR provides a CEL representation of an network address.
type CIDR struct {
netip.Prefix
}

var (
CIDRType = cel.OpaqueType("net.CIDR")
cidrTypeValue = types.NewTypeValue("net.CIDR")
)

// ConvertToNative implements ref.Val.ConvertToNative.
func (d CIDR) ConvertToNative(typeDesc reflect.Type) (any, error) {
if reflect.TypeOf(d.Prefix).AssignableTo(typeDesc) {
return d.Prefix, nil
}
if reflect.TypeOf("").AssignableTo(typeDesc) {
return d.Prefix.String(), nil
}
return nil, fmt.Errorf("type conversion error from 'CIDR' to '%v'", typeDesc)
}

// ConvertToType implements ref.Val.ConvertToType.
func (d CIDR) ConvertToType(typeVal ref.Type) ref.Val {
switch typeVal {
case cidrTypeValue:
return d
case types.TypeType:
return cidrTypeValue
case types.StringType:
return types.String(d.Prefix.String())
}
return types.NewErr("type conversion error from '%s' to '%s'", CIDRType, typeVal)
}

// Equal implements ref.Val.Equal.
func (d CIDR) Equal(other ref.Val) ref.Val {
otherD, ok := other.(CIDR)
if !ok {
return types.ValOrErr(other, "no such overload")
}

return types.Bool(d.Prefix == otherD.Prefix)
}

// Type implements ref.Val.Type.
func (d CIDR) Type() ref.Type {
return cidrTypeValue
}

// Value implements ref.Val.Value.
func (d CIDR) Value() any {
return d.Prefix
}

// Size returns the size of the CIDR prefix address in bytes.
// Used in the size estimation of the runtime cost.
func (d CIDR) Size() ref.Val {
return types.Int(int(math.Ceil(float64(d.Prefix.Bits()) / 8)))
}
87 changes: 87 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/cel/ip.go
@@ -0,0 +1,87 @@
/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cel

import (
"fmt"
"math"
"net/netip"
"reflect"

"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
)

// IP provides a CEL representation of an IP address.
type IP struct {
netip.Addr
}

var (
IPType = cel.ObjectType("net.IP")
ipTypeValue = types.NewTypeValue("net.IP")
)

// ConvertToNative implements ref.Val.ConvertToNative.
func (d IP) ConvertToNative(typeDesc reflect.Type) (any, error) {
if reflect.TypeOf(d.Addr).AssignableTo(typeDesc) {
return d.Addr, nil
}
if reflect.TypeOf("").AssignableTo(typeDesc) {
return d.Addr.String(), nil
}
return nil, fmt.Errorf("type conversion error from 'IP' to '%v'", typeDesc)
}

// ConvertToType implements ref.Val.ConvertToType.
func (d IP) ConvertToType(typeVal ref.Type) ref.Val {
switch typeVal {
case ipTypeValue:
return d
case types.TypeType:
return ipTypeValue
case types.StringType:
return types.String(d.Addr.String())
}
return types.NewErr("type conversion error from '%s' to '%s'", IPType, typeVal)
}

// Equal implements ref.Val.Equal.
func (d IP) Equal(other ref.Val) ref.Val {
otherD, ok := other.(IP)
if !ok {
return types.ValOrErr(other, "no such overload")
}
return types.Bool(d.Addr == otherD.Addr)
}

// Type implements ref.Val.Type.
func (d IP) Type() ref.Type {
return ipTypeValue
}

// Value implements ref.Val.Value.
func (d IP) Value() any {
return d.Addr
}

// Size returns the size of the IP address in bytes.
// Used in the size estimation of the runtime cost.
func (d IP) Size() ref.Val {
return types.Int(int(math.Ceil(float64(d.Addr.BitLen()) / 8)))
}

0 comments on commit 749fe1d

Please sign in to comment.