Skip to content

Commit e4b2523

Browse files
committed
Update HTTPRoutePolicy and related components
This commit updates the `HTTPRoutePolicy` CRD with more detailed validation for Kubernetes object references, adds status and ancestor information to the policy, and updates the corresponding controller and test files. Additionally, it refactors the `StringOrSlice` type and adjusts the indexing and translation logic.
1 parent acee110 commit e4b2523

File tree

11 files changed

+224
-96
lines changed

11 files changed

+224
-96
lines changed

api/common/types.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,26 @@ func (vars *Vars) UnmarshalJSON(p []byte) error {
3131

3232
// StringOrSlice represents a string or a string slice.
3333
// TODO Do not use interface{} to avoid the reflection overheads.
34+
//
35+
// +kubebuilder:validation:Schemaless
3436
type StringOrSlice struct {
35-
StrVal string `json:"-"`
36-
SliceVal []string `json:"-"`
37+
StrVal string `json:"-"`
38+
SliceVal []StringOrSlice `json:"-"`
3739
}
3840

3941
func (s *StringOrSlice) MarshalJSON() ([]byte, error) {
40-
var (
41-
p []byte
42-
err error
43-
)
4442
if s.SliceVal != nil {
45-
p, err = json.Marshal(s.SliceVal)
46-
} else {
47-
p, err = json.Marshal(s.StrVal)
43+
return json.Marshal(s.SliceVal)
4844
}
49-
return p, err
45+
return json.Marshal(s.StrVal)
5046
}
5147

5248
func (s *StringOrSlice) UnmarshalJSON(p []byte) error {
53-
var err error
54-
5549
if len(p) == 0 {
5650
return errors.New("empty object")
5751
}
5852
if p[0] == '[' {
59-
err = json.Unmarshal(p, &s.SliceVal)
60-
} else {
61-
err = json.Unmarshal(p, &s.StrVal)
53+
return json.Unmarshal(p, &s.SliceVal)
6254
}
63-
return err
55+
return json.Unmarshal(p, &s.StrVal)
6456
}

api/common/zz_generated.deepcopy.go

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha1/httproutepolicy_types.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ limitations under the License.
1717
package v1alpha1
1818

1919
import (
20+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2021
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
v1 "sigs.k8s.io/gateway-api/apis/v1"
2123
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
22-
23-
"github.com/api7/api7-ingress-controller/api/common"
2424
)
2525

2626
// HTTPRoutePolicySpec defines the desired state of HTTPRoutePolicy.
@@ -34,10 +34,20 @@ type HTTPRoutePolicySpec struct {
3434
// +listMapKey=name
3535
// +kubebuilder:validation:MinItems=1
3636
// +kubebuilder:validation:MaxItems=16
37-
TargetRefs []gatewayv1alpha2.LocalPolicyTargetReferenceWithSectionName `json:"targetRefs"`
37+
TargetRefs []TargetReference `json:"targetRefs"`
38+
39+
Priority *int64 `json:"priority,omitempty" yaml:"priority,omitempty"`
40+
Vars []apiextensionsv1.JSON `json:"vars,omitempty" yaml:"vars,omitempty"`
41+
}
3842

39-
Priority *int64 `json:"priority,omitempty" yaml:"priority,omitempty"`
40-
Vars Vars `json:"vars,omitempty" yaml:"vars,omitempty"`
43+
type TargetReference struct {
44+
Group v1.Group `json:"group"`
45+
Kind v1.Kind `json:"kind"`
46+
// +optional
47+
Namespace *v1.Namespace `json:"namespace,omitempty"`
48+
Name v1.ObjectName `json:"name"`
49+
// +optional
50+
SectionName *v1.SectionName `json:"sectionName,omitempty"`
4151
}
4252

4353
// +kubebuilder:object:root=true
@@ -61,10 +71,6 @@ type HTTPRoutePolicyList struct {
6171
Items []HTTPRoutePolicy `json:"items"`
6272
}
6373

64-
// Vars represents the route match expressions of APISIX.
65-
// +kubebuilder:object:generate=false
66-
type Vars = common.Vars
67-
6874
func init() {
6975
SchemeBuilder.Register(&HTTPRoutePolicy{}, &HTTPRoutePolicyList{})
7076
}

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 29 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/gateway.apisix.io_httproutepolicies.yaml

Lines changed: 93 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,49 +49,121 @@ spec:
4949
5050
target references.
5151
items:
52-
description: |-
53-
LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a
54-
direct policy to. This should be used as part of Policy resources that can
55-
target single resources. For more information on how this policy attachment
56-
mode works, and a sample Policy resource, refer to the policy attachment
57-
documentation for Gateway API.
58-
59-
60-
Note: This should only be used for direct policy attachment when references
61-
to SectionName are actually needed. In all other cases,
62-
LocalPolicyTargetReference should be used.
6352
properties:
6453
group:
65-
description: Group is the group of the target resource.
54+
description: |-
55+
Group refers to a Kubernetes Group. It must either be an empty string or a
56+
RFC 1123 subdomain.
57+
58+
59+
This validation is based off of the corresponding Kubernetes validation:
60+
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L208
61+
62+
63+
Valid values include:
64+
65+
66+
* "" - empty string implies core Kubernetes API group
67+
* "gateway.networking.k8s.io"
68+
* "foo.example.com"
69+
70+
71+
Invalid values include:
72+
73+
74+
* "example.com/bar" - "/" is an invalid character
6675
maxLength: 253
6776
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
6877
type: string
6978
kind:
70-
description: Kind is kind of the target resource.
79+
description: |-
80+
Kind refers to a Kubernetes Kind.
81+
82+
83+
Valid values include:
84+
85+
86+
* "Service"
87+
* "HTTPRoute"
88+
89+
90+
Invalid values include:
91+
92+
93+
* "invalid/kind" - "/" is an invalid character
7194
maxLength: 63
7295
minLength: 1
7396
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
7497
type: string
7598
name:
76-
description: Name is the name of the target resource.
99+
description: |-
100+
ObjectName refers to the name of a Kubernetes object.
101+
Object names can have a variety of forms, including RFC 1123 subdomains,
102+
RFC 1123 labels, or RFC 1035 labels.
77103
maxLength: 253
78104
minLength: 1
79105
type: string
106+
namespace:
107+
description: |-
108+
Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
109+
110+
111+
This validation is based off of the corresponding Kubernetes validation:
112+
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
113+
114+
115+
This is used for Namespace name validation here:
116+
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
117+
118+
119+
Valid values include:
120+
121+
122+
* "example"
123+
124+
125+
Invalid values include:
126+
127+
128+
* "example.com" - "." is an invalid character
129+
maxLength: 63
130+
minLength: 1
131+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
132+
type: string
80133
sectionName:
81134
description: |-
82-
SectionName is the name of a section within the target resource. When
83-
unspecified, this targetRef targets the entire resource. In the following
84-
resources, SectionName is interpreted as the following:
135+
SectionName is the name of a section in a Kubernetes resource.
136+
137+
138+
In the following resources, SectionName is interpreted as the following:
85139
86140
87141
* Gateway: Listener name
88142
* HTTPRoute: HTTPRouteRule name
89143
* Service: Port name
90144
91145
92-
If a SectionName is specified, but does not exist on the targeted object,
93-
the Policy must fail to attach, and the policy implementation should record
94-
a `ResolvedRefs` or similar Condition in the Policy's status.
146+
Section names can have a variety of forms, including RFC 1123 subdomains,
147+
RFC 1123 labels, or RFC 1035 labels.
148+
149+
150+
This validation is based off of the corresponding Kubernetes validation:
151+
https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L208
152+
153+
154+
Valid values include:
155+
156+
157+
* "example"
158+
* "foo-example"
159+
* "example.com"
160+
* "foo.example.com"
161+
162+
163+
Invalid values include:
164+
165+
166+
* "example.com/bar" - "/" is an invalid character
95167
maxLength: 253
96168
minLength: 1
97169
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -110,14 +182,8 @@ spec:
110182
- name
111183
x-kubernetes-list-type: map
112184
vars:
113-
description: Vars represents the route match expressions of APISIX.
114185
items:
115-
items:
116-
description: |-
117-
StringOrSlice represents a string or a string slice.
118-
TODO Do not use interface{} to avoid the reflection overheads.
119-
type: object
120-
type: array
186+
x-kubernetes-preserve-unknown-fields: true
121187
type: array
122188
required:
123189
- targetRefs

internal/controller/httproute_controller.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import (
55
"fmt"
66
"strings"
77

8+
"github.com/api7/api7-ingress-controller/internal/controller/config"
89
"github.com/go-logr/logr"
910
corev1 "k8s.io/api/core/v1"
1011
discoveryv1 "k8s.io/api/discovery/v1"
12+
"k8s.io/apimachinery/pkg/api/meta"
1113
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1214
"k8s.io/apimachinery/pkg/runtime"
1315
"k8s.io/apimachinery/pkg/types"
@@ -19,6 +21,7 @@ import (
1921
"sigs.k8s.io/controller-runtime/pkg/predicate"
2022
"sigs.k8s.io/controller-runtime/pkg/reconcile"
2123
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
24+
"sigs.k8s.io/gateway-api/apis/v1alpha2"
2225

2326
"github.com/api7/api7-ingress-controller/api/v1alpha1"
2427
"github.com/api7/api7-ingress-controller/internal/controller/indexer"
@@ -386,6 +389,24 @@ func (r *HTTPRouteReconciler) processHTTPRoute(tctx *provider.TranslateContext,
386389
}
387390
for _, item := range httpRoutePolicyList.Items {
388391
tctx.HTTPRoutePolicies[ruleName] = append(tctx.HTTPRoutePolicies[key], item.Spec)
392+
item.Status.Ancestors = []v1alpha2.PolicyAncestorStatus{
393+
{
394+
AncestorRef: v1alpha2.ParentReference{
395+
Group: nil,
396+
Kind: nil,
397+
Namespace: nil,
398+
Name: gatewayv1.ObjectName(httpRoute.GetName()),
399+
SectionName: nil,
400+
Port: nil,
401+
},
402+
ControllerName: v1alpha2.GatewayController(config.GetControllerName()),
403+
Conditions: []metav1.Condition{},
404+
},
405+
}
406+
meta.SetStatusCondition(&item.Status.Ancestors[0].Conditions, NewCondition(item.Generation, true, "Successfully"))
407+
if err := r.Status().Update(context.Background(), &item); err != nil {
408+
r.Log.Error(err, "failed to Update policy status")
409+
}
389410
}
390411
}
391412

0 commit comments

Comments
 (0)