Skip to content

Commit 014712f

Browse files
authored
Merge branch 'main' into RHOAIENG-40473-add-debugging-for-gen-ai-bff
2 parents 851f48b + 5d538c6 commit 014712f

260 files changed

Lines changed: 37334 additions & 1012 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Onboarding a New Modular Architecture Module
2+
3+
This guide outlines the steps to create and onboard a new modular architecture module into the ODH Dashboard.
4+
5+
## Prerequisites
6+
7+
- Node.js and npm installed.
8+
- Access to the ODH Dashboard repository.
9+
10+
## Steps
11+
12+
### 1. Navigate to the Packages Directory
13+
14+
Open your terminal and navigate to the `packages` folder within the repository:
15+
16+
```bash
17+
cd packages
18+
```
19+
20+
### 2. Initialize the Module
21+
22+
Start a new modular architecture project using the installer. Replace `<your-module-name>` with the desired name for your module.
23+
24+
```bash
25+
npx mod-arch-installer <your-module-name> --flavor default
26+
```
27+
28+
### 3. Adapt the Module Name
29+
30+
After initialization, you need to update the generated code to match your specific module name. Search for occurrences of `mod-arch` and `modArch` in your new package and replace them with your module's identifier.
31+
32+
Key files to check:
33+
34+
- `package.json`
35+
- `frontend/src/odh/extensions.ts` (or similar entry point to change the nav)
36+
- `frontend/config/moduleFederation.js`
37+
38+
In BFF you can do a replace-all searching for `mod-arch` and will change the package name.
39+
40+
### 4. Configure the Port
41+
42+
By default, the modular architecture component runs on port `9103`. If you need to use a different port or want to ensure it doesn't conflict with other modules:
43+
44+
1. **Update `Makefile`**:
45+
Open `packages/<your-module-name>/Makefile` and find the `dev-frontend-federated` target. Update the `PORT` variable:
46+
47+
```makefile
48+
dev-frontend-federated:
49+
cd frontend && AUTH_METHOD=user_token DEPLOYMENT_MODE=federated STYLE_THEME=patternfly PORT=<your-port> npm run start:dev
50+
```
51+
52+
2. **Update `package.json`**:
53+
Open `packages/<your-module-name>/package.json` and update the `module-federation` configuration:
54+
55+
```json
56+
"module-federation": {
57+
"local": {
58+
"port": <your-port>
59+
}
60+
}
61+
```
62+
63+
### 5. Add Feature Flag
64+
65+
To enable your module in the main dashboard, you need to add a feature flag.
66+
67+
1. Open `frontend/src/concepts/areas/const.ts` in the root of the repository.
68+
2. Search for existing flags (e.g., search for `disable` or `techPreviewFlags`).
69+
3. Add your new feature flag to the appropriate group (e.g., `techPreviewFlags`):
70+
71+
```typescript
72+
export const techPreviewFlags = {
73+
// ... existing flags
74+
// yourModuleName: true, // Set to true to enable by default in tech preview, or false otherwise
75+
} satisfies Partial<DashboardCommonConfig>;
76+
```
77+
78+
### 6. Run the Application
79+
80+
Now that your project is configured, you can run the entire stack (backend, frontend, and your new module).
81+
82+
From the root of the repository, run:
83+
84+
```bash
85+
npm run dev:frontend
86+
```
87+
88+
And in other terminal
89+
90+
```bash
91+
npm run dev:backend
92+
```
93+
94+
And once you have that in another terminal run
95+
96+
```bash
97+
cd packages/<your-module>
98+
make dev-start-federated
99+
```
100+
101+
This command will start:
102+
103+
- The Dashboard Backend
104+
- The Dashboard Frontend (Shell)
105+
- Your new Modular Architecture Module (Federated)
106+
107+
Access the dashboard in your browser (usually at `http://localhost:4000` or the port configured for the shell) and verify that your module is loaded.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Feature Store test data
2+
projectName: "test-fs-ui-proj"
3+
feastInstanceName: "test-s3"
4+
feastCreditScoringProject: "credit_scoring_local"
5+
feastDriverRankingProject: "driver_ranking"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
kind: Secret
2+
apiVersion: v1
3+
metadata:
4+
name: s3-credentials-secret
5+
namespace: ${namespace}
6+
stringData:
7+
AWS_ACCESS_KEY_ID: ${awsAccessKey}
8+
AWS_SECRET_ACCESS_KEY: ${awsSecretKey}
9+
AWS_DEFAULT_REGION: ${awsDefaultRegion}
10+
---
11+
apiVersion: feast.dev/v1alpha1
12+
kind: FeatureStore
13+
metadata:
14+
name: test-s3
15+
namespace: ${namespace}
16+
labels:
17+
feature-store-ui: enabled
18+
spec:
19+
feastProject: driver_ranking
20+
services:
21+
onlineStore:
22+
server:
23+
envFrom:
24+
- secretRef:
25+
name: s3-credentials-secret
26+
registry:
27+
local:
28+
persistence:
29+
file:
30+
path: s3://${awsBucketName}/feast-test/feast-credit-score-remote-data/registry.pb
31+
server:
32+
envFrom:
33+
- secretRef:
34+
name: s3-credentials-secret
35+
grpc: true
36+
restAPI: true

