Skip to content

Commit e712d44

Browse files
authored
Enhance groups endpoint (kubeflow#1206)
Signed-off-by: lucferbux <[email protected]>
1 parent 2078202 commit e712d44

File tree

6 files changed

+167
-16
lines changed

6 files changed

+167
-16
lines changed

clients/ui/api/openapi/mod-arch.yaml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,35 @@ paths:
300300
description: Deletes an existing Role Binding associated with Model Registries.
301301
parameters: # Add parameters at the path level
302302
- $ref: '#/components/parameters/roleBindingName' # Ensure this path parameter is defined
303+
/api/v1/settings/groups:
304+
summary: Path used to get available groups.
305+
description: >-
306+
The REST endpoint/path used to get a list of all available OpenShift/Kubernetes groups in the cluster.
307+
get:
308+
tags:
309+
- K8SOperation
310+
parameters:
311+
- $ref: "#/components/parameters/kubeflowUserId"
312+
- $ref: "#/components/parameters/namespace"
313+
responses:
314+
"200":
315+
description: 'Ok'
316+
content:
317+
application/json:
318+
schema:
319+
type: object
320+
properties:
321+
data:
322+
type: array
323+
items:
324+
$ref: "#/components/schemas/Group"
325+
"401":
326+
$ref: "#/components/responses/Unauthorized"
327+
"500":
328+
$ref: "#/components/responses/InternalServerError"
329+
operationId: getGroups
330+
summary: Get Available Groups
331+
description: Returns available OpenShift/Kubernetes groups in the cluster.
303332
/api/v1/model_registry/{modelRegistryName}/model_versions/{modelversionId}:
304333
summary: Path used to manage a single ModelVersion.
305334
description: >-
@@ -1469,6 +1498,56 @@ components:
14691498
-----BEGIN CERTIFICATE-----
14701499
MIID...
14711500
-----END CERTIFICATE-----
1501+
Group:
1502+
description: OpenShift/Kubernetes Group object
1503+
type: object
1504+
required:
1505+
- metadata
1506+
- users
1507+
properties:
1508+
apiVersion:
1509+
type: string
1510+
example: "user.openshift.io/v1"
1511+
kind:
1512+
type: string
1513+
example: "Group"
1514+
metadata:
1515+
type: object
1516+
required:
1517+
- name
1518+
properties:
1519+
name:
1520+
type: string
1521+
example: "dora-group"
1522+
namespace:
1523+
type: string
1524+
nullable: true
1525+
annotations:
1526+
type: object
1527+
additionalProperties:
1528+
type: string
1529+
nullable: true
1530+
labels:
1531+
type: object
1532+
additionalProperties:
1533+
type: string
1534+
nullable: true
1535+
creationTimestamp:
1536+
type: string
1537+
format: date-time
1538+
nullable: true
1539+
example: "2023-01-15T10:30:00Z"
1540+
resourceVersion:
1541+
type: string
1542+
nullable: true
1543+
uid:
1544+
type: string
1545+
nullable: true
1546+
users:
1547+
type: array
1548+
items:
1549+
type: string
1550+
14721551
responses:
14731552
NotFound:
14741553
content:
@@ -1887,6 +1966,13 @@ components:
18871966
type: string
18881967
in: path
18891968
required: true
1969+
namespace:
1970+
name: namespace
1971+
description: The namespace to filter resources by.
1972+
schema:
1973+
type: string
1974+
in: query
1975+
required: false
18901976
securitySchemes:
18911977
Bearer:
18921978
scheme: bearer

clients/ui/bff/internal/api/model_registry_settings_groups_handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"github.com/kubeflow/model-registry/ui/bff/internal/models"
1111
)
1212

13-
type GroupsEnvelope Envelope[[]models.GroupModel, None]
13+
type GroupsEnvelope Envelope[[]models.Group, None]
1414

1515
// STUB IMPLEMENTATION (see kubernetes clients for more details)
1616
func (app *App) GetGroupsHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

clients/ui/bff/internal/api/model_registry_settings_groups_handler_test.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"github.com/kubeflow/model-registry/ui/bff/internal/config"
1111
"github.com/kubeflow/model-registry/ui/bff/internal/constants"
1212
"github.com/kubeflow/model-registry/ui/bff/internal/integrations/kubernetes"
13-
"github.com/kubeflow/model-registry/ui/bff/internal/models"
1413
"github.com/kubeflow/model-registry/ui/bff/internal/repositories"
1514
. "github.com/onsi/ginkgo/v2"
1615
. "github.com/onsi/gomega"
@@ -51,13 +50,18 @@ var _ = Describe("TestGroupsHandler", func() {
5150
err = json.Unmarshal(body, &actual)
5251
Expect(err).NotTo(HaveOccurred())
5352

54-
expected := []models.GroupModel{
55-
{Name: "dora-group-mock"},
56-
{Name: "bella-group-mock"},
57-
}
58-
5953
Expect(rr.Code).To(Equal(http.StatusOK))
60-
Expect(actual.Data).To(ConsistOf(expected))
54+
Expect(actual.Data).To(HaveLen(2))
55+
56+
// Verify first group
57+
firstGroup := actual.Data[0]
58+
Expect(firstGroup.Metadata.Name).To(Equal("dora-group-mock"))
59+
Expect(firstGroup.Users).To(ConsistOf("[email protected]", "[email protected]"))
60+
61+
// Verify second group
62+
secondGroup := actual.Data[1]
63+
Expect(secondGroup.Metadata.Name).To(Equal("bella-group-mock"))
64+
Expect(secondGroup.Users).To(ConsistOf("[email protected]", "[email protected]"))
6165
})
6266
})
6367
})

