Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NET-7450] setup crud hooks for APIGateway v2 #3580

Merged
merged 6 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions charts/consul/templates/crd-apigateways.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,6 @@ spec:
format: date-time
type: string
type: object
required:
- addresses
- listeners
type: object
type: object
served: true
Expand Down
34 changes: 17 additions & 17 deletions control-plane/api/mesh/v2beta1/api_gateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const (
)

func init() {
MeshSchemeBuilder.Register(&GatewayClass{}, &GatewayClassList{}, &APIGateway{}, &APIGatewayList{})
MeshSchemeBuilder.Register(&APIGateway{}, &APIGatewayList{})
}

// +kubebuilder:object:root=true
Expand All @@ -46,22 +46,8 @@ type APIGateway struct {

type APIGatewayStatus struct {
Status `json:"status,omitempty"`
Addresses []GatewayAddress `json:"addresses"`
Listeners []ListenerStatus `json:"listeners"`
}

func (in *APIGatewayList) ReconcileRequests() []reconcile.Request {
requests := make([]reconcile.Request, 0, len(in.Items))

for _, item := range in.Items {
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: item.Name,
Namespace: item.Namespace,
},
})
}
return requests
Addresses []GatewayAddress `json:"addresses,omitempty"`
Listeners []ListenerStatus `json:"listeners,omitempty"`
}

type ListenerStatus struct {
Expand All @@ -85,6 +71,20 @@ type APIGatewayList struct {
Items []*APIGateway `json:"items"`
}

func (in *APIGatewayList) ReconcileRequests() []reconcile.Request {
requests := make([]reconcile.Request, 0, len(in.Items))

for _, item := range in.Items {
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: item.Name,
Namespace: item.Namespace,
},
})
}
return requests
}

func (in *APIGateway) ResourceID(namespace, partition string) *pbresource.ID {
return &pbresource.ID{
Name: in.Name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,6 @@ spec:
format: date-time
type: string
type: object
required:
- addresses
- listeners
type: object
type: object
served: true
Expand Down
39 changes: 23 additions & 16 deletions control-plane/controllers/resources/api-gateway-controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"

meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1"
"github.com/hashicorp/consul-k8s/control-plane/gateways"
)

// APIGatewayController reconciles a APIGateway object.
type APIGatewayController struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
Controller *ConsulResourceController
Log logr.Logger
Scheme *runtime.Scheme
Controller *ConsulResourceController
GatewayConfig gateways.GatewayConfig
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear on this -- is this derived from the global helm configuration? The idea of GatewayConfig just seems kind of close to GatewayClassConfig to me, so the naming is slightly confusing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, this is an existing struct we have that takes the gateway specific stuff from the helm chart, I'm down for renaming it as it is very similar to GatewayClassConfig

}

// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=tcproute,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -40,14 +42,29 @@ func (r *APIGatewayController) Reconcile(ctx context.Context, req ctrl.Request)
}

