Skip to content

Commit b4c425d

Browse files
committed
init gw controller
1 parent d125b0a commit b4c425d

40 files changed

+4695
-0
lines changed

.github/workflows/goreleaser.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: goreleaser
3+
on:
4+
push:
5+
tags:
6+
- v*
7+
jobs:
8+
goreleaser:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v3
13+
with:
14+
fetch-depth: 0
15+
- name: Set up Go
16+
uses: actions/setup-go@v4
17+
with:
18+
go-version: "1.22"
19+
- name: Set up QEMU
20+
uses: docker/setup-qemu-action@v2
21+
- name: Setup Docker Buildx
22+
uses: docker/setup-buildx-action@v2
23+
- name: Login to GHCR
24+
uses: docker/login-action@v2
25+
with:
26+
registry: ghcr.io
27+
username: ${{ github.actor }}
28+
password: ${{ secrets.GITHUB_TOKEN }}
29+
- name: Run GoReleaser for tag
30+
if: "startsWith(github.ref, 'refs/tags/')"
31+
uses: goreleaser/goreleaser-action@v4
32+
with:
33+
version: latest
34+
args: release --clean
35+
env:
36+
GORELEASER_CURRENT_TAG: ${{ github.ref_name }}
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
- name: Clear
39+
if: always()
40+
run: rm -f ${HOME}/.docker/config.json

.github/workflows/test.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
on: [push, pull_request]
2+
name: Test
3+
jobs:
4+
test:
5+
strategy:
6+
matrix:
7+
go-version: [1.24.x]
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Install Go
11+
uses: actions/setup-go@v2
12+
with:
13+
go-version: ${{ matrix.go-version }}
14+
- name: Checkout code
15+
uses: actions/checkout@v2
16+
- name: Test
17+
run: go test ./...

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
.vscode
33
vendor
44
build
5+
api-gateway-controller

.goreleaser.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
before:
3+
hooks:
4+
- go mod tidy
5+
builds:
6+
- id: api-gateway-controller
7+
dir: ./cmd
8+
env:
9+
- CGO_ENABLED=0
10+
goos:
11+
- linux
12+
goarch:
13+
- amd64
14+
- arm64
15+
- arm
16+
binary: api-gateway-controller
17+
ldflags:
18+
- "-s -w -X main.version={{ if not .IsSnapshot }}v{{ end }}{{ .Version }} -X main.gitCommit={{ .ShortCommit }}"
19+
20+
dockers:
21+
- build_flag_templates: [--platform=linux/amd64]
22+
dockerfile: Dockerfile
23+
goarch: amd64
24+
image_templates: ["ghcr.io/serverscom/api-gateway-controller:{{ if not .IsSnapshot }}v{{ end }}{{ .Version }}-amd64"]
25+
use: buildx
26+
- build_flag_templates: [--platform=linux/arm64]
27+
dockerfile: Dockerfile
28+
goarch: arm64
29+
image_templates: ["ghcr.io/serverscom/api-gateway-controller:{{ if not .IsSnapshot }}v{{ end }}{{ .Version }}-arm64v8"]
30+
use: buildx
31+
- build_flag_templates: [--platform=linux/arm/v6]
32+
dockerfile: Dockerfile
33+
goarch: arm
34+
goarm: 6
35+
image_templates: ["ghcr.io/serverscom/api-gateway-controller:{{ if not .IsSnapshot }}v{{ end }}{{ .Version }}-armv6"]
36+
37+
docker_manifests:
38+
- name_template: ghcr.io/serverscom/api-gateway-controller:{{ if not .IsSnapshot }}v{{ end }}{{ .Version }}
39+
image_templates:
40+
- ghcr.io/serverscom/api-gateway-controller:{{ if not .IsSnapshot }}v{{ end }}{{ .Version }}-amd64
41+
- ghcr.io/serverscom/api-gateway-controller:{{ if not .IsSnapshot }}v{{ end }}{{ .Version }}-arm64v8
42+
- ghcr.io/serverscom/api-gateway-controller:{{ if not .IsSnapshot }}v{{ end }}{{ .Version }}-armv6
43+
44+
release:
45+
ids: [""]
46+
draft: true
47+
extra_files:
48+
- glob: "./api-gateway-controller-*.tgz"

Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM alpine:3.22
2+
3+
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
4+
COPY api-gateway-controller /bin/api-gateway-controller
5+
6+
ENTRYPOINT ["/bin/api-gateway-controller"]

