diff --git a/api/adc/types.go b/api/adc/types.go index 2e510b7f4..39ebbf336 100644 --- a/api/adc/types.go +++ b/api/adc/types.go @@ -10,8 +10,6 @@ import ( "time" "github.com/incubator4/go-resty-expr/expr" - - "github.com/api7/api7-ingress-controller/api/common" ) const ( @@ -115,16 +113,16 @@ type Service struct { type Route struct { Metadata `json:",inline" yaml:",inline"` - EnableWebsocket *bool `json:"enable_websocket,omitempty" yaml:"enable_websocket,omitempty"` - FilterFunc string `json:"filter_func,omitempty" yaml:"filter_func,omitempty"` - Hosts []string `json:"hosts,omitempty" yaml:"hosts,omitempty"` - Methods []string `json:"methods,omitempty" yaml:"methods,omitempty"` - Plugins Plugins `json:"plugins,omitempty" yaml:"plugins,omitempty"` - Priority *int64 `json:"priority,omitempty" yaml:"priority,omitempty"` - RemoteAddrs []string `json:"remote_addrs,omitempty" yaml:"remote_addrs,omitempty"` - Timeout *Timeout `json:"timeout,omitempty" yaml:"timeout,omitempty"` - Uris []string `json:"uris" yaml:"uris"` - Vars common.Vars `json:"vars,omitempty" yaml:"vars,omitempty"` + EnableWebsocket *bool `json:"enable_websocket,omitempty" yaml:"enable_websocket,omitempty"` + FilterFunc string `json:"filter_func,omitempty" yaml:"filter_func,omitempty"` + Hosts []string `json:"hosts,omitempty" yaml:"hosts,omitempty"` + Methods []string `json:"methods,omitempty" yaml:"methods,omitempty"` + Plugins Plugins `json:"plugins,omitempty" yaml:"plugins,omitempty"` + Priority *int64 `json:"priority,omitempty" yaml:"priority,omitempty"` + RemoteAddrs []string `json:"remote_addrs,omitempty" yaml:"remote_addrs,omitempty"` + Timeout *Timeout `json:"timeout,omitempty" yaml:"timeout,omitempty"` + Uris []string `json:"uris" yaml:"uris"` + Vars Vars `json:"vars,omitempty" yaml:"vars,omitempty"` } type Timeout struct { @@ -502,3 +500,49 @@ type ResponseData struct { Value map[string]any `json:"value"` ErrorMsg string `json:"error_msg"` } + +// Vars represents the route match expressions of APISIX. +type Vars [][]StringOrSlice + +// UnmarshalJSON implements json.Unmarshaler interface. +// lua-cjson doesn't distinguish empty array and table, +// and by default empty array will be encoded as '{}'. +// We have to maintain the compatibility. +func (vars *Vars) UnmarshalJSON(p []byte) error { + if p[0] == '{' { + if len(p) != 2 { + return errors.New("unexpected non-empty object") + } + return nil + } + var data [][]StringOrSlice + if err := json.Unmarshal(p, &data); err != nil { + return err + } + *vars = data + return nil +} + +// StringOrSlice represents a string or a string slice. +// TODO Do not use interface{} to avoid the reflection overheads. +type StringOrSlice struct { + StrVal string `json:"-"` + SliceVal []StringOrSlice `json:"-"` +} + +func (s *StringOrSlice) MarshalJSON() ([]byte, error) { + if s.SliceVal != nil { + return json.Marshal(s.SliceVal) + } + return json.Marshal(s.StrVal) +} + +func (s *StringOrSlice) UnmarshalJSON(p []byte) error { + if len(p) == 0 { + return errors.New("empty object") + } + if p[0] == '[' { + return json.Unmarshal(p, &s.SliceVal) + } + return json.Unmarshal(p, &s.StrVal) +} diff --git a/api/common/types.go b/api/common/types.go deleted file mode 100644 index 358857ac3..000000000 --- a/api/common/types.go +++ /dev/null @@ -1,64 +0,0 @@ -// +kubebuilder:object:generate=true - -package common - -import ( - "encoding/json" - "errors" -) - -// Vars represents the route match expressions of APISIX. -type Vars [][]StringOrSlice - -// UnmarshalJSON implements json.Unmarshaler interface. -// lua-cjson doesn't distinguish empty array and table, -// and by default empty array will be encoded as '{}'. -// We have to maintain the compatibility. -func (vars *Vars) UnmarshalJSON(p []byte) error { - if p[0] == '{' { - if len(p) != 2 { - return errors.New("unexpected non-empty object") - } - return nil - } - var data [][]StringOrSlice - if err := json.Unmarshal(p, &data); err != nil { - return err - } - *vars = data - return nil -} - -// StringOrSlice represents a string or a string slice. -// TODO Do not use interface{} to avoid the reflection overheads. -type StringOrSlice struct { - StrVal string `json:"-"` - SliceVal []string `json:"-"` -} - -func (s *StringOrSlice) MarshalJSON() ([]byte, error) { - var ( - p []byte - err error - ) - if s.SliceVal != nil { - p, err = json.Marshal(s.SliceVal) - } else { - p, err = json.Marshal(s.StrVal) - } - return p, err -} - -func (s *StringOrSlice) UnmarshalJSON(p []byte) error { - var err error - - if len(p) == 0 { - return errors.New("empty object") - } - if p[0] == '[' { - err = json.Unmarshal(p, &s.SliceVal) - } else { - err = json.Unmarshal(p, &s.StrVal) - } - return err -} diff --git a/api/common/zz_generated.deepcopy.go b/api/common/zz_generated.deepcopy.go deleted file mode 100644 index ee65e53d2..000000000 --- a/api/common/zz_generated.deepcopy.go +++ /dev/null @@ -1,70 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2024. - -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. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package common - -import () - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StringOrSlice) DeepCopyInto(out *StringOrSlice) { - *out = *in - if in.SliceVal != nil { - in, out := &in.SliceVal, &out.SliceVal - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StringOrSlice. -func (in *StringOrSlice) DeepCopy() *StringOrSlice { - if in == nil { - return nil - } - out := new(StringOrSlice) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in Vars) DeepCopyInto(out *Vars) { - { - in := &in - *out = make(Vars, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = make([]StringOrSlice, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Vars. -func (in Vars) DeepCopy() Vars { - if in == nil { - return nil - } - out := new(Vars) - in.DeepCopyInto(out) - return *out -} diff --git a/api/v1alpha1/httproutepolicy_types.go b/api/v1alpha1/httproutepolicy_types.go index 9da663d36..d2fd74a3d 100644 --- a/api/v1alpha1/httproutepolicy_types.go +++ b/api/v1alpha1/httproutepolicy_types.go @@ -17,10 +17,9 @@ limitations under the License. package v1alpha1 import ( + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - - "github.com/api7/api7-ingress-controller/api/common" ) // HTTPRoutePolicySpec defines the desired state of HTTPRoutePolicy. @@ -36,8 +35,8 @@ type HTTPRoutePolicySpec struct { // +kubebuilder:validation:MaxItems=16 TargetRefs []gatewayv1alpha2.LocalPolicyTargetReferenceWithSectionName `json:"targetRefs"` - Priority *int64 `json:"priority,omitempty" yaml:"priority,omitempty"` - Vars Vars `json:"vars,omitempty" yaml:"vars,omitempty"` + Priority *int64 `json:"priority,omitempty" yaml:"priority,omitempty"` + Vars []apiextensionsv1.JSON `json:"vars,omitempty" yaml:"vars,omitempty"` } // +kubebuilder:object:root=true @@ -61,10 +60,6 @@ type HTTPRoutePolicyList struct { Items []HTTPRoutePolicy `json:"items"` } -// Vars represents the route match expressions of APISIX. -// +kubebuilder:object:generate=false -type Vars = common.Vars - func init() { SchemeBuilder.Register(&HTTPRoutePolicy{}, &HTTPRoutePolicyList{}) } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 04ff10e12..9dc527fa7 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -21,7 +21,6 @@ limitations under the License. package v1alpha1 import ( - "github.com/api7/api7-ingress-controller/api/common" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -554,15 +553,9 @@ func (in *HTTPRoutePolicySpec) DeepCopyInto(out *HTTPRoutePolicySpec) { } if in.Vars != nil { in, out := &in.Vars, &out.Vars - *out = make(common.Vars, len(*in)) + *out = make([]v1.JSON, len(*in)) for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = make([]common.StringOrSlice, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + (*in)[i].DeepCopyInto(&(*out)[i]) } } } diff --git a/config/crd/bases/gateway.apisix.io_httproutepolicies.yaml b/config/crd/bases/gateway.apisix.io_httproutepolicies.yaml index 39b484fcd..f9afb85c8 100644 --- a/config/crd/bases/gateway.apisix.io_httproutepolicies.yaml +++ b/config/crd/bases/gateway.apisix.io_httproutepolicies.yaml @@ -110,14 +110,8 @@ spec: - name x-kubernetes-list-type: map vars: - description: Vars represents the route match expressions of APISIX. items: - items: - description: |- - StringOrSlice represents a string or a string slice. - TODO Do not use interface{} to avoid the reflection overheads. - type: object - type: array + x-kubernetes-preserve-unknown-fields: true type: array required: - targetRefs diff --git a/internal/provider/adc/translator/httproute.go b/internal/provider/adc/translator/httproute.go index 8dea67a97..531fe4e19 100644 --- a/internal/provider/adc/translator/httproute.go +++ b/internal/provider/adc/translator/httproute.go @@ -11,7 +11,6 @@ import ( "k8s.io/apimachinery/pkg/types" gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" - "github.com/api7/api7-ingress-controller/api/common" "github.com/api7/gopkg/pkg/log" adctypes "github.com/api7/api7-ingress-controller/api/adc" @@ -356,14 +355,14 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa case gatewayv1.PathMatchPathPrefix: route.Uris = []string{*match.Path.Value + "*"} case gatewayv1.PathMatchRegularExpression: - var this []common.StringOrSlice - this = append(this, common.StringOrSlice{ + var this []adctypes.StringOrSlice + this = append(this, adctypes.StringOrSlice{ StrVal: "uri", }) - this = append(this, common.StringOrSlice{ + this = append(this, adctypes.StringOrSlice{ StrVal: "~~", }) - this = append(this, common.StringOrSlice{ + this = append(this, adctypes.StringOrSlice{ StrVal: *match.Path.Value, }) @@ -378,25 +377,25 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa name := strings.ToLower(string(header.Name)) name = strings.ReplaceAll(name, "-", "_") - var this []common.StringOrSlice - this = append(this, common.StringOrSlice{ + var this []adctypes.StringOrSlice + this = append(this, adctypes.StringOrSlice{ StrVal: "http_" + name, }) switch *header.Type { case gatewayv1.HeaderMatchExact: - this = append(this, common.StringOrSlice{ + this = append(this, adctypes.StringOrSlice{ StrVal: "==", }) case gatewayv1.HeaderMatchRegularExpression: - this = append(this, common.StringOrSlice{ + this = append(this, adctypes.StringOrSlice{ StrVal: "~~", }) default: return nil, errors.New("unknown header match type " + string(*header.Type)) } - this = append(this, common.StringOrSlice{ + this = append(this, adctypes.StringOrSlice{ StrVal: header.Value, }) @@ -406,25 +405,25 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa if len(match.QueryParams) > 0 { for _, query := range match.QueryParams { - var this []common.StringOrSlice - this = append(this, common.StringOrSlice{ + var this []adctypes.StringOrSlice + this = append(this, adctypes.StringOrSlice{ StrVal: "arg_" + strings.ToLower(fmt.Sprintf("%v", query.Name)), }) switch *query.Type { case gatewayv1.QueryParamMatchExact: - this = append(this, common.StringOrSlice{ + this = append(this, adctypes.StringOrSlice{ StrVal: "==", }) case gatewayv1.QueryParamMatchRegularExpression: - this = append(this, common.StringOrSlice{ + this = append(this, adctypes.StringOrSlice{ StrVal: "~~", }) default: return nil, errors.New("unknown query match type " + string(*query.Type)) } - this = append(this, common.StringOrSlice{ + this = append(this, adctypes.StringOrSlice{ StrVal: query.Value, }) diff --git a/internal/types/duration.go b/internal/types/duration.go index f0b2cc2f1..56d6a4ef7 100644 --- a/internal/types/duration.go +++ b/internal/types/duration.go @@ -35,7 +35,7 @@ func (d *TimeDuration) MarshalJSON() ([]byte, error) { } func (d *TimeDuration) UnmarshalJSON(data []byte) error { - var value interface{} + var value any if err := json.Unmarshal(data, &value); err != nil { return err } @@ -54,11 +54,11 @@ func (d *TimeDuration) UnmarshalJSON(data []byte) error { return nil } -func (d *TimeDuration) MarshalYAML() (interface{}, error) { +func (d *TimeDuration) MarshalYAML() (any, error) { return d.Duration.String(), nil } -func (d *TimeDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (d *TimeDuration) UnmarshalYAML(unmarshal func(any) error) error { var s string if err := unmarshal(&s); err != nil { return err