1
0
Fork 0
mirror of https://github.com/imjasonh/client-go2 synced 2026-07-13 03:18:27 +00:00
client-go2/README.md
Jason Hall e5071fc0cf
Add support for label and field selectors in informers
- Add InformOptions struct with ListOptions and ResyncPeriod fields
- Update all client methods to accept options parameters
- Add comprehensive examples in main.go demonstrating:
  - Label selector filtering (test=example)
  - Field selector filtering (status.phase=Running)
  - Custom resync periods
- Add tests for label and field selectors with mock query parameter support
- Fix nil pointer handling in all client methods
- Update mock transport to handle query parameters correctly

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 17:13:22 -04:00

80 lines
2.2 KiB
Markdown

## Experimenting with `k8s.io/client-go` and Go generics
[![Build](https://github.com/imjasonh/client-go2/actions/workflows/build.yaml/badge.svg)](https://github.com/imjasonh/client-go2/actions/workflows/build.yaml)
This is an experimental type-parameter-aware client that wraps [`k8s.io/client-go/rest`](https://pkg.go.dev/k8s.io/client-go/rest).
## Features
- **Type-safe generic client** - Work with strongly-typed Kubernetes objects instead of `unstructured.Unstructured`
- **Zero code generation** - Uses Go generics instead of code generation
- **Full CRUD operations** - List, Get, Create, Update, Delete, and Patch support
- **Informer support** - Watch for changes with type-safe event handlers
- **Automatic GVR inference** - No need to manually specify GroupVersionResource for standard Kubernetes types
## Usage
```go
// Create a client that automatically infers the GVR from the type
podClient, err := generic.NewClient[*corev1.Pod](config)
if err != nil {
log.Fatal(err)
}
// List pods in a namespace
pods, err := podClient.List(ctx, "kube-system")
if err != nil {
log.Fatal(err)
}
// Create a ConfigMap
cmClient, err := generic.NewClient[*corev1.ConfigMap](config)
if err != nil {
log.Fatal(err)
}
cm, err = cmClient.Create(ctx, "default", &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "my-config",
},
Data: map[string]string{
"key": "value",
},
})
// If you need to specify a custom GVR, use NewClientGVR
customClient := generic.NewClientGVR[*corev1.Pod](customGVR, config)
```
## Running the Example
```
$ go run ./
2025/07/23 11:23:10 LISTING PODS
2025/07/23 11:23:10 - coredns-674b8bbfcf-ddcww
2025/07/23 11:23:10 - coredns-674b8bbfcf-dqqx5
2025/07/23 11:23:10 - etcd-kind-control-plane
2025/07/23 11:23:10 - kindnet-tkf6l
2025/07/23 11:23:10 - kube-apiserver-kind-control-plane
2025/07/23 11:23:10 - kube-controller-manager-kind-control-plane
2025/07/23 11:23:10 - kube-proxy-76tcd
2025/07/23 11:23:10 - kube-scheduler-kind-control-plane
...
```
## Testing
Run unit tests:
```bash
go test ./generic
```
Run e2e tests (requires a Kubernetes cluster):
```bash
go test ./generic -tags=e2e
```
# THIS IS AN EXPERIMENT
None of this is anywhere near set in stone.
The name `client-go2` is a placeholder, and a joke.