Skip to content
Closed
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,6 @@ hyperfleet-operator/bin/
# Compiled operator binaries (built outside bin/)
hyperfleet-operator/manager
hyperfleet-operator/compactor

# Codegen intermediate files
*.passthrough.go.raw
45 changes: 41 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
test-e2e test-e2e-api test-e2e-cli test-e2e-platform-monitoring test-e2e-zoa test-e2e-authz test-e2e-sdk \
e2e-authz-infra-up e2e-authz-infra-down e2e-init-db \
fmt vet verify deps \
manifests generate generate-clientset verify-clientset setup-envtest \
manifests generate generate-clientset verify-clientset \
generate-public-deepcopy setup-envtest \
codegen-passthrough codegen-registry codegen-verify codegen verify-codegen \
image-api image-operator image-push-api image-push-operator

# ── Configuration ────────────────────────────────────────────────────────
Expand Down Expand Up @@ -106,9 +108,15 @@ help:
@echo ""
@echo "Code Generation:"
@echo " manifests Generate CRD manifests"
@echo " generate Generate deepcopy methods"
@echo " generate-clientset Generate typed client SDK from CRD types"
@echo " verify-clientset Fail if generated clientset is out of date"
@echo " generate Generate deepcopy methods (v1alpha1)"
@echo " generate-clientset Generate typed client SDK from CRD types"
@echo " verify-clientset Fail if generated clientset is out of date"
@echo " generate-public-deepcopy Generate deepcopy methods (v2alpha1 public API)"
@echo " codegen Full codegen pipeline (passthrough → deepcopy → registry)"
@echo " codegen-passthrough Generate passthrough types from HyperShift"
@echo " codegen-registry Generate field metadata registry from markers"
@echo " codegen-verify Verify codegen outputs compile"
@echo " verify-codegen Fail if codegen outputs are out of date"
@echo " setup-envtest Install envtest binaries (etcd, kube-apiserver)"
@echo " deps Download and tidy all modules"
@echo ""
Expand Down Expand Up @@ -260,6 +268,7 @@ verify:
cd hyperfleet-db && go mod tidy
cd hyperfleet-operator/api && go mod tidy
cd hyperfleet-operator && go mod tidy
cd api/public/v2alpha1 && go mod tidy
cd platform-api && go mod tidy
cd test && go mod tidy
cd hack/tools && go mod tidy
Expand All @@ -268,6 +277,7 @@ verify:
hyperfleet-db/go.mod hyperfleet-db/go.sum \
hyperfleet-operator/api/go.mod hyperfleet-operator/api/go.sum \
hyperfleet-operator/go.mod hyperfleet-operator/go.sum \
api/public/v2alpha1/go.mod api/public/v2alpha1/go.sum \
platform-api/go.mod platform-api/go.sum \
test/go.mod test/go.sum \
hack/tools/go.mod hack/tools/go.sum \
Expand All @@ -277,6 +287,7 @@ deps:
cd hyperfleet-db && go mod download && go mod tidy
cd hyperfleet-operator/api && go mod download && go mod tidy
cd hyperfleet-operator && go mod download && go mod tidy
cd api/public/v2alpha1 && go mod download && go mod tidy
cd platform-api && go mod download && go mod tidy
cd test && go mod download && go mod tidy
cd hack/api-codegen && go mod download && go mod tidy
Expand Down Expand Up @@ -315,6 +326,32 @@ generate-clientset: $(CLIENT_GEN) $(WIRE_GEN)
verify-clientset: generate-clientset
git diff --exit-code clientset/

codegen-passthrough: build-api-codegen
cd api/public/v2alpha1 && ../../../bin/passthrough-gen \
-import-path github.com/openshift/hypershift/api/hypershift/v1beta1 \
-types HostedClusterSpec,NodePoolSpec \
-output-dir . \
-package v2alpha1
mv api/public/v2alpha1/zz_generated.passthrough.go api/public/v2alpha1/zz_generated.passthrough.go.raw

generate-public-deepcopy: codegen-passthrough $(CONTROLLER_GEN)
$(CONTROLLER_GEN) object paths="./api/public/v2alpha1/..."

codegen-registry: generate-public-deepcopy build-api-codegen
./bin/marker-scanner \
-input-dirs api/public/v2alpha1 \
-output-file platform-api/internal/codegen/registry/field_metadata.go

codegen-verify: codegen-registry
cd api/public/v2alpha1 && go build ./...
cd platform-api && go build ./internal/codegen/...

codegen: codegen-verify

verify-codegen: codegen
git diff --exit-code api/public/v2alpha1/zz_generated.deepcopy.go
git diff --exit-code platform-api/internal/codegen/registry/

