Skip to content

Commit 1ceed8f

Browse files
authored
Merge branch 'main' into load-balacer-prefix
2 parents c9af4f3 + 5a59a82 commit 1ceed8f

File tree

5 files changed

+126
-7
lines changed

5 files changed

+126
-7
lines changed

.github/copilot-instructions.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Linode Cloud Controller Manager - AI Coding Assistant Instructions
2+
3+
## Project Overview
4+
This is the Kubernetes Cloud Controller Manager for Linode infrastructure. It integrates Kubernetes clusters with Linode's cloud services, managing load balancers (NodeBalancers), firewalls (Cloud Firewalls), nodes, networking routes, and IP allocation.
5+
6+
## Architecture & Core Components
7+
8+
### Cloud Provider Interface
9+
- `cloud/linode/cloud.go` - Main cloud provider implementation following Kubernetes CloudProvider interface
10+
- Implements 4 controllers: Node, Service, Route, and NodeIPAM controllers
11+
- All controllers run as goroutines initialized in `Initialize()` method
12+
13+
### Controllers Structure
14+
- **Node Controller** (`node_controller.go`) - Manages node metadata, addresses, and lifecycle
15+
- **Service Controller** (`service_controller.go`) - Handles service deletions and cleanup
16+
- **Route Controller** (`route_controller.go`) - Manages VPC routes and pod networking
17+
- **NodeIPAM Controller** (`nodeipamcontroller.go`) - Allocates pod CIDRs to nodes
18+
19+
### Load Balancer Types
20+
Two distinct implementations:
21+
1. **NodeBalancer** (`loadbalancers.go`) - Traditional Linode NodeBalancers
22+
2. **Cilium BGP** (`cilium_loadbalancers.go`) - BGP-based IP sharing
23+
24+
## Development Patterns
25+
26+
### Client Abstraction
27+
- `cloud/linode/client/client.go` - Interface wrapping Linode API
28+
- `client_with_metrics.go` - Prometheus metrics decorator using generated code
29+
- Use `//go:generate` with gowrap for automatic client instrumentation
30+
31+
### Testing Strategy
32+
- Extensive use of gomock for Linode API client mocking
33+
- `fake_linode_test.go` - In-memory fake implementation for integration tests
34+
- Table-driven tests pattern throughout codebase
35+
- Mock generation: `//go:generate go run github.com/golang/mock/mockgen`
36+
37+
### Configuration Management
38+
- `Options` global struct in `cloud.go` for CLI flags and environment variables
39+
- Annotation-driven service configuration via `cloud/annotations/annotations.go`
40+
- All annotations prefixed with `service.beta.kubernetes.io/linode-loadbalancer-`
41+
42+
## Key Development Workflows
43+
44+
### Building & Testing
45+
```bash
46+
# Use devbox for development environment
47+
devbox shell
48+
49+
# Build binary
50+
make build
51+
52+
# Run tests with coverage
53+
make test-coverage
54+
55+
# Generate mocks (run after changing client interface)
56+
make mockgen
57+
```
58+
59+
### Adding New Annotations
60+
1. Add constant to `cloud/annotations/annotations.go`
61+
2. Update `docs/configuration/annotations.md` documentation
62+
3. Implement parsing logic in relevant controller
63+
4. Add validation and tests
64+
65+
### Working with Load Balancers
66+
- Check `loadbalancers.go` for NodeBalancer implementation patterns
67+
- Use `portConfigAnnotation` struct for JSON port configurations
68+
- VPC integration uses `getVPCCreateOptions()` for subnet selection
69+
- Health check configuration follows annotation-driven pattern
70+
71+
## Project-Specific Conventions
72+
73+
### Error Handling
74+
- Custom error types: `invalidProviderIDError`, `lbNotFoundError`
75+
- Use `ignoreLinodeAPIError()` helper for handling expected API errors
76+
- Sentry integration for error reporting in production
77+
78+
### Logging Patterns
79+
- Use `klog` package throughout (Kubernetes standard)
80+
- Log levels: Info for normal operations, Error for failures, V(3) for debug
81+
- Include context like service names, node names in log messages
82+
83+
### Resource Management
84+
- Provider ID format: `linode://12345` (instance ID)
85+
- Node caching with TTL in `k8sNodeCache` for performance
86+
- Workqueue pattern for asynchronous controller processing
87+
88+
### Deployment
89+
- DaemonSet deployment on control plane nodes only
90+
- Uses `hostNetwork: true` for API access
91+
- Requires `LINODE_API_TOKEN` and `LINODE_REGION` environment variables
92+
- RBAC permissions defined in `deploy/ccm-linode-template.yaml`
93+
94+
## Integration Points
95+
96+
### Kubernetes APIs
97+
- Implements standard CloudProvider interface from `k8s.io/cloud-provider`
98+
- Node informers for real-time node updates
99+
- Service informers for load balancer lifecycle management
100+
101+
### Linode API Integration
102+
- Wrapped via `linodego` client library
103+
- Rate limiting and retry logic built into client wrapper
104+
- Prometheus metrics automatically generated for all API calls
105+
106+
### Cilium Integration
107+
- BGP mode requires Cilium CNI with BGP peering
108+
- Creates CiliumLoadBalancerIPPool resources for IP management
109+
- Uses node selectors for BGP-enabled nodes
110+
111+
## Common Gotchas
112+
- NodeBalancer backends require VPC configuration when `Options.VPCNames` is set
113+
- Node exclusion annotation: `node.k8s.linode.com/exclude-from-nb`
114+
- Port configurations must be valid JSON in annotations
115+
- Health check types depend on protocol (UDP vs TCP/HTTP)
116+
- Instance cache is global and shared across controllers
117+
118+
## Documentation
119+
- Keep `docs/configuration/annotations.md` synchronized with code changes
120+
- All new features require documentation in `docs/` directory
121+
- Examples in `docs/examples/` should reflect real-world usage patterns

