Skip to content

Commit fb42db2

Browse files
yu-teoYuriy Teodorovych
andauthored
fix: standardize CRDs (#520)
https://issues.redhat.com/browse/RHOAIENG-49788 ## Description **Context** MaaS CRDs (MaaSModelRef, MaaSAuthPolicy, MaaSSubscription) have no human-readable display metadata. The `GET /v1/models` API already has a Details struct with `displayName`, `description`, and `genaiUseCase` fields, and annotation constants already exist (openshift.io/display-name, openshift.io/description, opendatahub.io/genai-use-case), but `maasModelRefToModel()` never reads annotations — so modelDetails is always `nil`. **Approach**: mainly using Annotations - [x] Use existing OpenShift-standard annotations for display name/description on all 3 CRDs - [x] Use opendatahub.io/* annotations for model-specific metadata (contextWindow) - [x] No CRD spec field changes — no regeneration needed - [x] Enrich GET /v1/models API response with annotation data ## How Has This Been Tested? Successfully ran the full test suite locally. ## Merge criteria: <!--- This PR will be merged by any repository approver when it meets all the points in the checklist --> <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] The commits are squashed in a cohesive manner and have meaningful messages. - [x] Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious). - [x] The developer has manually tested the changes and verified that the changes work <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added a CRD Annotations Reference and updated configuration/flow guides to document supported annotations (display name, description, GenAI use case, context window) and their appearance in model listings; added tier-based access guidance. * **New Features** * Model listing/response now surfaces annotation-driven metadata (modelDetails: displayName, description, genaiUseCase, contextWindow). * Sample manifests and examples updated with annotation usage. * **Tests** * Tests updated to validate annotation-driven model details. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Yuriy Teodorovych <Yuriy@ibm.com>
1 parent 17a81e2 commit fb42db2

File tree

16 files changed

+264
-31
lines changed

16 files changed

+264
-31
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# CRD Annotations Reference
2+
3+
This page documents the standard annotations supported on MaaS custom resources.
4+
5+
## Common annotations (all CRDs)
6+
7+
These annotations are supported on **MaaSModelRef**, **MaaSAuthPolicy**, and **MaaSSubscription**. They follow OpenShift conventions and are recognized by the OpenShift console, `kubectl`, and other tooling.
8+
9+
| Annotation | Description | Example |
10+
| ---------- | ----------- | ------- |
11+
| `openshift.io/display-name` | Human-readable display name | `"Llama 2 7B Chat"` |
12+
| `openshift.io/description` | Free-text description of the resource | `"A general-purpose LLM for chat"` |
13+
14+
## MaaSModelRef annotations
15+
16+
In addition to the common annotations above, the MaaS API reads these annotations from **MaaSModelRef** and returns them in the `modelDetails` field of the `GET /v1/models` response.
17+
18+
| Annotation | Description | Returned in API | Example |
19+
| ---------- | ----------- | --------------- | ------- |
20+
| `openshift.io/display-name` | Human-readable model name | `modelDetails.displayName` | `"Llama 2 7B Chat"` |
21+
| `openshift.io/description` | Model description | `modelDetails.description` | `"A large language model optimized for chat"` |
22+
| `opendatahub.io/genai-use-case` | GenAI use case category | `modelDetails.genaiUseCase` | `"chat"` |
23+
| `opendatahub.io/context-window` | Context window size | `modelDetails.contextWindow` | `"4096"` |
24+
25+
### Example MaaSModelRef with annotations
26+
27+
```yaml
28+
apiVersion: maas.opendatahub.io/v1alpha1
29+
kind: MaaSModelRef
30+
metadata:
31+
name: llama-2-7b-chat
32+
namespace: opendatahub
33+
annotations:
34+
openshift.io/display-name: "Llama 2 7B Chat"
35+
openshift.io/description: "A large language model optimized for chat use cases"
36+
opendatahub.io/genai-use-case: "chat"
37+
opendatahub.io/context-window: "4096"
38+
spec:
39+
modelRef:
40+
kind: LLMInferenceService
41+
name: llama-2-7b-chat
42+
```
43+
44+
### API response
45+
46+
When annotations are set, the `GET /v1/models` response includes a `modelDetails` object:
47+
48+
```json
49+
{
50+
"id": "llama-2-7b-chat",
51+
"object": "model",
52+
"created": 1672531200,
53+
"owned_by": "opendatahub",
54+
"ready": true,
55+
"url": "https://...",
56+
"modelDetails": {
57+
"displayName": "Llama 2 7B Chat",
58+
"description": "A large language model optimized for chat use cases",
59+
"genaiUseCase": "chat",
60+
"contextWindow": "4096"
61+
}
62+
}
63+
```
64+
65+
When no annotations are set (or all values are empty), `modelDetails` is omitted from the response.
66+
67+
## MaaSAuthPolicy and MaaSSubscription annotations
68+
69+
The common annotations (`openshift.io/display-name`, `openshift.io/description`) can be set on MaaSAuthPolicy and MaaSSubscription resources for use by `kubectl`, the OpenShift console, and other tooling. They are **not** returned in the `GET /v1/models` API response.
70+
71+
### Example
72+
73+
```yaml
74+
apiVersion: maas.opendatahub.io/v1alpha1
75+
kind: MaaSAuthPolicy
76+
metadata:
77+
name: premium-access
78+
namespace: models-as-a-service
79+
annotations:
80+
openshift.io/display-name: "Premium Access Policy"
81+
openshift.io/description: "Grants premium-users group access to premium models"
82+
spec:
83+
# ...
84+
```

docs/content/configuration-and-management/maas-model-kinds.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ To support a new backend type (a new **kind** in `spec.modelRef`):
8484
- **Option B:** Extend the API's access-validation logic to branch on **kind** and use a kind-specific probe (different URL path or client), while keeping the same contract: include a model only if the probe with the user's token succeeds.
8585

8686
3. **Enrichment (optional)**
87-
- Extra metadata (e.g. display name) can be set by the controller in status or annotations and mapped into the model response. For a new kind, add a small branch in the MaaSModelRef → API model conversion if needed.
87+
- The API reads standard annotations from MaaSModelRef (`openshift.io/display-name`, `openshift.io/description`, `opendatahub.io/genai-use-case`, `opendatahub.io/context-window`) and returns them in the `modelDetails` field of the GET /v1/models response. See [CRD annotations](crd-annotations.md) for the full list. For a new kind, add a small branch in the MaaSModelRef → API model conversion if needed.
8888

8989
4. **RBAC**
9090
- If the new kind’s reconciler or the API needs to read another resource, add the corresponding **list/watch** (and optionally **get**) permissions to the maas-api ClusterRole and/or the controller’s RBAC.

docs/content/configuration-and-management/model-listing-flow.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ When the [MaaS controller](https://github.com/opendatahub-io/models-as-a-service
2525

2626
3. **Access validation**: The API probes each model’s `/v1/models` endpoint with the **exact Authorization header** the client sent (passed through as-is). Only models that return **2xx**, **3xx** or **405** are included in the response. This ensures the list only shows models the client is authorized to use.
2727

28-
4. The filtered list is returned to the client.
28+
4. For each model, the API reads **annotations** from the MaaSModelRef to populate `modelDetails` in the response (display name, description, use case, context window). See [CRD annotations](crd-annotations.md) for the full list.
29+
30+
5. The filtered list is returned to the client.
2931

3032
```mermaid
3133
sequenceDiagram
@@ -172,7 +174,12 @@ To have models appear via the **MaaSModelRef** flow:
172174
kind: MaaSModelRef
173175
metadata:
174176
name: my-model-name # This becomes the model "id" in GET /v1/models
175-
namespace: llm # Same namespace as the LLMInferenceService
177+
namespace: llm # Same namespace as the LLMInferenceService
178+
annotations:
179+
openshift.io/display-name: "My Model" # optional: human-readable name
180+
openshift.io/description: "A general-purpose LLM" # optional: description
181+
opendatahub.io/genai-use-case: "chat" # optional: use case
182+
opendatahub.io/context-window: "4096" # optional: context window
176183
spec:
177184
modelRef:
178185
kind: LLMInferenceService

docs/content/configuration-and-management/model-setup.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,77 @@ spec:
122122

123123
### Complete example
124124

125+
Add the `alpha.maas.opendatahub.io/tiers` annotation to enable automatic RBAC setup for tier-based access:
126+
127+
```yaml
128+
apiVersion: serving.kserve.io/v1alpha1
129+
kind: LLMInferenceService
130+
metadata:
131+
name: my-production-model
132+
namespace: llm
133+
annotations:
134+
alpha.maas.opendatahub.io/tiers: '[]'
135+
spec:
136+
# ... rest of spec ...
137+
```
138+
139+
**Annotation Values:**
140+
141+
- **Empty list `[]`**: Grants access to **all tiers** (recommended for most models)
142+
- **List of tier names**: Grants access to specific tiers only
143+
- Example: `'["premium","enterprise"]'` - only premium and enterprise tiers can access
144+
- **Missing annotation**: **No tiers** have access by default (model won't be accessible via MaaS)
145+
146+
**Examples:**
147+
148+
Allow all tiers:
149+
150+
```yaml
151+
annotations:
152+
alpha.maas.opendatahub.io/tiers: '[]'
153+
```
154+
155+
Allow specific tiers:
156+
157+
```yaml
158+
annotations:
159+
alpha.maas.opendatahub.io/tiers: '["premium","enterprise"]'
160+
```
161+
162+
### Step 3: Add Display Metadata (Optional)
163+
164+
Add standard annotations to your **MaaSModelRef** to provide human-readable names and descriptions in the `GET /v1/models` API response:
165+
166+
```yaml
167+
apiVersion: maas.opendatahub.io/v1alpha1
168+
kind: MaaSModelRef
169+
metadata:
170+
name: my-production-model
171+
namespace: llm
172+
annotations:
173+
openshift.io/display-name: "My Production Model"
174+
openshift.io/description: "A fine-tuned model for production workloads"
175+
opendatahub.io/genai-use-case: "chat"
176+
opendatahub.io/context-window: "8192"
177+
spec:
178+
modelRef:
179+
kind: LLMInferenceService
180+
name: my-production-model
181+
```
182+
183+
These annotations are returned in the `modelDetails` field of the API response. All are optional. See [CRD annotations](crd-annotations.md) for the full list of supported annotations across all MaaS CRDs.
184+
185+
### What the Annotation Does
186+
187+
This annotation automatically creates the necessary RBAC resources (Roles and RoleBindings) that allow tier-specific service accounts to POST to your `LLMInferenceService`. The ODH Controller handles this automatically when the annotation is present.
188+
189+
Behind the scenes, it creates:
190+
191+
- **Role**: Grants `POST` permission on `llminferenceservices` resource
192+
- **RoleBinding**: Binds tier service account groups (e.g., `system:serviceaccounts:maas-default-gateway-tier-premium`) to the role
193+
194+
### Complete Example
195+
125196
Here's a complete example of an LLMInferenceService configured for MaaS:
126197

127198
```yaml

docs/samples/maas-system/free/maas/maas-auth-policy.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ kind: MaaSAuthPolicy
33
metadata:
44
name: simulator-access
55
namespace: models-as-a-service
6+
annotations:
7+
openshift.io/display-name: "Simulator Access (Free)"
8+
openshift.io/description: "Grants all authenticated users access to the free-tier simulator model"
69
spec:
710
modelRefs:
811
- name: facebook-opt-125m-simulated

docs/samples/maas-system/free/maas/maas-model.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ kind: MaaSModelRef
33
metadata:
44
name: facebook-opt-125m-simulated
55
namespace: llm
6+
annotations:
7+
openshift.io/display-name: "Facebook OPT 125M (Simulated)"
8+
openshift.io/description: "A simulated OPT-125M model for free-tier testing"
69
spec:
710
modelRef:
811
kind: LLMInferenceService

docs/samples/maas-system/free/maas/maas-subscription.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ kind: MaaSSubscription
33
metadata:
44
name: simulator-subscription
55
namespace: models-as-a-service
6+
annotations:
7+
openshift.io/display-name: "Simulator Subscription (Free)"
8+
openshift.io/description: "Free-tier subscription with 100 tokens/min rate limit"
69
spec:
710
owner:
811
groups:

docs/samples/maas-system/premium/maas/maas-auth-policy.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ kind: MaaSAuthPolicy
33
metadata:
44
name: premium-simulator-access
55
namespace: models-as-a-service
6+
annotations:
7+
openshift.io/display-name: "Premium Simulator Access"
8+
openshift.io/description: "Grants premium-user group access to the premium simulator model"
69
spec:
710
modelRefs:
811
- name: premium-simulated-simulated-premium

docs/samples/maas-system/premium/maas/maas-model.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ kind: MaaSModelRef
55
metadata:
66
name: premium-simulated-simulated-premium
77
namespace: llm
8+
annotations:
9+
openshift.io/display-name: "Premium Simulator"
10+
openshift.io/description: "A simulated model for premium-tier testing"
811
spec:
912
modelRef:
1013
kind: LLMInferenceService

docs/samples/maas-system/premium/maas/maas-subscription.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ kind: MaaSSubscription
33
metadata:
44
name: premium-simulator-subscription
55
namespace: models-as-a-service
6+
annotations:
7+
openshift.io/display-name: "Premium Simulator Subscription"
8+
openshift.io/description: "Premium-tier subscription with 1000 tokens/min rate limit"
69
spec:
710
owner:
811
groups:

0 commit comments

Comments
 (0)