-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(bff): list user namespaces in dev mode (#644)
* feat(bff): list user namespaces in dev mode Signed-off-by: Eder Ignatowicz <[email protected]> * Update clients/ui/bff/internal/api/namespaces_handler_test.go Co-authored-by: Alex Creasy <[email protected]> Signed-off-by: Eder Ignatowicz <[email protected]> --------- Signed-off-by: Eder Ignatowicz <[email protected]> Co-authored-by: Alex Creasy <[email protected]>
- Loading branch information
1 parent
a4e3600
commit 4867116
Showing
15 changed files
with
311 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,7 @@ make docker-build | |
|----------------------------------------------------------------------------------------------|----------------------------------------------|-------------------------------------------------------------| | ||
| GET /v1/healthcheck | HealthcheckHandler | Show application information. | | ||
| GET /v1/user | UserHandler | Show "kubeflow-user-id" from header information. | | ||
| GET /v1/namespaces | NamespacesHandler | Get all user namespaces. | | ||
| GET /v1/model_registry | ModelRegistryHandler | Get all model registries, | | ||
| GET /v1/model_registry/{model_registry_id}/registered_models | GetAllRegisteredModelsHandler | Gets a list of all RegisteredModel entities. | | ||
| POST /v1/model_registry/{model_registry_id}/registered_models | CreateRegisteredModelHandler | Create a RegisteredModel entity. | | ||
|
@@ -83,6 +84,10 @@ curl -i -H "kubeflow-userid: [email protected]" localhost:4000/api/v1/healthcheck | |
curl -i -H "kubeflow-userid: [email protected]" localhost:4000/api/v1/user | ||
``` | ||
``` | ||
# GET /v1/namespaces | ||
curl -i -H "kubeflow-userid: [email protected]" localhost:4000/api/v1/namespaces | ||
``` | ||
``` | ||
# GET /v1/model_registry | ||
curl -i -H "kubeflow-userid: [email protected]" localhost:4000/api/v1/model_registry | ||
``` | ||
|
@@ -250,4 +255,4 @@ The mock Kubernetes environment is activated when the environment variable `MOCK | |
- `model-registry`: resides in the `kubeflow` namespace with the label `component: model-registry`. | ||
- `model-registry-dora`: resides in the `dora-namespace` namespace with the label `component: model-registry`. | ||
- `model-registry-bella`: resides in the `kubeflow` namespace with the label `component: model-registry`. | ||
- `non-model-registry`: resides in the `kubeflow` namespace *without* the label `component: model-registry`. | ||
- `non-model-registry`: resides in the `kubeflow` namespace *without* the label `component: model-registry`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package api | ||
|
||
import ( | ||
"errors" | ||
"github.com/kubeflow/model-registry/ui/bff/internal/models" | ||
"net/http" | ||
|
||
"github.com/julienschmidt/httprouter" | ||
) | ||
|
||
type NamespacesEnvelope Envelope[[]models.NamespaceModel, None] | ||
|
||
func (app *App) GetNamespacesHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { | ||
|
||
userId, ok := r.Context().Value(KubeflowUserIdKey).(string) | ||
if !ok || userId == "" { | ||
app.serverErrorResponse(w, r, errors.New("failed to retrieve kubeflow-userid from context")) | ||
return | ||
} | ||
|
||
namespaces, err := app.repositories.Namespace.GetNamespaces(app.kubernetesClient, userId) | ||
if err != nil { | ||
app.serverErrorResponse(w, r, err) | ||
return | ||
} | ||
|
||
namespacesEnvelope := NamespacesEnvelope{ | ||
Data: namespaces, | ||
} | ||
|
||
err = app.WriteJSON(w, http.StatusOK, namespacesEnvelope, nil) | ||
|
||
if err != nil { | ||
app.serverErrorResponse(w, r, err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package api | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"github.com/kubeflow/model-registry/ui/bff/internal/config" | ||
"github.com/kubeflow/model-registry/ui/bff/internal/mocks" | ||
"github.com/kubeflow/model-registry/ui/bff/internal/models" | ||
"github.com/kubeflow/model-registry/ui/bff/internal/repositories" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
"io" | ||
"net/http" | ||
"net/http/httptest" | ||
) | ||
|
||
var _ = Describe("TestNamespacesHandler", func() { | ||
Context("when running in dev mode", Ordered, func() { | ||
var testApp App | ||
|
||
BeforeAll(func() { | ||
By("setting up the test app in dev mode") | ||
testApp = App{ | ||
config: config.EnvConfig{DevMode: true}, | ||
kubernetesClient: k8sClient, | ||
repositories: repositories.NewRepositories(mockMRClient), | ||
logger: logger, | ||
} | ||
}) | ||
|
||
It("should return only dora-namespace for [email protected]", func() { | ||
By("creating the HTTP request with the kubeflow-userid header") | ||
req, err := http.NewRequest(http.MethodGet, NamespaceListPath, nil) | ||
ctx := context.WithValue(req.Context(), KubeflowUserIdKey, mocks.DoraNonAdminUser) | ||
req = req.WithContext(ctx) | ||
Expect(err).NotTo(HaveOccurred()) | ||
rr := httptest.NewRecorder() | ||
|
||
By("calling the GetNamespacesHandler") | ||
testApp.GetNamespacesHandler(rr, req, nil) | ||
rs := rr.Result() | ||
defer rs.Body.Close() | ||
body, err := io.ReadAll(rs.Body) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
By("unmarshalling the response") | ||
var actual NamespacesEnvelope | ||
err = json.Unmarshal(body, &actual) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(rr.Code).To(Equal(http.StatusOK)) | ||
|
||
By("validating the response contains only dora-namespace") | ||
expected := []models.NamespaceModel{{Name: "dora-namespace"}} | ||
Expect(actual.Data).To(ConsistOf(expected)) | ||
}) | ||
|
||
It("should return all namespaces for [email protected]", func() { | ||
By("creating the HTTP request with the kubeflow-userid header") | ||
req, err := http.NewRequest(http.MethodGet, NamespaceListPath, nil) | ||
ctx := context.WithValue(req.Context(), KubeflowUserIdKey, mocks.KubeflowUserIDHeaderValue) | ||
req = req.WithContext(ctx) | ||
Expect(err).NotTo(HaveOccurred()) | ||
req.Header.Set("kubeflow-userid", "[email protected]") | ||
rr := httptest.NewRecorder() | ||
|
||
By("calling the GetNamespacesHandler") | ||
testApp.GetNamespacesHandler(rr, req, nil) | ||
rs := rr.Result() | ||
defer rs.Body.Close() | ||
body, err := io.ReadAll(rs.Body) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
By("unmarshalling the response") | ||
var actual NamespacesEnvelope | ||
err = json.Unmarshal(body, &actual) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(rr.Code).To(Equal(http.StatusOK)) | ||
|
||
By("validating the response contains all namespaces") | ||
expected := []models.NamespaceModel{ | ||
{Name: "kubeflow"}, | ||
{Name: "dora-namespace"}, | ||
} | ||
Expect(actual.Data).To(ContainElements(expected)) | ||
}) | ||
|
||
It("should return no namespaces for non-existent user", func() { | ||
By("creating the HTTP request with a non-existent kubeflow-userid") | ||
req, err := http.NewRequest(http.MethodGet, NamespaceListPath, nil) | ||
ctx := context.WithValue(req.Context(), KubeflowUserIdKey, "[email protected]") | ||
req = req.WithContext(ctx) | ||
Expect(err).NotTo(HaveOccurred()) | ||
rr := httptest.NewRecorder() | ||
|
||
By("calling the GetNamespacesHandler") | ||
testApp.GetNamespacesHandler(rr, req, nil) | ||
rs := rr.Result() | ||
defer rs.Body.Close() | ||
body, err := io.ReadAll(rs.Body) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
By("unmarshalling the response") | ||
var actual NamespacesEnvelope | ||
err = json.Unmarshal(body, &actual) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(rr.Code).To(Equal(http.StatusOK)) | ||
|
||
By("validating the response contains no namespaces") | ||
Expect(actual.Data).To(BeEmpty()) | ||
}) | ||
}) | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.