frontend/src/__tests__/cypress/cypress/fixtures/resources/yaml/model_registry.yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,24 @@ spec:
1111
rest: {}
1212
kubeRBACProxy: {}
1313
mysql:
14-
host: model-registry-db
14+
host: {{DATABASE_NAME}}
1515
port: 3306
1616
database: model_registry
1717
username: mlmduser
1818
skipDBCreation: false
1919
passwordSecret:
20-
name: model-registry-db
20+
name: {{DATABASE_NAME}}
2121
key: database-password
2222
---
2323
apiVersion: v1
2424
kind: Secret
2525
metadata:
26-
name: model-registry-db
26+
name: {{DATABASE_NAME}}
2727
namespace: {{NAMESPACE}}
2828
labels:
29-
app.kubernetes.io/name: model-registry-db
30-
app.kubernetes.io/instance: model-registry-db
31-
app.kubernetes.io/part-of: model-registry-db
29+
app.kubernetes.io/name: {{DATABASE_NAME}}
30+
app.kubernetes.io/instance: {{DATABASE_NAME}}
31+
app.kubernetes.io/part-of: {{DATABASE_NAME}}
3232
app.kubernetes.io/managed-by: kustomize
3333
annotations:
3434
template.openshift.io/expose-database_name: '{.data[''database-name'']}'
@@ -37,4 +37,4 @@ metadata:
3737
stringData:
3838
database-name: "model_registry"
3939
database-password: "TheBlurstOfTimes"
40-
database-user: "mlmduser"
40+
database-user: "mlmduser"

frontend/src/__tests__/cypress/cypress/fixtures/resources/yaml/model_registry_database.yaml

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ items:
44
kind: Service
55
metadata:
66
labels:
7-
app.kubernetes.io/name: model-registry-db
8-
app.kubernetes.io/instance: model-registry-db
9-
app.kubernetes.io/part-of: model-registry-db
7+
app.kubernetes.io/name: {{DATABASE_NAME}}
8+
app.kubernetes.io/instance: {{DATABASE_NAME}}
9+
app.kubernetes.io/part-of: {{DATABASE_NAME}}
1010
app.kubernetes.io/managed-by: kustomize
1111
annotations:
1212
template.openshift.io/expose-uri: mysql://{.spec.clusterIP}:{.spec.ports[?(.name==\mysql\)].port}
13-
name: model-registry-db
13+
name: {{DATABASE_NAME}}
1414
namespace: {{NAMESPACE}}
1515
spec:
1616
ports:
@@ -21,18 +21,18 @@ items:
2121
appProtocol: tcp
2222
targetPort: 3306
2323
selector:
24-
name: model-registry-db
24+
name: {{DATABASE_NAME}}
2525
sessionAffinity: None
2626
type: ClusterIP
2727
- apiVersion: v1
2828
kind: PersistentVolumeClaim
2929
metadata:
3030
labels:
31-
app.kubernetes.io/name: model-registry-db
32-
app.kubernetes.io/instance: model-registry-db
33-
app.kubernetes.io/part-of: model-registry-db
31+
app.kubernetes.io/name: {{DATABASE_NAME}}
32+
app.kubernetes.io/instance: {{DATABASE_NAME}}
33+
app.kubernetes.io/part-of: {{DATABASE_NAME}}
3434
app.kubernetes.io/managed-by: kustomize
35-
name: model-registry-db
35+
name: {{DATABASE_NAME}}
3636
namespace: {{NAMESPACE}}
3737
spec:
3838
accessModes:
@@ -44,26 +44,26 @@ items:
4444
kind: Deployment
4545
metadata:
4646
labels:
47-
app.kubernetes.io/name: model-registry-db
48-
app.kubernetes.io/instance: model-registry-db
49-
app.kubernetes.io/part-of: model-registry-db
47+
app.kubernetes.io/name: {{DATABASE_NAME}}
48+
app.kubernetes.io/instance: {{DATABASE_NAME}}
49+
app.kubernetes.io/part-of: {{DATABASE_NAME}}
5050
app.kubernetes.io/managed-by: kustomize
5151
annotations:
5252
template.alpha.openshift.io/wait-for-ready: "true"
53-
name: model-registry-db
53+
name: {{DATABASE_NAME}}
5454
namespace: {{NAMESPACE}}
5555
spec:
5656
replicas: 1
5757
revisionHistoryLimit: 0
5858
selector:
5959
matchLabels:
60-
name: model-registry-db
60+
name: {{DATABASE_NAME}}
6161
strategy:
6262
type: Recreate
6363
template:
6464
metadata:
6565
labels:
66-
name: model-registry-db
66+
name: {{DATABASE_NAME}}
6767
sidecar.istio.io/inject: "false"
6868
spec:
6969
containers:
@@ -72,22 +72,22 @@ items:
7272
valueFrom:
7373
secretKeyRef:
7474
key: database-user
75-
name: model-registry-db
75+
name: {{DATABASE_NAME}}
7676
- name: MYSQL_PASSWORD
7777
valueFrom:
7878
secretKeyRef:
7979
key: database-password
80-
name: model-registry-db
80+
name: {{DATABASE_NAME}}
8181
- name: MYSQL_ROOT_PASSWORD
8282
valueFrom:
8383
secretKeyRef:
8484
key: database-password
85-
name: model-registry-db
85+
name: {{DATABASE_NAME}}
8686
- name: MYSQL_DATABASE
8787
valueFrom:
8888
secretKeyRef:
8989
key: database-name
90-
name: model-registry-db
90+
name: {{DATABASE_NAME}}
9191
args:
9292
- --datadir
9393
- /var/lib/mysql/datadir
@@ -126,30 +126,30 @@ items:
126126
terminationMessagePath: /dev/termination-log
127127
volumeMounts:
128128
- mountPath: /var/lib/mysql
129-
name: model-registry-db-data
129+
name: {{DATABASE_NAME}}-data
130130
dnsPolicy: ClusterFirst
131131
restartPolicy: Always
132132
volumes:
133-
- name: model-registry-db-data
133+
- name: {{DATABASE_NAME}}-data
134134
persistentVolumeClaim:
135-
claimName: model-registry-db
135+
claimName: {{DATABASE_NAME}}
136136
- apiVersion: v1
137137
kind: Secret
138138
metadata:
139139
labels:
140-
app.kubernetes.io/name: model-registry-db
141-
app.kubernetes.io/instance: model-registry-db
142-
app.kubernetes.io/part-of: model-registry-db
140+
app.kubernetes.io/name: {{DATABASE_NAME}}
141+
app.kubernetes.io/instance: {{DATABASE_NAME}}
142+
app.kubernetes.io/part-of: {{DATABASE_NAME}}
143143
app.kubernetes.io/managed-by: kustomize
144144
annotations:
145145
template.openshift.io/expose-database_name: '{.data[''database-name'']}'
146146
template.openshift.io/expose-password: '{.data[''database-password'']}'
147147
template.openshift.io/expose-username: '{.data[''database-user'']}'
148-
name: model-registry-db
148+
name: {{DATABASE_NAME}}
149149
namespace: {{NAMESPACE}}
150150
stringData:
151151
database-name: "model_registry"
152152
database-password: "TheBlurstOfTimes" # notsecret
153153
database-user: "mlmduser" # notsecret
154154
kind: List
155-
metadata: {}
155+
metadata: {}

