Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
350 changes: 350 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,350 @@
# Open Cluster Management API

The canonical source for all Open Cluster Management (OCM) API definitions, client libraries, and CRDs for multicluster and multicloud Kubernetes scenarios.

## Project Overview

**Type**: Go API Library / Kubernetes CRDs
**Language**: Go
**Framework**: Kubernetes API Machinery / controller-runtime
**Primary Purpose**: API definitions and client libraries for OCM ecosystem
**Target Users**: Platform engineers, multicluster operators, OCM addon developers

## Technical Stack

- **Language**: Go 1.23+ with modern module structure
- **Kubernetes Integration**: API Machinery for CRD definitions
- **Code Generation**: Kubernetes code generators for clients and deepcopy
- **API Versioning**: Multiple API versions (v1, v1beta1, v1alpha1)
- **Client Libraries**: Kubernetes-style typed clientsets
- **Validation**: OpenAPI schema generation for CRD validation

Comment on lines +15 to +21
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Align Go version with repo toolchain (go.mod/CI).

Doc says “Go 1.23+”. Please confirm this matches go.mod and CI images to avoid confusing contributors.

Run to verify and surface mismatches:


🏁 Script executed:

#!/bin/bash
# go.mod version(s)
fd -a go.mod | xargs -I{} sh -c 'echo "== {} =="; rg -n "^go\s+\d+\.\d+" {}'

# GitHub Actions: setup-go versions
fd -a .github -t f -e yml -e yaml | xargs -I{} sh -c 'echo "== {} =="; rg -n "setup-go|go-version" {} -n -C2'

# Makefile toolchain pins (if any)
fd -a Makefile | xargs -I{} sh -c 'echo "== {} =="; rg -n "GO_VERSION|golang:" {}'

Length of output: 359


Update Go version in CLAUDE.md to match go.mod
Doc lists “Go 1.23+” but go.mod specifies go 1.24.0; change the requirement to “Go 1.24+” and verify any CI workflows also use Go 1.24.

🧰 Tools
🪛 LanguageTool

[grammar] ~15-~15: There might be a mistake here.
Context: ...*: Go 1.23+ with modern module structure

  • Kubernetes Integration: API Machinery ...

(QB_NEW_EN)


[grammar] ~16-~16: There might be a mistake here.
Context: ...ion**: API Machinery for CRD definitions

  • Code Generation: Kubernetes code gener...

(QB_NEW_EN)


[grammar] ~17-~17: There might be a mistake here.
Context: ...code generators for clients and deepcopy

  • API Versioning: Multiple API versions ...

(QB_NEW_EN)


[grammar] ~18-~18: There might be a mistake here.
Context: ...ple API versions (v1, v1beta1, v1alpha1)

  • Client Libraries: Kubernetes-style typ...

(QB_NEW_EN)


[grammar] ~19-~19: There might be a mistake here.
Context: ...ies**: Kubernetes-style typed clientsets

  • Validation: OpenAPI schema generation ...

(QB_NEW_EN)

