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

Backport of [NET-7657,NET-6934] Define v2 GatewayClass + GatewayClassConfig locally into release/1.4.x #3572

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
18 changes: 6 additions & 12 deletions charts/consul/templates/crd-gatewayclasses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ spec:
scope: Cluster
versions:
- additionalPrinterColumns:
- description: The sync status of the resource with Consul
jsonPath: .status.conditions[?(@.type=="Synced")].status
name: Synced
type: string
- description: The last successful synced time of the resource with Consul
jsonPath: .status.lastSyncedTime
name: Last Synced
type: date
- description: The age of the resource
jsonPath: .metadata.creationTimestamp
name: Age
Expand All @@ -51,9 +43,6 @@ spec:
metadata:
type: object
spec:
description: "NOTE: this should align to the GAMMA/gateway-api version,
or at least be easily translatable. \n https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass
\n This is a Resource type."
properties:
controllerName:
description: ControllerName is the name of the Kubernetes controller
Expand All @@ -74,13 +63,18 @@ spec:
description: The Kubernetes Kind that the referred object is
type: string
name:
description: The name of the referred object
description: The Name of the referred object
type: string
namespace:
description: The kubernetes namespace that the referred object
is in
type: string
required:
- name
type: object
required:
- controllerName
- parametersRef
type: object
status:
properties:
Expand Down
2 changes: 2 additions & 0 deletions control-plane/api/mesh/v2beta1/gateway_class_config_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const KindGatewayClassConfig = "GatewayClassConfig"

func init() {
MeshSchemeBuilder.Register(&GatewayClassConfig{}, &GatewayClassConfigList{})
}
Expand Down
128 changes: 20 additions & 108 deletions control-plane/api/mesh/v2beta1/gateway_class_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,10 @@
package v2beta1

import (
"fmt"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
"github.com/hashicorp/consul/proto-public/pbresource"
"google.golang.org/protobuf/testing/protocmp"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/hashicorp/consul-k8s/control-plane/api/common"
inject "github.com/hashicorp/consul-k8s/control-plane/connect-inject/common"
"github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants"
)

const (
gatewayClassKubeKind = "gatewayclass"
)
const KindGatewayClass = "GatewayClass"