// Call hooks
if !resource.DeletionTimestamp.IsZero() {
if !resource.GetDeletionTimestamp().IsZero() {
logger.Info("deletion event")

if err := r.onDelete(ctx, req, resource); err != nil {
if err := onDelete(ctx, req, r.Client, resource); err != nil {
return ctrl.Result{}, err
}
} else {
if err := r.onCreateUpdate(ctx, req, resource); err != nil {
// Fetch GatewayClassConfig for the gateway
if resource.Namespace == "" {
resource.Namespace = "default"
}

gcc, err := getGatewayClassConfigByGatewayClassName(ctx, r.Client, resource.Spec.GatewayClassName)
if err != nil {
r.Log.Error(err, "unable to get gatewayclassconfig for gateway: %s gatewayclass: %s", resource.Name, resource.Spec.GatewayClassName)
return ctrl.Result{}, err
}

if err := onCreateUpdate(ctx, r.Client, gatewayConfigs{
gcc: gcc,
gatewayConfig: r.GatewayConfig,
}, resource, gateways.APIGatewayAnnotationKind); err != nil {
logger.Error(err, "unable to create/update gateway")
return ctrl.Result{}, err
}
}
Expand All @@ -66,13 +83,3 @@ func (r *APIGatewayController) UpdateStatus(ctx context.Context, obj client.Obje
func (r *APIGatewayController) SetupWithManager(mgr ctrl.Manager) error {
return setupGatewayControllerWithManager[*meshv2beta1.APIGatewayList](mgr, &meshv2beta1.APIGateway{}, r.Client, r, APIGateway_GatewayClassIndex)
}

func (r *APIGatewayController) onCreateUpdate(ctx context.Context, req ctrl.Request, resource *meshv2beta1.APIGateway) error {
// TODO: NET-7449, NET-7450, and NET-7451
return nil
}

func (r *APIGatewayController) onDelete(ctx context.Context, req ctrl.Request, resource *meshv2beta1.APIGateway) error {
// TODO: NET-7449, NET-7450, and NET-7451
return nil
}
20 changes: 16 additions & 4 deletions control-plane/controllers/resources/api-gateway-controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import (
"google.golang.org/protobuf/testing/protocmp"

logrtest "github.com/go-logr/logr/testr"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand All @@ -31,10 +34,19 @@ func TestAPIGatewayController_ReconcileResourceExists(t *testing.T) {
ctx := context.Background()

s := runtime.NewScheme()
s.AddKnownTypes(schema.GroupVersion{
Group: "mesh.consul.hashicorp.com",
Version: pbmesh.Version,
}, &v2beta1.APIGateway{}, &v2beta1.APIGatewayList{})
require.NoError(t, corev1.AddToScheme(s))
require.NoError(t, appsv1.AddToScheme(s))
require.NoError(t, rbacv1.AddToScheme(s))
require.NoError(t, v2beta1.AddMeshToScheme(s))
s.AddKnownTypes(
schema.GroupVersion{
Group: "mesh.consul.hashicorp.com",
Version: pbmesh.Version,
},
&v2beta1.APIGateway{},
&v2beta1.GatewayClass{},
&v2beta1.GatewayClassConfig{},
)

apiGW := &v2beta1.APIGateway{
ObjectMeta: metav1.ObjectMeta{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package resources

import (
Expand Down Expand Up @@ -31,8 +34,8 @@ type gatewayConfigs struct {
// 3. Service
// 4. Role
// 5. RoleBinding
func onCreateUpdate[T gateways.Gateway](ctx context.Context, k8sClient client.Client, cfg gatewayConfigs, resource T) error {
builder := gateways.NewGatewayBuilder[T](resource, cfg.gatewayConfig, cfg.gcc)
func onCreateUpdate[T gateways.Gateway](ctx context.Context, k8sClient client.Client, cfg gatewayConfigs, resource T, gatewayKind string) error {
builder := gateways.NewGatewayBuilder[T](resource, cfg.gatewayConfig, cfg.gcc, gatewayKind)

// Create ServiceAccount
desiredAccount := builder.ServiceAccount()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (r *MeshGatewayController) Reconcile(ctx context.Context, req ctrl.Request)
if err := onCreateUpdate(ctx, r.Client, gatewayConfigs{
gcc: gcc,
gatewayConfig: r.GatewayConfig,
}, resource); err != nil {
}, resource, gateways.MeshGatewayAnnotationKind); err != nil {
return ctrl.Result{}, err
}
}
Expand Down
16 changes: 9 additions & 7 deletions control-plane/gateways/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ type Gateway interface {
// This includes Deployment, Role, Service, and ServiceAccount resources.
// Configuration is combined from the MeshGateway, GatewayConfig, and GatewayClassConfig.
type gatewayBuilder[T Gateway] struct {
gateway T
gcc *meshv2beta1.GatewayClassConfig
config GatewayConfig
gateway T
gcc *meshv2beta1.GatewayClassConfig
config GatewayConfig
gatewayKind string
}

// NewGatewayBuilder returns a new meshGatewayBuilder for the given MeshGateway,
// GatewayConfig, and GatewayClassConfig.
func NewGatewayBuilder[T Gateway](gateway T, gatewayConfig GatewayConfig, gatewayClassConfig *meshv2beta1.GatewayClassConfig) *gatewayBuilder[T] {
func NewGatewayBuilder[T Gateway](gateway T, gatewayConfig GatewayConfig, gatewayClassConfig *meshv2beta1.GatewayClassConfig, gatewayKind string) *gatewayBuilder[T] {
return &gatewayBuilder[T]{
gateway: gateway,
config: gatewayConfig,
gcc: gatewayClassConfig,
gateway: gateway,
config: gatewayConfig,
gcc: gatewayClassConfig,
gatewayKind: gatewayKind,
}
}
5 changes: 3 additions & 2 deletions control-plane/gateways/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import (

const (
globalDefaultInstances int32 = 1
meshGatewayAnnotationKind = "mesh-gateway"
MeshGatewayAnnotationKind = "mesh-gateway"
APIGatewayAnnotationKind = "api-gateway"
)

func (b *gatewayBuilder[T]) Deployment() (*appsv1.Deployment, error) {
Expand Down Expand Up @@ -67,7 +68,7 @@ func (b *gatewayBuilder[T]) deploymentSpec() (*appsv1.DeploymentSpec, error) {
Annotations: map[string]string{
// Indicate that this pod is a mesh gateway pod so that the Pod controller,
// consul-k8s CLI, etc. can key off of it
constants.AnnotationGatewayKind: meshGatewayAnnotationKind,
constants.AnnotationGatewayKind: b.gatewayKind,
// It's not logical to add a proxy sidecar since our workload is itself a proxy
constants.AnnotationMeshInject: "false",
// This functionality only applies when proxy sidecars are used
Expand Down
13 changes: 7 additions & 6 deletions control-plane/gateways/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func Test_gatewayBuilder_Deployment(t *testing.T) {
"release": "consul",
},
Annotations: map[string]string{
constants.AnnotationGatewayKind: meshGatewayAnnotationKind,
constants.AnnotationGatewayKind: MeshGatewayAnnotationKind,
constants.AnnotationMeshInject: "false",
constants.AnnotationTransparentProxyOverwriteProbes: "false",
constants.AnnotationGatewayWANSource: "Service",
Expand Down Expand Up @@ -607,7 +607,7 @@ func Test_gatewayBuilder_Deployment(t *testing.T) {
"release": "consul",
},
Annotations: map[string]string{
constants.AnnotationGatewayKind: meshGatewayAnnotationKind,
constants.AnnotationGatewayKind: MeshGatewayAnnotationKind,
constants.AnnotationMeshInject: "false",
constants.AnnotationTransparentProxyOverwriteProbes: "false",
constants.AnnotationGatewayWANSource: "Service",
Expand Down Expand Up @@ -918,7 +918,7 @@ func Test_gatewayBuilder_Deployment(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Labels: defaultLabels,
Annotations: map[string]string{
constants.AnnotationGatewayKind: meshGatewayAnnotationKind,
constants.AnnotationGatewayKind: MeshGatewayAnnotationKind,
constants.AnnotationMeshInject: "false",
constants.AnnotationTransparentProxyOverwriteProbes: "false",
constants.AnnotationGatewayWANSource: "Service",
Expand Down Expand Up @@ -1140,9 +1140,10 @@ func Test_gatewayBuilder_Deployment(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := &gatewayBuilder[*meshv2beta1.MeshGateway]{
gateway: tt.fields.gateway,
config: tt.fields.config,
gcc: tt.fields.gcc,
gateway: tt.fields.gateway,
config: tt.fields.config,
gcc: tt.fields.gcc,
gatewayKind: MeshGatewayAnnotationKind,
}
got, err := b.Deployment()
if !tt.wantErr && (err != nil) {
Expand Down
6 changes: 3 additions & 3 deletions control-plane/gateways/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func TestGatewayBuilder_Annotations(t *testing.T) {
},
}

b := NewGatewayBuilder[*meshv2beta1.MeshGateway](gateway, GatewayConfig{}, gatewayClassConfig)
b := NewGatewayBuilder[*meshv2beta1.MeshGateway](gateway, GatewayConfig{}, gatewayClassConfig, MeshGatewayAnnotationKind)

for _, testCase := range []struct {
Actual map[string]string
Expand Down Expand Up @@ -198,7 +198,7 @@ func TestGatewayBuilder_Labels(t *testing.T) {
},
}

b := NewGatewayBuilder[*meshv2beta1.MeshGateway](gateway, GatewayConfig{}, gatewayClassConfig)
b := NewGatewayBuilder[*meshv2beta1.MeshGateway](gateway, GatewayConfig{}, gatewayClassConfig, MeshGatewayAnnotationKind)

for _, testCase := range []struct {
Actual map[string]string
Expand Down Expand Up @@ -298,7 +298,7 @@ func TestGatewayBuilder_LogLevel(t *testing.T) {
},
},
}
b := NewGatewayBuilder(&meshv2beta1.MeshGateway{}, GatewayConfig{LogLevel: testCase.GatewayLogLevel}, gcc)
b := NewGatewayBuilder(&meshv2beta1.MeshGateway{}, GatewayConfig{LogLevel: testCase.GatewayLogLevel}, gcc, MeshGatewayAnnotationKind)

assert.Equal(t, debug, b.logLevelForDataplaneContainer())
})
Expand Down
2 changes: 1 addition & 1 deletion control-plane/gateways/serviceaccount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestNewMeshGatewayBuilder_ServiceAccount(t *testing.T) {
Namespace: "default",
Name: "mesh-gateway",
},
}, GatewayConfig{}, nil)
}, GatewayConfig{}, nil, MeshGatewayAnnotationKind)

expected := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Expand Down
59 changes: 31 additions & 28 deletions control-plane/subcommand/inject-connect/v2controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,41 +215,44 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage
return err
}

if err := (&resourceControllers.MeshGatewayController{
Controller: consulResourceController,
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controller").WithName(common.MeshGateway),
Scheme: mgr.GetScheme(),
GatewayConfig: gateways.GatewayConfig{
ConsulConfig: common.ConsulConfig{
Address: c.consul.Addresses,
GRPCPort: consulConfig.GRPCPort,
HTTPPort: consulConfig.HTTPPort,
APITimeout: consulConfig.APITimeout,
},
ImageDataplane: c.flagConsulDataplaneImage,
ImageConsulK8S: c.flagConsulK8sImage,
ConsulTenancyConfig: consulTenancyConfig,
PeeringEnabled: c.flagEnablePeering,
EnableOpenShift: c.flagEnableOpenShift,
AuthMethod: c.consul.ConsulLogin.AuthMethod,
LogLevel: c.flagLogLevel,
LogJSON: c.flagLogJSON,
TLSEnabled: c.consul.UseTLS,
ConsulTLSServerName: c.consul.TLSServerName,
ConsulCACert: string(c.caCertPem),
SkipServerWatch: c.consul.SkipServerWatch,
gatewayConfig := gateways.GatewayConfig{
ConsulConfig: common.ConsulConfig{
Address: c.consul.Addresses,
GRPCPort: consulConfig.GRPCPort,
HTTPPort: consulConfig.HTTPPort,
APITimeout: consulConfig.APITimeout,
},
ImageDataplane: c.flagConsulDataplaneImage,
ImageConsulK8S: c.flagConsulK8sImage,
ConsulTenancyConfig: consulTenancyConfig,
PeeringEnabled: c.flagEnablePeering,
EnableOpenShift: c.flagEnableOpenShift,
AuthMethod: c.consul.ConsulLogin.AuthMethod,
LogLevel: c.flagLogLevel,
LogJSON: c.flagLogJSON,
TLSEnabled: c.consul.UseTLS,
ConsulTLSServerName: c.consul.TLSServerName,
ConsulCACert: string(c.caCertPem),
SkipServerWatch: c.consul.SkipServerWatch,
}

if err := (&resourceControllers.MeshGatewayController{
Controller: consulResourceController,
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controller").WithName(common.MeshGateway),
Scheme: mgr.GetScheme(),
GatewayConfig: gatewayConfig,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", common.MeshGateway)
return err
}

if err := (&resourceControllers.APIGatewayController{
Controller: consulResourceController,
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controller").WithName(common.APIGateway),
Scheme: mgr.GetScheme(),
Controller: consulResourceController,
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controller").WithName(common.APIGateway),
Scheme: mgr.GetScheme(),
GatewayConfig: gatewayConfig,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", common.APIGateway)
return err
Expand Down
Loading