🤖 Prompt for AI Agents
In CLAUDE.md around lines 15 to 21, the doc currently states "Go 1.23+" but
go.mod specifies go 1.24.0; update the Go requirement text to "Go 1.24+" (or "Go
1.24+ with modern module structure") to match go.mod, and also search and update
any other documentation or CI workflow files (e.g., GitHub Actions, Makefiles,
Dockerfiles) to ensure they reference and use Go 1.24.

## API Architecture

### Four Core API Groups

#### 1. Cluster Management (`cluster.open-cluster-management.io`)
- **v1**: Core cluster registration and grouping
- `ManagedCluster`: Represents a cluster joined to the hub
- `ManagedClusterSet`: Logical grouping of clusters
- `ManagedClusterSetBinding`: Namespace-level cluster set access
- **v1beta1**: Advanced cluster selection and placement
- `Placement`: Intelligent cluster selection with constraints
- `PlacementDecision`: Results of placement decisions
- **v1alpha1**: Extended cluster capabilities
- `ClusterClaim`: Cluster-specific capability declarations
- `AddonPlacementScore`: Scoring for placement decisions

#### 2. Work Distribution (`work.open-cluster-management.io`)
- **v1**: Resource deployment across clusters
- `ManifestWork`: Kubernetes resources to deploy on managed clusters
- `AppliedManifestWork`: Status of deployed resources
- **v1alpha1**: Bulk deployment capabilities
- `ManifestWorkReplicaSet`: Deploy to multiple clusters in a set

#### 3. Addon Management (`addon.open-cluster-management.io`)
- **v1alpha1**: Addon lifecycle and configuration
- `ClusterManagementAddOn`: Hub-side addon definition
- `ManagedClusterAddOn`: Cluster-specific addon instance
- `AddonDeploymentConfig`: Addon configuration templates

#### 4. Operator APIs (`operator.open-cluster-management.io`)
- **v1**: OCM component installation
- `ClusterManager`: Hub cluster OCM installation
- `Klusterlet`: Managed cluster agent installation

## Development Workflow

### Code Generation
```bash
# Update all generated code (clients, deepcopy, CRDs)
make update

# Verify code generation is up to date
make verify

# Run all tests
make test
```

### Generated Components
- **DeepCopy Methods**: For all API struct types
- **Typed Clients**: Kubernetes-style clientsets for each API group
- **Informers/Listers**: Efficient caching and watching mechanisms
- **OpenAPI Schemas**: CRD validation and documentation

## AI Development Guidelines

### API Design Patterns

#### Resource Structure
```go
// Standard Kubernetes API resource pattern
type ManagedCluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ManagedClusterSpec `json:"spec,omitempty"`
Status ManagedClusterStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster
```

#### Client Usage Patterns
```go
import (
clusterv1 "open-cluster-management.io/api/cluster/v1"
clusterclient "open-cluster-management.io/api/client/cluster/clientset/versioned"
)

// Create typed client
config, err := ctrl.GetConfig()
client := clusterclient.NewForConfigOrDie(config)

// List managed clusters
clusters, err := client.ClusterV1().ManagedClusters().List(ctx, metav1.ListOptions{})

// Watch for changes
watchInterface, err := client.ClusterV1().ManagedClusters().Watch(ctx, metav1.ListOptions{})
```

#### Status Management
```go
// Standard status update pattern
managedCluster.Status.Conditions = []metav1.Condition{
{
Type: "ManagedClusterJoined",
Status: metav1.ConditionTrue,
Reason: "ManagedClusterJoined",
Message: "Cluster successfully joined the hub",
},
}
```

### Common Development Tasks

#### Adding New API Types
1. **Define Structure**: Create Go structs with proper kubebuilder tags
2. **Register Types**: Add to scheme registration in `register.go`
3. **Generate Code**: Run `make update` to generate clients and deepcopy
4. **Add Tests**: Create comprehensive unit tests for new types
5. **Update Documentation**: Add examples and usage patterns

#### Working with Placements
```go
// Create placement with cluster selection
placement := &clusterv1beta1.Placement{
ObjectMeta: metav1.ObjectMeta{
Name: "my-placement",
Namespace: "default",
},
Spec: clusterv1beta1.PlacementSpec{
ClusterSets: []string{"clusterset1"},
Predicates: []clusterv1beta1.ClusterPredicate{
{
RequiredClusterSelector: clusterv1beta1.ClusterSelector{
LabelSelector: metav1.LabelSelector{
MatchLabels: map[string]string{
"environment": "production",
},
},
},
},
},
},
}
```

#### ManifestWork Deployment
```go
// Deploy resources to managed clusters
manifestWork := &workv1.ManifestWork{
ObjectMeta: metav1.ObjectMeta{
Name: "my-workload",
Namespace: "cluster1", // managed cluster namespace
},
Spec: workv1.ManifestWorkSpec{
Workload: workv1.ManifestsTemplate{
Manifests: []workv1.Manifest{
{
Object: unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "my-app",
"namespace": "default",
},
// ... deployment spec
},
},
},
},
},
},
}
```

### Integration Patterns

#### Controller Development
```go
// Standard controller setup for OCM APIs
import (
clusterv1 "open-cluster-management.io/api/cluster/v1"
"sigs.k8s.io/controller-runtime/pkg/controller"
)

func (r *MyReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&clusterv1.ManagedCluster{}).
Watches(&workv1.ManifestWork{}, &handler.EnqueueRequestForObject{}).
Complete(r)
}
```

#### Informer Usage
```go
// Use generated informers for efficient watching
import (
clusterinformers "open-cluster-management.io/api/client/cluster/informers/externalversions"
)

informerFactory := clusterinformers.NewSharedInformerFactory(client, time.Minute*30)
clusterInformer := informerFactory.Cluster().V1().ManagedClusters()

clusterInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: handleClusterAdd,
UpdateFunc: handleClusterUpdate,
DeleteFunc: handleClusterDelete,
})
```

### Best Practices

#### API Versioning
- **v1alpha1**: Experimental APIs, may have breaking changes
- **v1beta1**: Stable APIs, backward compatible changes only
- **v1**: Stable APIs, no breaking changes allowed
- Use feature gates for experimental functionality

#### Resource Naming
- Follow Kubernetes naming conventions
- Use descriptive, action-oriented names
- Maintain consistency across API groups
- Consider plural/singular forms carefully

#### Status Conventions
```go
// Use standard Kubernetes condition types
const (
ConditionReady = "Ready"
ConditionAvailable = "Available"
ConditionDegraded = "Degraded"
)

// Include helpful error messages
condition := metav1.Condition{
Type: ConditionReady,
Status: metav1.ConditionFalse,
Reason: "InvalidConfiguration",
Message: "Cluster configuration validation failed: missing required labels",
LastTransitionTime: metav1.Now(),
}
```

#### Validation and Defaults
```go
// Use kubebuilder tags for validation
type ManagedClusterSpec struct {
// +kubebuilder:validation:Required
// +kubebuilder:default=true
HubAcceptsClient bool `json:"hubAcceptsClient"`

// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty"`
}
Comment on lines +260 to +268
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect kubebuilder tag for integer field; use numeric validators, not Pattern.