cmd/main.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"log"
7+
"os"
8+
9+
"github.com/serverscom/api-gateway-controller/internal/config"
10+
"github.com/serverscom/api-gateway-controller/internal/flags"
11+
"github.com/serverscom/api-gateway-controller/internal/gateway/controller"
12+
lbsrv "github.com/serverscom/api-gateway-controller/internal/service/lb"
13+
tlssrv "github.com/serverscom/api-gateway-controller/internal/service/tls"
14+
15+
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
16+
ctrl "sigs.k8s.io/controller-runtime"
17+
"sigs.k8s.io/controller-runtime/pkg/cache"
18+
"sigs.k8s.io/controller-runtime/pkg/healthz"
19+
ctrlZap "sigs.k8s.io/controller-runtime/pkg/log/zap"
20+
"sigs.k8s.io/controller-runtime/pkg/metrics/server"
21+
22+
"k8s.io/apimachinery/pkg/runtime"
23+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
24+
)
25+
26+
var (
27+
version string
28+
gitCommit string
29+
scheme = runtime.NewScheme()
30+
setupLog = ctrl.Log.WithName("setup")
31+
)
32+
33+
func init() {
34+
_ = clientgoscheme.AddToScheme(scheme)
35+
_ = gatewayv1.Install(scheme)
36+
}
37+
38+
func main() {
39+
var opts ctrlZap.Options
40+
opts.BindFlags(flag.CommandLine)
41+
ctrlConf, err := flags.ParseFlags()
42+
if err != nil {
43+
log.Fatalf("Error parsing flags: %v\n", err)
44+
}
45+
46+
if ctrlConf.ShowVersion {
47+
fmt.Printf("Version=%v GitCommit=%v\n", version, gitCommit)
48+
os.Exit(0)
49+
}
50+
51+
ctrl.SetLogger(ctrlZap.New(ctrlZap.UseFlagOptions(&opts)))
52+
53+
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
54+
Scheme: scheme,
55+
Cache: cache.Options{
56+
DefaultNamespaces: map[string]cache.Config{
57+
ctrlConf.Namespace: {},
58+
},
59+
},
60+
Metrics: server.Options{
61+
BindAddress: ctrlConf.MetricsAddr,
62+
},
63+
HealthProbeBindAddress: ctrlConf.ProbeAddr,
64+
LeaderElection: ctrlConf.EnableLeaderElection,
65+
})
66+
if err != nil {
67+
setupLog.Error(err, "unable to start manager")
68+
os.Exit(1)
69+
}
70+
71+
// setup sc client
72+
scCli, err := config.NewServerscomClient()
73+
if err != nil {
74+
setupLog.Error(err, "unable to create servers.com client")
75+
os.Exit(1)
76+
}
77+
scCli.SetupUserAgent(fmt.Sprintf("%s/%s %s", ctrlConf.ControllerName, version, gitCommit))
78+
79+
// setup gw class reconciler
80+
if err = (&controller.GatewayClassReconciler{
81+
Client: mgr.GetClient(),
82+
ControllerName: ctrlConf.ControllerName,
83+
}).SetupWithManager(mgr); err != nil {
84+
setupLog.Error(err, "unable to create controller", "controller", "GatewayClass")
85+
os.Exit(1)
86+
}
87+
88+
// setup gw reconciler
89+
if err = (&controller.GatewayReconciler{
90+
Client: mgr.GetClient(),
91+
Recorder: mgr.GetEventRecorderFor("gateway-controller"),
92+
ControllerName: ctrlConf.ControllerName,
93+
GatewayClassName: ctrlConf.GatewayClassName,
94+
LBMgr: lbsrv.NewManager(scCli),
95+
TLSMgr: tlssrv.NewManager(scCli),
96+
}).SetupWithManager(mgr); err != nil {
97+
setupLog.Error(err, "unable to create controller", "controller", "Gateway")
98+
os.Exit(1)
99+
}
100+
101+
// Health checks
102+
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
103+
setupLog.Error(err, "unable to set up health check")
104+
os.Exit(1)
105+
}
106+
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
107+
setupLog.Error(err, "unable to set up ready check")
108+
os.Exit(1)
109+
}
110+
111+
setupLog.Info("starting manager", "version", version, "gitCommit", gitCommit)
112+
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
113+
setupLog.Error(err, "problem running manager")
114+
os.Exit(1)
115+
}
116+
117+
}

