Skip to content

Commit 37c81ac

Browse files
authored
feat: support httproute (#43)
1 parent b1b39cf commit 37c81ac

File tree

30 files changed

+1364
-99
lines changed

30 files changed

+1364
-99
lines changed

api/dashboard/v1/types.go

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ type Metadata struct {
108108
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
109109
}
110110

111+
func (m *Metadata) GetID() string {
112+
return m.ID
113+
}
114+
115+
func (m *Metadata) GetName() string {
116+
return m.Name
117+
}
118+
119+
func (m *Metadata) GetLabels() map[string]string {
120+
return m.Labels
121+
}
122+
111123
// Upstream is the apisix upstream definition.
112124
// +k8s:deepcopy-gen=true
113125
type Upstream struct {
@@ -615,31 +627,41 @@ func NewDefaultGlobalRule() *GlobalRule {
615627
// ComposeUpstreamName uses namespace, name, subset (optional), port, resolveGranularity info to compose
616628
// the upstream name.
617629
// the resolveGranularity is not composited in the upstream name when it is endpoint.
618-
func ComposeUpstreamName(namespace, name, subset string, port int32, resolveGranularity string) string {
630+
func ComposeUpstreamName(namespace, name string, port int32) string {
619631
pstr := strconv.Itoa(int(port))
620632
// FIXME Use sync.Pool to reuse this buffer if the upstream
621633
// name composing code path is hot.
622634
var p []byte
623635
plen := len(namespace) + len(name) + len(pstr) + 2
624-
if subset != "" {
625-
plen = plen + len(subset) + 1
626-
}
627636

628637
p = make([]byte, 0, plen)
629638
buf := bytes.NewBuffer(p)
630639
buf.WriteString(namespace)
631640
buf.WriteByte('_')
632641
buf.WriteString(name)
633642
buf.WriteByte('_')
634-
if subset != "" {
635-
buf.WriteString(subset)
636-
buf.WriteByte('_')
637-
}
638643
buf.WriteString(pstr)
639644

640645
return buf.String()
641646
}
642647

648+
func ComposeServiceNameWithRule(namespace, name string, rule string) string {
649+
// FIXME Use sync.Pool to reuse this buffer if the upstream
650+
// name composing code path is hot.
651+
var p []byte
652+
plen := len(namespace) + len(name) + 2
653+
654+
p = make([]byte, 0, plen)
655+
buf := bytes.NewBuffer(p)
656+
buf.WriteString(namespace)
657+
buf.WriteByte('_')
658+
buf.WriteString(name)
659+
buf.WriteByte('_')
660+
buf.WriteString(rule)
661+
662+
return buf.String()
663+
}
664+
643665
// ComposeExternalUpstreamName uses ApisixUpstream namespace, name to compose the upstream name.
644666
func ComposeExternalUpstreamName(namespace, name string) string {
645667
return namespace + "_" + name

cmd/root/root.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package root
1818

1919
import (
2020
"fmt"
21+
"os"
2122

2223
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
2324
// to ensure that exec-entrypoint and run can make use of them.
@@ -26,16 +27,17 @@ import (
2627
"gopkg.in/yaml.v2"
2728
_ "k8s.io/client-go/plugin/pkg/client/auth"
2829

29-
ctrl "sigs.k8s.io/controller-runtime"
30-
"sigs.k8s.io/controller-runtime/pkg/log/zap"
31-
30+
"github.com/go-logr/zapr"
3231
"github.com/spf13/cobra"
32+
"go.uber.org/zap"
33+
ctrl "sigs.k8s.io/controller-runtime"
3334

3435
// +kubebuilder:scaffold:imports
3536

3637
"github.com/api7/api7-ingress-controller/internal/controller/config"
3738
"github.com/api7/api7-ingress-controller/internal/manager"
3839
"github.com/api7/api7-ingress-controller/internal/version"
40+
"github.com/api7/gopkg/pkg/log"
3941
)
4042

4143
type ControlPlanesFlag struct {
@@ -115,13 +117,27 @@ func newAPI7IngressController() *cobra.Command {
115117
return err
116118
}
117119

118-
logger := zap.New(zap.UseFlagOptions(&zap.Options{
119-
Development: true,
120-
Level: logLevel,
121-
}))
120+
// dashboard sdk log
121+
l, err := log.NewLogger(
122+
log.WithOutputFile("stderr"),
123+
log.WithLogLevel(cfg.LogLevel),
124+
log.WithSkipFrames(3),
125+
)
126+
if err != nil {
127+
return err
128+
}
129+
log.DefaultLogger = l
130+
131+
// controllers log
132+
core := zapcore.NewCore(
133+
zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
134+
zapcore.AddSync(zapcore.Lock(os.Stderr)),
135+
logLevel,
136+
)
137+
logger := zapr.NewLogger(zap.New(core, zap.AddCaller()))
122138

123139
logger.Info("controller start configuration", "config", cfg)
124-
ctrl.SetLogger(logger)
140+
ctrl.SetLogger(logger.WithName("controller-runtime"))
125141

126142
ctx := ctrl.LoggerInto(cmd.Context(), logger)
127143
return manager.Run(ctx, logger)

config/rbac/role.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ rules:
1111
verbs:
1212
- create
1313
- patch
14+
- apiGroups:
15+
- ""
16+
resources:
17+
- services
18+
verbs:
19+
- get
20+
- list
21+
- watch
1422
- apiGroups:
1523
- coordination.k8s.io
1624
resources:
@@ -23,6 +31,14 @@ rules:
2331
- patch
2432
- update
2533
- watch
34+
- apiGroups:
35+
- discovery.k8s.io
36+
resources:
37+
- endpointslices
38+
verbs:
39+
- get
40+
- list
41+
- watch
2642
- apiGroups:
2743
- gateway.apisix.io.github.com
2844
resources:
@@ -81,3 +97,18 @@ rules:
8197
verbs:
8298
- get
8399
- update
100+
- apiGroups:
101+
- gateway.networking.k8s.io
102+
resources:
103+
- httproutes
104+
verbs:
105+
- get
106+
- list
107+
- watch
108+
- apiGroups:
109+
- gateway.networking.k8s.io
110+
resources:
111+
- httproutes/status
112+
verbs:
113+
- get
114+
- update

internal/controller/config/config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,10 @@ func (c *Config) validateControlPlanes(cpc []*ControlPlaneConfig) error {
9494
if len(cp.AdminAPI.Endpoints) == 0 {
9595
return fmt.Errorf("control_planes[].admin_api.endpoints is required")
9696
}
97-
cp.AdminAPI.TLSVerify = new(bool)
98-
*cp.AdminAPI.TLSVerify = true
97+
if cp.AdminAPI.TLSVerify == nil {
98+
cp.AdminAPI.TLSVerify = new(bool)
99+
*cp.AdminAPI.TLSVerify = true
100+
}
99101
}
100102
return nil
101103
}

internal/controller/gateway_controller.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"sigs.k8s.io/controller-runtime/pkg/handler"
1515
"sigs.k8s.io/controller-runtime/pkg/predicate"
1616
"sigs.k8s.io/controller-runtime/pkg/reconcile"
17-
gatewayapi "sigs.k8s.io/gateway-api/apis/v1"
17+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
1818
)
1919

2020
// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways,verbs=get;list;watch;update
@@ -31,7 +31,7 @@ type GatewayReconciler struct { //nolint:revive
3131
// SetupWithManager sets up the controller with the Manager.
3232
func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
3333
return ctrl.NewControllerManagedBy(mgr).
34-
For(&gatewayapi.Gateway{},
34+
For(&gatewayv1.Gateway{},
3535
builder.WithPredicates(
3636
predicate.And(
3737
predicate.NewPredicateFuncs(r.matchesGatewayForControlPlaneConfig),
@@ -40,7 +40,7 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
4040
),
4141
).
4242
Watches(
43-
&gatewayapi.GatewayClass{},
43+
&gatewayv1.GatewayClass{},
4444
handler.EnqueueRequestsFromMapFunc(r.listGatewayForGatewayClass),
4545
builder.WithPredicates(predicate.NewPredicateFuncs(r.matchesGatewayClass)),
4646
).
@@ -50,31 +50,31 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
5050
}
5151

5252
func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
53-
var gateway gatewayapi.Gateway
54-
if err := r.Get(ctx, req.NamespacedName, &gateway); err != nil {
53+
gateway := new(gatewayv1.Gateway)
54+
if err := r.Get(ctx, req.NamespacedName, gateway); err != nil {
5555
return ctrl.Result{}, client.IgnoreNotFound(err)
5656
}
5757

5858
condition := meta.Condition{
59-
Type: string(gatewayapi.GatewayConditionAccepted),
59+
Type: string(gatewayv1.GatewayConditionAccepted),
6060
Status: meta.ConditionTrue,
61-
Reason: string(gatewayapi.GatewayReasonAccepted),
61+
Reason: string(gatewayv1.GatewayReasonAccepted),
6262
ObservedGeneration: gateway.Generation,
6363
Message: acceptedMessage("gateway"),
6464
LastTransitionTime: meta.Now(),
6565
}
6666
if !IsConditionPresentAndEqual(gateway.Status.Conditions, condition) {
6767
r.Log.Info("gateway has been accepted", "gateway", gateway.Name)
68-
setGatewayCondition(&gateway, condition)
69-
if err := r.Status().Update(ctx, &gateway); err != nil {
68+
setGatewayCondition(gateway, condition)
69+
if err := r.Status().Update(ctx, gateway); err != nil {
7070
return ctrl.Result{}, err
7171
}
7272
}
7373
return ctrl.Result{}, nil
7474
}
7575

7676
func (r *GatewayReconciler) matchesGatewayClass(obj client.Object) bool {
77-
gateway, ok := obj.(*gatewayapi.GatewayClass)
77+
gateway, ok := obj.(*gatewayv1.GatewayClass)
7878
if !ok {
7979
r.Log.Error(fmt.Errorf("unexpected object type"), "failed to convert object to Gateway")
8080
return false
@@ -83,7 +83,7 @@ func (r *GatewayReconciler) matchesGatewayClass(obj client.Object) bool {
8383
}
8484

8585
func (r *GatewayReconciler) matchesGatewayForControlPlaneConfig(obj client.Object) bool {
86-
gateway, ok := obj.(*gatewayapi.Gateway)
86+
gateway, ok := obj.(*gatewayv1.Gateway)
8787
if !ok {
8888
r.Log.Error(fmt.Errorf("unexpected object type"), "failed to convert object to Gateway")
8989
return false
@@ -97,15 +97,15 @@ func (r *GatewayReconciler) matchesGatewayForControlPlaneConfig(obj client.Objec
9797
}
9898

9999
func (r *GatewayReconciler) listGatewayForGatewayClass(ctx context.Context, gatewayClass client.Object) []reconcile.Request {
100-
gatewayList := &gatewayapi.GatewayList{}
100+
gatewayList := &gatewayv1.GatewayList{}
101101
if err := r.List(context.Background(), gatewayList); err != nil {
102102
r.Log.Error(err, "failed to list gateways for gateway class",
103103
"gatewayclass", gatewayClass.GetName(),
104104
)
105105
return nil
106106
}
107107

108-
gateways := []gatewayapi.Gateway{}
108+
gateways := []gatewayv1.Gateway{}
109109
for _, gateway := range gatewayList.Items {
110110
if cp := config.GetControlPlaneConfigByGatewatName(gateway.GetName()); cp != nil {
111111
gateways = append(gateways, gateway)
@@ -115,13 +115,13 @@ func (r *GatewayReconciler) listGatewayForGatewayClass(ctx context.Context, gate
115115
}
116116

117117
func (r *GatewayReconciler) checkGatewayClass(obj client.Object) bool {
118-
gateway, ok := obj.(*gatewayapi.Gateway)
118+
gateway, ok := obj.(*gatewayv1.Gateway)
119119
if !ok {
120120
r.Log.Error(fmt.Errorf("unexpected object type"), "failed to convert object to Gateway")
121121
return false
122122
}
123123

124-
gatewayClass := &gatewayapi.GatewayClass{}
124+
gatewayClass := &gatewayv1.GatewayClass{}
125125
if err := r.Client.Get(context.Background(), client.ObjectKey{Name: string(gateway.Spec.GatewayClassName)}, gatewayClass); err != nil {
126126
r.Log.Error(err, "failed to get gateway class", "gatewayclass", gateway.Spec.GatewayClassName)
127127
return false

internal/controller/gatewayclass_congroller.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
ctrl "sigs.k8s.io/controller-runtime"
1212
"sigs.k8s.io/controller-runtime/pkg/client"
1313
"sigs.k8s.io/controller-runtime/pkg/predicate"
14-
gatewayapi "sigs.k8s.io/gateway-api/apis/v1"
14+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
1515
)
1616

1717
// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gatewayclasses,verbs=get;list;watch;update
@@ -28,39 +28,39 @@ type GatewayClassReconciler struct { //nolint:revive
2828
// SetupWithManager sets up the controller with the Manager.
2929
func (r *GatewayClassReconciler) SetupWithManager(mgr ctrl.Manager) error {
3030
return ctrl.NewControllerManagedBy(mgr).
31-
For(&gatewayapi.GatewayClass{}).
31+
For(&gatewayv1.GatewayClass{}).
3232
WithEventFilter(predicate.NewPredicateFuncs(r.GatewayClassFilter)).
3333
WithEventFilter(predicate.GenerationChangedPredicate{}).
3434
Complete(r)
3535
}
3636

3737
func (r *GatewayClassReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
38-
var gc gatewayapi.GatewayClass
39-
if err := r.Get(ctx, req.NamespacedName, &gc); err != nil {
38+
gc := new(gatewayv1.GatewayClass)
39+
if err := r.Get(ctx, req.NamespacedName, gc); err != nil {
4040
return ctrl.Result{}, client.IgnoreNotFound(err)
4141
}
4242

4343
condition := meta.Condition{
44-
Type: string(gatewayapi.GatewayClassConditionStatusAccepted),
44+
Type: string(gatewayv1.GatewayClassConditionStatusAccepted),
4545
Status: meta.ConditionTrue,
46-
Reason: string(gatewayapi.GatewayClassReasonAccepted),
46+
Reason: string(gatewayv1.GatewayClassReasonAccepted),
4747
ObservedGeneration: gc.Generation,
4848
Message: "the gatewayclass has been accepted by the api7-ingress-controller",
4949
LastTransitionTime: meta.Now(),
5050
}
5151

5252
if !IsConditionPresentAndEqual(gc.Status.Conditions, condition) {
5353
r.Log.Info("gatewayclass has been accepted", "gatewayclass", gc.Name)
54-
setGatewayClassCondition(&gc, condition)
55-
if err := r.Status().Update(ctx, &gc); err != nil {
54+
setGatewayClassCondition(gc, condition)
55+
if err := r.Status().Update(ctx, gc); err != nil {
5656
return ctrl.Result{}, err
5757
}
5858
}
5959
return ctrl.Result{}, nil
6060
}
6161

6262
func (r *GatewayClassReconciler) GatewayClassFilter(obj client.Object) bool {
63-
gatewayClass, ok := obj.(*gatewayapi.GatewayClass)
63+
gatewayClass, ok := obj.(*gatewayv1.GatewayClass)
6464
if !ok {
6565
r.Log.Error(fmt.Errorf("unexpected object type"), "failed to convert object to GatewayClass")
6666
return false
@@ -73,7 +73,7 @@ func matchesController(controllerName string) bool {
7373
return controllerName == config.ControllerConfig.ControllerName
7474
}
7575

76-
func setGatewayClassCondition(gwc *gatewayapi.GatewayClass, newCondition meta.Condition) {
76+
func setGatewayClassCondition(gwc *gatewayv1.GatewayClass, newCondition meta.Condition) {
7777
newConditions := []meta.Condition{}
7878
for _, condition := range gwc.Status.Conditions {
7979
if condition.Type != newCondition.Type {

0 commit comments

Comments
 (0)