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
101 changes: 97 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: build test test-unit test-authz test-coverage test-e2e test-e2e-api test-e2e-cli test-e2e-platform-monitoring test-e2e-zoa lint clean image image-push run generate generate-swagger help fmt vet
.PHONY: build test test-unit test-authz test-coverage test-e2e test-e2e-api test-e2e-cli test-e2e-platform-monitoring test-e2e-zoa lint clean image image-push run generate generate-swagger help fmt vet codegen-install-tools codegen-passthrough codegen-registry codegen-openapi codegen-verify get-hypershift-version swagger-ui-serve swagger-ui-open

BINARY_NAME := rosa-regional-platform-api
IMAGE_REPO ?= quay.io/openshift-online/rosa-regional-platform-api
Expand Down Expand Up @@ -76,11 +76,23 @@ help:
@echo " image-e2e-push-multiarch - Build and push E2E test container (multiarch)"
@echo ""
@echo "Code Generation:"
@echo " deps - Download and tidy dependencies"
@echo " generate - Generate OpenAPI code"
@echo " deps - Download and tidy dependencies"
@echo " generate - Generate OpenAPI code"
@echo " generate-swagger - Regenerate swagger-ui.html"
@echo ""
@echo " all - Run all checks (deps, fmt, vet, lint, test, build)"
@echo "Codegen Integration:"
@echo " codegen-install-tools - Install passthrough-gen, marker-scanner, and openapi-gen binaries"
@echo " codegen-passthrough - Regenerate passthrough types from HyperShift CRDs"
@echo " codegen-registry - Regenerate field metadata registry from annotated types"
@echo " codegen-openapi - Generate OpenAPI schemas from Go types and merge into openapi.yaml"
@echo " codegen-verify - Verify codegen and dependent packages compile"
@echo " get-hypershift-version - Show current HyperShift version in go.mod"
@echo ""
@echo "API Documentation:"
@echo " swagger-ui-serve - Serve Swagger UI locally (requires Python 3)"
@echo " swagger-ui-open - Open Swagger UI in browser (requires swagger-ui-serve running)"
@echo ""
@echo " all - Run all checks (deps, fmt, vet, lint, test, build)"

# Build the binary
build:
Expand Down Expand Up @@ -340,5 +352,86 @@ verify:
go mod tidy
git diff --exit-code go.mod go.sum

# --- Codegen integration ---
# API types with markers live in api/v2alpha1/ (checked in).
# Runtime libraries (registry, featuregate, validation) live in internal/codegen/.
# Generator tools are installed as binaries from the codegen repo.

CODEGEN_TOOLS_MODULE ?= github.com/cdoan1/hyperfleet-api-codegen
CODEGEN_TOOLS_VERSION ?= v0.1.7
HYPERSHIFT_IMPORT_PATH ?= github.com/openshift/hypershift/api/hypershift/v1beta1
HYPERSHIFT_TYPES ?= HostedClusterSpec,NodePoolSpec

codegen-install-tools:
GOBIN=$(PWD)/bin go install $(CODEGEN_TOOLS_MODULE)/cmd/passthrough-gen@$(CODEGEN_TOOLS_VERSION)
GOBIN=$(PWD)/bin go install $(CODEGEN_TOOLS_MODULE)/cmd/marker-scanner@$(CODEGEN_TOOLS_VERSION)
GOBIN=$(PWD)/bin go install $(CODEGEN_TOOLS_MODULE)/cmd/openapi-gen@$(CODEGEN_TOOLS_VERSION)

codegen-passthrough: codegen-install-tools
@echo "Generating passthrough types from $(HYPERSHIFT_IMPORT_PATH)..."
bin/passthrough-gen \
--import-path=$(HYPERSHIFT_IMPORT_PATH) \
--types=$(HYPERSHIFT_TYPES) \
--output-dir=api/v2alpha1 \
--package=v2alpha1
@if [ -f api/v2alpha1/zz_generated.passthrough.go ]; then \
cp api/v2alpha1/zz_generated.passthrough.go api/v2alpha1/hostedclusterspec.passthrough.go; \
rm api/v2alpha1/zz_generated.passthrough.go; \
fi
@echo "Done. Edit api/v2alpha1/hostedclusterspec.passthrough.go to curate field markers."

VERBOSE ?=

codegen-registry: codegen-install-tools
@echo "Generating field metadata registry from api/v2alpha1/..."
bin/marker-scanner \
--input-dirs=api/v2alpha1 \
--output-file=internal/codegen/registry/field_metadata.go \
$(if $(VERBOSE),--verbose)

KEEP_MARKERS ?=

codegen-openapi: codegen-install-tools
@echo "Generating OpenAPI schemas from api/v2alpha1/..."
bin/openapi-gen \
--input-dirs=api/v2alpha1 \
--output-file=openapi/generated-schemas.json \
--title="ROSA Regional Platform API" \
--version=v2alpha1
@echo "Merging generated schemas into openapi/openapi.yaml..."
hack/merge-openapi.sh $(if $(KEEP_MARKERS),--keep-markers) openapi/generated-schemas.json openapi/openapi.yaml

codegen-verify:
@echo "Verifying codegen packages compile..."
go build ./api/v2alpha1/...
go build ./internal/codegen/...
go build ./pkg/middleware/...
go build ./pkg/handlers/...

