diff --git a/.github/actions/devcontainer_run_command/action.yml b/.github/actions/devcontainer_run_command/action.yml index e72c285d19..e36fd92aee 100644 --- a/.github/actions/devcontainer_run_command/action.yml +++ b/.github/actions/devcontainer_run_command/action.yml @@ -51,6 +51,9 @@ inputs: TRE_ADDRESS_SPACE: description: "TRE address apace." required: false + ENABLE_SWAGGER: + description: "Determines whether the Swagger interface for the API will be available." + required: false SWAGGER_UI_CLIENT_ID: description: "The Swagger UI Client ID." required: false @@ -154,6 +157,7 @@ runs: -e TF_VAR_application_admin_client_id="${{ inputs.APPLICATION_ADMIN_CLIENT_ID }}" \ -e TF_VAR_application_admin_client_secret="${{ inputs.APPLICATION_ADMIN_CLIENT_SECRET }}" \ -e TF_VAR_arm_subscription_id="${{ fromJSON(inputs.AZURE_CREDENTIALS).subscriptionId }}" \ + -e ENABLE_SWAGGER="${{ inputs.ENABLE_SWAGGER }}" \ -e SWAGGER_UI_CLIENT_ID="${{ inputs.SWAGGER_UI_CLIENT_ID }}" \ -e TF_VAR_swagger_ui_client_id="${{ inputs.SWAGGER_UI_CLIENT_ID }}" \ -e TF_VAR_core_address_space="${{ inputs.core_address_space }}" \ diff --git a/.github/workflows/deploy_tre.yml b/.github/workflows/deploy_tre.yml index 9e93d6955d..dfbb69f5cc 100644 --- a/.github/workflows/deploy_tre.yml +++ b/.github/workflows/deploy_tre.yml @@ -54,6 +54,7 @@ jobs: TEST_ACCOUNT_CLIENT_SECRET: "${{ secrets.TEST_ACCOUNT_CLIENT_SECRET }}" TERRAFORM_STATE_CONTAINER_NAME: ${{ secrets.TERRAFORM_STATE_CONTAINER_NAMEs }} TRE_ADDRESS_SPACE: ${{ secrets.TRE_ADDRESS_SPACE }} + ENABLE_SWAGGER: ${{ secrets.ENABLE_SWAGGER }} TRE_ID: ${{ secrets.TRE_ID }} CI_CACHE_ACR_NAME: ${{ secrets.ACR_NAME }} CORE_APP_SERVICE_PLAN_SKU: ${{ secrets.CORE_APP_SERVICE_PLAN_SKU }} diff --git a/.github/workflows/deploy_tre_branch.yml b/.github/workflows/deploy_tre_branch.yml index 4108b9979a..2cbf1cafd6 100644 --- a/.github/workflows/deploy_tre_branch.yml +++ b/.github/workflows/deploy_tre_branch.yml @@ -80,6 +80,7 @@ jobs: TEST_ACCOUNT_CLIENT_SECRET: "${{ secrets.TEST_ACCOUNT_CLIENT_SECRET }}" TERRAFORM_STATE_CONTAINER_NAME: ${{ secrets.TERRAFORM_STATE_CONTAINER_NAME }} TRE_ADDRESS_SPACE: ${{ secrets.TRE_ADDRESS_SPACE }} + ENABLE_SWAGGER: ${{ secrets.ENABLE_SWAGGER }} TRE_ID: ${{ format('tre{0}', needs.prepare-not-main.outputs.refid) }} CI_CACHE_ACR_NAME: ${{ secrets.ACR_NAME }} TF_LOG: ${{ secrets.TF_LOG }} diff --git a/.github/workflows/deploy_tre_reusable.yml b/.github/workflows/deploy_tre_reusable.yml index cf702afe31..efc1c149cb 100644 --- a/.github/workflows/deploy_tre_reusable.yml +++ b/.github/workflows/deploy_tre_reusable.yml @@ -88,6 +88,9 @@ on: # yamllint disable-line rule:truthy TRE_ADDRESS_SPACE: description: "" required: true + ENABLE_SWAGGER: + description: "" + required: false TRE_ID: description: "" required: true @@ -292,6 +295,7 @@ jobs: MGMT_STORAGE_ACCOUNT_NAME: ${{ secrets.MGMT_STORAGE_ACCOUNT_NAME }} CORE_ADDRESS_SPACE: ${{ secrets.CORE_ADDRESS_SPACE }} TRE_ADDRESS_SPACE: ${{ secrets.TRE_ADDRESS_SPACE }} + ENABLE_SWAGGER: ${{ secrets.ENABLE_SWAGGER }} SWAGGER_UI_CLIENT_ID: "${{ secrets.SWAGGER_UI_CLIENT_ID }}" API_CLIENT_SECRET: "${{ secrets.API_CLIENT_SECRET }}" APPLICATION_ADMIN_CLIENT_ID: "${{ secrets.APPLICATION_ADMIN_CLIENT_ID }}" diff --git a/.github/workflows/pr_comment_bot.yml b/.github/workflows/pr_comment_bot.yml index 571de510cc..2de9158595 100644 --- a/.github/workflows/pr_comment_bot.yml +++ b/.github/workflows/pr_comment_bot.yml @@ -172,6 +172,7 @@ jobs: TEST_ACCOUNT_CLIENT_SECRET: "${{ secrets.TEST_ACCOUNT_CLIENT_SECRET }}" TERRAFORM_STATE_CONTAINER_NAME: ${{ secrets.TERRAFORM_STATE_CONTAINER_NAME }} TRE_ADDRESS_SPACE: ${{ secrets.TRE_ADDRESS_SPACE }} + ENABLE_SWAGGER: ${{ secrets.ENABLE_SWAGGER }} TRE_ID: ${{ format('tre{0}', needs.pr_comment.outputs.prRefId) }} CI_CACHE_ACR_NAME: ${{ secrets.ACR_NAME }} TF_LOG: ${{ secrets.TF_LOG }} diff --git a/CHANGELOG.md b/CHANGELOG.md index a00f4b0dc6..39a5119fa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ ENHANCEMENTS: * Support updating the firewall when installing via makefile/CICD ([#2942](https://github.com/microsoft/AzureTRE/pull/2942)) * Add the ability for workspace services to request addional address spaces from a workspace ([#2902](https://github.com/microsoft/AzureTRE/pull/2902)) * Airlock processor function and api app service work with http2 +* Added the option to disable Swagger ([#2981](https://github.com/microsoft/AzureTRE/pull/2981)) BUG FIXES: diff --git a/api_app/api/routes/api.py b/api_app/api/routes/api.py index 56619a3d39..5cf104f976 100644 --- a/api_app/api/routes/api.py +++ b/api_app/api/routes/api.py @@ -1,7 +1,7 @@ from collections import defaultdict from typing import Any, DefaultDict, Dict, Optional -from fastapi import APIRouter, Request, Depends +from fastapi import APIRouter, Request, Depends, HTTPException, status from fastapi.openapi.docs import get_swagger_ui_html, get_swagger_ui_oauth2_redirect_html from fastapi.openapi.utils import get_openapi @@ -10,6 +10,7 @@ from api.routes import health, ping, workspaces, workspace_templates, workspace_service_templates, user_resource_templates, \ shared_services, shared_service_templates, migrations, costs, airlock, operations, metadata from core import config +from resources import strings core_tags_metadata = [ {"name": "health", "description": "Verify that the TRE is up and running"}, @@ -50,6 +51,7 @@ core_router.include_router(costs.costs_workspace_router, tags=["costs"]) core_swagger_router = APIRouter() +swagger_disabled_router = APIRouter() openapi_definitions: DefaultDict[str, Optional[Dict[str, Any]]] = defaultdict(lambda: None) @@ -70,6 +72,11 @@ async def core_openapi(request: Request): return openapi_definitions["core"] +@core_swagger_router.get('/docs/oauth2-redirect', include_in_schema=False) +async def swagger_ui_redirect(): + return get_swagger_ui_oauth2_redirect_html() + + @core_swagger_router.get("/docs", include_in_schema=False, name="core_swagger") async def get_swagger(request: Request): swagger_ui_html = get_swagger_ui_html( @@ -86,12 +93,10 @@ async def get_swagger(request: Request): return swagger_ui_html -@core_swagger_router.get('/docs/oauth2-redirect', include_in_schema=False) -async def swagger_ui_redirect(): - return get_swagger_ui_oauth2_redirect_html() +@swagger_disabled_router.get("/docs", include_in_schema=False, name="swagger_disabled") +async def get_disabled_swagger(): + raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=strings.SWAGGER_DISABLED) -core_router.include_router(core_swagger_router) -router.include_router(core_router) # Workspace API workspace_router = APIRouter(prefix=config.API_PREFIX) @@ -102,6 +107,7 @@ async def swagger_ui_redirect(): workspace_router.include_router(airlock.airlock_workspace_router, tags=["airlock"]) workspace_swagger_router = APIRouter() +workspace_swagger_disabled_router = APIRouter() def get_scope(workspace) -> str: @@ -157,5 +163,18 @@ async def get_workspace_swagger(workspace_id, request: Request, workspace_repo=D return swagger_ui_html -workspace_router.include_router(workspace_swagger_router) + +@workspace_swagger_disabled_router.get("/workspaces/{workspace_id}/docs", include_in_schema=False, name="workspace_swagger_disabled") +async def get_disabled_workspace_swagger(): + raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=strings.SWAGGER_DISABLED) + + +if config.ENABLE_SWAGGER: + core_router.include_router(core_swagger_router) + workspace_router.include_router(workspace_swagger_router) +else: + core_router.include_router(swagger_disabled_router) + workspace_router.include_router(workspace_swagger_disabled_router) + +router.include_router(core_router) router.include_router(workspace_router) diff --git a/api_app/core/config.py b/api_app/core/config.py index dbc9e12596..cc926e2eac 100644 --- a/api_app/core/config.py +++ b/api_app/core/config.py @@ -8,6 +8,7 @@ PROJECT_NAME: str = config("PROJECT_NAME", default="Azure TRE API") DEBUG: bool = config("DEBUG", cast=bool, default=False) ENABLE_LOCAL_DEBUGGING: bool = config("ENABLE_LOCAL_DEBUGGING", cast=bool, default=False) +ENABLE_SWAGGER: bool = config("ENABLE_SWAGGER", cast=bool, default=False) VERSION = __version__ API_DESCRIPTION = "Welcome to the Azure TRE API - for more information about templates and workspaces see the [Azure TRE documentation](https://microsoft.github.io/AzureTRE)" diff --git a/api_app/resources/strings.py b/api_app/resources/strings.py index 716abfed2f..ac33e845bb 100644 --- a/api_app/resources/strings.py +++ b/api_app/resources/strings.py @@ -148,6 +148,7 @@ SHARED_SERVICE_TEMPLATE_VERSION_EXISTS = "A template with this version already exists" ETAG_CONFLICT = "This document has been modified by another user or process since you last retrieved it. Please get the document again and retry." +SWAGGER_DISABLED = "Swagger is disabled. Set 'ENABLE_SWAGGER' to true in order to access Swagger." # Resource Status RESOURCE_STATUS_AWAITING_DEPLOYMENT = "awaiting_deployment" diff --git a/config.sample.yaml b/config.sample.yaml index 1bd0cea004..9be23f169d 100644 --- a/config.sample.yaml +++ b/config.sample.yaml @@ -30,6 +30,7 @@ tre: core_app_service_plan_sku: P1v2 resource_processor_vmss_sku: Standard_B2s + enable_swagger: true enable_airlock_malware_scanning: false # TODO: move to RP default with https://github.com/microsoft/AzureTRE/issues/2948 diff --git a/config_schema.json b/config_schema.json index 982c281560..078965e78c 100644 --- a/config_schema.json +++ b/config_schema.json @@ -76,6 +76,10 @@ "tre_address_space": { "description": "TRE address spaces.", "type": "string" + }, + "enable_swagger": { + "description": "Determines whether the Swagger interface for the API will be available.", + "type": "boolean" } } }, diff --git a/docs/tre-admins/environment-variables.md b/docs/tre-admins/environment-variables.md index ead29defda..cbe881d621 100644 --- a/docs/tre-admins/environment-variables.md +++ b/docs/tre-admins/environment-variables.md @@ -25,6 +25,7 @@ | `TRE_URL`| This will be generated for you by populating your `TRE_ID`. This is used so that you can automatically register bundles | | `CORE_ADDRESS_SPACE` | The address space for the Azure TRE core virtual network. `/22` or larger. | | `TRE_ADDRESS_SPACE` | The address space for the whole TRE environment virtual network where workspaces networks will be created (can include the core network as well). E.g. `10.0.0.0/12`| +| `ENABLE_SWAGGER` | Determines whether the Swagger interface for the API will be available. | | `SWAGGER_UI_CLIENT_ID` | Generated when following [pre-deployment steps](./setup-instructions/setup-auth-entities.md) guide. Client ID for swagger client to make requests. | | `AAD_TENANT_ID` | Generated when following [pre-deployment steps](./setup-instructions/setup-auth-entities.md) guide. Tenant id against which auth is performed. | | `API_CLIENT_ID` | Generated when following [pre-deployment steps](./setup-instructions/setup-auth-entities.md) guide. Client id of the "TRE API". | diff --git a/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md b/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md index 6804809b93..3b8ebf9098 100644 --- a/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md +++ b/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md @@ -73,6 +73,7 @@ Configure the following secrets in your github environment - | `CORE_APP_SERVICE_PLAN_SKU` | Optional. The SKU used for AppService plan for core infrastructure. Default value is `P1v2`. | | `WORKSPACE_APP_SERVICE_PLAN_SKU` | Optional. The SKU used for AppService plan used in E2E tests. Default value is `P1v2`. | | `RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE` | Optional. The number of processes to instantiate when the Resource Processor starts. Equates to the number of parallel deployment operations possible in your TRE. Defaults to `5`. | +| `ENABLE_SWAGGER` | Optional. Determines whether the Swagger interface for the API will be available. Default value is `false`. | ### Configure Authentication Secrets diff --git a/docs/tre-admins/setup-instructions/workflows.md b/docs/tre-admins/setup-instructions/workflows.md index 7882e1266f..492581b294 100644 --- a/docs/tre-admins/setup-instructions/workflows.md +++ b/docs/tre-admins/setup-instructions/workflows.md @@ -131,6 +131,7 @@ Configure additional repository secrets used in the deployment workflow | `TERRAFORM_STATE_CONTAINER_NAME` | Optional. The name of the blob container to hold the Terraform state. Default value is `tfstate`. | | `CORE_APP_SERVICE_PLAN_SKU` | Optional. The SKU used for AppService plan for core infrastructure. Default value is `P1v2`. | | `WORKSPACE_APP_SERVICE_PLAN_SKU` | Optional. The SKU used for AppService plan used in E2E tests. Default value is `P1v2`. | +| `ENABLE_SWAGGER` | Optional. Determines whether the Swagger interface for the API will be available. Default value is `false`. | ### Deploy the TRE using the workflow diff --git a/templates/core/terraform/api-webapp.tf b/templates/core/terraform/api-webapp.tf index 467b5f5349..75483c7529 100644 --- a/templates/core/terraform/api-webapp.tf +++ b/templates/core/terraform/api-webapp.tf @@ -44,6 +44,7 @@ resource "azurerm_linux_web_app" "api" { "MANAGED_IDENTITY_CLIENT_ID" = azurerm_user_assigned_identity.id.client_id "TRE_ID" = var.tre_id "RESOURCE_LOCATION" = azurerm_resource_group.core.location + "ENABLE_SWAGGER" = var.enable_swagger "SWAGGER_UI_CLIENT_ID" = var.swagger_ui_client_id "AAD_TENANT_ID" = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.auth_tenant_id.id})" "API_CLIENT_ID" = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.api_client_id.id})" diff --git a/templates/core/terraform/variables.tf b/templates/core/terraform/variables.tf index ae0e1bdb6b..66f6c429eb 100644 --- a/templates/core/terraform/variables.tf +++ b/templates/core/terraform/variables.tf @@ -65,6 +65,13 @@ variable "resource_processor_number_processes_per_instance" { description = "The number of CPU processes to run the RP on per VM instance" } +variable "enable_swagger" { + type = bool + default = false + description = "Determines whether the Swagger interface for the API will be available." + sensitive = false +} + variable "swagger_ui_client_id" { type = string description = "The client id (app id) of the registration in Azure AD for the Swagger UI" diff --git a/templates/core/version.txt b/templates/core/version.txt index 4980fecc88..50becf4230 100644 --- a/templates/core/version.txt +++ b/templates/core/version.txt @@ -1 +1 @@ -__version__ = "0.4.48" +__version__ = "0.4.49"