clients/ui/bff/internal/models/groups.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,48 @@
11
package models
22

3+
import "time"
4+
5+
// K8sObjectMeta represents the metadata of a Kubernetes object
6+
type K8sObjectMeta struct {
7+
Name string `json:"name"`
8+
Namespace *string `json:"namespace,omitempty"`
9+
Annotations map[string]string `json:"annotations,omitempty"`
10+
Labels map[string]string `json:"labels,omitempty"`
11+
CreationTimestamp *time.Time `json:"creationTimestamp,omitempty"`
12+
ResourceVersion *string `json:"resourceVersion,omitempty"`
13+
UID *string `json:"uid,omitempty"`
14+
}
15+
16+
// Group represents an OpenShift/Kubernetes Group object
17+
type Group struct {
18+
APIVersion *string `json:"apiVersion,omitempty"`
19+
Kind *string `json:"kind,omitempty"`
20+
Metadata K8sObjectMeta `json:"metadata"`
21+
Users []string `json:"users"`
22+
}
23+
24+
// Legacy GroupModel for backward compatibility (if needed)
325
type GroupModel struct {
426
Name string `json:"name"`
527
}
628

29+
// NewGroup creates a new Group with the specified name and users
30+
func NewGroup(name string, users []string) Group {
31+
apiVersion := "user.openshift.io/v1"
32+
kind := "Group"
33+
now := time.Now()
34+
35+
return Group{
36+
APIVersion: &apiVersion,
37+
Kind: &kind,
38+
Metadata: K8sObjectMeta{
39+
Name: name,
40+
CreationTimestamp: &now,
41+
},
42+
Users: users,
43+
}
44+
}
45+
746
func NewGroupModel(name string) GroupModel {
847
return GroupModel{
948
Name: name,

clients/ui/bff/internal/repositories/model_registry_settings.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,26 @@ func NewModelRegistrySettingsRepository() *ModelRegistrySettingsRepository {
1515
return &ModelRegistrySettingsRepository{}
1616
}
1717

18-
func (r *ModelRegistrySettingsRepository) GetGroups(ctx context.Context, client k8s.KubernetesClientInterface) ([]models.GroupModel, error) {
18+
func (r *ModelRegistrySettingsRepository) GetGroups(ctx context.Context, client k8s.KubernetesClientInterface) ([]models.Group, error) {
1919
groupNames, err := client.GetGroups(ctx)
2020
if err != nil {
2121
return nil, fmt.Errorf("error fetching groups: %w", err)
2222
}
2323

24-
var groups []models.GroupModel
24+
var groups []models.Group
2525
for _, name := range groupNames {
26-
groups = append(groups, models.NewGroupModel(name))
26+
// Create mock users for each group to make the data more realistic
27+
var users []string
28+
switch name {
29+
case "dora-group-mock":
30+
users = []string{"[email protected]", "[email protected]"}
31+
case "bella-group-mock":
32+
users = []string{"[email protected]", "[email protected]"}
33+
default:
34+
users = []string{fmt.Sprintf("%[email protected]", name)}
35+
}
36+
37+
groups = append(groups, models.NewGroup(name, users))
2738
}
2839

2940
return groups, nil

clients/ui/bff/internal/repositories/model_registry_settings_test.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,22 @@ var _ = Describe("TestModelRegistrySettingsRepository", func() {
2323
Expect(err).NotTo(HaveOccurred())
2424

2525
By("verifying the returned group models")
26-
expected := []models.GroupModel{
27-
{Name: "dora-group-mock"},
28-
{Name: "bella-group-mock"},
29-
}
30-
Expect(groups).To(ConsistOf(expected))
26+
Expect(groups).To(HaveLen(2))
27+
28+
// Verify first group
29+
firstGroup := groups[0]
30+
Expect(firstGroup.Metadata.Name).To(Equal("dora-group-mock"))
31+
Expect(firstGroup.Users).To(ConsistOf("[email protected]", "[email protected]"))
32+
Expect(*firstGroup.APIVersion).To(Equal("user.openshift.io/v1"))
33+
Expect(*firstGroup.Kind).To(Equal("Group"))
34+
Expect(firstGroup).To(BeAssignableToTypeOf(models.Group{}))
35+
36+
// Verify second group
37+
secondGroup := groups[1]
38+
Expect(secondGroup.Metadata.Name).To(Equal("bella-group-mock"))
39+
Expect(secondGroup.Users).To(ConsistOf("[email protected]", "[email protected]"))
40+
Expect(*secondGroup.APIVersion).To(Equal("user.openshift.io/v1"))
41+
Expect(*secondGroup.Kind).To(Equal("Group"))
3142
})
3243
})
3344
})

0 commit comments

Comments
 (0)