https://github.com/openshift-hyperfleet/adapter-validation-gcp
The validation adapter used for GCP HCP preflight validations
https://github.com/openshift-hyperfleet/adapter-validation-gcp
Last synced: 5 months ago
JSON representation
The validation adapter used for GCP HCP preflight validations
- Host: GitHub
- URL: https://github.com/openshift-hyperfleet/adapter-validation-gcp
- Owner: openshift-hyperfleet
- License: apache-2.0
- Created: 2025-12-03T02:04:02.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-12-31T05:46:39.000Z (6 months ago)
- Last Synced: 2026-01-02T18:22:14.930Z (5 months ago)
- Language: Shell
- Size: 47.9 KB
- Stars: 1
- Watchers: 0
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# HyperFleet GCP Validation Adapter
Event-driven adapter for HyperFleet GCP cluster validation. Validates GCP cluster configurations and prerequisites before provisioning. Consumes CloudEvents from message brokers (GCP Pub/Sub, RabbitMQ), processes AdapterConfig, manages validation jobs in Kubernetes, and reports status via API.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Deployment Modes](#deployment-modes)
- [Local Development](#local-development)
- [Helm Chart Installation](#helm-chart-installation)
- [Configuration](#configuration)
- [Examples](#examples)
## Prerequisites
- Kubernetes 1.19+
- Helm 3.0+
- GCP Workload Identity (for Pub/Sub access)
- `gcloud` CLI configured with appropriate permissions
## Deployment Modes
This adapter supports two deployment modes via the `deploymentMode` parameter:
### Dummy Mode (Current)
- **Value**: `deploymentMode: "dummy"`
- **Description**: Simulates GCP validation for testing and development
- **Config File**: Uses `charts/configs/validation-dummy-adapter.yaml`
- **Features**:
- Configurable simulation results (success, failure, hang, crash, invalid-json, missing-status)
- No actual GCP API calls
- Fast validation cycles for testing
### Real Mode (Future)
- **Value**: `deploymentMode: "real"`
- **Description**: Performs actual GCP validation checks
- **Config File**: Will use `charts/configs/validation-gcp-adapter.yaml` (to be created)
- **Features**:
- Real GCP API validation
- Production-ready validation checks
- Comprehensive error reporting
## Local Development
Run the adapter locally for development and testing.
### Prerequisites
- `hyperfleet-adapter` binary installed and in PATH
- GCP service account key for Pub/Sub access
- Access to a GKE cluster (for applying Kubernetes resources)
- `podman` or `docker` for RabbitMQ (if `BROKER_TYPE=rabbitmq`)
### Setup
1. Copy environment template:
```bash
cp env.example .env
```
2. Edit `.env` with your configuration:
```bash
# Required for Google Pub/Sub (default)
GCP_PROJECT_ID="your-gcp-project-id"
BROKER_TOPIC="hyperfleet-adapter-topic"
BROKER_SUBSCRIPTION_ID="hyperfleet-adapter-validation-gcp-subscription"
# Required for all broker types
HYPERFLEET_API_BASE_URL="https://localhost:8000"
# Optional (defaults provided)
SUBSCRIBER_PARALLELISM="1"
HYPERFLEET_API_VERSION="v1"
# Validation-specific settings
STATUS_REPORTER_IMAGE=""
SIMULATE_RESULT="success" # success, failure, hang, crash, invalid-json, missing-status
RESULTS_PATH="/results/adapter-result.json"
MAX_WAIT_TIME_SECONDS="300"
# Required for RabbitMQ (if BROKER_TYPE=rabbitmq)
# RABBITMQ_URL="amqp://guest:guest@localhost:5672/"
```
3. Set up GCP authentication:
```bash
# Create service account key and set in .env
export GOOGLE_APPLICATION_CREDENTIALS="./sa-key.json"
```
4. Connect to your GKE cluster:
```bash
gcloud container clusters get-credentials "$GKE_CLUSTER_NAME" \
--region "$GKE_CLUSTER_REGION" \
--project "$GCP_PROJECT_ID"
kubectl cluster-info
```
### Run
```bash
# For Google Pub/Sub (default)
./run-local.sh
# For RabbitMQ
BROKER_TYPE=rabbitmq ./run-local.sh
```
## Helm Chart Installation
### Installing the Chart
**Dummy Validation Mode (Default):**
```bash
helm install validation-gcp ./charts/ \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=my-gcp-project \
--set broker.googlepubsub.topic=my-topic \
--set broker.googlepubsub.subscription=my-subscription \
--set hyperfleetApi.baseUrl=https://api.hyperfleet.example.com
```
**With Specific Deployment Mode:**
```bash
# Dummy mode (simulated validation)
helm install validation-gcp ./charts/ \
--set deploymentMode=dummy \
--set validation.dummy.simulateResult=success \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=my-gcp-project \
--set broker.googlepubsub.topic=my-topic \
--set broker.googlepubsub.subscription=my-subscription
# Real mode (not yet available; keep commented until implemented — see HYPERFLEET-267)
# helm install validation-gcp ./charts/ \
# --set deploymentMode=real \
# --set broker.type=googlepubsub \
# ...
```
### Install to a Specific Namespace
```bash
helm install validation-gcp ./charts/ \
--namespace hyperfleet-system \
--create-namespace \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=my-gcp-project \
--set broker.googlepubsub.topic=my-topic \
--set broker.googlepubsub.subscription=my-subscription
```
### Uninstalling the Chart
```bash
helm delete validation-gcp
# Or with namespace
helm delete validation-gcp --namespace hyperfleet-system
```
## Configuration
All configurable parameters are in `values.yaml`. For advanced customization, modify the templates directly.
### Deployment Mode
| Parameter | Description | Default |
|-----------|-------------|---------|
| `deploymentMode` | Deployment mode: "dummy" or "real" | `"dummy"` |
### Image & Replica
| Parameter | Description | Default |
|-----------|-------------|---------|
| `replicaCount` | Number of replicas | `1` |
| `image.registry` | Image registry | `registry.ci.openshift.org` |
| `image.repository` | Image repository | `ci/hyperfleet-adapter` |
| `image.tag` | Image tag | `latest` |
| `image.pullPolicy` | Image pull policy | `Always` |
| `imagePullSecrets` | Image pull secrets | `[]` |
### Naming
| Parameter | Description | Default |
|-----------|-------------|---------|
| `nameOverride` | Override chart name | `""` |
| `fullnameOverride` | Override full release name | `""` |
### ServiceAccount & RBAC
| Parameter | Description | Default |
|-----------|-------------|---------|
| `serviceAccount.create` | Create ServiceAccount | `true` |
| `serviceAccount.name` | ServiceAccount name (auto-generated if empty) | `""` |
| `serviceAccount.annotations` | ServiceAccount annotations (for Workload Identity) | `{}` |
| `rbac.create` | Create ClusterRole and ClusterRoleBinding | `false` |
When `rbac.create=true`, the adapter gets **minimal permissions** needed for validation:
- **Namespaces**: `get`, `list`, `watch` (read-only, to verify target namespace exists)
- **ServiceAccounts**: Full management (`create`, `update`, `patch`, `delete`, `get`, `list`, `watch`)
- **Roles/RoleBindings**: Full management (for validation job RBAC)
- **Jobs**: Full management (for validation job lifecycle)
- **Jobs/status**: `get`, `update`, `patch` (for status reporter sidecar)
- **Pods**: `get`, `list`, `watch` (read-only, to check validation job pod status)
### Logging
| Parameter | Description | Default |
|-----------|-------------|---------|
| `logging.level` | Log level: `debug`, `info`, `warn`, `error` | `info` |
| `logging.format` | Log format: `text`, `json` | `text` |
| `logging.output` | Log output: `stdout`, `stderr` | `stderr` |
### Scheduling
| Parameter | Description | Default |
|-----------|-------------|---------|
| `nodeSelector` | Node selector | `{}` |
| `tolerations` | Tolerations | `[]` |
| `affinity` | Affinity rules | `{}` |
### Broker Configuration
| Parameter | Description | Default |
|-----------|-------------|---------|
| `broker.type` | Broker type: `googlepubsub` or `rabbitmq` (**required**) | `""` |
| `broker.subscriber.parallelism` | Number of parallel workers | `1` |
| `broker.yaml` | Raw YAML override (advanced use) | `""` |
#### Google Pub/Sub (when `broker.type=googlepubsub`)
| Parameter | Description | Default |
|-----------|-------------|---------|
| `broker.googlepubsub.projectId` | GCP project ID (**required**) | `""` |
| `broker.googlepubsub.topic` | Pub/Sub topic name (**required**) | `""` |
| `broker.googlepubsub.subscription` | Pub/Sub subscription ID (**required**) | `""` |
| `broker.googlepubsub.deadLetterTopic` | Dead letter topic name (optional) | `""` |
#### RabbitMQ (when `broker.type=rabbitmq`)
| Parameter | Description | Default |
|-----------|-------------|---------|
| `broker.rabbitmq.url` | RabbitMQ connection URL (**required**) | `""` |
### HyperFleet API
| Parameter | Description | Default |
|-----------|-------------|---------|
| `hyperfleetApi.baseUrl` | HyperFleet API base URL | `""` |
| `hyperfleetApi.version` | API version | `v1` |
### Validation Configuration
| Parameter | Description | Default |
|-----------|-------------|---------|
| `validation.statusReporterImage` | Status reporter sidecar image | `` |
#### Dummy Validation Mode Settings
| Parameter | Description | Default |
|-----------|-------------|---------|
| `validation.dummy.simulateResult` | Simulated result (success, failure, hang, crash, invalid-json, missing-status) | `"success"` |
| `validation.dummy.resultsPath` | Path where validation results are written | `"/results/adapter-result.json"` |
| `validation.dummy.maxWaitTimeSeconds` | Maximum time to wait for validation completion | `"300"` |
### Environment Variables
| Parameter | Description | Default |
|-----------|-------------|---------|
| `env` | Additional environment variables | `[]` |
Example:
```yaml
env:
- name: MY_VAR
value: "my-value"
- name: MY_SECRET
valueFrom:
secretKeyRef:
name: my-secret
key: key
```
## Examples
### Basic Dummy Validation with Google Pub/Sub
```bash
helm install validation-gcp ./charts/ \
--set deploymentMode=dummy \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=my-gcp-project \
--set broker.googlepubsub.topic=my-topic \
--set broker.googlepubsub.subscription=my-subscription \
--set hyperfleetApi.baseUrl=https://api.hyperfleet.example.com
```
### Dummy Validation with Different Simulation Results
```bash
# Simulate failure
helm install validation-gcp ./charts/ \
--set validation.dummy.simulateResult=failure \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=my-gcp-project \
--set broker.googlepubsub.topic=my-topic \
--set broker.googlepubsub.subscription=my-subscription
# Simulate hang (for timeout testing)
helm install validation-gcp ./charts/ \
--set validation.dummy.simulateResult=hang \
--set validation.dummy.maxWaitTimeSeconds=60 \
--set broker.type=googlepubsub \
...
```
### With RabbitMQ
```bash
helm install validation-gcp ./charts/ \
--set deploymentMode=dummy \
--set broker.type=rabbitmq \
--set broker.rabbitmq.url="amqp://user:password@rabbitmq.svc:5672/"
```
### With GCP Workload Identity and RBAC
First, grant Pub/Sub permissions to the KSA (Kubernetes Service Account) :
```bash
# Get project number
PROJECT_NUMBER=$(gcloud projects describe my-gcp-project --format="value(projectNumber)")
# Grant permissions using direct principal binding
gcloud projects add-iam-policy-binding my-gcp-project \
--role="roles/pubsub.subscriber" \
--member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/my-gcp-project.svc.id.goog/subject/ns/hyperfleet-system/sa/validation-gcp" \
--condition=None
gcloud projects add-iam-policy-binding my-gcp-project \
--role="roles/pubsub.viewer" \
--member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/my-gcp-project.svc.id.goog/subject/ns/hyperfleet-system/sa/validation-gcp" \
--condition=None
```
Then deploy:
```bash
helm install validation-gcp ./charts/ \
--namespace hyperfleet-system \
--create-namespace \
--set deploymentMode=dummy \
--set image.registry=us-central1-docker.pkg.dev/my-project/my-repo \
--set image.repository=hyperfleet-adapter \
--set image.tag=v0.1.0 \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=my-gcp-project \
--set broker.googlepubsub.topic=my-topic \
--set broker.googlepubsub.subscription=my-subscription \
--set hyperfleetApi.baseUrl=https://api.hyperfleet.example.com \
--set rbac.create=true
```
### With Values File
Example my-values.yaml
```yaml
deploymentMode: dummy
replicaCount: 1
image:
registry: registry.ci.openshift.org
repository: ci/hyperfleet-adapter
tag: latest
serviceAccount:
create: true
rbac:
create: true
logging:
level: debug
format: json
output: stderr
hyperfleetApi:
baseUrl: https://api.hyperfleet.example.com
version: v1
broker:
type: googlepubsub
googlepubsub:
projectId: my-gcp-project
topic: hyperfleet-events
subscription: hyperfleet-validation-subscription
subscriber:
parallelism: 1
validation:
statusReporterImage:
dummy:
simulateResult: success
resultsPath: /results/adapter-result.json
maxWaitTimeSeconds: "300"
```
Install with values file
```bash
helm install validation-gcp ./charts/ -f my-values.yaml
```
> Note: If you encounter a `PermissionDenied` related subscription error in the Pod, refer to [With GCP Workload Identity and RBAC](#with-gcp-workload-identity-and-rbac) to grant the required permissions first.
## Deployment Environment Variables
The deployment sets these environment variables automatically:
| Variable | Value | Condition |
|----------|-------|-----------|
| `HYPERFLEET_API_BASE_URL` | From `hyperfleetApi.baseUrl` | When set |
| `HYPERFLEET_API_VERSION` | From `hyperfleetApi.version` | Always (default: v1) |
| `ADAPTER_CONFIG_PATH` | `/etc/adapter/adapter.yaml` | Always |
| `BROKER_CONFIG_FILE` | `/etc/broker/broker.yaml` | When `broker.type` is set |
| `BROKER_SUBSCRIPTION_ID` | From `broker.googlepubsub.subscription` | When `broker.type=googlepubsub` |
| `BROKER_TOPIC` | From `broker.googlepubsub.topic` | When `broker.type=googlepubsub` |
| `GCP_PROJECT_ID` | From `broker.googlepubsub.projectId` | When `broker.type=googlepubsub` |
| `STATUS_REPORTER_IMAGE` | From `validation.statusReporterImage` | When `deploymentMode=dummy` |
| `SIMULATE_RESULT` | From `validation.dummy.simulateResult` | When `deploymentMode=dummy` |
| `RESULTS_PATH` | From `validation.dummy.resultsPath` | When `deploymentMode=dummy` |
| `MAX_WAIT_TIME_SECONDS` | From `validation.dummy.maxWaitTimeSeconds` | When `deploymentMode=dummy` |
## License
See [LICENSE](LICENSE) for details.