frontend/src/__tests__/cypress/cypress/pages/featureStore/featureStoreGlobal.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ class FeatureStoreGlobal {
8888
this.waitForFeatureServiceDetails(featureService);
8989
}
9090

91+
navigateToOverview() {
92+
appChrome
93+
.findNavItem({
94+
name: 'Overview',
95+
rootSection: 'Develop & train',
96+
subSection: 'Feature store',
97+
})
98+
.click();
99+
this.waitForOverview();
100+
}
101+
91102
navigateToFeatureViews() {
92103
appChrome
93104
.findNavItem({
@@ -121,6 +132,39 @@ class FeatureStoreGlobal {
121132
this.waitForFeatures();
122133
}
123134

135+
navigateToDataSources() {
136+
appChrome
137+
.findNavItem({
138+
name: 'Data sources',
139+
rootSection: 'Develop & train',
140+
subSection: 'Feature store',
141+
})
142+
.click();
143+
this.waitForDataSources();
144+
}
145+
146+
navigateToDatasets() {
147+
appChrome
148+
.findNavItem({
149+
name: 'Datasets',
150+
rootSection: 'Develop & train',
151+
subSection: 'Feature store',
152+
})
153+
.click();
154+
this.waitForDataSets();
155+
}
156+
157+
navigateToFeatureServices() {
158+
appChrome
159+
.findNavItem({
160+
name: 'Feature services',
161+
rootSection: 'Develop & train',
162+
subSection: 'Feature store',
163+
})
164+
.click();
165+
this.waitForFeatureServices();
166+
}
167+
124168
findHeading() {
125169
return cy.findByTestId('app-page-title');
126170
}
@@ -252,6 +296,10 @@ class FeatureStoreGlobal {
252296
const testId = `global-search-item-${type}-${title.toLowerCase().replace(/\s+/g, '-')}`;
253297
return cy.findByTestId(testId);
254298
}
299+
300+
findPaginationToggle() {
301+
return cy.get('#table-pagination-top-toggle');
302+
}
255303
}
256304

257305
class FeatureStoreProjectSelector extends Contextual<HTMLElement> {

0 commit comments

Comments
 (0)