Skip to content
Closed
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
4 changes: 4 additions & 0 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
name: Build & Check (Lint & Unit Test)

on:
# TODO remove before merge in main!
push:
branches:
- 'issue_829_gateway_support'
pull_request:
branches:
- 'main'
Expand Down
53 changes: 53 additions & 0 deletions api/v1beta1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,59 @@ type IngressOptions struct {
IngressClassName *string `json:"ingressClassName,omitempty"`
}

// HTTPRouteOptions defines the options for generating an HTTPRoute resource of the Gateway API.
type HTTPRouteOptions struct {
// Name is the name of the HTTPRoute Kubernetes resource to be created.
Name string `json:"name"`

// Annotations to be added for the HTTPRoute.
// +optional
Annotations map[string]string `json:"annotations,omitempty"`

// Labels to be added for the HTTPRoute.
// +optional
Labels map[string]string `json:"labels,omitempty"`

// ParentRefs references the resources (usually Gateways) that this HTTPRoute wants to be attached to.
// +optional
ParentRefs []HTTPRouteParentReference `json:"parentRefs,omitempty"`

// Hostnames defines a set of hostnames that should match this HTTPRoute.
// At least one hostname should be provided.
// +optional
Hostnames []string `json:"hostnames,omitempty"`
}

// HTTPRouteParentReference defines a reference to a parent resource to which an HTTPRoute should be attached.
// This is typically a Gateway resource.
type HTTPRouteParentReference struct {
// Group is the group of the referent.
// Defaults to "gateway.networking.k8s.io".
// +optional
Group *string `json:"group,omitempty"`

// Kind is the Kubernetes kind of the referent.
// Defaults to "Gateway".
// +optional
Kind *string `json:"kind,omitempty"`

// Namespace is the namespace of the referent.
// Defaults to the namespace of the HTTPRoute.
// +optional
Namespace *string `json:"namespace,omitempty"`

// Name is the name of the referent.
Name string `json:"name"`

// SectionName is the name of a section within the target resource (e.g., a listener name on a Gateway).
// +optional
SectionName *string `json:"sectionName,omitempty"`

// Port is the network port this Route targets on the referenced parent resource.
// +optional
Port *int32 `json:"port,omitempty"`
}