ENVTEST_BIN_DIR ?= $(shell pwd)/.envtest

setup-envtest: $(SETUP_ENVTEST)
Expand Down
156 changes: 156 additions & 0 deletions api/public/v2alpha1/cluster_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
Copyright 2026.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v2alpha1

import (
hypershiftv1beta1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

// ClusterPhase represents the lifecycle phase of a Cluster.
// +kubebuilder:validation:Enum=WaitingForPlacement;Provisioning;Ready;Deleting
type ClusterPhase string

const (
ClusterPhaseWaitingForPlacement ClusterPhase = "WaitingForPlacement"
ClusterPhaseProvisioning ClusterPhase = "Provisioning"
ClusterPhaseReady ClusterPhase = "Ready"
ClusterPhaseDeleting ClusterPhase = "Deleting"
)

// ClusterSpec defines the desired state of a ROSA HCP cluster.
type ClusterSpec struct {
// DisplayName is a human-readable name for the cluster.
// +hyperfleet:write-mode=mutable
// +kubebuilder:validation:MaxLength=256
// +optional
DisplayName string `json:"displayName,omitempty"`

// DeleteProtection prevents accidental deletion when enabled.
// +hyperfleet:write-mode=mutable
// +optional
DeleteProtection *bool `json:"deleteProtection,omitempty"`

// ExpirationTimestamp marks when this cluster should be automatically deleted.
// +k8s:openapi-gen=true
// +hyperfleet:write-mode=mutable
// +optional
ExpirationTimestamp *metav1.Time `json:"expirationTimestamp,omitempty"`

// Properties are arbitrary key-value pairs for customer metadata.
// +hyperfleet:write-mode=mutable
// +optional
Properties map[string]string `json:"properties,omitempty"`

// Tags are customer-defined labels for organizational purposes.
// +hyperfleet:write-mode=mutable
// +openshift:enable:FeatureGate=HyperFleetAutoScaling
// +optional
Tags map[string]string `json:"tags,omitempty"`

// AccountID identifies the customer account (platform-managed, hidden from API).
// +k8s:openapi-gen=false
// +hyperfleet:write-mode=service-set
// +optional
AccountID string `json:"accountId,omitempty"`

// CreatorARN is the IAM ARN of the user who created this cluster.
// +k8s:openapi-gen=false
// +hyperfleet:write-mode=service-set
// +optional
// +kubebuilder:validation:Pattern=`^arn:aws:`
CreatorARN string `json:"creatorARN,omitempty"`

// InternalID is an internal platform identifier (platform-managed, hidden).
// +k8s:openapi-gen=false
// +hyperfleet:write-mode=service-set
// +optional
InternalID string `json:"internalId,omitempty"`

// HostedCluster is the full HyperShift HostedClusterSpec.
// +kubebuilder:validation:Required
HostedCluster hypershiftv1beta1.HostedClusterSpec `json:"hostedCluster"`
}

// ClusterStatus defines the observed state of a Cluster.
type ClusterStatus struct {
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// +optional
Phase ClusterPhase `json:"phase,omitempty"`

// +optional
ControlPlaneEndpoint hypershiftv1beta1.APIEndpoint `json:"controlPlaneEndpoint,omitempty"`

// +optional
Version string `json:"version,omitempty"`

// +optional
PlacementRef *PlacementReference `json:"placementRef,omitempty"`

// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}

// PlacementReference identifies the management cluster assignment.
type PlacementReference struct {
Name string `json:"name"`
ManagementCluster string `json:"managementCluster"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Namespaced,shortName=hfc
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=".status.phase"
// +kubebuilder:printcolumn:name="MC",type=string,JSONPath=".status.placementRef.managementCluster"
// +kubebuilder:printcolumn:name="Endpoint",type=string,JSONPath=".status.controlPlaneEndpoint.host",priority=1
// +kubebuilder:printcolumn:name="Expires",type=date,JSONPath=".spec.expirationTimestamp",priority=1
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=".metadata.creationTimestamp"

// Cluster is the Schema for the clusters API.
type Cluster struct {
metav1.TypeMeta `json:",inline"`

// +optional
metav1.ObjectMeta `json:"metadata,omitzero"`

// +required
Spec ClusterSpec `json:"spec"`

// +optional
Status ClusterStatus `json:"status,omitzero"`
}

// +kubebuilder:object:root=true

// ClusterList contains a list of Cluster.
type ClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitzero"`
Items []Cluster `json:"items"`
}

func init() {
SchemeBuilder.Register(func(s *runtime.Scheme) error {
s.AddKnownTypes(SchemeGroupVersion, &Cluster{}, &ClusterList{})
return nil
})
}
Loading