Skip to content

Commit 5bce15a

Browse files
Ingress to Gateway API migration (#21)
Signed-off-by: Waleed Malik <ahmedwaleedmalik@gmail.com>
1 parent c4f389e commit 5bce15a

48 files changed

Lines changed: 6812 additions & 191 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.prow/verify.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ presubmits:
2222
preset-goproxy: "true"
2323
spec:
2424
containers:
25-
- image: quay.io/kubermatic/build:go-1.25-node-22-2
25+
- image: quay.io/kubermatic/build:go-1.25-node-22-kind-0.30-6
2626
command:
2727
- make
2828
args:
@@ -41,7 +41,7 @@ presubmits:
4141
preset-kubelb-cli: "true"
4242
spec:
4343
containers:
44-
- image: quay.io/kubermatic/build:go-1.25-node-22-2
44+
- image: quay.io/kubermatic/build:go-1.25-node-22-kind-0.30-6
4545
command:
4646
- make
4747
args:

CLAUDE.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Build Commands
6+
7+
```bash
8+
make build # Build binary to bin/kubelb
9+
make test # Run all tests
10+
go test ./internal/... # Run specific package tests
11+
go test -run TestName ./internal/logger/ # Run single test
12+
make lint # Run golangci-lint
13+
make verify-all # All checks (boilerplate, imports, licenses, shfmt)
14+
make install # Install to Go bin directory
15+
```
16+
17+
## Architecture
18+
19+
### Edition Detection Flow
20+
21+
CLI auto-detects KubeLB backend edition (CE vs EE) at startup via `PersistentPreRunE`:
22+
23+
1. Check cache (`~/.kubelb/cache/`, 48h TTL)
24+
2. If miss: query TenantState resource for edition field
25+
3. Fallback: check if tunnel CRDs exist (EE-only)
26+
4. Load appropriate API types from `k8c.io/kubelb/api/{ce,ee}/`
27+
28+
### Key Packages
29+
30+
- `cmd/` - Cobra commands, config init happens in root.go PersistentPreRunE
31+
- `internal/edition/` - Edition detection logic
32+
- `internal/config/` - Kubeconfig/tenant resolution with precedence: flags > env vars > error
33+
- `internal/tunnel/connect.go` - HTTP/2 SSE client with auto-reconnect (exponential backoff, max 10 retries)
34+
- `internal/logger/` - Custom slog-based logging with CLI/JSON/text formats
35+
36+
### Tenant Namespace
37+
38+
Tenant names auto-prefix with `tenant-` if not already prefixed. Namespace = `tenant-{name}`.
39+
40+
### Config Requirements
41+
42+
No defaults for kubeconfig or tenant - both must be explicitly provided via flags or env vars (KUBECONFIG, TENANT_NAME).
43+
44+
### Environment Variables
45+
46+
All flags can be configured via env vars. Precedence: flags > env vars > defaults.
47+
48+
**Global:**
49+
50+
| Env Var | Flag | Default |
51+
|---------|------|---------|
52+
| `KUBECONFIG` | `--kubeconfig` | (required) |
53+
| `TENANT_NAME` | `--tenant` | (required) |
54+
| `KUBELB_INSECURE_SKIP_VERIFY` | - | `false` |
55+
| `KUBELB_LOG_LEVEL` | `--log-level` | - |
56+
| `KUBELB_LOG_FORMAT` | `--log-format` | `cli` |
57+
| `KUBELB_LOG_PATH` | `--log-file` | - |
58+
59+
**Ingress conversion (`kubelb ingress`):**
60+
61+
| Env Var | Flag | Default |
62+
|---------|------|---------|
63+
| `KUBELB_GATEWAY_NAME` | `--gateway-name` | `kubelb` |
64+
| `KUBELB_GATEWAY_NAMESPACE` | `--gateway-namespace` | `kubelb` |
65+
| `KUBELB_GATEWAY_CLASS` | `--gateway-class` | `kubelb` |
66+
| `KUBELB_INGRESS_CLASS` | `--ingress-class` | (all) |
67+
| `KUBELB_DOMAIN_REPLACE` | `--domain-replace` | - |
68+
| `KUBELB_DOMAIN_SUFFIX` | `--domain-suffix` | - |
69+
| `KUBELB_PROPAGATE_EXTERNAL_DNS` | `--propagate-external-dns` | `true` |
70+
| `KUBELB_GATEWAY_ANNOTATIONS` | `--gateway-annotations` | - |
71+
| `KUBELB_DISABLE_ENVOY_GATEWAY_FEATURES` | `--disable-envoy-gateway-features` | `false` |
72+
| `KUBELB_COPY_TLS_SECRETS` | `--copy-tls-secrets` | `true` |
73+
74+
### Commands Skipping Config
75+
76+
version, help, completion, docs - skip kubeconfig/tenant loading.
77+
78+
## Module Path
79+
80+
`k8c.io/kubelb-cli`

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ run-version: build
7575

7676
update-docs:
7777
@echo "Updating docs..."
78-
./$(BUILD_DIR)/$(BINARY_NAME) docs --output=./docs/cli
78+
./$(BUILD_DIR)/$(BINARY_NAME) docs --hugo --output=./docs/cli
7979

8080

8181
.PHONY: snapshot

cmd/docs.go

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2025 The KubeLB Authors.
2+
Copyright 2026 The KubeLB Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -19,37 +19,59 @@ package cmd
1919
import (
2020
"fmt"
2121
"os"
22+
"path/filepath"
23+
"strings"
24+
"time"
2225

2326
"github.com/spf13/cobra"
2427
"github.com/spf13/cobra/doc"
2528
)
2629

2730
func docsCmd() *cobra.Command {
2831
var outputDir string
32+
var hugoFormat bool
2933

3034
cmd := &cobra.Command{
3135
Use: "docs",
3236
Short: "Generate markdown documentation for all commands",
3337
Long: `Generate markdown documentation for all CLI commands and their parameters.
34-
This creates individual markdown files for each command with complete usage information.`,
35-
RunE: func(root *cobra.Command, _ []string) error {
38+
This creates individual markdown files for each command with complete usage information.
39+
40+
Use --hugo flag to generate Hugo-compatible documentation with front matter
41+
for integration with static site generators.`,
42+
RunE: func(cmd *cobra.Command, _ []string) error {
3643
if err := os.MkdirAll(outputDir, 0755); err != nil {
3744
return fmt.Errorf("failed to create output directory: %w", err)
3845
}
39-
prepender := empty
40-
linkHandler := identity
41-
root.DisableAutoGenTag = true
42-
err := doc.GenMarkdownTreeCustom(root, outputDir, prepender, linkHandler)
46+
47+
var prepender func(string) string
48+
var linkHandler func(string) string
49+
50+
if hugoFormat {
51+
prepender = hugoPrepender
52+
linkHandler = hugoLinkHandler
53+
} else {
54+
prepender = empty
55+
linkHandler = identity
56+
}
57+
58+
rootCmd := cmd.Root()
59+
rootCmd.DisableAutoGenTag = true
60+
err := doc.GenMarkdownTreeCustom(rootCmd, outputDir, prepender, linkHandler)
4361
if err != nil {
4462
return fmt.Errorf("failed to generate documentation: %w", err)
4563
}
4664

4765
fmt.Printf("Documentation generated successfully in: %s\n", outputDir)
66+
if hugoFormat {
67+
fmt.Println("Hugo format enabled - files include front matter and Hugo-compatible links")
68+
}
4869
return nil
4970
},
5071
}
5172

5273
cmd.Flags().StringVarP(&outputDir, "output", "o", "./docs", "Output directory for generated documentation")
74+
cmd.Flags().BoolVar(&hugoFormat, "hugo", false, "Generate Hugo-compatible docs with front matter")
5375
return cmd
5476
}
5577

@@ -60,3 +82,30 @@ func identity(s string) string {
6082
func empty(_ string) string {
6183
return ""
6284
}
85+
86+
// hugoPrepender adds Hugo front matter to generated docs
87+
func hugoPrepender(filename string) string {
88+
// Extract command name from filename (e.g., "kubelb_tunnel_connect.md" -> "kubelb tunnel connect")
89+
name := strings.TrimSuffix(filepath.Base(filename), ".md")
90+
title := strings.ReplaceAll(name, "_", " ")
91+
92+
// Calculate weight based on command depth (more underscores = higher weight = appears later)
93+
depth := strings.Count(name, "_")
94+
weight := 10 + (depth * 20)
95+
96+
date := time.Now().Format("2006-01-02T00:00:00+00:00")
97+
98+
return fmt.Sprintf(`+++
99+
title = "%s"
100+
date = %s
101+
weight = %d
102+
+++
103+
104+
`, title, date, weight)
105+
}
106+
107+
// hugoLinkHandler converts links to Hugo-compatible format
108+
// Changes: "kubelb_tunnel.md" -> "../kubelb_tunnel" (relative path, no .md extension)
109+
func hugoLinkHandler(name string) string {
110+
return "../" + strings.TrimSuffix(name, ".md")
111+
}

0 commit comments

Comments
 (0)