Skip to content

Add httproute typed sdk - #473

Merged
andrleite merged 4 commits into
v2from
add-httproute-typed-sdk
Sep 1, 2026
Merged

Add httproute typed sdk#473
andrleite merged 4 commits into
v2from
add-httproute-typed-sdk

Conversation

@andrleite

@andrleite andrleite commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

This pull request introduces support for configuring an HTTPRoute (Gateway API) resource in the Mattermost Operator, allowing users to use Gateway API-based routing instead of, or alongside, traditional Kubernetes Ingress resources. The changes add new CRD fields, validation logic, accessors, and comprehensive unit tests to ensure correct behavior and backward compatibility.

HTTPRoute (Gateway API) support:

  • Added a new HTTPRoute field to MattermostSpec, with a corresponding HTTPRouteSpec struct that allows enabling/disabling HTTPRoute, specifying hosts, referencing a Gateway, setting annotations, and timeouts. This includes a nested GatewayReference type. [1] [2]
  • Updated OpenAPI schema generation and deepcopy methods to support the new HTTPRoute and GatewayReference types, ensuring CRD compatibility and proper code generation. [1] [2] [3] [4]

Validation and logic changes:

  • Enhanced SetDefaults to validate that when HTTPRoute is enabled, a host and gateway reference name are required, and to ensure Ingress and HTTPRoute interaction is handled correctly.
  • Updated IngressEnabled logic to allow HTTPRoute to opt out of the default Ingress creation, preserving legacy behavior and supporting side-by-side migration scenarios.

Accessors and helpers:

  • Added new methods to the Mattermost type for accessing HTTPRoute configuration, including enablement, host(s), annotations, and a unified method for determining the site URL host, which respects the new HTTPRoute logic while preserving legacy behavior.

Unit tests:

  • Added comprehensive tests to cover HTTPRoute validation, Ingress/HTTPRoute interaction, accessors, and to ensure that legacy behavior is preserved when HTTPRoute is not used.

These changes provide a robust foundation for Gateway API support in the Mattermost Operator, while maintaining backward compatibility and a smooth migration path for existing users.

Release Note

