Skip to content

Commit 87bdaa3

Browse files
Merge branch 'main' of github.com:opendatahub-io/models-as-a-service into feature/external-oidc
2 parents 715642e + 661ac33 commit 87bdaa3

File tree

7 files changed

+82
-4
lines changed

7 files changed

+82
-4
lines changed

deployment/base/maas-controller/rbac/clusterrole.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ rules:
1818
- apiGroups: ["gateway.networking.k8s.io"]
1919
resources: ["httproutes"]
2020
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
21+
- apiGroups: ["gateway.networking.k8s.io"]
22+
resources: ["httproutes/finalizers"]
23+
verbs: ["update"]
2124
- apiGroups: ["kuadrant.io"]
2225
resources: ["authpolicies", "tokenratelimitpolicies"]
2326
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]

maas-controller/pkg/controller/maas/maassubscription_controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ type MaaSSubscriptionReconciler struct {
5858
//+kubebuilder:rbac:groups=maas.opendatahub.io,resources=maasmodelrefs,verbs=get;list;watch
5959
//+kubebuilder:rbac:groups=kuadrant.io,resources=tokenratelimitpolicies,verbs=get;list;watch;create;update;patch;delete
6060
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch
61+
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes/finalizers,verbs=update
6162

6263
const (
6364
maasSubscriptionFinalizer = "maas.opendatahub.io/subscription-cleanup"

test/e2e/scripts/auth_utils.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,15 @@ run_auth_debug_report() {
209209
_run "maas-controller MAAS_API_NAMESPACE" "echo '$env_display'"
210210
_append ""
211211

212-
_section "Kuadrant AuthPolicies"
212+
_section "Kuadrant Policies"
213213
_run "AuthPolicies (all namespaces)" "kubectl get authpolicies -A -o wide 2>/dev/null || true"
214+
_run "TokenRateLimitPolicies (all namespaces)" "kubectl get tokenratelimitpolicies -A -o wide 2>/dev/null || true"
214215
_append ""
215216

216217
_section "MaaS CRs"
217218
_run "MaaSAuthPolicies" "kubectl get maasauthpolicies -n $MAAS_SUBSCRIPTION_NAMESPACE -o wide 2>/dev/null || true"
218219
_run "MaaSSubscriptions" "kubectl get maassubscriptions -n $MAAS_SUBSCRIPTION_NAMESPACE -o wide 2>/dev/null || true"
220+
_run "MaaSSubscription status details" "kubectl get maassubscriptions -n $MAAS_SUBSCRIPTION_NAMESPACE -o jsonpath='{range .items[*]}{.metadata.name}: {.status.phase} - {.status.conditions[?(@.type==\"Ready\")].message}{\"\\n\"}{end}' 2>/dev/null || true"
219221
_run "MaaSModelRefs (all namespaces)" "kubectl get maasmodelrefs -A -o wide 2>/dev/null || true"
220222
_append ""
221223

test/e2e/scripts/prow_run_smoke_test.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,34 @@ setup_test_tokens() {
662662
fi
663663
fi
664664

665+
# Grant odh-admins RBAC so SAR-based admin check passes.
666+
# maas-api IsAdmin does a SubjectAccessReview: "can user create maasauthpolicies?"
667+
# The ODH operator will provide this via opendatahub-operator#3301; until then, create it here.
668+
oc apply -f - <<RBAC_EOF
669+
apiVersion: rbac.authorization.k8s.io/v1
670+
kind: ClusterRole
671+
metadata:
672+
name: maas-admin
673+
rules:
674+
- apiGroups: ["maas.opendatahub.io"]
675+
resources: ["maasauthpolicies", "maassubscriptions"]
676+
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
677+
---
678+
apiVersion: rbac.authorization.k8s.io/v1
679+
kind: RoleBinding
680+
metadata:
681+
name: odh-admins-maas-admin
682+
namespace: $MAAS_SUBSCRIPTION_NAMESPACE
683+
roleRef:
684+
apiGroup: rbac.authorization.k8s.io
685+
kind: ClusterRole
686+
name: maas-admin
687+
subjects:
688+
- apiGroup: rbac.authorization.k8s.io
689+
kind: Group
690+
name: odh-admins
691+
RBAC_EOF
692+
665693
# 3. Fallback for regular user: always use a separate SA to ensure distinct users
666694
# This is required for IDOR tests that verify users cannot access each other's keys
667695
# Regular user stays in default namespace (system:serviceaccounts:default) - NOT in adminGroups

test/e2e/smoke.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,35 @@ setup_admin_token() {
126126
return 0
127127
fi
128128

129+
# Grant odh-admins RBAC so SAR-based admin check passes.
130+
# maas-api IsAdmin does a SubjectAccessReview: "can user create maasauthpolicies?"
131+
# The ODH operator will provide this via opendatahub-operator#3301; until then, create it here.
132+
local maas_sub_ns="${MAAS_SUBSCRIPTION_NAMESPACE:-models-as-a-service}"
133+
oc apply -f - <<RBAC_EOF
134+
apiVersion: rbac.authorization.k8s.io/v1
135+
kind: ClusterRole
136+
metadata:
137+
name: maas-admin
138+
rules:
139+
- apiGroups: ["maas.opendatahub.io"]
140+
resources: ["maasauthpolicies", "maassubscriptions"]
141+
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
142+
---
143+
apiVersion: rbac.authorization.k8s.io/v1
144+
kind: RoleBinding
145+
metadata:
146+
name: odh-admins-maas-admin
147+
namespace: $maas_sub_ns
148+
roleRef:
149+
apiGroup: rbac.authorization.k8s.io
150+
kind: ClusterRole
151+
name: maas-admin
152+
subjects:
153+
- apiGroup: rbac.authorization.k8s.io
154+
kind: Group
155+
name: odh-admins
156+
RBAC_EOF
157+
129158
# Use current user's token
130159
ADMIN_OC_TOKEN="$(oc whoami -t 2>/dev/null || true)"
131160
if [[ -n "${ADMIN_OC_TOKEN}" ]]; then

test/e2e/tests/test_models_endpoint.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
_ns,
3737
_sa_to_user,
3838
_snapshot_cr,
39+
_wait_for_maas_auth_policy_ready,
40+
_wait_for_maas_subscription_ready,
3941
_wait_reconcile,
4042
DISTINCT_MODEL_ID,
4143
DISTINCT_MODEL_REF,
@@ -1099,7 +1101,10 @@ def test_user_token_returns_all_models(self):
10991101
_create_test_auth_policy(auth2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
11001102
_create_test_subscription(sub2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
11011103

1102-
_wait_reconcile()
1104+
_wait_for_maas_auth_policy_ready(auth1_name)
1105+
_wait_for_maas_auth_policy_ready(auth2_name)
1106+
_wait_for_maas_subscription_ready(sub1_name)
1107+
_wait_for_maas_subscription_ready(sub2_name)
11031108

11041109
# Query with user token (no X-MaaS-Subscription header)
11051110
log.info("Querying /v1/models with user token (no header)")
@@ -1954,7 +1959,10 @@ def test_service_account_token_multiple_subs_no_header(self):
19541959
_create_test_auth_policy(auth2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
19551960
_create_test_subscription(sub2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
19561961

1957-
_wait_reconcile()
1962+
_wait_for_maas_auth_policy_ready(auth1_name)
1963+
_wait_for_maas_auth_policy_ready(auth2_name)
1964+
_wait_for_maas_subscription_ready(sub1_name)
1965+
_wait_for_maas_subscription_ready(sub2_name)
19581966

19591967
# Query with K8s token (no header)
19601968
log.info("Querying /v1/models with K8s token (no header) - should return models from both subscriptions")
@@ -2018,7 +2026,10 @@ def test_service_account_token_multiple_subs_with_header(self):
20182026
_create_test_auth_policy(auth2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
20192027
_create_test_subscription(sub2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
20202028

2021-
_wait_reconcile()
2029+
_wait_for_maas_auth_policy_ready(auth1_name)
2030+
_wait_for_maas_auth_policy_ready(auth2_name)
2031+
_wait_for_maas_subscription_ready(sub1_name)
2032+
_wait_for_maas_subscription_ready(sub2_name)
20222033

20232034
# Query with K8s token and header specifying sub1
20242035
log.info(f"Querying /v1/models with K8s token and header: {sub1_name}")

test/e2e/tests/test_subscription.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,10 @@ def test_rate_limit_exhaustion_gets_429(self):
10481048
)
10491049
_wait_reconcile()
10501050

1051+
# Wait for TRLP to be created AND enforced by Kuadrant/Limitador.
1052+
# Without this, requests bypass token rate limiting entirely.
1053+
_wait_for_token_rate_limit_policy(model_ref, model_namespace=MODEL_NAMESPACE, timeout=90)
1054+
10511055
# 3. API key must be minted for this subscription
10521056
oc_token = _get_cluster_token()
10531057
api_key = _create_api_key(

0 commit comments

Comments
 (0)