diff --git a/.github/workflows/linting_bash_python_yaml_files.yaml b/.github/workflows/linting_bash_python_yaml_files.yaml index f64419ce..ccb96859 100644 --- a/.github/workflows/linting_bash_python_yaml_files.yaml +++ b/.github/workflows/linting_bash_python_yaml_files.yaml @@ -131,7 +131,7 @@ jobs: fi - name: Display changed files - if: always() # Always run this step + if: always() # Always run this step run: cat changed_files_in_PR.txt || echo "No bash files have changed in this PR." - name: Run ShellCheck on changed files diff --git a/.github/workflows/oci-release.yml b/.github/workflows/oci-release.yml index f5b6549d..24886ef5 100644 --- a/.github/workflows/oci-release.yml +++ b/.github/workflows/oci-release.yml @@ -4,12 +4,12 @@ on: push: # Publish `master` as `latest` OCI image. branches: - - master - - v* + - master + - v* # Publish `v1.2.3` tags as releases. tags: - - v* + - v* # Run tests for any PRs. pull_request: @@ -22,11 +22,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Run tests - run: | - make docker-build + - name: Run tests + run: | + make docker-build push: needs: test @@ -38,46 +38,46 @@ jobs: contents: read steps: - - name: Check out code - uses: actions/checkout@v4 + - name: Check out code + uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: amd64,ppc64le,arm64 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: amd64,ppc64le,arm64 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - - name: Log into GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + - name: Log into GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata (tags, labels) for OCI image - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/${{ github.repository }} - tags: | - type=schedule - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=sha - # Add 'latest' tag for master branch pushes - type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }} + - name: Extract metadata (tags, labels) for OCI image + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=sha + # Add 'latest' tag for master branch pushes + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }} - - name: Build and push multi-architecture OCI image - uses: docker/build-push-action@v5 - with: - context: . - file: ./Dockerfile - platforms: ${{ env.PLATFORMS }} - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max + - name: Build and push multi-architecture OCI image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + platforms: ${{ env.PLATFORMS }} + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 87a49432..6208ff02 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -7,7 +7,7 @@ name: Mark stale issues and pull requests on: schedule: - - cron: '0 0 * * *' # Run every day at midnight + - cron: '0 0 * * *' # Run every day at midnight workflow_dispatch: jobs: diff --git a/.github/workflows/test-node.yaml b/.github/workflows/test-node.yaml index 29beea62..c403f676 100644 --- a/.github/workflows/test-node.yaml +++ b/.github/workflows/test-node.yaml @@ -2,103 +2,103 @@ name: Frontend Test on: pull_request: paths: - - frontend/** + - frontend/** jobs: frontend-format-linting-check: name: Code format and lint runs-on: ubuntu-latest steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: frontend/package-lock.json - - name: Format code - run: | - npm install prettier@2.8.8 --prefix ./frontend - make prettier-check - - name: Lint code - run: | - cd frontend - npm ci --no-audit - npm run lint-check + - name: Check out code + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + - name: Format code + run: | + npm install prettier@2.8.8 --prefix ./frontend + make prettier-check + - name: Lint code + run: | + cd frontend + npm ci --no-audit + npm run lint-check frontend-unit-tests: - name: Frontend Unit Tests - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: frontend/package-lock.json - - name: Fetch Kubeflow and Build Common Library - run: | - COMMIT=$(cat frontend/COMMIT) - cd /tmp && git clone https://github.com/kubeflow/kubeflow.git - cd kubeflow - git checkout $COMMIT - cd components/crud-web-apps/common/frontend/kubeflow-common-lib - npm ci --no-audit - npm run build - npm link ./dist/kubeflow - - name: Install Frontend Dependencies and Setup Styles - run: | - cd frontend - npm ci --no-audit - npm link kubeflow - # Copy styles from kubeflow source to local styles directory - mkdir -p ./src/styles/ - cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/styles/* ./src/styles/ - # Also copy to node_modules for the copyCSS script - mkdir -p ./node_modules/kubeflow/styles/ - cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/styles/* ./node_modules/kubeflow/styles/ - - name: Run Unit Tests - run: | - cd frontend - npm run test:jest + name: Frontend Unit Tests + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + - name: Fetch Kubeflow and Build Common Library + run: | + COMMIT=$(cat frontend/COMMIT) + cd /tmp && git clone https://github.com/kubeflow/kubeflow.git + cd kubeflow + git checkout $COMMIT + cd components/crud-web-apps/common/frontend/kubeflow-common-lib + npm ci --no-audit + npm run build + npm link ./dist/kubeflow + - name: Install Frontend Dependencies and Setup Styles + run: | + cd frontend + npm ci --no-audit + npm link kubeflow + # Copy styles from kubeflow source to local styles directory + mkdir -p ./src/styles/ + cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/styles/* ./src/styles/ + # Also copy to node_modules for the copyCSS script + mkdir -p ./node_modules/kubeflow/styles/ + cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/styles/* ./node_modules/kubeflow/styles/ + - name: Run Unit Tests + run: | + cd frontend + npm run test:jest frontend-mock-tests: - name: Frontend Mock Tests - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: frontend/package-lock.json - - name: Fetch Kubeflow and Build Common Library - run: | - COMMIT=$(cat frontend/COMMIT) - cd /tmp && git clone https://github.com/kubeflow/kubeflow.git - cd kubeflow - git checkout $COMMIT - cd components/crud-web-apps/common/frontend/kubeflow-common-lib - npm ci --no-audit - npm run build - npm link ./dist/kubeflow - - name: Install Frontend Dependencies and Setup Styles - run: | - cd frontend - npm ci --no-audit - npm link kubeflow - # Copy styles from kubeflow source to local styles directory - mkdir -p ./src/styles/ - cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/styles/* ./src/styles/ - # Also copy to node_modules for the copyCSS script - mkdir -p ./node_modules/kubeflow/styles/ - cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/styles/* ./node_modules/kubeflow/styles/ - # Copy assets as well - mkdir -p ./node_modules/kubeflow/assets/ - cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/assets/* ./node_modules/kubeflow/assets/ - - name: Run E2E Tests - run: | - cd frontend - npm run e2e:cypress:ci + name: Frontend Mock Tests + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + - name: Fetch Kubeflow and Build Common Library + run: | + COMMIT=$(cat frontend/COMMIT) + cd /tmp && git clone https://github.com/kubeflow/kubeflow.git + cd kubeflow + git checkout $COMMIT + cd components/crud-web-apps/common/frontend/kubeflow-common-lib + npm ci --no-audit + npm run build + npm link ./dist/kubeflow + - name: Install Frontend Dependencies and Setup Styles + run: | + cd frontend + npm ci --no-audit + npm link kubeflow + # Copy styles from kubeflow source to local styles directory + mkdir -p ./src/styles/ + cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/styles/* ./src/styles/ + # Also copy to node_modules for the copyCSS script + mkdir -p ./node_modules/kubeflow/styles/ + cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/styles/* ./node_modules/kubeflow/styles/ + # Copy assets as well + mkdir -p ./node_modules/kubeflow/assets/ + cp -r /tmp/kubeflow/components/crud-web-apps/common/frontend/kubeflow-common-lib/projects/kubeflow/src/assets/* ./node_modules/kubeflow/assets/ + - name: Run E2E Tests + run: | + cd frontend + npm run e2e:cypress:ci diff --git a/README.md b/README.md index e2b6fa0e..2a83fe25 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,30 @@ The following is a list of environment variables that can be set for any web app | GRAFANA_PREFIX | /grafana | Controls the Grafana endpoint prefix for metrics dashboards | | GRAFANA_CPU_MEMORY_DB | db/knative-serving-revision-cpu-and-memory-usage | Grafana dashboard name for CPU and memory metrics | | GRAFANA_HTTP_REQUESTS_DB | db/knative-serving-revision-http-requests | Grafana dashboard name for HTTP request metrics | +| ALLOWED_NAMESPACES | "" | Comma-separated list of namespaces to show in the namespace selector. If only one namespace is specified, it will be auto-selected and the dropdown will be hidden. Empty means all namespaces are shown. | + +## Namespace Configuration + +The application supports configuring which namespaces are available in the namespace selector. This is particularly useful for standalone deployments where you want to limit access to specific namespaces. + +### Environment Variable +Set the `ALLOWED_NAMESPACES` environment variable with a comma-separated list of namespaces: + +```bash +# Single namespace (auto-selected, dropdown hidden) +ALLOWED_NAMESPACES="kubeflow-user" + +# Multiple namespaces (dropdown shows only these) +ALLOWED_NAMESPACES="kubeflow,kubeflow-user,production" +``` + +### Behavior +- **No configuration**: All namespaces are shown (default behavior) +- **Single namespace**: Namespace is auto-selected and dropdown is hidden +- **Multiple namespaces**: Dropdown shows only the specified namespaces +- **Error handling**: Falls back to all namespaces if specified ones don't exist + +For detailed configuration options and examples, see [CONFIGURABLE_NAMESPACES.md](./CONFIGURABLE_NAMESPACES.md). ## Grafana Configuration diff --git a/backend/apps/v1beta1/routes/get.py b/backend/apps/v1beta1/routes/get.py index ed294bf1..b603d8e9 100644 --- a/backend/apps/v1beta1/routes/get.py +++ b/backend/apps/v1beta1/routes/get.py @@ -30,3 +30,40 @@ def get_config(): except Exception as e: log.error("Error retrieving configuration: %s", str(e)) return api.error_response("message", "Failed to retrieve configuration"), 500 + + +@bp.route("/api/namespaces", methods=["GET"]) +def get_namespaces(): + """Handle retrieval of allowed namespaces based on ALLOWED_NAMESPACES env var.""" + try: + allowed_namespaces_env = os.environ.get("ALLOWED_NAMESPACES", "") + + if allowed_namespaces_env: + + allowed_list = [ + ns.strip() for ns in allowed_namespaces_env.split(",") if ns.strip() + ] + log.info( + "Filtering namespaces based on ALLOWED_NAMESPACES: %s", allowed_list + ) + all_namespaces = api.list_namespaces() + existing_namespaces = [ns.metadata.name for ns in all_namespaces.items] + filtered_namespaces = [ + ns for ns in allowed_list if ns in existing_namespaces + ] + + if not filtered_namespaces: + log.warning("None of the allowed namespaces exist: %s", allowed_list) + response_namespaces = existing_namespaces + else: + response_namespaces = filtered_namespaces + else: + log.info("No ALLOWED_NAMESPACES specified, returning all namespaces") + all_namespaces = api.list_namespaces() + response_namespaces = [ns.metadata.name for ns in all_namespaces.items] + + log.info("Returning namespaces: %s", response_namespaces) + return api.success_response("namespaces", response_namespaces) + except Exception as e: + log.error("Error retrieving namespaces: %s", str(e)) + return api.error_response("message", "Failed to retrieve namespaces"), 500 diff --git a/frontend/src/app/pages/index/index.component.html b/frontend/src/app/pages/index/index.component.html index 0c564e27..7bb0e054 100644 --- a/frontend/src/app/pages/index/index.component.html +++ b/frontend/src/app/pages/index/index.component.html @@ -1,8 +1,9 @@