From c9fa4de50770e942adebaaab091bbd5b7453a08e Mon Sep 17 00:00:00 2001 From: lucferbux Date: Fri, 20 Dec 2024 00:47:52 +0100 Subject: [PATCH] Wrap up kubeflow deployment --- clients/ui/.env.development | 3 ++ clients/ui/.env.production | 1 + clients/ui/Makefile | 2 +- clients/ui/bff/Makefile | 3 +- clients/ui/bff/cmd/main.go | 1 + clients/ui/bff/internal/api/app.go | 7 ++-- clients/ui/bff/internal/config/environment.go | 11 +++--- clients/ui/frontend/Dockerfile | 2 +- clients/ui/frontend/src/app/App.tsx | 11 +++++- clients/ui/frontend/src/app/NavBar.tsx | 30 ++++++++++---- .../ui/frontend/src/shared/api/apiUtils.ts | 7 +++- clients/ui/frontend/src/shared/api/k8s.ts | 14 ++++++- .../frontend/src/shared/hooks/useSettings.tsx | 39 ++++++++++++++----- clients/ui/frontend/src/shared/types.ts | 4 ++ .../ui/frontend/src/shared/utilities/const.ts | 11 +++++- .../ui/manifests/kubeflow/kustomization.yaml | 16 ++++++++ .../model-registry-bff-deployment.yaml | 4 ++ .../model-registry-ui-deployment.yaml | 9 +++++ .../kubeflow-dashboard-rbac.yaml | 0 .../manifests/standalone/kustomization.yaml | 19 +++++++++ .../model-registry-bff-deployment.yaml | 4 ++ .../model-registry-ui-deployment.yaml | 9 +++++ .../ui/manifests/user-rbac/admin-rbac.yaml | 18 --------- .../ui/manifests/user-rbac/kustomization.yaml | 6 --- 24 files changed, 173 insertions(+), 58 deletions(-) create mode 100644 clients/ui/.env.development create mode 100644 clients/ui/.env.production create mode 100644 clients/ui/manifests/kubeflow/kustomization.yaml create mode 100644 clients/ui/manifests/kubeflow/model-registry-bff-deployment.yaml create mode 100644 clients/ui/manifests/kubeflow/model-registry-ui-deployment.yaml rename clients/ui/manifests/{user-rbac => standalone}/kubeflow-dashboard-rbac.yaml (100%) create mode 100644 clients/ui/manifests/standalone/kustomization.yaml create mode 100644 clients/ui/manifests/standalone/model-registry-bff-deployment.yaml create mode 100644 clients/ui/manifests/standalone/model-registry-ui-deployment.yaml delete mode 100644 clients/ui/manifests/user-rbac/admin-rbac.yaml delete mode 100644 clients/ui/manifests/user-rbac/kustomization.yaml diff --git a/clients/ui/.env.development b/clients/ui/.env.development new file mode 100644 index 00000000..7d7cc8e8 --- /dev/null +++ b/clients/ui/.env.development @@ -0,0 +1,3 @@ +APP_ENV=development +MOCK_AUTH=true +DEPLOYMENT_MODE=standalone \ No newline at end of file diff --git a/clients/ui/.env.production b/clients/ui/.env.production new file mode 100644 index 00000000..a904f4a9 --- /dev/null +++ b/clients/ui/.env.production @@ -0,0 +1 @@ +APP_ENV=production diff --git a/clients/ui/Makefile b/clients/ui/Makefile index 648d578c..cf3dbc4d 100644 --- a/clients/ui/Makefile +++ b/clients/ui/Makefile @@ -32,7 +32,7 @@ dev-install-dependencies: .PHONY: dev-bff dev-bff: - cd bff && make run PORT=4000 MOCK_K8S_CLIENT=true MOCK_MR_CLIENT=true + cd bff && make run PORT=4000 MOCK_K8S_CLIENT=true MOCK_MR_CLIENT=true DEV_MODE=true STANDALONE_MODE=true .PHONY: dev-frontend dev-frontend: diff --git a/clients/ui/bff/Makefile b/clients/ui/bff/Makefile index 103d914d..98707718 100644 --- a/clients/ui/bff/Makefile +++ b/clients/ui/bff/Makefile @@ -5,6 +5,7 @@ MOCK_K8S_CLIENT ?= false MOCK_MR_CLIENT ?= false DEV_MODE ?= false DEV_MODE_PORT ?= 8080 +STANDALONE_MODE ?= true # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.29.0 @@ -47,7 +48,7 @@ build: fmt vet test ## Builds the project to produce a binary executable. .PHONY: run run: fmt vet envtest ## Runs the project. ENVTEST_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" \ - go run ./cmd/main.go --port=$(PORT) --mock-k8s-client=$(MOCK_K8S_CLIENT) --mock-mr-client=$(MOCK_MR_CLIENT) --dev-mode=$(DEV_MODE) --dev-mode-port=$(DEV_MODE_PORT) + go run ./cmd/main.go --port=$(PORT) --mock-k8s-client=$(MOCK_K8S_CLIENT) --mock-mr-client=$(MOCK_MR_CLIENT) --dev-mode=$(DEV_MODE) --dev-mode-port=$(DEV_MODE_PORT) --standalone-mode=$(STANDALONE_MODE) .PHONY: docker-build docker-build: ## Builds a container for the project. diff --git a/clients/ui/bff/cmd/main.go b/clients/ui/bff/cmd/main.go index eb719229..5ed0979d 100644 --- a/clients/ui/bff/cmd/main.go +++ b/clients/ui/bff/cmd/main.go @@ -24,6 +24,7 @@ func main() { flag.BoolVar(&cfg.MockMRClient, "mock-mr-client", false, "Use mock Model Registry client") flag.BoolVar(&cfg.DevMode, "dev-mode", false, "Use development mode for access to local K8s cluster") flag.IntVar(&cfg.DevModePort, "dev-mode-port", getEnvAsInt("DEV_MODE_PORT", 8080), "Use port when in development mode") + flag.BoolVar(&cfg.StandaloneMode, "standalone-mode", false, "Use standalone mode for enabling endpoints in standalone mode") flag.Parse() logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) diff --git a/clients/ui/bff/internal/api/app.go b/clients/ui/bff/internal/api/app.go index 52425e67..08a32076 100644 --- a/clients/ui/bff/internal/api/app.go +++ b/clients/ui/bff/internal/api/app.go @@ -3,11 +3,12 @@ package api import ( "context" "fmt" + "log/slog" + "net/http" + "github.com/kubeflow/model-registry/ui/bff/internal/config" "github.com/kubeflow/model-registry/ui/bff/internal/integrations" "github.com/kubeflow/model-registry/ui/bff/internal/repositories" - "log/slog" - "net/http" "github.com/julienschmidt/httprouter" "github.com/kubeflow/model-registry/ui/bff/internal/mocks" @@ -110,7 +111,7 @@ func (app *App) Routes() http.Handler { router.GET(UserPath, app.UserHandler) // Perform SAR to Get List Services by Namspace router.GET(ModelRegistryListPath, app.AttachNamespace(app.PerformSARonGetListServicesByNamespace(app.ModelRegistryHandler))) - if app.config.DevMode { + if app.config.StandaloneMode { router.GET(NamespaceListPath, app.AttachNamespace(app.GetNamespacesHandler)) } diff --git a/clients/ui/bff/internal/config/environment.go b/clients/ui/bff/internal/config/environment.go index f63dcce8..7b905e12 100644 --- a/clients/ui/bff/internal/config/environment.go +++ b/clients/ui/bff/internal/config/environment.go @@ -1,9 +1,10 @@ package config type EnvConfig struct { - Port int - MockK8Client bool - MockMRClient bool - DevMode bool - DevModePort int + Port int + MockK8Client bool + MockMRClient bool + DevMode bool + StandaloneMode bool + DevModePort int } diff --git a/clients/ui/frontend/Dockerfile b/clients/ui/frontend/Dockerfile index c25a2b1c..448f724b 100644 --- a/clients/ui/frontend/Dockerfile +++ b/clients/ui/frontend/Dockerfile @@ -6,7 +6,7 @@ COPY . /usr/src/app RUN npm cache clean --force RUN npm ci --omit=optional -RUN npm run build +RUN npm run build:prod FROM nginxinc/nginx-unprivileged diff --git a/clients/ui/frontend/src/app/App.tsx b/clients/ui/frontend/src/app/App.tsx index 66fc6967..d6256a45 100644 --- a/clients/ui/frontend/src/app/App.tsx +++ b/clients/ui/frontend/src/app/App.tsx @@ -13,7 +13,7 @@ import { } from '@patternfly/react-core'; import ToastNotifications from '~/shared/components/ToastNotifications'; import { useSettings } from '~/shared/hooks/useSettings'; -import { isMUITheme, Theme, AUTH_HEADER, DEV_MODE } from '~/shared/utilities/const'; +import { isMUITheme, Theme, AUTH_HEADER, MOCK_AUTH } from '~/shared/utilities/const'; import { logout } from '~/shared/utilities/appUtils'; import NavSidebar from './NavSidebar'; import AppRoutes from './AppRoutes'; @@ -25,11 +25,17 @@ const App: React.FC = () => { const { configSettings, userSettings, + namespaceSettings, loaded: configLoaded, loadError: configError, } = useSettings(); const username = userSettings?.userId; + const options = + namespaceSettings?.map((namespace) => ({ + content: namespace.name, + value: namespace.name, + })) || []; React.useEffect(() => { // Apply the theme based on the value of STYLE_THEME @@ -41,7 +47,7 @@ const App: React.FC = () => { }, []); React.useEffect(() => { - if (DEV_MODE && username) { + if (MOCK_AUTH && username) { localStorage.setItem(AUTH_HEADER, username); } else { localStorage.removeItem(AUTH_HEADER); @@ -103,6 +109,7 @@ const App: React.FC = () => { onLogout={() => { logout().then(() => window.location.reload()); }} + options={options} /> } isManagedSidebar diff --git a/clients/ui/frontend/src/app/NavBar.tsx b/clients/ui/frontend/src/app/NavBar.tsx index 62876c85..dc9a219c 100644 --- a/clients/ui/frontend/src/app/NavBar.tsx +++ b/clients/ui/frontend/src/app/NavBar.tsx @@ -13,24 +13,34 @@ import { ToolbarGroup, ToolbarItem, } from '@patternfly/react-core'; +import { useNavigate } from 'react-router-dom'; import { SimpleSelect, SimpleSelectOption } from '@patternfly/react-templates'; +import { useDeepCompareMemoize } from '~/shared/utilities/useDeepCompareMemoize'; interface NavBarProps { username?: string; onLogout: () => void; + options: SimpleSelectOption[]; + onNamespaceSelect?: (namespace: string) => void; } -const Options: SimpleSelectOption[] = [{ content: 'All Namespaces', value: 'All' }]; - -const NavBar: React.FC = ({ username, onLogout }) => { - const [selected, setSelected] = React.useState('All'); +const NavBar: React.FC = ({ username, onLogout, options, onNamespaceSelect }) => { + const [selected, setSelected] = React.useState(String(options[0]?.value)); const [userMenuOpen, setUserMenuOpen] = React.useState(false); + const optionsMemo = useDeepCompareMemoize(options); + const navigate = useNavigate(); const initialOptions = React.useMemo( - () => Options.map((o) => ({ ...o, selected: o.value === selected })), - [selected], + () => optionsMemo.map((o) => ({ ...o, selected: o.value === selected })), + [selected, optionsMemo], ); + React.useEffect(() => { + if (selected) { + navigate(`?namespace=${selected}`); + } + }, [selected, navigate]); + const handleLogout = () => { setUserMenuOpen(false); onLogout(); @@ -51,9 +61,13 @@ const NavBar: React.FC = ({ username, onLogout }) => { setSelected(String(selection))} + onSelect={(_ev, selection) => { + setSelected(String(selection)); + if (onNamespaceSelect) { + onNamespaceSelect(String(selection)); + } + }} /> diff --git a/clients/ui/frontend/src/shared/api/apiUtils.ts b/clients/ui/frontend/src/shared/api/apiUtils.ts index 01d03161..71037585 100644 --- a/clients/ui/frontend/src/shared/api/apiUtils.ts +++ b/clients/ui/frontend/src/shared/api/apiUtils.ts @@ -1,7 +1,7 @@ import { APIOptions } from '~/shared/api/types'; import { EitherOrNone } from '~/shared/typeHelpers'; import { ModelRegistryBody } from '~/app/types'; -import { DEV_MODE, AUTH_HEADER } from '~/shared/utilities/const'; +import { AUTH_HEADER, MOCK_AUTH } from '~/shared/utilities/const'; export const mergeRequestInit = ( opts: APIOptions = {}, @@ -65,11 +65,14 @@ const callRestJSON = ( requestData = JSON.stringify(data); } + // Workaround if we wanna force in a call to add the AUTH_HEADER + const authHeader = Object.keys(otherOptions.headers || {}).some((key) => key === AUTH_HEADER); + return fetch(`${host}${path}${searchParams ? `?${searchParams}` : ''}`, { ...otherOptions, headers: { ...otherOptions.headers, - ...(DEV_MODE && { [AUTH_HEADER]: localStorage.getItem(AUTH_HEADER) }), + ...(MOCK_AUTH && !authHeader && { [AUTH_HEADER]: localStorage.getItem(AUTH_HEADER) }), ...(contentType && { 'Content-Type': contentType }), }, method, diff --git a/clients/ui/frontend/src/shared/api/k8s.ts b/clients/ui/frontend/src/shared/api/k8s.ts index 6c483eae..468baf46 100644 --- a/clients/ui/frontend/src/shared/api/k8s.ts +++ b/clients/ui/frontend/src/shared/api/k8s.ts @@ -3,7 +3,7 @@ import { handleRestFailures } from '~/shared/api/errorUtils'; import { isModelRegistryResponse, restGET } from '~/shared/api/apiUtils'; import { ModelRegistry } from '~/app/types'; import { BFF_API_VERSION } from '~/app/const'; -import { UserSettings } from '~/shared/types'; +import { Namespace, UserSettings } from '~/shared/types'; export const getListModelRegistries = (hostPath: string) => @@ -28,3 +28,15 @@ export const getUser = throw new Error('Invalid response format'); }, ); + +export const getNamespaces = + (hostPath: string) => + (opts: APIOptions): Promise => + handleRestFailures(restGET(hostPath, `/api/${BFF_API_VERSION}/namespaces`, {}, opts)).then( + (response) => { + if (isModelRegistryResponse(response)) { + return response.data; + } + throw new Error('Invalid response format'); + }, + ); diff --git a/clients/ui/frontend/src/shared/hooks/useSettings.tsx b/clients/ui/frontend/src/shared/hooks/useSettings.tsx index d81488c6..20a59421 100644 --- a/clients/ui/frontend/src/shared/hooks/useSettings.tsx +++ b/clients/ui/frontend/src/shared/hooks/useSettings.tsx @@ -1,35 +1,49 @@ import * as React from 'react'; -import { USERNAME, POLL_INTERVAL, AUTH_HEADER, DEV_MODE } from '~/shared/utilities/const'; +import { + USERNAME, + POLL_INTERVAL, + AUTH_HEADER, + MOCK_AUTH, + isStandalone, +} from '~/shared/utilities/const'; import { useDeepCompareMemoize } from '~/shared/utilities/useDeepCompareMemoize'; -import { ConfigSettings, UserSettings } from '~/shared/types'; +import { ConfigSettings, Namespace, UserSettings } from '~/shared/types'; import useTimeBasedRefresh from '~/shared/hooks/useTimeBasedRefresh'; -import { getUser } from '~/shared/api/k8s'; +import { getNamespaces, getUser } from '~/shared/api/k8s'; export const useSettings = (): { configSettings: ConfigSettings | null; userSettings: UserSettings | null; + namespaceSettings: Namespace[] | null; loaded: boolean; loadError: Error | undefined; } => { const [loaded, setLoaded] = React.useState(false); const [loadError, setLoadError] = React.useState(); const [config, setConfig] = React.useState(null); + const [namespaces, setNamespaces] = React.useState(null); const [user, setUser] = React.useState(null); - const userSettings = React.useMemo(() => getUser(''), []); + const userRest = React.useMemo(() => getUser(''), []); + const namespaceRest = React.useMemo(() => getNamespaces(''), []); const setRefreshMarker = useTimeBasedRefresh(); React.useEffect(() => { let watchHandle: ReturnType; let cancelled = false; const watchConfig = () => { - const headers = DEV_MODE ? { [AUTH_HEADER]: USERNAME } : undefined; - Promise.all([fetchConfig(), userSettings({ headers })]) - .then(([fetchedConfig, fetchedUser]) => { + const headers = MOCK_AUTH ? { [AUTH_HEADER]: USERNAME } : undefined; + Promise.all([ + fetchConfig(), + userRest({ headers }), + ...(isStandalone() ? [namespaceRest({ headers })] : []), + ]) + .then(([fetchedConfig, fetchedUser, fetchNamespace]) => { if (cancelled) { return; } setConfig(fetchedConfig); setUser(fetchedUser); + setNamespaces(fetchNamespace); setLoaded(true); setLoadError(undefined); }) @@ -56,12 +70,19 @@ export const useSettings = (): { cancelled = true; clearTimeout(watchHandle); }; - }, [setRefreshMarker, userSettings]); + }, [setRefreshMarker, userRest, namespaceRest]); const retConfig = useDeepCompareMemoize(config); const retUser = useDeepCompareMemoize(user); + const retNamespace = useDeepCompareMemoize(namespaces); - return { configSettings: retConfig, userSettings: retUser, loaded, loadError }; + return { + configSettings: retConfig, + userSettings: retUser, + namespaceSettings: retNamespace, + loaded, + loadError, + }; }; // Mock a settings config call diff --git a/clients/ui/frontend/src/shared/types.ts b/clients/ui/frontend/src/shared/types.ts index 31658843..14aabb0b 100644 --- a/clients/ui/frontend/src/shared/types.ts +++ b/clients/ui/frontend/src/shared/types.ts @@ -13,6 +13,10 @@ export type CommonConfig = { featureFlags: FeatureFlag; }; +export type Namespace = { + name: string; +}; + export type FeatureFlag = { modelRegistry: boolean; }; diff --git a/clients/ui/frontend/src/shared/utilities/const.ts b/clients/ui/frontend/src/shared/utilities/const.ts index 5fcb7e79..eef4905f 100644 --- a/clients/ui/frontend/src/shared/utilities/const.ts +++ b/clients/ui/frontend/src/shared/utilities/const.ts @@ -4,14 +4,23 @@ export enum Theme { // Future themes can be added here } +export enum DeploymentMode { + Standalone = 'standalone', + Integrated = 'integrated', +} + export const isMUITheme = (): boolean => STYLE_THEME === Theme.MUI; +export const isStandalone = (): boolean => DEPLOYMENT_MODE === DeploymentMode.Standalone; +export const isIntegrated = (): boolean => DEPLOYMENT_MODE === DeploymentMode.Integrated; const STYLE_THEME = process.env.STYLE_THEME || Theme.MUI; const DEV_MODE = process.env.APP_ENV === 'development'; +const MOCK_AUTH = process.env.MOCK_AUTH === 'true'; +const DEPLOYMENT_MODE = process.env.DEPLOYMENT_MODE || DeploymentMode.Integrated; const POLL_INTERVAL = process.env.POLL_INTERVAL ? parseInt(process.env.POLL_INTERVAL) : 30000; const AUTH_HEADER = process.env.AUTH_HEADER || 'kubeflow-userid'; const USERNAME = process.env.USERNAME || 'user@example.com'; const IMAGE_DIR = process.env.IMAGE_DIR || 'images'; const LOGO_LIGHT = process.env.LOGO || 'logo-light-theme.svg'; -export { POLL_INTERVAL, DEV_MODE, AUTH_HEADER, USERNAME, IMAGE_DIR, LOGO_LIGHT }; +export { POLL_INTERVAL, DEV_MODE, AUTH_HEADER, USERNAME, IMAGE_DIR, LOGO_LIGHT, MOCK_AUTH }; diff --git a/clients/ui/manifests/kubeflow/kustomization.yaml b/clients/ui/manifests/kubeflow/kustomization.yaml new file mode 100644 index 00000000..418e7642 --- /dev/null +++ b/clients/ui/manifests/kubeflow/kustomization.yaml @@ -0,0 +1,16 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +patchesJson6902: + - path: model-registry-ui-deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: model-registry-ui-deployment + - path: deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: model-registry-bff-deployment \ No newline at end of file diff --git a/clients/ui/manifests/kubeflow/model-registry-bff-deployment.yaml b/clients/ui/manifests/kubeflow/model-registry-bff-deployment.yaml new file mode 100644 index 00000000..b7216756 --- /dev/null +++ b/clients/ui/manifests/kubeflow/model-registry-bff-deployment.yaml @@ -0,0 +1,4 @@ +- op: add + path: /spec/template/spec/containers/0/args + value: + - "--standalone-mode=false" diff --git a/clients/ui/manifests/kubeflow/model-registry-ui-deployment.yaml b/clients/ui/manifests/kubeflow/model-registry-ui-deployment.yaml new file mode 100644 index 00000000..1959e4bb --- /dev/null +++ b/clients/ui/manifests/kubeflow/model-registry-ui-deployment.yaml @@ -0,0 +1,9 @@ +- op: add + path: /spec/template/spec/containers/0/env + value: + - name: API_URL + value: "http://model-registry-bff-service:4000" + - name: MOCK_AUTH + value: "false" + - name: DEPLOYMENT_MODE + value: "integrated" \ No newline at end of file diff --git a/clients/ui/manifests/user-rbac/kubeflow-dashboard-rbac.yaml b/clients/ui/manifests/standalone/kubeflow-dashboard-rbac.yaml similarity index 100% rename from clients/ui/manifests/user-rbac/kubeflow-dashboard-rbac.yaml rename to clients/ui/manifests/standalone/kubeflow-dashboard-rbac.yaml diff --git a/clients/ui/manifests/standalone/kustomization.yaml b/clients/ui/manifests/standalone/kustomization.yaml new file mode 100644 index 00000000..fda80e7d --- /dev/null +++ b/clients/ui/manifests/standalone/kustomization.yaml @@ -0,0 +1,19 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - kubeflow-dashboard-rbac.yaml + +patchesJson6902: + - path: model-registry-ui-deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: model-registry-bff-deployment + - path: deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: model-registry-bff-deployment \ No newline at end of file diff --git a/clients/ui/manifests/standalone/model-registry-bff-deployment.yaml b/clients/ui/manifests/standalone/model-registry-bff-deployment.yaml new file mode 100644 index 00000000..38b5569a --- /dev/null +++ b/clients/ui/manifests/standalone/model-registry-bff-deployment.yaml @@ -0,0 +1,4 @@ +- op: add + path: /spec/template/spec/containers/0/args + value: + - "--standalone-mode=true" diff --git a/clients/ui/manifests/standalone/model-registry-ui-deployment.yaml b/clients/ui/manifests/standalone/model-registry-ui-deployment.yaml new file mode 100644 index 00000000..5211d0b0 --- /dev/null +++ b/clients/ui/manifests/standalone/model-registry-ui-deployment.yaml @@ -0,0 +1,9 @@ +- op: add + path: /spec/template/spec/containers/0/env + value: + - name: API_URL + value: "http://model-registry-bff-service:4000" + - name: MOCK_AUTH + value: "true" + - name: DEPLOYMENT_MODE + value: "standalone" \ No newline at end of file diff --git a/clients/ui/manifests/user-rbac/admin-rbac.yaml b/clients/ui/manifests/user-rbac/admin-rbac.yaml deleted file mode 100644 index 592a58bf..00000000 --- a/clients/ui/manifests/user-rbac/admin-rbac.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: admin-user - namespace: kube-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: admin-user -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cluster-admin -subjects: - - kind: ServiceAccount - name: admin-user - namespace: kube-system \ No newline at end of file diff --git a/clients/ui/manifests/user-rbac/kustomization.yaml b/clients/ui/manifests/user-rbac/kustomization.yaml deleted file mode 100644 index 3e513a32..00000000 --- a/clients/ui/manifests/user-rbac/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - - admin-rbac.yaml - - kubeflow-dashboard-rbac.yaml \ No newline at end of file