.github/workflows/build-test.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,11 @@ jobs:
5353
golang.org:443
5454
proxy.golang.org:443
5555
sum.golang.org:443
56-
objects.githubusercontent.com:443
56+
*.githubusercontent.com:443
5757
storage.googleapis.com:443
5858
cli.codecov.io:443
5959
api.codecov.io:443
6060
ingest.codecov.io:443
61-
raw.githubusercontent.com:443
6261
get.helm.sh:443
6362
golangci-lint.run:443
6463

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,11 @@ jobs:
5555
golang.org:443
5656
proxy.golang.org:443
5757
sum.golang.org:443
58-
objects.githubusercontent.com:443
58+
*.githubusercontent.com:443
5959
storage.googleapis.com:443
6060
cli.codecov.io:443
6161
api.codecov.io:443
6262
ingest.codecov.io:443
63-
raw.githubusercontent.com:443
6463
6564
- uses: actions/[email protected]
6665
with:

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ toolchain go1.24.1
77
require (
88
github.com/appscode/go v0.0.0-20201105063637-5613f3b8169f
99
github.com/cilium/cilium v1.17.5
10-
github.com/getsentry/sentry-go v0.34.0
10+
github.com/getsentry/sentry-go v0.34.1
1111
github.com/golang/mock v1.6.0
1212
github.com/google/uuid v1.6.0
1313
github.com/hexdigest/gowrap v1.4.2

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/
7676
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
7777
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
7878
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
79-
github.com/getsentry/sentry-go v0.34.0 h1:1FCHBVp8TfSc8L10zqSwXUZNiOSF+10qw4czjarTiY4=
80-
github.com/getsentry/sentry-go v0.34.0/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE=
79+
github.com/getsentry/sentry-go v0.34.1 h1:HSjc1C/OsnZttohEPrrqKH42Iud0HuLCXpv8cU1pWcw=
80+
github.com/getsentry/sentry-go v0.34.1/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE=
8181
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
8282
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
8383
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=

0 commit comments

Comments
 (0)