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 6529 Gatewayclassconfig CRD #3225

Merged
merged 3 commits into from
Nov 21, 2023
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
152 changes: 152 additions & 0 deletions control-plane/api/mesh/v2beta1/gateway_class_config_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// // Copyright (c) HashiCorp, Inc.
// // SPDX-License-Identifier: MPL-2.0

package v2beta1

import (
"fmt"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"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"
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"
)

const (
gatewayClassConfigKubeKind = "gatewayclassconfig"
)

func init() {
MeshSchemeBuilder.Register(&GatewayClassConfig{}, &GatewayClassConfigList{})
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status

// GatewayClassConfig is the Schema for the Mesh Gateway 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:shortName="gateway-class-config"
// +kubebuilder:resource:scope=Cluster
type GatewayClassConfig struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

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

// +kubebuilder:object:root=true

// GatewayClassConfigList contains a list of GatewayClassConfig.
type GatewayClassConfigList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []*GatewayClassConfig `json:"items"`
}

func (in *GatewayClassConfig) ResourceID(namespace, partition string) *pbresource.ID {
return &pbresource.ID{
Name: in.Name,
Type: pbmesh.GatewayClassConfigType,
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 *GatewayClassConfig) Resource(namespace, partition string) *pbresource.Resource {
return &pbresource.Resource{
Id: in.ResourceID(namespace, partition),
Data: inject.ToProtoAny(&in.Spec),
Metadata: meshConfigMeta(),
}
}

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

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

func (in *GatewayClassConfig) Finalizers() []string {
return in.ObjectMeta.Finalizers
}

func (in *GatewayClassConfig) 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) }),
)
}

func (in *GatewayClassConfig) KubeKind() string {
return gatewayClassConfigKubeKind
}

func (in *GatewayClassConfig) KubernetesName() string {
return in.ObjectMeta.Name
}

func (in *GatewayClassConfig) SetSyncedCondition(status corev1.ConditionStatus, reason, message string) {
in.Status.Conditions = Conditions{
{
Type: ConditionSynced,
Status: status,
LastTransitionTime: metav1.Now(),
Reason: reason,
Message: message,
},
}
}

func (in *GatewayClassConfig) SetLastSyncedTime(time *metav1.Time) {
in.Status.LastSyncedTime = time
}

func (in *GatewayClassConfig) 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
}

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

func (in *GatewayClassConfig) Validate(tenancy common.ConsulTenancyConfig) error {
// TODO add validation logic that ensures we only ever write this to the default namespace.
return nil
}

// DefaultNamespaceFields is required as part of the common.MeshConfig interface.
func (in *GatewayClassConfig) DefaultNamespaceFields(tenancy common.ConsulTenancyConfig) {}
63 changes: 63 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
@@ -0,0 +1,161 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.1
name: gatewayclassconfigs.mesh.consul.hashicorp.com
spec:
group: mesh.consul.hashicorp.com
names:
kind: GatewayClassConfig
listKind: GatewayClassConfigList
plural: gatewayclassconfigs
singular: gatewayclassconfig
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
type: date
name: v2beta1
schema:
openAPIV3Schema:
description: GatewayClassConfig is the Schema for the Mesh Gateway API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: This is a Resource type.
properties:
consul:
properties:
address:
type: string
authentication:
properties:
address:
type: string
managed:
type: boolean
method:
type: string
namespace:
type: string
type: object
ports:
properties:
grpc:
format: int32
type: integer
http:
format: int32
type: integer
type: object
scheme:
type: string
type: object
copyAnnotations:
properties:
service:
items:
type: string
type: array
type: object
deployment:
properties:
defaultInstances:
format: int32
type: integer
maxInstances:
format: int32
type: integer
minInstances:
format: int32
type: integer
type: object
image:
properties:
consulApiGateway:
type: string
envoy:
type: string
type: object
logLevel:
type: string
mapPrivilegedContainerPorts:
format: int32
type: integer
nodeSelector:
type: string
openshiftSccName:
type: string
serviceType:
type: string
useHostPorts:
type: boolean
type: object
status:
properties:
conditions:
description: Conditions indicate the latest available observations
of a resource's current state.
items:
description: 'Conditions define a readiness condition for a Consul
resource. See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties'
properties:
lastTransitionTime:
description: LastTransitionTime is the last time the condition
transitioned from one status to another.
format: date-time
type: string
message:
description: A human readable message indicating details about
the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition.
type: string
required:
- status
- type
type: object
type: array
lastSyncedTime:
description: LastSyncedTime is the last time the resource successfully
synced with Consul.
format: date-time
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}