Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
207dd30
fix: match model_base_url fixture to model_id instead of first catalo…
mynhardtburger Apr 9, 2026
0ca48f1
fix: update webhook deploy name (#699)
ryancham715 Apr 9, 2026
bbaa45a
fix: correct AuthPolicy name in validation script (#658) (#659)
bryonbaker Apr 10, 2026
36dbeb4
feat: add Granite Model that can work on CPU (#723)
jland-redhat Apr 10, 2026
e3da035
feat(maas-controller): add granular status reporting for MaaSSubscrip…
ishitasequeira Apr 10, 2026
95f8645
chore(docs): document shared HTTPRoute TRLP limitation and cross-link…
ishitasequeira Apr 10, 2026
8f22073
chore(deps): bump google.golang.org/grpc from 1.75.1 to 1.79.3 in /ma…
dependabot[bot] Apr 10, 2026
bbfea0d
chore: update smoke.sh to use API Keys (#573)
ishitasequeira Apr 10, 2026
b265e54
feat: add E2E tests for external models (egress) (#632)
noyitz Apr 10, 2026
08ff5b4
ci: add OpenAPI validation and automation infrastructure (#693)
somya-bhatnagar Apr 10, 2026
99bcd1b
fix: replace third-party curl image with UBI-based image for disconne…
liangwen12year Apr 10, 2026
6d31fd8
test(e2e): enable unconfigured model deny-by-default test (#728)
mynhardtburger Apr 10, 2026
e069c5f
fix: mitigate authorization timing race in /v1/models listing (#549)
liangwen12year Apr 10, 2026
b77630b
test: expand negative-path and security-focused E2E tests (#724)
yu-teo Apr 11, 2026
c5468b2
feat: add RBAC aggregation for namespace users (#716)
somya-bhatnagar Apr 11, 2026
b5b5afb
test: fix `test_subscription_status_transitions_on_model_deletion()` …
yu-teo Apr 11, 2026
beced7f
fix: patch params.env for custom image injection in kustomize mode (#…
chaitanya1731 Apr 11, 2026
6842e33
fix: restore /v1/models rate limiting exemption (#729)
jrhyness Apr 13, 2026
5b9127e
fix: avoid duplicate deployments of controller in deploy.sh (#732)
ryancham715 Apr 13, 2026
c93e879
feat(e2e): collect full MaaS CR definitions and RHOAI namespace logs …
chaitanya1731 Apr 13, 2026
0ed1fb3
fix: add ns prefix to ExternalModel HTTPRoute path for llmisvc parity…
nerdalert Apr 14, 2026
05f08df
feat: enable group testing for MaaS components (#741)
mynhardtburger Apr 14, 2026
d91dc39
test: fix flaky test_rate_limit_exhaustion_gets_429 (#730)
somya-bhatnagar Apr 14, 2026
fa03af7
refactor: reduce ListLLMs complexity to pass maintidx linter (#739)
somya-bhatnagar Apr 14, 2026
93bc750
feat: deploy admin-usage dashboard via ODH (#686)
ahadas Apr 15, 2026
7b81a7e
fix: resolve OpenAPI spec validation errors and warnings (#694)
somya-bhatnagar Apr 15, 2026
5afc49c
refactor: refactor and consolidate test helper functions (#738)
yu-teo Apr 15, 2026
9b4672a
fix: cleanup script handles RHOAI namespace and AuthConfig CRs (#749)
Apr 15, 2026
4681ffd
feat(kustomize): add operator-managed image for api key cleanup cronj…
chaitanya1731 Apr 15, 2026
ffcb990
fix: use targetModel in HTTPRoute header match (#753)
noyitz Apr 15, 2026
3d93d30
fix: handle Terminating namespace during RHOAI reinstall/upgrade (#742)
somya-bhatnagar Apr 16, 2026
6190476
fix: align MaaSSubscription token rate limit window validation with K…
yu-teo Apr 16, 2026
28c456c
chore: promote main to stable (#734)
chaitanya1731 Apr 16, 2026
b6a0381
chore: promote stable to rhoai (#754)
chaitanya1731 Apr 16, 2026
37ffae1
Merge remote-tracking branch 'upstream/rhoai'
moulalis Apr 16, 2026
c789577
feat: reject degraded/failed subscriptions at auth layer (#721)
jrhyness Apr 16, 2026
5d06621
docs: fix broken links (#755)
jrhyness Apr 16, 2026
2ce457c
docs: fix instructions to match code for modelsAsService managementSt…
jrhyness Apr 16, 2026
266a130
chore: sync security config files (#736)
security-config-sync[bot] Apr 16, 2026
ce75696
fix: rename dashboard title and panel name to 'Token Consumption' (#758)
andrewballantyne Apr 16, 2026
3a6a9b8
docs: documentation updates (#687)
jland-redhat Apr 17, 2026
c098422
docs: fix API response format in self-service model listing (#761)
jrhyness Apr 17, 2026
fa142c4
fix: enforce fail-close logic when limitador pod is down (#626)
ryancham715 Apr 17, 2026
94b7341
docs: document --cluster-audience CLI flag for maas-controller (#757)
jrhyness Apr 17, 2026
0e2b91e
docs: correct ExternalModel implementation status (#759)
jrhyness Apr 17, 2026
dd5474e
feat(maas-controller): maas`Tenant` CR and reconciler (#735)
ishitasequeira Apr 17, 2026
8f38b4c
docs: document maas-api environment variables and CLI flags (#763)
jrhyness Apr 17, 2026
dd4cb3a
chore: promote main to stable (#766)
chaitanya1731 Apr 17, 2026
1a599d3
chore: promote stable to rhoai (#767)
chaitanya1731 Apr 17, 2026
ec90d84
Merge remote-tracking branch 'upstream/rhoai'
moulalis Apr 17, 2026
8ed1cfd
Merge branch 'main' into sync-main
ckhordiasma Apr 20, 2026
41864d9
Merge pull request #358 from red-hat-data-services/sync-main
chaitanya1731 Apr 20, 2026
083d29a
fix(tekton): correct dockerfile path and build context for maas-contr…
chaitanya1731 Apr 20, 2026
cd60141
Merge pull request #359 from chaitanya1731/fix-controller-tekton-context
ckhordiasma Apr 20, 2026
cb3c300
fix: cve-2026-33815 and cve-2026-33816 in pgx
Apr 21, 2026
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
83 changes: 74 additions & 9 deletions .github/hack/cleanup-odh.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#!/bin/bash
#
# cleanup-odh.sh - Remove OpenDataHub operator and all related resources
# cleanup-odh.sh - Remove OpenDataHub/RHOAI MaaS resources and related operators
#
# This script removes:
# - DataScienceCluster and DSCInitialization custom resources
# - ODH operator Subscription and CSV
# - Custom CatalogSource (odh-custom-catalog)
# - ODH operator namespace (odh-operator)
# - OpenDataHub application namespace (opendatahub)
# - MaaS resources from RHOAI namespace (redhat-ods-applications)
# - MaaS subscription namespace (models-as-a-service)
# - Policy engine artifacts (Kuadrant/RHCL OLM resources, AuthConfig CRs)
# - Keycloak identity provider (if deployed)
# - ODH CRDs (optional)
#
Expand Down Expand Up @@ -40,6 +42,19 @@ fi
echo "Connected to cluster. Starting cleanup..."
echo ""

# Detect operator type to find the right application namespace
MAAS_APP_NAMESPACE=""
if kubectl get subscription rhods-operator -n redhat-ods-operator &>/dev/null; then
MAAS_APP_NAMESPACE="redhat-ods-applications"
echo "Detected RHOAI operator (application namespace: $MAAS_APP_NAMESPACE)"
elif kubectl get subscription opendatahub-operator -A &>/dev/null; then
MAAS_APP_NAMESPACE="opendatahub"
echo "Detected ODH operator (application namespace: $MAAS_APP_NAMESPACE)"
else
echo "No operator detected, will clean both namespaces"
fi
echo ""

# 1. Delete DataScienceCluster instances
echo "1. Deleting DataScienceCluster instances..."
kubectl delete datasciencecluster --all -A --ignore-not-found --timeout=120s 2>/dev/null || true
Expand Down Expand Up @@ -82,6 +97,41 @@ kubectl delete ns odh-operator --ignore-not-found --timeout=120s 2>/dev/null ||
echo "8. Deleting opendatahub namespace..."
kubectl delete ns opendatahub --ignore-not-found --timeout=120s 2>/dev/null || true

# 8b. Clean MaaS resources from RHOAI application namespace
# On RHOAI clusters, MaaS resources live in redhat-ods-applications which is
# operator-managed. We delete MaaS resources individually instead of the namespace.
cleanup_maas_resources() {
local ns=$1
if ! kubectl get namespace "$ns" &>/dev/null; then
echo " $ns not found, skipping"
return 0
fi

echo " Cleaning MaaS resources from $ns..."
kubectl delete deployment maas-api maas-controller postgres -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete service maas-api postgres -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete secret maas-db-config postgres-creds -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete authpolicy maas-api-auth-policy -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete httproute maas-api-route -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete destinationrule maas-api-backend-tls -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete networkpolicy maas-api-cleanup-restrict maas-authorino-allow -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete cronjob maas-api-key-cleanup -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete role maas-api-db-secret maas-controller-leader-election-role -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete rolebinding maas-api-db-secret maas-controller-leader-election-rolebinding -n "$ns" --ignore-not-found 2>/dev/null || true
kubectl delete serviceaccount maas-api maas-controller -n "$ns" --ignore-not-found 2>/dev/null || true
echo " ✅ MaaS resources cleaned from $ns"
}

if [[ "$MAAS_APP_NAMESPACE" == "redhat-ods-applications" ]]; then
echo "8b. Cleaning MaaS resources from RHOAI namespace..."
cleanup_maas_resources "redhat-ods-applications"
elif [[ -z "$MAAS_APP_NAMESPACE" ]]; then
# No operator detected, clean both just in case
echo "8b. Cleaning MaaS resources from both possible namespaces..."
cleanup_maas_resources "redhat-ods-applications"
cleanup_maas_resources "opendatahub"
fi

force_delete_namespace() {
local ns=$1
shift
Expand Down Expand Up @@ -172,6 +222,11 @@ if kubectl get namespace rh-connectivity-link &>/dev/null; then
echo " ✅ RHCL OLM resources cleaned"
fi

# 11b. Delete AuthConfig CRs cluster-wide
# Old AuthConfig CRs can block new policy engine installs if the CRD schema changes.
echo "11b. Deleting AuthConfig CRs..."
kubectl delete authconfig --all --all-namespaces --ignore-not-found 2>/dev/null || true

# 12. Delete policy engine namespaces (Kuadrant or RHCL)
for policy_ns in kuadrant-system rh-connectivity-link; do
echo "12. Deleting $policy_ns namespace (if installed)..."
Expand Down Expand Up @@ -210,21 +265,30 @@ kubectl delete envoyfilter kuadrant-auth-tls-fix -n openshift-ingress --ignore-n
kubectl delete authpolicy -n openshift-ingress --all --ignore-not-found 2>/dev/null || true
kubectl delete ratelimitpolicy -n openshift-ingress --all --ignore-not-found 2>/dev/null || true
kubectl delete tokenratelimitpolicy -n openshift-ingress --all --ignore-not-found 2>/dev/null || true
kubectl delete gatewayclass openshift-default --ignore-not-found 2>/dev/null || true

# 16. Delete MaaS RBAC (ClusterRoles, ClusterRoleBindings - can conflict with other managers)
echo "16. Deleting MaaS RBAC..."
kubectl delete clusterrolebinding maas-api maas-controller-rolebinding --ignore-not-found 2>/dev/null || true
kubectl delete clusterrole maas-api maas-controller-role --ignore-not-found 2>/dev/null || true

# 17. Optionally delete CRDs
# 17. Delete CRDs
# Always delete KServe/MaaS CRDs to prevent storedVersions schema conflicts on reinstall.
# ODH-internal CRDs are only deleted with --include-crds.
echo "17. Deleting KServe/MaaS CRDs (always removed to prevent version conflicts)..."
for crd in $(kubectl get crd -o name 2>/dev/null | grep -E 'serving\.kserve\.io|maas\.opendatahub\.io'); do
echo " Deleting $crd"
kubectl delete "$crd" --ignore-not-found --timeout=30s 2>/dev/null || true
done

if $INCLUDE_CRDS; then
echo "17. Deleting ODH CRDs..."
kubectl delete crd datascienceclusters.datasciencecluster.opendatahub.io --ignore-not-found 2>/dev/null || true
kubectl delete crd dscinitializations.dscinitialization.opendatahub.io --ignore-not-found 2>/dev/null || true
kubectl delete crd datasciencepipelinesapplications.datasciencepipelinesapplications.opendatahub.io --ignore-not-found 2>/dev/null || true
# Add more CRDs as needed
echo "17b. Deleting all ODH CRDs..."
for crd in $(kubectl get crd -o name 2>/dev/null | grep -E 'opendatahub\.io|trustyai\.opendatahub'); do
echo " Deleting $crd"
kubectl delete "$crd" --ignore-not-found --timeout=30s 2>/dev/null || true
done
else
echo "17. Skipping CRD deletion (use --include-crds to remove CRDs)"
echo "17b. Skipping ODH-internal CRD deletion (use --include-crds to remove all)"
fi

echo ""
Expand All @@ -233,4 +297,5 @@ echo ""
echo "Verify cleanup with:"
echo " kubectl get subscription -A | grep -i odh"
echo " kubectl get csv -A | grep -i odh"
echo " kubectl get ns | grep -E 'odh|opendatahub|models-as-a-service|kuadrant|rh-connectivity-link|keycloak-system|llm'"
echo " kubectl get ns | grep -E 'odh|opendatahub|models-as-a-service|kuadrant|rh-connectivity-link|keycloak-system|llm'
kubectl get deployment maas-api maas-controller postgres -n redhat-ods-applications 2>/dev/null || echo ' (no MaaS resources in redhat-ods-applications)'"
47 changes: 47 additions & 0 deletions .github/hack/install-odh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# OPERATOR_INSTALL_PLAN_APPROVAL - Manual (default) or Automatic; use "-" to omit.
# Manual: blocks auto-upgrades; this script auto-approves only the first InstallPlan so install does not stall.
# OPERATOR_IMAGE - Custom operator image to patch into CSV (optional)
# OPERATOR_OPERANDS_MAP - Path to operands-map.yaml for RELATED_IMAGE env var injection (optional)
# Used with OPERATOR_IMAGE to ensure component images match the operator.
#
# Usage: ./install-odh.sh

Expand Down Expand Up @@ -59,6 +61,51 @@ patch_operator_csv_if_needed() {
{\"op\": \"replace\", \"path\": \"/spec/install/spec/deployments/0/spec/template/spec/containers/0/image\", \"value\": \"$OPERATOR_IMAGE\"}
]"
log_info "CSV $csv_name patched with image $OPERATOR_IMAGE"

# When using a custom operator image, the community CSV may lack RELATED_IMAGE env vars
# that the operator needs to deploy the correct component versions.
# If OPERATOR_OPERANDS_MAP points to a local operands-map.yaml, inject its env vars into the CSV.
if [[ -n "${OPERATOR_OPERANDS_MAP:-}" && -f "$OPERATOR_OPERANDS_MAP" ]]; then
log_info "Injecting RELATED_IMAGE env vars from $OPERATOR_OPERANDS_MAP into CSV"
local env_patches="["
local first=true
while IFS= read -r line; do
local name value
name=$(echo "$line" | sed -n 's/.*name: \(RELATED_IMAGE_[^ ]*\)/\1/p')
if [[ -n "$name" ]]; then
read -r value_line
value=$(echo "$value_line" | sed -n 's/.*value: \(.*\)/\1/p')
if [[ -n "$value" ]]; then
$first || env_patches+=","
first=false
env_patches+="{\"name\":\"$name\",\"value\":\"$value\"}"
fi
fi
done < "$OPERATOR_OPERANDS_MAP"

if [[ "$env_patches" != "[" ]]; then
env_patches+="]"
local container_path="/spec/install/spec/deployments/0/spec/template/spec/containers/0"
local existing_env
existing_env=$(kubectl get csv "$csv_name" -n "$namespace" -o jsonpath="{${container_path}.env}" 2>/dev/null || echo "[]")

local merged_env
merged_env=$(python3 -c "
import json, sys
existing = json.loads('${existing_env}')
new_envs = json.loads(sys.stdin.read())
existing_names = {e['name'] for e in existing}
for e in new_envs:
if e['name'] not in existing_names:
existing.append(e)
print(json.dumps(existing))
" <<< "$env_patches")

kubectl patch csv "$csv_name" -n "$namespace" --type='json' \
-p="[{\"op\": \"replace\", \"path\": \"${container_path}/env\", \"value\": ${merged_env}}]"
log_info "CSV env vars patched with RELATED_IMAGE entries"
fi
fi
}

echo "=== Installing OpenDataHub operator ==="
Expand Down
Loading
Loading