Added opt-in [Gateway API](https://gateway-api.sigs.k8s.io/) HTTPRoute support. Operators running on clusters with the Gateway API CRDs installed can now route traffic to Mattermost through a Gateway instead of an Ingress by setting httpRoute.enabled: true and referencing a Gateway:


spec:
  httpRoute:
    enabled: true
    host: mattermost.example.com
    gatewayRef:
      name: shared-gateway
      namespace: gateway-system   # optional, defaults to MM namespace
      sectionName: https          # optional
    requestTimeout: "3600s"       # optional, default
    backendRequestTimeout: "3600s"
Ingress and HTTPRoute can coexist during migration — set ingress.enabled: false explicitly to stop the Operator from creating an Ingress alongside the HTTPRoute. Clusters without the Gateway API CRDs installed are unaffected: the Operator skips HTTPRoute deletion silently on installations that never opted in.

andrleite and others added 2 commits August 31, 2026 10:48
Adds  to the Mattermost CR, reconciling a
gateway.networking.k8s.io/v1 HTTPRoute as an alternative to the nginx
Ingress. Opt-in and additive: existing CRs have no  key, so
behaviour is unchanged.
…ay-api SDK

The original implementation used *unstructured.Unstructured to avoid a transitive
dependency conflict: gateway-api required structured-merge-diff/v6 while the module
was pinned to v4 via k8s.io/apimachinery v0.33.x.

Now that k8s.io/* has been upgraded to v0.36.x and controller-runtime to v0.24.1
(both of which already depend on structured-merge-diff/v6), the conflict is gone.
gateway-api v1.6.1 now adds cleanly.

Replace GenerateHTTPRouteV1Beta, CreateHTTPRouteIfNotExists, DeleteHTTPRoute,
and CheckHTTPRoute with typed *gatewayv1.HTTPRoute / *gatewayv1.HTTPRouteList.
Register the gateway-api scheme in main.go init() and in prepareSchema for tests.
Remove the CRD YAML testdata and schema-pruning test — the compiler now checks
field names and types directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mm-cloud-bot

Copy link
Copy Markdown

@andrleite: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

I understand the commands that are listed here

@mm-cloud-bot mm-cloud-bot added do-not-merge/release-note-label-needed release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed do-not-merge/release-note-label-needed labels Aug 31, 2026
andrleite and others added 2 commits August 31, 2026 11:11
The committed CRD was generated with an older controller-gen binary that
truncated descriptions differently than the current CI binary, causing the
CI CRD-diff check to fail. Regenerated with the project's pinned binary
using `bin/controller-gen "crd:maxDescLen=200"`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SetDefaults validates FileStore and Database on every call, but the
HTTPRoute test cases were building minimal Mattermost structs without
those fields, causing unrelated validation errors to surface. Added a
validMMBase() helper that provides the minimum external configs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@andrleite
andrleite requested review from a team, fmartingr and nickmisasi August 31, 2026 16:07
Comment on lines +223 to +263
func (mm *Mattermost) HTTPRouteEnabled() bool {
if mm.Spec.HTTPRoute != nil {
return mm.Spec.HTTPRoute.Enabled
}
return false
}

// GetHTTPRouteHost returns the primary hostname for the HTTPRoute.
func (mm *Mattermost) GetHTTPRouteHost() string {
if mm.Spec.HTTPRoute == nil {
return ""
}
return mm.Spec.HTTPRoute.Host
}

// GetHTTPRouteHostNames returns all HTTPRoute hostnames, deduplicated.
func (mm *Mattermost) GetHTTPRouteHostNames() []string {
if mm.Spec.HTTPRoute == nil || mm.Spec.HTTPRoute.Host == "" {
return []string{}
}

hostsSet := map[string]struct{}{mm.Spec.HTTPRoute.Host: {}}
hosts := []string{mm.Spec.HTTPRoute.Host}

for _, host := range mm.Spec.HTTPRoute.Hosts {
if _, found := hostsSet[host.HostName]; !found {
hosts = append(hosts, host.HostName)
hostsSet[host.HostName] = struct{}{}
}
}

return hosts
}

// GetHTTPRouteAnnotations returns HTTPRoute annotations.
func (mm *Mattermost) GetHTTPRouteAnnotations() map[string]string {
if mm.Spec.HTTPRoute == nil {
return nil
}
return mm.Spec.HTTPRoute.Annotations
}

@nickmisasi nickmisasi Aug 31, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it would make more sense to move these under HTTPRoute. For example:

// GetHTTPRouteAnnotations returns HTTPRoute annotations.
func (mm *Mattermost) GetHTTPRouteAnnotations() map[string]string {
	if mm.Spec.HTTPRoute == nil {
		return nil
	}
	return mm.Spec.HTTPRoute.Annotations
}

Would become:

func (h *HTTPRoute) Annotations() map[string]string {
	if h == nil {
		return nil
	}
	return h.Annotations
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hey Nick, good suggestion. One thing: Go doesn't allow a method and a field to share the same name, so Annotations() on a struct that already has an Annotations field won't compile — same for Enabled(). Two options:

Use Get prefix — GetEnabled(), GetAnnotations(), etc.
Keep the accessors on *Mattermost as-is, matching the existing Ingress pattern (GetIngressAnnotations(), GetIngressHost())
Which do you think?

@nickmisasi nickmisasi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall LGTM. One refactor suggestion

// See checkMattermostIngress: UseServiceLoadBalancer takes precedence over any
// L7 routing configuration, and suppressing it means removing the resource, not
// merely declining to create one.
if mattermost.Spec.UseServiceLoadBalancer && mattermost.HTTPRouteEnabled() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The above suggestion would make access better too IMO. mattermost.HTTPRoute.Enabled()

@andrleite
andrleite requested a review from nickmisasi September 1, 2026 12:41

@nickmisasi nickmisasi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks Andre!

@andrleite
andrleite merged commit b03fd86 into v2 Sep 1, 2026
14 checks passed
@andrleite
andrleite deleted the add-httproute-typed-sdk branch September 1, 2026 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note Denotes a PR that will be considered when it comes time to generate release notes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants