Files
41ec6d6f1a rebrand(ingress): finish de-Traefik + own yaegi/grpc-web framework deps (#29) (#8)
* rebrand: strip "traefik" branding from the ingress controller

Removes all "traefik" branding/paths/env/comments from the shipping
surface while keeping load-bearing config schema and external deps intact.

Paths / binary:
- cmd/traefik/ -> cmd/ingress/ (traefik.go->ingress.go, etc.); merged out
  the empty cmd/ingress/generate.go stub. Build refs updated in Dockerfile,
  Makefile, .goreleaser.yml.tmpl, script/crossbinary-default.sh, README.
- contrib/systemd/traefik.service -> ingress.service (Hanzo Ingress unit,
  /etc/ingress paths, hanzo-ingress binary).
- contrib/grafana/traefik*.json -> ingress*.json; metric queries
  traefik_* -> ingress_* (now match the engine's ingress_ prefix) + titles.
- script/gcg/traefik-*.toml -> ingress-*.toml; Owner/Repo -> hanzoai/ingress.

Code/config branding (comments + non-schema strings):
- doc.go, mount.go, client/router.go, zap_backend.go, forward_backend.go,
  register.go: "Traefik" -> "the ingress"/"Hanzo Ingress"; corrected the
  annotation example to ingress.kubernetes.io/.
- ingress.sample.{toml,yml}: header + log + entryPoint example.
- pkg/config/dynamic/fixtures/sample.toml comment.
- pkg/redactor/testdata example+expected: /etc/traefik/traefik.toml ->
  /etc/ingress/ingress.toml, TraefikLogsFile -> IngressLogsFile (both files
  kept identical so the redactor golden test stays green).
- .golangci.yml importas aliases traefik* -> ingress* and the stale
  crd/traefikio path -> crd/hanzoai; unused-var exclude ingressVersion.
- .dockerignore / .gitignore: drop stale /traefik artifacts.
- script/code-gen.sh: PROJECT_MODULE -> github.com/hanzoai/ingress,
  v1alpha1 path -> crd/hanzoai, CRD output -> hanzo.ai_*.yaml /
  01-ingress-crd.yml.
- script/deploy.sh: drop the upstream traefik-library-image push.
- Removed dead, disabled upstream docs-publish workflow
  (.github/workflows/documentation.yaml, pushed to traefik/doc).
- LLM.md: rewrote rebrand notes; documented load-bearing "traefik" that
  stays (external imports, hash-bound realm, upstream issue URL, license
  attribution) and vendored upstream docs/webui/changelog as out of scope.

Load-bearing "traefik" intentionally KEPT (not branding):
- external Go modules github.com/traefik/{oxy,yaegi,grpc-web};
- digest_auth_test.go htdigest realm "traefik" (invalidates the hashes);
- consul_test.go upstream issue URL #8092 (provenance citation);
- LICENSE.md + boilerplate.go.tmpl Containous/Traefik Labs copyright
  (MIT attribution; Hanzo AI appended);
- integration/ test fixtures (traefik/whoami images, rawdata-*.json
  golden entrypoint names, nomad traefik.* tags) — test-only, semantics-
  sensitive; out of scope for this pass.

Verify: `go build $(go list ./... | grep -v /webui)` passes; redactor /
config/dynamic / nomad / server/service tests pass. The webui go:embed
failure and the kubernetes/crd test (ingress.k8s.io group mismatch) are
pre-existing on main, not caused by this rebrand.

* build(ingress): own yaegi + grpc-web via hanzoai source-fork replaces (#29)

Task #29 — own the framework deps (Traefik half). The Traefik engine is
already fully source-forked into github.com/hanzoai/ingress and the
user-facing surface is debranded (cmd/ingress -> hanzo-ingress, CRD group
hanzo.ai, ingress_ metrics, X-Ingress-* headers). The last upstream
traefik/* runtime libraries are now pinned to hanzoai source-forks:

  github.com/traefik/grpc-web => github.com/hanzoai/grpc-web v0.16.0
  github.com/traefik/yaegi    => github.com/hanzoai/yaegi    v0.16.1

Both forks keep the upstream module path at the identical version tag, so
the import lines in pkg/plugins (yaegi Go-interpreter for plugins) and
pkg/middlewares/grpcweb are unchanged — only resolution moves to a path
hanzoai controls (immune to upstream re-tag/deletion; patchable in-house).

oxy has no hanzoai fork yet and stays on the existing traefik/oxy replace —
tracked next-wave (create hanzoai/oxy first).

Proof:
  go list -m github.com/traefik/{yaegi,grpc-web}  -> both => hanzoai/*
  go build ./...                                  -> exit 0 (webui assets staged)
  go test ./pkg/plugins/...                       -> ok (yaegi consumer)
  readonly (CI-mode) build of swapped pkgs        -> exit 0 (go.sum complete)

* docs(ingress): document traefik/* framework-dep ownership boundary (#29)

---------

Co-authored-by: Antje Worring <[email protected]>

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-03 03:34:30 -07:00

119 lines
3.6 KiB
Go

// Package client — canonical client interface for Hanzo Ingress.
//
// import ing "github.com/hanzoai/ingress/client"
// var r ing.Router = hanzoingress.NewRouter(cfg)
package client
import "context"
// Router is the L7 control surface: declare/update/list virtual hosts +
// route tables + middleware chains. The data plane (request forwarding)
// runs in-process inside the ingress binary; this interface is the
// management API every operator + admin tool uses.
type Router interface {
// Kind reports the backend identifier
// (hanzo-ingress | envoy | nginx).
Kind() string
// UpsertVHost creates or replaces a virtual host. Idempotent.
UpsertVHost(ctx context.Context, v VHost) error
// DeleteVHost removes a virtual host. Idempotent.
DeleteVHost(ctx context.Context, name string) error
// ListVHosts returns every virtual host in scope.
ListVHosts(ctx context.Context) ([]VHost, error)
// UpsertRoute creates or replaces a route on the named vhost.
UpsertRoute(ctx context.Context, vhost string, r Route) error
// DeleteRoute removes a route.
DeleteRoute(ctx context.Context, vhost, routeID string) error
// Reload triggers a hot-reload of the running data plane. Returns the
// new config version id on success.
Reload(ctx context.Context) (string, error)
// Health reports the data-plane state.
Health(ctx context.Context) (*Status, error)
}
// VHost is a virtual host. One vhost handles one ServerName + ports.
type VHost struct {
// Name is the canonical identifier used in routes and reload logs.
Name string
// Hosts is the SNI / Host-header match set (apex + wildcards).
Hosts []string
// TLS configures HTTPS. Empty means HTTP-only.
TLS *TLSConfig
// HTTP3 enables QUIC + Alt-Svc advertisement.
HTTP3 bool
// EntryPoints names the listener IDs this vhost binds to
// (web | websecure | grpc | internal).
EntryPoints []string
// Labels carry routing metadata (env, tenant, app) consumed by
// dashboards and policy plugins.
Labels map[string]string
}
// TLSConfig is the HTTPS settings for a vhost.
type TLSConfig struct {
// SecretRef points at a KMS-managed cert/key pair (preferred) or a
// k8s tls Secret (legacy). One of SecretRef or InlineCert+InlineKey
// must be set.
SecretRef string
InlineCert []byte
InlineKey []byte
// MinVersion: TLS1.2 | TLS1.3. Empty defaults to TLS1.3.
MinVersion string
// ALPN is the negotiated-protocol allowlist (h2 | http/1.1 | h3).
ALPN []string
}
// Route is one L7 rule on a vhost.
type Route struct {
ID string
Path string // exact | prefix= | regex=
Methods []string
Backend Backend
Middleware []Middleware
// Priority disambiguates overlapping rules; higher wins.
Priority int
}
// Backend is the upstream target.
type Backend struct {
// Kind: k8s_service | static | function | redirect.
Kind string
// For Kind=k8s_service: Namespace + Name + Port.
Namespace string
Name string
Port int
// For Kind=static: explicit upstream URLs.
URLs []string
// For Kind=redirect: target URL + status.
RedirectTo string
RedirectStatus int
}
// Middleware is one filter applied in the route's chain.
type Middleware struct {
// Kind: rate_limit | auth_iam | auth_basic | cors | rewrite |
// strip_prefix | redirect | request_size_limit | gzip | brotli |
// otel_trace | plugin.
Kind string
// Config is the kind-specific config blob.
Config map[string]any
}
// Status is the data-plane health snapshot.
type Status struct {
Version string // config version id
UpSince int64 // unix seconds
VHostCount int
RouteCount int
ActiveConns int
Ready bool
}