diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go index f2114e466b..042a8cfc30 100644 --- a/cmd/dashboard/main.go +++ b/cmd/dashboard/main.go @@ -34,12 +34,13 @@ var ( kubeConfigPath = flag.String("kube-config", "", "Path to kube config file") portNumber = flag.Int("port", 8080, "Dashboard port number") readOnly = flag.Bool("read-only", true, "Enable or disable read-only mode") - logoutURL = flag.String("logout-url", "", "If set, enables logout on the frontend and binds the logout button to this url") + logoutURL = flag.String("logout-url", "", "If set, enables logout on the frontend and binds the logout button to this URL") + defaultNamespace = flag.String("default-namespace", "", "If set, configures the default selected namespace to the provided namespace instead of All Namespaces") tenantNamespaces = flag.String("namespaces", "", "If set, limits the scope of resources displayed to this comma-separated list of namespaces only") logLevel = flag.String("log-level", "info", "Minimum log level output by the logger") logFormat = flag.String("log-format", "json", "Format for log output (json or console)") streamLogs = flag.Bool("stream-logs", true, "Enable log streaming instead of polling") - externalLogs = flag.String("external-logs", "", "External logs provider url") + externalLogs = flag.String("external-logs", "", "External logs provider URL") xFrameOptions = flag.String("x-frame-options", "DENY", "Value for the X-Frame-Options response header, set '' to omit it") ) @@ -91,6 +92,7 @@ func main() { PipelinesNamespace: *pipelinesNamespace, TriggersNamespace: *triggersNamespace, TenantNamespaces: tenants, + DefaultNamespace: *defaultNamespace, ReadOnly: *readOnly, LogoutURL: *logoutURL, StreamLogs: *streamLogs, diff --git a/docs/dev/README.md b/docs/dev/README.md index 3359ec50b7..c6ba8d7972 100644 --- a/docs/dev/README.md +++ b/docs/dev/README.md @@ -103,7 +103,8 @@ These options are documented below: | `--triggers-namespace` | Namespace where Tekton triggers is installed (assumes same namespace as dashboard if not set) | `string` | `""` | | `--port` | Dashboard port number | `int` | `8080` | | `--read-only` | Enable or disable read-only mode | `bool` | `true` | -| `--logout-url` | If set, enables logout on the frontend and binds the logout button to this url | `string` | `""` | +| `--logout-url` | If set, enables logout on the frontend and binds the logout button to this URL | `string` | `""` | +| `--default-namespace` | If set, configures the default selected namespace to the provided namespace instead of All Namespaces | `string` | `""` | | `--namespaces` | If set, limits the scope of resources displayed to this comma-separated list of namespaces only | `string` | `""` | | `--log-level` | Minimum log level output by the logger | `string` | `"info"` | | `--log-format` | Format for log output (json or console) | `string` | `"json"` | diff --git a/overlays/patches/installer/deployment-patch.yaml b/overlays/patches/installer/deployment-patch.yaml index 92fdda19f0..067b17fcd6 100644 --- a/overlays/patches/installer/deployment-patch.yaml +++ b/overlays/patches/installer/deployment-patch.yaml @@ -37,6 +37,10 @@ path: /spec/template/spec/containers/0/args/- value: --log-format=--log-format +- op: add + path: /spec/template/spec/containers/0/args/- + value: + --default-namespace=--default-namespace - op: add path: /spec/template/spec/containers/0/args/- value: diff --git a/pkg/endpoints/cluster.go b/pkg/endpoints/cluster.go index 7da46be838..3864dc00cb 100644 --- a/pkg/endpoints/cluster.go +++ b/pkg/endpoints/cluster.go @@ -24,13 +24,14 @@ import ( type Properties struct { DashboardNamespace string `json:"dashboardNamespace"` DashboardVersion string `json:"dashboardVersion"` + DefaultNamespace string `json:"defaultNamespace,omitempty"` ExternalLogsURL string `json:"externalLogsURL"` LogoutURL string `json:"logoutURL,omitempty"` PipelineNamespace string `json:"pipelinesNamespace"` PipelineVersion string `json:"pipelinesVersion"` ReadOnly bool `json:"isReadOnly"` StreamLogs bool `json:"streamLogs"` - TenantNamespaces []string `json:"tenantNamespaces,omitEmpty"` + TenantNamespaces []string `json:"tenantNamespaces,omitempty"` TriggersNamespace string `json:"triggersNamespace,omitempty"` TriggersVersion string `json:"triggersVersion,omitempty"` } @@ -47,6 +48,7 @@ func (r Resource) GetProperties(response http.ResponseWriter, _ *http.Request) { properties := Properties{ DashboardNamespace: r.Options.InstallNamespace, DashboardVersion: dashboardVersion, + DefaultNamespace: r.Options.DefaultNamespace, PipelineNamespace: pipelineNamespace, PipelineVersion: pipelineVersion, ReadOnly: r.Options.ReadOnly, diff --git a/pkg/endpoints/types.go b/pkg/endpoints/types.go index 40ffbc8ba8..6a6d0bcf35 100644 --- a/pkg/endpoints/types.go +++ b/pkg/endpoints/types.go @@ -24,6 +24,7 @@ type Options struct { PipelinesNamespace string TriggersNamespace string TenantNamespaces []string + DefaultNamespace string ReadOnly bool LogoutURL string StreamLogs bool diff --git a/scripts/installer b/scripts/installer index 360d174e8f..c55c62d4df 100755 --- a/scripts/installer +++ b/scripts/installer @@ -23,6 +23,7 @@ EXTENSIONS_RBAC="false" LOGOUT_URL="" LOG_LEVEL="info" LOG_FORMAT="json" +DEFAULT_NAMESPACE="" TENANT_NAMESPACES="" STREAM_LOGS="true" EXTERNAL_LOGS="" @@ -172,6 +173,7 @@ patch() { replace "--log-format=--log-format" "--log-format=$LOG_FORMAT" replace "--logout-url=--logout-url" "--logout-url=$LOGOUT_URL" replace "--read-only=--read-only" "--read-only=$READONLY" + replace "--default-namespace=--default-namespace" "--default-namespace=$DEFAULT_NAMESPACE" replace "--namespaces=--tenant-namespaces" "--namespaces=$TENANT_NAMESPACES" replace "--stream-logs=--stream-logs" "--stream-logs=$STREAM_LOGS" replace "--external-logs=--external-logs" "--external-logs=$EXTERNAL_LOGS" @@ -503,6 +505,10 @@ while [[ $# -gt 0 ]]; do shift OVERRIDE_TRIGGERS_NAMESPACE="${1}" ;; + '--default-namespace') + shift + DEFAULT_NAMESPACE="${1}" + ;; '--tenant-namespaces') shift TENANT_NAMESPACES="${1}" diff --git a/src/api/index.js b/src/api/index.js index a6b72c6f40..3275c8303b 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -340,3 +340,8 @@ export function useTenantNamespaces() { const { data } = useProperties(); return data.tenantNamespaces || []; } + +export function useDefaultNamespace() { + const { data } = useProperties(); + return data.defaultNamespace; +} diff --git a/src/api/index.test.js b/src/api/index.test.js index 820f754eba..ec6a87926f 100644 --- a/src/api/index.test.js +++ b/src/api/index.test.js @@ -601,3 +601,26 @@ it('useTenantNamespaces', async () => { ); expect(tenantNamespacesResult.current).toEqual(tenantNamespaces); }); + +it('useDefaultNamespace', async () => { + const queryClient = getQueryClient(); + + const defaultNamespace = 'fake_defaultNamespace'; + + const properties = { defaultNamespace }; + server.use(http.get(/\/properties$/, () => HttpResponse.json(properties))); + const { result, waitFor } = renderHook(() => API.useProperties(), { + wrapper: getAPIWrapper({ queryClient }) + }); + await waitFor(() => result.current.isFetching); + await waitFor(() => !result.current.isFetching); + expect(result.current.data).toEqual(properties); + + const { result: defaultNamespacesResult } = renderHook( + () => API.useDefaultNamespace(), + { + wrapper: getAPIWrapper({ queryClient }) + } + ); + expect(defaultNamespacesResult.current).toEqual(defaultNamespace); +}); diff --git a/src/containers/App/App.jsx b/src/containers/App/App.jsx index a675eda450..e7681e33b7 100644 --- a/src/containers/App/App.jsx +++ b/src/containers/App/App.jsx @@ -78,6 +78,7 @@ import { import { NamespaceContext, + useDefaultNamespace, useExtensions, useLogoutURL, useNamespaces, @@ -145,6 +146,7 @@ export function App({ lang }) { } = useProperties(); const logoutURL = useLogoutURL(); const tenantNamespaces = useTenantNamespaces(); + const defaultNamespace = useDefaultNamespace(); const [isSideNavExpanded, setIsSideNavExpanded] = useState(true); const [selectedNamespace, setSelectedNamespace] = useState( @@ -210,6 +212,13 @@ export function App({ lang }) { ); + function HandleDefaultNamespace() { + if (defaultNamespace) { + setTimeout(() => setSelectedNamespace(defaultNamespace), 0); + } + return null; + } + return ( - + <> + + +