Pattern applies to strings; LeaseDurationSeconds is an int. Provide min/max as needed.

 type ManagedClusterSpec struct {
     // +kubebuilder:validation:Required
     // +kubebuilder:default=true
     HubAcceptsClient bool `json:"hubAcceptsClient"`
-    
-    // +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
-    LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty"`
+
+    // +kubebuilder:validation:Minimum=1
+    // +kubebuilder:validation:Maximum=3600
+    LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty"`
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Use kubebuilder tags for validation
type ManagedClusterSpec struct {
// +kubebuilder:validation:Required
// +kubebuilder:default=true
HubAcceptsClient bool `json:"hubAcceptsClient"`
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty"`
}
// Use kubebuilder tags for validation
type ManagedClusterSpec struct {
// +kubebuilder:validation:Required
// +kubebuilder:default=true
HubAcceptsClient bool `json:"hubAcceptsClient"`
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=3600
LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty"`
}
🤖 Prompt for AI Agents
In CLAUDE.md around lines 260 to 268, the kubebuilder tag on
LeaseDurationSeconds incorrectly uses Pattern (a string validator) for an int32
field; replace the Pattern tag with numeric validators such as
+kubebuilder:validation:Minimum=<min> and/or
+kubebuilder:validation:Maximum=<max> (or
+kubebuilder:validation:ExclusiveMinimum/ExclusiveMaximum if needed), remove the
Pattern line, and keep the field as LeaseDurationSeconds *int32
`json:"leaseDurationSeconds,omitempty"` so the CRD uses proper integer
validation.

```

## Useful Commands

```bash
# Code Generation
make update # Generate all code (clients, deepcopy, etc.)
make verify # Verify generated code is up to date
make clean # Clean generated code

# Testing
make test # Run unit tests
make test-integration # Run integration tests
make verify-crds # Verify CRD manifests

# Development
make fmt # Format Go code
make vet # Run go vet
make lint # Run linters
```
Comment on lines +271 to +288
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Validate make targets to prevent dead commands.

Please confirm test-integration/verify-crds exist in this repo; if not, either add them or adjust the doc.


🏁 Script executed:

#!/bin/bash
fd -a Makefile | xargs -I{} sh -c 'echo "== {} =="; rg -n "test-integration|verify-crds|fmt|vet|lint|update|verify|clean" {} -n'

Length of output: 1004


Ensure referenced make targets exist or update documentation
In CLAUDE.md (lines 271–288), remove or update references to non-existent make test-integration and make verify-crds targets, or add those targets to the Makefile.

🤖 Prompt for AI Agents
In CLAUDE.md around lines 271–288, the documentation references two Make targets
(make test-integration and make verify-crds) that do not exist; either remove or
update those entries to match actual Makefile targets, or add corresponding
targets to the repo Makefile. If you choose to update the doc, replace or remove
the two lines and ensure the remaining commands reflect real targets; if you
choose to add targets, create make test-integration and make verify-crds with
sensible commands (integration test runner and CRD verification steps) and
update the Makefile index so the doc is accurate.


## Integration Examples

### External Project Integration
```go
// go.mod
module my-ocm-controller

require (
open-cluster-management.io/api v0.13.0
sigs.k8s.io/controller-runtime v0.16.0
)

// main.go
import (
clusterv1 "open-cluster-management.io/api/cluster/v1"
clusterscheme "open-cluster-management.io/api/client/cluster/clientset/versioned/scheme"
)

// Add OCM APIs to your scheme
scheme := runtime.NewScheme()
clusterscheme.AddToScheme(scheme)
```
Comment on lines +292 to +311
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Version pins in go.mod example may drift; align with current tags.

Ensure the versions reflect the latest compatible releases used by this repo’s consumers.


🏁 Script executed:

#!/bin/bash
# Show the latest tags
gh repo view open-cluster-management-io/api --json releases -q '.releases[0:5][] | {name: .name, tag: .tagName, publishedAt: .publishedAt}'
# If gh is unavailable, list module versions from proxy:
curl -s https://proxy.golang.org/open-cluster-management.io/api/@v/list | tail -n 10

Length of output: 1444


🏁 Script executed:

#!/bin/bash
# List the latest versions of controller-runtime from Go proxy
curl -s https://proxy.golang.org/sigs.k8s.io/controller-runtime/@v/list | tail -n 5

Length of output: 130


🏁 Script executed:

#!/bin/bash
# Determine latest semver tag for open-cluster-management.io/api
echo "OCM API latest version:"
curl -s https://proxy.golang.org/open-cluster-management.io/api/@v/list | sort -V | tail -n 1

# Determine latest semver tag for sigs.k8s.io/controller-runtime
echo "Controller-runtime latest version:"
curl -s https://proxy.golang.org/sigs.k8s.io/controller-runtime/@v/list | sort -V | tail -n 1

Length of output: 342


Update go.mod example to latest module versions

In the CLAUDE.md snippet (lines 292–311), replace

require (
    open-cluster-management.io/api v0.13.0
    sigs.k8s.io/controller-runtime v0.16.0
)

with

require (
    open-cluster-management.io/api v1.0.0
    sigs.k8s.io/controller-runtime v0.22.0
)

to align the example with the current latest releases.

🤖 Prompt for AI Agents
In CLAUDE.md around lines 292 to 311, the go.mod example pins outdated module
versions; update the require block to use the current releases by replacing
open-cluster-management.io/api v0.13.0 with open-cluster-management.io/api
v1.0.0 and sigs.k8s.io/controller-runtime v0.16.0 with
sigs.k8s.io/controller-runtime v0.22.0 so the documentation shows the latest
compatible module versions.


### CRD Installation
```bash
# Install CRDs from this repository
kubectl apply -f https://raw.githubusercontent.com/open-cluster-management-io/api/main/cluster/v1/0000_00_clusters.open-cluster-management.io_managedclusters.crd.yaml
```
Comment on lines +313 to +317
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid applying CRDs from ‘main’; pin to a release tag or commit SHA.

Prevents breaking changes from landing on users unexpectedly.

- kubectl apply -f https://raw.githubusercontent.com/open-cluster-management-io/api/main/cluster/v1/0000_00_clusters.open-cluster-management.io_managedclusters.crd.yaml
+ # Replace vX.Y.Z with a tested release tag
+ kubectl apply -f https://raw.githubusercontent.com/open-cluster-management-io/api/vX.Y.Z/cluster/v1/0000_00_clusters.open-cluster-management.io_managedclusters.crd.yaml
🤖 Prompt for AI Agents
In CLAUDE.md around lines 313 to 317, the CRD installation snippet points to the
repository's main branch which risks unexpected breakages; update the example to
reference a specific release tag or commit SHA (e.g., vX.Y.Z or a specific SHA)
instead of "main", and mention how to find the correct tag/SHA (releases page or
git log) so the kubectl apply URL is deterministic and reproducible.


## Project Structure

```
├── addon/ # Addon management API definitions
│ └── v1alpha1/ # Addon API types and client code
├── cluster/ # Cluster management API definitions
│ ├── v1/ # Stable cluster APIs
│ ├── v1beta1/ # Beta placement APIs
│ └── v1alpha1/ # Alpha cluster capabilities APIs
├── work/ # Work distribution API definitions
│ ├── v1/ # Stable work APIs
│ └── v1alpha1/ # Alpha work APIs
├── operator/ # Operator installation APIs
│ └── v1/ # Operator APIs
├── client/ # Generated Kubernetes clients
│ ├── addon/ # Addon client packages
│ ├── cluster/ # Cluster client packages
│ ├── work/ # Work client packages
│ └── operator/ # Operator client packages
└── utils/ # Utility libraries and helpers
```

## Contributing Guidelines

- **API Compatibility**: Maintain backward compatibility for stable APIs
- **Code Generation**: Always run `make update` after API changes
- **Testing**: Comprehensive unit tests for all API types
- **Documentation**: Update examples and API documentation
- **Validation**: Add appropriate kubebuilder validation tags
- **Versioning**: Follow Kubernetes API versioning guidelines

This repository serves as the foundation for the entire Open Cluster Management ecosystem, enabling multicluster Kubernetes management at scale.
Loading