func init() {
MeshSchemeBuilder.Register(&GatewayClass{}, &GatewayClassList{})
Expand All @@ -30,15 +16,13 @@ func init() {
// +kubebuilder:subresource:status

// GatewayClass is the Schema for the Gateway Class API
// +kubebuilder:printcolumn:name="Synced",type="string",JSONPath=".status.conditions[?(@.type==\"Synced\")].status",description="The sync status of the resource with Consul"
// +kubebuilder:printcolumn:name="Last Synced",type="date",JSONPath=".status.lastSyncedTime",description="The last successful synced time of the resource with Consul"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the resource"
// +kubebuilder:resource:scope=Cluster
type GatewayClass struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec pbmesh.GatewayClass `json:"spec,omitempty"`
Spec GatewayClassSpec `json:"spec,omitempty"`
Status `json:"status,omitempty"`
}

Expand All @@ -51,101 +35,29 @@ type GatewayClassList struct {
Items []*GatewayClass `json:"items"`
}

func (in *GatewayClass) ResourceID(namespace, partition string) *pbresource.ID {
return &pbresource.ID{
Name: in.Name,
Type: pbmesh.GatewayClassType,
Tenancy: &pbresource.Tenancy{
Partition: partition,
Namespace: namespace,

// Because we are explicitly defining NS/partition, this will not default and must be explicit.
// At a future point, this will move out of the Tenancy block.
PeerName: constants.DefaultConsulPeer,
},
}
}

func (in *GatewayClass) Resource(namespace, partition string) *pbresource.Resource {
return &pbresource.Resource{
Id: in.ResourceID(namespace, partition),
Data: inject.ToProtoAny(&in.Spec),
Metadata: meshConfigMeta(),
}
}

func (in *GatewayClass) AddFinalizer(f string) {
in.ObjectMeta.Finalizers = append(in.Finalizers(), f)
}

func (in *GatewayClass) RemoveFinalizer(f string) {
var newFinalizers []string
for _, oldF := range in.Finalizers() {
if oldF != f {
newFinalizers = append(newFinalizers, oldF)
}
}
in.ObjectMeta.Finalizers = newFinalizers
}

func (in *GatewayClass) Finalizers() []string {
return in.ObjectMeta.Finalizers
}
type GatewayClassSpec struct {
// ControllerName is the name of the Kubernetes controller
// that manages Gateways of this class
ControllerName string `json:"controllerName"`

func (in *GatewayClass) MatchesConsul(candidate *pbresource.Resource, namespace, partition string) bool {
return cmp.Equal(
in.Resource(namespace, partition),
candidate,
protocmp.IgnoreFields(&pbresource.Resource{}, "status", "generation", "version"),
protocmp.IgnoreFields(&pbresource.ID{}, "uid"),
protocmp.Transform(),
cmpopts.SortSlices(func(a, b any) bool { return fmt.Sprintf("%v", a) < fmt.Sprintf("%v", b) }),
)
}
// ParametersRef refers to a resource responsible for configuring
// the behavior of the GatewayClass.
ParametersRef *ParametersReference `json:"parametersRef"`

func (in *GatewayClass) KubeKind() string {
return gatewayClassKubeKind
// Description of GatewayClass
Description string `json:"description,omitempty"`
}

func (in *GatewayClass) KubernetesName() string {
return in.ObjectMeta.Name
}
type ParametersReference struct {
// The Kubernetes Group that the referred object belongs to
Group string `json:"group,omitempty"`

func (in *GatewayClass) SetSyncedCondition(status corev1.ConditionStatus, reason, message string) {
in.Status.Conditions = Conditions{
{
Type: ConditionSynced,
Status: status,
LastTransitionTime: metav1.Now(),
Reason: reason,
Message: message,
},
}
}
// The Kubernetes Kind that the referred object is
Kind string `json:"kind,omitempty"`

func (in *GatewayClass) SetLastSyncedTime(time *metav1.Time) {
in.Status.LastSyncedTime = time
}
// The Name of the referred object
Name string `json:"name"`

func (in *GatewayClass) SyncedCondition() (status corev1.ConditionStatus, reason, message string) {
cond := in.Status.GetCondition(ConditionSynced)
if cond == nil {
return corev1.ConditionUnknown, "", ""
}
return cond.Status, cond.Reason, cond.Message
// The kubernetes namespace that the referred object is in
Namespace *string `json:"namespace,omitempty"`
}

func (in *GatewayClass) SyncedConditionStatus() corev1.ConditionStatus {
condition := in.Status.GetCondition(ConditionSynced)
if condition == nil {
return corev1.ConditionUnknown
}
return condition.Status
}

func (in *GatewayClass) Validate(tenancy common.ConsulTenancyConfig) error {
return nil
}

// DefaultNamespaceFields is required as part of the common.MeshConfig interface.
func (in *GatewayClass) DefaultNamespaceFields(tenancy common.ConsulTenancyConfig) {}
40 changes: 40 additions & 0 deletions control-plane/api/mesh/v2beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,6 @@ spec:
scope: Cluster
versions:
- additionalPrinterColumns:
- description: The sync status of the resource with Consul
jsonPath: .status.conditions[?(@.type=="Synced")].status
name: Synced
type: string
- description: The last successful synced time of the resource with Consul
jsonPath: .status.lastSyncedTime
name: Last Synced
type: date
- description: The age of the resource
jsonPath: .metadata.creationTimestamp
name: Age
Expand All @@ -47,9 +39,6 @@ spec:
metadata:
type: object
spec:
description: "NOTE: this should align to the GAMMA/gateway-api version,
or at least be easily translatable. \n https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass
\n This is a Resource type."
properties:
controllerName:
description: ControllerName is the name of the Kubernetes controller
Expand All @@ -70,13 +59,18 @@ spec:
description: The Kubernetes Kind that the referred object is
type: string
name:
description: The name of the referred object
description: The Name of the referred object
type: string
namespace:
description: The kubernetes namespace that the referred object
is in
type: string
required:
- name
type: object
required:
- controllerName
- parametersRef
type: object
status:
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type GatewayClassConfigController struct {
// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=gatewayclassconfig,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=gatewayclassconfig/status,verbs=get;update;patch

func (r *GatewayClassConfigController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
func (r *GatewayClassConfigController) Reconcile(_ context.Context, _ ctrl.Request) (ctrl.Result, error) {
// GatewayClassConfig is not synced into Consul because Consul has no use for it.
// Consul is only aware of the resource for the sake of Kubernetes CRD generation.
return ctrl.Result{}, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type GatewayClassController struct {
// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=gatewayclass,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=gatewayclass/status,verbs=get;update;patch

func (r *GatewayClassController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
func (r *GatewayClassController) Reconcile(_ context.Context, _ ctrl.Request) (ctrl.Result, error) {
// GatewayClass is not synced into Consul because Consul has no use for it.
// Consul is only aware of the resource for the sake of Kubernetes CRD generation.
return ctrl.Result{}, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ func (r *MeshGatewayController) getGatewayClassConfigForGatewayClass(ctx context

config := &meshv2beta1.GatewayClassConfig{}
if ref := gatewayClass.Spec.ParametersRef; ref != nil {
if ref.Group != meshv2beta1.MeshGroup || ref.Kind != "GatewayClassConfig" {
if ref.Group != meshv2beta1.MeshGroup || ref.Kind != meshv2beta1.KindGatewayClassConfig {
// TODO @Gateway-Management additionally check for controller name when available
return nil, nil
}
Expand Down
11 changes: 4 additions & 7 deletions control-plane/subcommand/gateway-resources/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ import (
gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
k8syaml "sigs.k8s.io/yaml"

meshv2beta1 "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"

authv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/auth/v2beta1"

"github.com/hashicorp/consul-k8s/control-plane/api-gateway/common"
Expand Down Expand Up @@ -432,15 +430,14 @@ func (c *Command) createV2GatewayClassAndClassConfigs(ctx context.Context, compo
return err
}

// TODO: NET-6934 remove hardcoded values
class := &v2beta1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{Name: cfg.Name, Labels: labels},
TypeMeta: metav1.TypeMeta{Kind: "GatewayClass"},
Spec: meshv2beta1.GatewayClass{
TypeMeta: metav1.TypeMeta{Kind: v2beta1.KindGatewayClass},
Spec: v2beta1.GatewayClassSpec{
ControllerName: controllerName,
ParametersRef: &meshv2beta1.ParametersReference{
ParametersRef: &v2beta1.ParametersReference{
Group: v2beta1.MeshGroup,
Kind: "GatewayClassConfig",
Kind: v2beta1.KindGatewayClassConfig,
Namespace: &cfg.Namespace,
Name: cfg.Name,
},
Expand Down
5 changes: 3 additions & 2 deletions control-plane/subcommand/gateway-resources/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

meshv2beta1 "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"

"github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1"
"github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1"
meshv2beta1 "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
)

func TestRun_flagValidation(t *testing.T) {
Expand Down Expand Up @@ -549,7 +550,7 @@ func TestRun_loadGatewayConfigs(t *testing.T) {
expectedClassConfig := v2beta1.GatewayClassConfig{
TypeMeta: metav1.TypeMeta{
APIVersion: v2beta1.MeshGroupVersion.String(),
Kind: "GatewayClassConfig",
Kind: v2beta1.KindGatewayClassConfig,
},
ObjectMeta: metav1.ObjectMeta{
Name: "consul-mesh-gateway",
Expand Down
Loading