get-hypershift-version: ## Show current HyperShift version in go.mod
@PSEUDO_VERSION=$$(grep "github.com/openshift/hypershift/api" go.mod | awk '{print $$2}'); \
COMMIT=$$(echo $$PSEUDO_VERSION | rev | cut -d'-' -f1 | rev); \
echo "Current HyperShift in go.mod:"; \
echo " Pseudo-version: $$PSEUDO_VERSION"; \
echo " Commit: $$COMMIT"; \
TAG=$$(curl -s https://api.github.com/repos/openshift/hypershift/tags | jq -r ".[] | select(.commit.sha | startswith(\"$$COMMIT\")) | .name" | head -1); \
if [ -z "$$TAG" ]; then \
echo " Tag: (no tag found - using commit)"; \
else \
echo " Tag: $$TAG"; \
fi

swagger-ui-serve: ## Serve Swagger UI locally (requires Python 3)
@command -v python3 >/dev/null 2>&1 || { echo "Error: python3 is required"; exit 1; }
@echo "Swagger UI: http://localhost:8080/openapi/swagger-ui/"
@echo "OpenAPI spec: http://localhost:8080/openapi/openapi.yaml"
@echo "Press Ctrl+C to stop"
@python3 -m http.server 8080 --directory .

swagger-ui-open: ## Open Swagger UI in browser (requires swagger-ui-serve running)
@command -v open >/dev/null 2>&1 && open http://localhost:8080/openapi/swagger-ui/ || \
command -v xdg-open >/dev/null 2>&1 && xdg-open http://localhost:8080/openapi/swagger-ui/ || \
echo "Open http://localhost:8080/openapi/swagger-ui/ in your browser"
Comment on lines +424 to +434

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Makefile excerpt ==\n'
nl -ba Makefile | sed -n '418,440p'

printf '\n== OpenAPI-related files ==\n'
git ls-files | rg '^openapi(/|$)|swagger-ui|openapi\.ya?ml$' || true

printf '\n== OpenAPI directory tree (top-level only) ==\n'
find openapi -maxdepth 2 -type f 2>/dev/null | sort | sed -n '1,200p'

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 238


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import urllib.request, ssl
for url in [
    "https://docs.python.org/3/library/http.server.html",
]:
    try:
        with urllib.request.urlopen(url, context=ssl.create_default_context(), timeout=10) as r:
            text = r.read(12000).decode("utf-8", "ignore")
        print(text[:5000])
    except Exception as e:
        print("ERR", url, e)
PY

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 363


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Makefile excerpt ==\n'
sed -n '424,434p' Makefile | cat -n

printf '\n== OpenAPI-related files ==\n'
git ls-files | rg '^openapi(/|$)|swagger-ui|openapi\.ya?ml$' || true

printf '\n== OpenAPI directory tree ==\n'
find openapi -maxdepth 2 -type f 2>/dev/null | sort | sed -n '1,200p'

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 1194


Bind the Swagger server to loopback and serve only openapi/. python3 -m http.server 8080 --directory . exposes the whole repository on all interfaces; switch to --bind 127.0.0.1 --directory openapi and update the URLs to /swagger-ui/ and /openapi.yaml.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 424 - 434, Update the swagger-ui-serve target to bind
Python’s HTTP server to 127.0.0.1 and serve only the openapi directory, using
the requested --bind and --directory values. Adjust its displayed Swagger UI and
OpenAPI spec URLs to /swagger-ui/ and /openapi.yaml, and update swagger-ui-open
to open the new Swagger UI URL.


# All checks
all: deps fmt vet lint test build
103 changes: 103 additions & 0 deletions api/v2alpha1/cluster_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package v2alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// Cluster represents a HyperFleet managed OpenShift cluster
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Namespaced
type Cluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ClusterSpec `json:"spec"`
Status ClusterStatus `json:"status,omitempty"`
}

// ClusterSpec defines the desired state of a Cluster
type ClusterSpec struct {
// === HyperFleet Envelope Fields ===
// These are HyperFleet-specific fields that wrap the HyperShift cluster

// DisplayName is a human-readable name for the cluster
// +hyperfleet:write-mode=mutable
// +kubebuilder:validation:MaxLength=256
DisplayName string `json:"displayName,omitempty"`

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

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

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

// Tags are customer-defined labels for organizational purposes
// This is a TechPreview feature
// +hyperfleet:write-mode=mutable
// +openshift:enable:FeatureGate=HyperFleetAutoScaling
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
AccountID string `json:"accountId,omitempty"`

// CreatorARN is the AWS ARN of the user who created this cluster (platform-managed, hidden)
// +k8s:openapi-gen=false
// +hyperfleet:write-mode=service-set
CreatorARN string `json:"creatorARN,omitempty"`

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

// === HyperShift Passthrough ===
// This embeds all upstream HyperShift HostedCluster fields

// HostedCluster contains the full HyperShift HostedCluster configuration
// All fields are generated from upstream and have safe defaults (hidden + service-set)
// until explicitly reviewed and exposed
// +kubebuilder:validation:Required
HostedCluster HostedClusterSpecPassthrough `json:"hostedCluster"`
}

// ClusterStatus defines the observed state of a Cluster
type ClusterStatus struct {
// State represents the high-level cluster state
// +kubebuilder:validation:Enum=pending;provisioning;ready;degraded;deleting;failed
State string `json:"state,omitempty"`

// Conditions represent detailed cluster status
Conditions []metav1.Condition `json:"conditions,omitempty"`

// Version is the observed OpenShift version
Version string `json:"version,omitempty"`

// APIEndpoint is the cluster API server endpoint
APIEndpoint string `json:"apiEndpoint,omitempty"`

// ConsoleURL is the web console URL
ConsoleURL string `json:"consoleUrl,omitempty"`

// ProvisionStartTime is when provisioning began
ProvisionStartTime *metav1.Time `json:"provisionStartTime,omitempty"`

// ReadyTime is when the cluster became ready
ReadyTime *metav1.Time `json:"readyTime,omitempty"`
}

// ClusterList contains a list of Clusters
// +kubebuilder:object:root=true
type ClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Cluster `json:"items"`
}
Loading