// ConfigMapOptions defines custom options for configMaps
type ConfigMapOptions struct {
// Annotations to be added for the ConfigMap.
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta1/solrcloud_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ type CustomSolrKubeOptions struct {
// IngressOptions defines the custom options for the solrCloud Ingress.
// +optional
IngressOptions *IngressOptions `json:"ingressOptions,omitempty"`

// HTTPRouteOptions defines the custom options for HTTPRoute resources of the Gateway API to be generated for the solrCloud.
// A separate HTTPRoute resource will be generated for each entry in this list.
// +optional
HTTPRouteOptions []HTTPRouteOptions `json:"httpRouteOptions,omitempty"`
}

type SolrDataStorageOptions struct {
Expand Down
88 changes: 88 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

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

70 changes: 70 additions & 0 deletions config/crd/bases/solr.apache.org_solrclouds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2192,6 +2192,76 @@ spec:
description: Labels to be added for the Ingress.
type: object
type: object
httpRouteOptions:
description: HTTPRouteOptions defines a list of custom options
for HTTPRoute resources of the Gateway API to be generated for
the solrCloud. A separate HTTPRoute resource will be generated
for each entry in this list.
items:
description: HTTPRouteOptions defines the options for generating
an HTTPRoute resource of the Gateway API.
properties:
annotations:
additionalProperties:
type: string
description: Annotations to be added for the HTTPRoute.
type: object
hostnames:
description: Hostnames defines a set of hostnames that should
match this HTTPRoute. At least one hostname should be provided.
items:
type: string
type: array
labels:
additionalProperties:
type: string
description: Labels to be added for the HTTPRoute.
type: object
name:
description: Name is the name of the HTTPRoute Kubernetes
resource to be created.
type: string
parentRefs:
description: ParentRefs references the resources (usually
Gateways) that this HTTPRoute wants to be attached to.
items:
description: HTTPRouteParentReference defines a reference
to a parent resource to which an HTTPRoute should be
attached. This is typically a Gateway resource.
properties:
group:
description: Group is the group of the referent. Defaults
to gateway.networking.k8s.io.
type: string
kind:
description: Kind is the Kubernetes kind of the referent.
Defaults to Gateway.
type: string
name:
description: Name is the name of the referent.
type: string
namespace:
description: Namespace is the namespace of the referent.
Defaults to the namespace of the HTTPRoute.
type: string
port:
description: Port is the network port this Route targets
on the referenced parent resource.
format: int32
type: integer
sectionName:
description: SectionName is the name of a section
within the target resource (e.g., a listener name
on a Gateway).
type: string
required:
- name
type: object
type: array
required:
- name
type: object
type: array
nodeServiceOptions:
description: |-
NodeServiceOptions defines the custom options for the individual solrCloud Node services, if they are created.
Expand Down
51 changes: 51 additions & 0 deletions controllers/solrcloud_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
)

// SolrCloudReconciler reconciles a SolrCloud object
Expand All @@ -70,6 +71,8 @@ func UseZkCRD(useCRD bool) {
//+kubebuilder:rbac:groups=apps,resources=statefulsets/status,verbs=get
//+kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses/status,verbs=get
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes/status,verbs=get
//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups="",resources=configmaps/status,verbs=get
//+kubebuilder:rbac:groups="",resources=persistentvolumeclaims,verbs=get;list;watch;delete
Expand Down Expand Up @@ -436,6 +439,53 @@ func (r *SolrCloudReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
}
}

// Reconcile HTTPRoutes defined in HTTPRouteOptions
desiredHTTPRoutes := util.GenerateHTTPRoutes(instance)
desiredHTTPRouteNames := make(map[string]struct{}, len(desiredHTTPRoutes))
for _, httpRoute := range desiredHTTPRoutes {
desiredHTTPRouteNames[httpRoute.Name] = struct{}{}
httpRouteLogger := logger.WithValues("httpRoute", httpRoute.Name)
foundHTTPRoute := &gatewayv1.HTTPRoute{}
err = r.Get(ctx, types.NamespacedName{Name: httpRoute.Name, Namespace: httpRoute.Namespace}, foundHTTPRoute)
if err != nil && errors.IsNotFound(err) {
httpRouteLogger.Info("Creating HTTPRoute")
if err = controllerutil.SetControllerReference(instance, httpRoute, r.Scheme); err == nil {
err = r.Create(ctx, httpRoute)
}
} else if err == nil {
var needsUpdate bool
needsUpdate, err = util.OvertakeControllerRef(instance, foundHTTPRoute, r.Scheme)
needsUpdate = util.CopyHTTPRouteFields(httpRoute, foundHTTPRoute, httpRouteLogger) || needsUpdate
if needsUpdate && err == nil {
httpRouteLogger.Info("Updating HTTPRoute")
err = r.Update(ctx, foundHTTPRoute)
}
}
if err != nil {
return requeueOrNot, err
}
}

// Delete any HTTPRoutes that are owned by this SolrCloud but are no longer desired
existingHTTPRoutes := &gatewayv1.HTTPRouteList{}
if listErr := r.List(ctx, existingHTTPRoutes,
client.InNamespace(instance.GetNamespace()),
client.MatchingLabels(instance.SharedLabelsWith(map[string]string{})),
); listErr == nil {
for i := range existingHTTPRoutes.Items {
existing := &existingHTTPRoutes.Items[i]
if metav1.IsControlledBy(existing, instance) {
if _, stillDesired := desiredHTTPRouteNames[existing.Name]; !stillDesired {
deleteLogger := logger.WithValues("httpRoute", existing.Name)
deleteLogger.Info("Deleting orphaned HTTPRoute")
if deleteErr := r.Delete(ctx, existing); deleteErr != nil && !errors.IsNotFound(deleteErr) {
return requeueOrNot, deleteErr
}
}
}
}
}

// *********************************************************
// The operations after this require a statefulSet to exist,
// including updating the solrCloud status
Expand Down Expand Up @@ -1191,6 +1241,7 @@ func (r *SolrCloudReconciler) SetupWithManager(mgr ctrl.Manager) error {
Owns(&corev1.Service{}).
Owns(&corev1.Secret{}). /* for authentication */
Owns(&netv1.Ingress{}).
Owns(&gatewayv1.HTTPRoute{}).
Owns(&policyv1.PodDisruptionBudget{})

var err error
Expand Down
Loading