examples/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Gateway API Controller — Example Installation for local machine
2+
3+
This directory contains sample manifests and step-by-step instructions for deploying a Gateway API controller on Kubernetes local setup.
4+
5+
## Prerequisites
6+
7+
- A running Kubernetes cluster (tested with Docker Desktop)
8+
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
9+
- Your controller image built locally as `gw-controller:local`
10+
The image can be built by running the following command from the root of this repo:
11+
```bash
12+
CGO_ENABLED=0 GOOS=linux go build -o api-gateway-controller cmd/main.go && docker build -t gw-controller:local .
13+
```
14+
15+
## Installation Steps
16+
17+
### 1. Install Gateway API CRDs
18+
19+
Apply the latest CRDs directly from the official repository:
20+
21+
```bash
22+
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml
23+
```
24+
25+
26+
### 2. Create the Namespace
27+
28+
```bash
29+
kubectl apply -f namespace.yaml
30+
```
31+
32+
33+
### 3. Create the serverscom API Secret
34+
35+
Update the values to your actual credentials before applying:
36+
37+
```bash
38+
kubectl apply -f secret.yaml
39+
```
40+
41+
42+
### 4. Create ServiceAccount, RBAC, and Bindings
43+
44+
```bash
45+
kubectl apply -f rbac.yaml
46+
```
47+
48+
49+
### 5. Deploy the Gateway Controller
50+
51+
```bash
52+
kubectl apply -f deployment.yaml
53+
```
54+
55+
## Files Overview
56+
57+
- `namespace.yaml` — Namespace for the controller
58+
- `secret.yaml` — API credentials for serverscom (update these for your environment)
59+
- `rbac.yaml` — ServiceAccount and required RBAC permissions
60+
- `deployment.yaml` — Deployment manifest for the controller
61+
62+
> **Note:** Adjust the image ( image with gw controller should exist ), environment variables, and secrets as needed for your cluster.

examples/deployment.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: gw-controller
5+
namespace: gateway-serverscom
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: gw-controller
11+
template:
12+
metadata:
13+
labels:
14+
app: gw-controller
15+
spec:
16+
serviceAccountName: gw-controller
17+
containers:
18+
- name: gw-controller
19+
image: gw-controller:local
20+
imagePullPolicy: IfNotPresent
21+
args:
22+
# - "--zap-log-level=debug"
23+
env:
24+
- name: SC_ACCESS_TOKEN
25+
valueFrom:
26+
secretKeyRef:
27+
name: serverscom
28+
key: access-token
29+
- name: SC_API_URL
30+
valueFrom:
31+
secretKeyRef:
32+
name: serverscom
33+
key: api-url
34+
- name: SC_CLUSTER_ID
35+
valueFrom:
36+
secretKeyRef:
37+
name: serverscom
38+
key: cluster-id
39+
- name: SC_LOCATION_ID
40+
valueFrom:
41+
secretKeyRef:
42+
name: serverscom
43+
key: location-id

examples/namespace.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: gateway-serverscom

examples/rbac.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
apiVersion: v1
2+
kind: ServiceAccount
3+
metadata:
4+
name: gw-controller
5+
namespace: gateway-serverscom
6+
---
7+
apiVersion: rbac.authorization.k8s.io/v1
8+
kind: ClusterRole
9+
metadata:
10+
name: system:controller:gw-controller
11+
rules:
12+
- apiGroups: [""]
13+
resources: ["secrets", "endpoints", "services", "pods", "nodes", "namespaces", "configmaps", "events"]
14+
verbs: ["get", "list", "watch", "update", "create", "patch"]
15+
- apiGroups: ["gateway.networking.k8s.io"]
16+
resources: ["gatewayclasses", "gateways", "httproutes", "grpcroutes", "referencegrants"]
17+
verbs: ["get", "list", "watch", "update", "create", "patch"]
18+
- apiGroups: ["gateway.networking.k8s.io"]
19+
resources: ["gatewayclasses/status", "gateways/status"]
20+
verbs: ["update", "patch"]
21+
- apiGroups: ["coordination.k8s.io"]
22+
resources: ["leases"]
23+
verbs: ["get", "watch", "list", "create", "update"]
24+
---
25+
apiVersion: rbac.authorization.k8s.io/v1
26+
kind: ClusterRoleBinding
27+
metadata:
28+
name: system:controller:gw-controller
29+
roleRef:
30+
apiGroup: rbac.authorization.k8s.io
31+
kind: ClusterRole
32+
name: system:controller:gw-controller
33+
subjects:
34+
- kind: ServiceAccount
35+
name: gw-controller
36+
namespace: gateway-serverscom

0 commit comments

Comments
 (0)