diff --git a/.github/workflows/ui-checks.yaml b/.github/workflows/ui-checks.yaml index 95f473a3e1..cfa50db128 100644 --- a/.github/workflows/ui-checks.yaml +++ b/.github/workflows/ui-checks.yaml @@ -20,7 +20,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - uses: pnpm/action-setup@v2 name: Install pnpm id: pnpm-install diff --git a/deepfence_frontend/apps/dashboard/api-spec.json b/deepfence_frontend/apps/dashboard/api-spec.json index 2cb7c93eab..6afa7a51dc 100644 --- a/deepfence_frontend/apps/dashboard/api-spec.json +++ b/deepfence_frontend/apps/dashboard/api-spec.json @@ -477,7 +477,7 @@ "security": [{ "bearer_token": [] }] } }, - "/deepfence/graph/topology": { + "/deepfence/graph/topology/": { "post": { "tags": ["Topology"], "summary": "Get Topology Graph", @@ -529,6 +529,214 @@ "security": [{ "bearer_token": [] }] } }, + "/deepfence/graph/topology/containers": { + "post": { + "tags": ["Topology"], + "summary": "Get Containers Topology Graph", + "description": "Retrieve the full topology graph associated with the account from Containers", + "operationId": "getContainersTopologyGraph", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ReportersTopologyFilters" } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsGraphResult" } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsBadRequestResponse" } + } + } + }, + "401": { "description": "Unauthorized" }, + "403": { "description": "Forbidden" }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + } + }, + "security": [{ "bearer_token": [] }] + } + }, + "/deepfence/graph/topology/hosts": { + "post": { + "tags": ["Topology"], + "summary": "Get Hosts Topology Graph", + "description": "Retrieve the full topology graph associated with the account from Hosts", + "operationId": "getHostsTopologyGraph", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ReportersTopologyFilters" } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsGraphResult" } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsBadRequestResponse" } + } + } + }, + "401": { "description": "Unauthorized" }, + "403": { "description": "Forbidden" }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + } + }, + "security": [{ "bearer_token": [] }] + } + }, + "/deepfence/graph/topology/kubernetes": { + "post": { + "tags": ["Topology"], + "summary": "Get Kubernetes Topology Graph", + "description": "Retrieve the full topology graph associated with the account from Kubernetes", + "operationId": "getKubernetesTopologyGraph", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ReportersTopologyFilters" } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsGraphResult" } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsBadRequestResponse" } + } + } + }, + "401": { "description": "Unauthorized" }, + "403": { "description": "Forbidden" }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + } + }, + "security": [{ "bearer_token": [] }] + } + }, + "/deepfence/graph/topology/pods": { + "post": { + "tags": ["Topology"], + "summary": "Get Pods Topology Graph", + "description": "Retrieve the full topology graph associated with the account from Pods", + "operationId": "getPodsTopologyGraph", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ReportersTopologyFilters" } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsGraphResult" } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsBadRequestResponse" } + } + } + }, + "401": { "description": "Unauthorized" }, + "403": { "description": "Forbidden" }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + } + }, + "security": [{ "bearer_token": [] }] + } + }, "/deepfence/ingest/cloud-compliance": { "post": { "tags": ["Cloud Compliance"], @@ -870,7 +1078,7 @@ }, "/deepfence/lookup/containers": { "post": { - "tags": ["Topology"], + "tags": ["Lookup"], "summary": "Retrieve Containers data", "description": "Retrieve all the data associated with containers", "operationId": "getContainers", @@ -925,7 +1133,7 @@ }, "/deepfence/lookup/hosts": { "post": { - "tags": ["Topology"], + "tags": ["Lookup"], "summary": "Retrieve Hosts data", "description": "Retrieve all the data associated with hosts", "operationId": "getHosts", @@ -980,7 +1188,7 @@ }, "/deepfence/lookup/processes": { "post": { - "tags": ["Topology"], + "tags": ["Lookup"], "summary": "Retrieve Processes data", "description": "Retrieve all the data associated with processes", "operationId": "getProcesses", @@ -2956,20 +3164,34 @@ "type": { "type": "string" } } }, + "ReportersContainsFilter": { + "required": ["filter_in"], + "type": "object", + "properties": { + "filter_in": { + "type": "object", + "additionalProperties": { "type": "array", "items": {} }, + "nullable": true + } + } + }, + "ReportersFieldsFilters": { + "required": ["contains_filter"], + "type": "object", + "properties": { + "contains_filter": { "$ref": "#/components/schemas/ReportersContainsFilter" } + } + }, "ReportersLookupFilter": { "required": ["in_field_filter", "node_ids"], "type": "object", "properties": { "in_field_filter": { - "type": "object", - "additionalProperties": { "type": "object" }, + "type": "array", + "items": { "type": "string" }, "nullable": true }, - "node_ids": { - "type": "object", - "additionalProperties": { "type": "object" }, - "nullable": true - } + "node_ids": { "type": "array", "items": { "type": "string" }, "nullable": true } } }, "ReportersNodeInfo": { @@ -3062,7 +3284,8 @@ "region_filter", "kubernetes_filter", "host_filter", - "pod_filter" + "pod_filter", + "field_filters" ], "type": "object", "properties": { @@ -3071,6 +3294,7 @@ "items": { "type": "string" }, "nullable": true }, + "field_filters": { "$ref": "#/components/schemas/ReportersFieldsFilters" }, "host_filter": { "type": "array", "items": { "type": "string" }, diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/.openapi-generator/FILES b/deepfence_frontend/apps/dashboard/src/api/generated/.openapi-generator/FILES index f7376a04ad..d9462c62f4 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/.openapi-generator/FILES +++ b/deepfence_frontend/apps/dashboard/src/api/generated/.openapi-generator/FILES @@ -5,6 +5,7 @@ apis/CloudResourcesApi.ts apis/ComplianceApi.ts apis/ControlsApi.ts apis/DiagnosisApi.ts +apis/LookupApi.ts apis/MalwareScanApi.ts apis/SecretScanApi.ts apis/ThreatApi.ts @@ -58,6 +59,8 @@ models/ReportColumn.ts models/ReportMetadataRow.ts models/ReportRow.ts models/ReportTable.ts +models/ReportersContainsFilter.ts +models/ReportersFieldsFilters.ts models/ReportersLookupFilter.ts models/ReportersNodeInfo.ts models/ReportersProviderThreatGraph.ts diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/apis/LookupApi.ts b/deepfence_frontend/apps/dashboard/src/api/generated/apis/LookupApi.ts new file mode 100644 index 0000000000..713e929475 --- /dev/null +++ b/deepfence_frontend/apps/dashboard/src/api/generated/apis/LookupApi.ts @@ -0,0 +1,231 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Deepfence ThreatMapper + * Deepfence Runtime API provides programmatic control over Deepfence microservice securing your container, kubernetes and cloud deployments. The API abstracts away underlying infrastructure details like cloud provider, container distros, container orchestrator and type of deployment. This is one uniform API to manage and control security alerts, policies and response to alerts for microservices running anywhere i.e. managed pure greenfield container deployments or a mix of containers, VMs and serverless paradigms like AWS Fargate. + * + * The version of the OpenAPI document: 2.0.0 + * Contact: community@deepfence.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + ApiDocsBadRequestResponse, + ApiDocsFailureResponse, + ModelContainer, + ModelHost, + ModelProcess, + ReportersLookupFilter, +} from '../models'; +import { + ApiDocsBadRequestResponseFromJSON, + ApiDocsBadRequestResponseToJSON, + ApiDocsFailureResponseFromJSON, + ApiDocsFailureResponseToJSON, + ModelContainerFromJSON, + ModelContainerToJSON, + ModelHostFromJSON, + ModelHostToJSON, + ModelProcessFromJSON, + ModelProcessToJSON, + ReportersLookupFilterFromJSON, + ReportersLookupFilterToJSON, +} from '../models'; + +export interface GetContainersRequest { + reportersLookupFilter?: ReportersLookupFilter; +} + +export interface GetHostsRequest { + reportersLookupFilter?: ReportersLookupFilter; +} + +export interface GetProcessesRequest { + reportersLookupFilter?: ReportersLookupFilter; +} + +/** + * LookupApi - interface + * + * @export + * @interface LookupApiInterface + */ +export interface LookupApiInterface { + /** + * Retrieve all the data associated with containers + * @summary Retrieve Containers data + * @param {ReportersLookupFilter} [reportersLookupFilter] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof LookupApiInterface + */ + getContainersRaw(requestParameters: GetContainersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; + + /** + * Retrieve all the data associated with containers + * Retrieve Containers data + */ + getContainers(requestParameters: GetContainersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve all the data associated with hosts + * @summary Retrieve Hosts data + * @param {ReportersLookupFilter} [reportersLookupFilter] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof LookupApiInterface + */ + getHostsRaw(requestParameters: GetHostsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; + + /** + * Retrieve all the data associated with hosts + * Retrieve Hosts data + */ + getHosts(requestParameters: GetHostsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve all the data associated with processes + * @summary Retrieve Processes data + * @param {ReportersLookupFilter} [reportersLookupFilter] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof LookupApiInterface + */ + getProcessesRaw(requestParameters: GetProcessesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; + + /** + * Retrieve all the data associated with processes + * Retrieve Processes data + */ + getProcesses(requestParameters: GetProcessesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + +} + +/** + * + */ +export class LookupApi extends runtime.BaseAPI implements LookupApiInterface { + + /** + * Retrieve all the data associated with containers + * Retrieve Containers data + */ + async getContainersRaw(requestParameters: GetContainersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer_token", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/deepfence/lookup/containers`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ReportersLookupFilterToJSON(requestParameters.reportersLookupFilter), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(ModelContainerFromJSON)); + } + + /** + * Retrieve all the data associated with containers + * Retrieve Containers data + */ + async getContainers(requestParameters: GetContainersRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getContainersRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve all the data associated with hosts + * Retrieve Hosts data + */ + async getHostsRaw(requestParameters: GetHostsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer_token", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/deepfence/lookup/hosts`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ReportersLookupFilterToJSON(requestParameters.reportersLookupFilter), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(ModelHostFromJSON)); + } + + /** + * Retrieve all the data associated with hosts + * Retrieve Hosts data + */ + async getHosts(requestParameters: GetHostsRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getHostsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve all the data associated with processes + * Retrieve Processes data + */ + async getProcessesRaw(requestParameters: GetProcessesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer_token", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/deepfence/lookup/processes`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ReportersLookupFilterToJSON(requestParameters.reportersLookupFilter), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(ModelProcessFromJSON)); + } + + /** + * Retrieve all the data associated with processes + * Retrieve Processes data + */ + async getProcesses(requestParameters: GetProcessesRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getProcessesRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/apis/TopologyApi.ts b/deepfence_frontend/apps/dashboard/src/api/generated/apis/TopologyApi.ts index e67f3f03f5..b5f1cded7e 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/apis/TopologyApi.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/apis/TopologyApi.ts @@ -18,11 +18,7 @@ import type { ApiDocsBadRequestResponse, ApiDocsFailureResponse, ApiDocsGraphResult, - ModelContainer, - ModelHost, - ModelProcess, ModelRawReport, - ReportersLookupFilter, ReportersTopologyFilters, } from '../models'; import { @@ -32,30 +28,26 @@ import { ApiDocsFailureResponseToJSON, ApiDocsGraphResultFromJSON, ApiDocsGraphResultToJSON, - ModelContainerFromJSON, - ModelContainerToJSON, - ModelHostFromJSON, - ModelHostToJSON, - ModelProcessFromJSON, - ModelProcessToJSON, ModelRawReportFromJSON, ModelRawReportToJSON, - ReportersLookupFilterFromJSON, - ReportersLookupFilterToJSON, ReportersTopologyFiltersFromJSON, ReportersTopologyFiltersToJSON, } from '../models'; -export interface GetContainersRequest { - reportersLookupFilter?: ReportersLookupFilter; +export interface GetContainersTopologyGraphRequest { + reportersTopologyFilters?: ReportersTopologyFilters; } -export interface GetHostsRequest { - reportersLookupFilter?: ReportersLookupFilter; +export interface GetHostsTopologyGraphRequest { + reportersTopologyFilters?: ReportersTopologyFilters; } -export interface GetProcessesRequest { - reportersLookupFilter?: ReportersLookupFilter; +export interface GetKubernetesTopologyGraphRequest { + reportersTopologyFilters?: ReportersTopologyFilters; +} + +export interface GetPodsTopologyGraphRequest { + reportersTopologyFilters?: ReportersTopologyFilters; } export interface GetTopologyGraphRequest { @@ -74,52 +66,68 @@ export interface IngestAgentReportRequest { */ export interface TopologyApiInterface { /** - * Retrieve all the data associated with containers - * @summary Retrieve Containers data - * @param {ReportersLookupFilter} [reportersLookupFilter] + * Retrieve the full topology graph associated with the account from Containers + * @summary Get Containers Topology Graph + * @param {ReportersTopologyFilters} [reportersTopologyFilters] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TopologyApiInterface + */ + getContainersTopologyGraphRaw(requestParameters: GetContainersTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve the full topology graph associated with the account from Containers + * Get Containers Topology Graph + */ + getContainersTopologyGraph(requestParameters: GetContainersTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve the full topology graph associated with the account from Hosts + * @summary Get Hosts Topology Graph + * @param {ReportersTopologyFilters} [reportersTopologyFilters] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TopologyApiInterface */ - getContainersRaw(requestParameters: GetContainersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; + getHostsTopologyGraphRaw(requestParameters: GetHostsTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** - * Retrieve all the data associated with containers - * Retrieve Containers data + * Retrieve the full topology graph associated with the account from Hosts + * Get Hosts Topology Graph */ - getContainers(requestParameters: GetContainersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + getHostsTopologyGraph(requestParameters: GetHostsTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * Retrieve all the data associated with hosts - * @summary Retrieve Hosts data - * @param {ReportersLookupFilter} [reportersLookupFilter] + * Retrieve the full topology graph associated with the account from Kubernetes + * @summary Get Kubernetes Topology Graph + * @param {ReportersTopologyFilters} [reportersTopologyFilters] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TopologyApiInterface */ - getHostsRaw(requestParameters: GetHostsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; + getKubernetesTopologyGraphRaw(requestParameters: GetKubernetesTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** - * Retrieve all the data associated with hosts - * Retrieve Hosts data + * Retrieve the full topology graph associated with the account from Kubernetes + * Get Kubernetes Topology Graph */ - getHosts(requestParameters: GetHostsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + getKubernetesTopologyGraph(requestParameters: GetKubernetesTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * Retrieve all the data associated with processes - * @summary Retrieve Processes data - * @param {ReportersLookupFilter} [reportersLookupFilter] + * Retrieve the full topology graph associated with the account from Pods + * @summary Get Pods Topology Graph + * @param {ReportersTopologyFilters} [reportersTopologyFilters] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TopologyApiInterface */ - getProcessesRaw(requestParameters: GetProcessesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; + getPodsTopologyGraphRaw(requestParameters: GetPodsTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** - * Retrieve all the data associated with processes - * Retrieve Processes data + * Retrieve the full topology graph associated with the account from Pods + * Get Pods Topology Graph */ - getProcesses(requestParameters: GetProcessesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + getPodsTopologyGraph(requestParameters: GetPodsTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** * Retrieve the full topology graph associated with the account @@ -161,10 +169,49 @@ export interface TopologyApiInterface { export class TopologyApi extends runtime.BaseAPI implements TopologyApiInterface { /** - * Retrieve all the data associated with containers - * Retrieve Containers data + * Retrieve the full topology graph associated with the account from Containers + * Get Containers Topology Graph + */ + async getContainersTopologyGraphRaw(requestParameters: GetContainersTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer_token", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/deepfence/graph/topology/containers`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ReportersTopologyFiltersToJSON(requestParameters.reportersTopologyFilters), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ApiDocsGraphResultFromJSON(jsonValue)); + } + + /** + * Retrieve the full topology graph associated with the account from Containers + * Get Containers Topology Graph + */ + async getContainersTopologyGraph(requestParameters: GetContainersTopologyGraphRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getContainersTopologyGraphRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve the full topology graph associated with the account from Hosts + * Get Hosts Topology Graph */ - async getContainersRaw(requestParameters: GetContainersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + async getHostsTopologyGraphRaw(requestParameters: GetHostsTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -180,30 +227,30 @@ export class TopologyApi extends runtime.BaseAPI implements TopologyApiInterface } } const response = await this.request({ - path: `/deepfence/lookup/containers`, + path: `/deepfence/graph/topology/hosts`, method: 'POST', headers: headerParameters, query: queryParameters, - body: ReportersLookupFilterToJSON(requestParameters.reportersLookupFilter), + body: ReportersTopologyFiltersToJSON(requestParameters.reportersTopologyFilters), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(ModelContainerFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => ApiDocsGraphResultFromJSON(jsonValue)); } /** - * Retrieve all the data associated with containers - * Retrieve Containers data + * Retrieve the full topology graph associated with the account from Hosts + * Get Hosts Topology Graph */ - async getContainers(requestParameters: GetContainersRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.getContainersRaw(requestParameters, initOverrides); + async getHostsTopologyGraph(requestParameters: GetHostsTopologyGraphRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getHostsTopologyGraphRaw(requestParameters, initOverrides); return await response.value(); } /** - * Retrieve all the data associated with hosts - * Retrieve Hosts data + * Retrieve the full topology graph associated with the account from Kubernetes + * Get Kubernetes Topology Graph */ - async getHostsRaw(requestParameters: GetHostsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + async getKubernetesTopologyGraphRaw(requestParameters: GetKubernetesTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -219,30 +266,30 @@ export class TopologyApi extends runtime.BaseAPI implements TopologyApiInterface } } const response = await this.request({ - path: `/deepfence/lookup/hosts`, + path: `/deepfence/graph/topology/kubernetes`, method: 'POST', headers: headerParameters, query: queryParameters, - body: ReportersLookupFilterToJSON(requestParameters.reportersLookupFilter), + body: ReportersTopologyFiltersToJSON(requestParameters.reportersTopologyFilters), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(ModelHostFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => ApiDocsGraphResultFromJSON(jsonValue)); } /** - * Retrieve all the data associated with hosts - * Retrieve Hosts data + * Retrieve the full topology graph associated with the account from Kubernetes + * Get Kubernetes Topology Graph */ - async getHosts(requestParameters: GetHostsRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.getHostsRaw(requestParameters, initOverrides); + async getKubernetesTopologyGraph(requestParameters: GetKubernetesTopologyGraphRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getKubernetesTopologyGraphRaw(requestParameters, initOverrides); return await response.value(); } /** - * Retrieve all the data associated with processes - * Retrieve Processes data + * Retrieve the full topology graph associated with the account from Pods + * Get Pods Topology Graph */ - async getProcessesRaw(requestParameters: GetProcessesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + async getPodsTopologyGraphRaw(requestParameters: GetPodsTopologyGraphRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -258,22 +305,22 @@ export class TopologyApi extends runtime.BaseAPI implements TopologyApiInterface } } const response = await this.request({ - path: `/deepfence/lookup/processes`, + path: `/deepfence/graph/topology/pods`, method: 'POST', headers: headerParameters, query: queryParameters, - body: ReportersLookupFilterToJSON(requestParameters.reportersLookupFilter), + body: ReportersTopologyFiltersToJSON(requestParameters.reportersTopologyFilters), }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(ModelProcessFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => ApiDocsGraphResultFromJSON(jsonValue)); } /** - * Retrieve all the data associated with processes - * Retrieve Processes data + * Retrieve the full topology graph associated with the account from Pods + * Get Pods Topology Graph */ - async getProcesses(requestParameters: GetProcessesRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.getProcessesRaw(requestParameters, initOverrides); + async getPodsTopologyGraph(requestParameters: GetPodsTopologyGraphRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getPodsTopologyGraphRaw(requestParameters, initOverrides); return await response.value(); } @@ -297,7 +344,7 @@ export class TopologyApi extends runtime.BaseAPI implements TopologyApiInterface } } const response = await this.request({ - path: `/deepfence/graph/topology`, + path: `/deepfence/graph/topology/`, method: 'POST', headers: headerParameters, query: queryParameters, diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/apis/index.ts b/deepfence_frontend/apps/dashboard/src/api/generated/apis/index.ts index 6e3747b5df..da0d977131 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/apis/index.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/apis/index.ts @@ -6,6 +6,7 @@ export * from './CloudResourcesApi'; export * from './ComplianceApi'; export * from './ControlsApi'; export * from './DiagnosisApi'; +export * from './LookupApi'; export * from './MalwareScanApi'; export * from './SecretScanApi'; export * from './ThreatApi'; diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersContainsFilter.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersContainsFilter.ts new file mode 100644 index 0000000000..3f50b949da --- /dev/null +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersContainsFilter.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Deepfence ThreatMapper + * Deepfence Runtime API provides programmatic control over Deepfence microservice securing your container, kubernetes and cloud deployments. The API abstracts away underlying infrastructure details like cloud provider, container distros, container orchestrator and type of deployment. This is one uniform API to manage and control security alerts, policies and response to alerts for microservices running anywhere i.e. managed pure greenfield container deployments or a mix of containers, VMs and serverless paradigms like AWS Fargate. + * + * The version of the OpenAPI document: 2.0.0 + * Contact: community@deepfence.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ReportersContainsFilter + */ +export interface ReportersContainsFilter { + /** + * + * @type {{ [key: string]: Array; }} + * @memberof ReportersContainsFilter + */ + filter_in: { [key: string]: Array; } | null; +} + +/** + * Check if a given object implements the ReportersContainsFilter interface. + */ +export function instanceOfReportersContainsFilter(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "filter_in" in value; + + return isInstance; +} + +export function ReportersContainsFilterFromJSON(json: any): ReportersContainsFilter { + return ReportersContainsFilterFromJSONTyped(json, false); +} + +export function ReportersContainsFilterFromJSONTyped(json: any, ignoreDiscriminator: boolean): ReportersContainsFilter { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'filter_in': json['filter_in'], + }; +} + +export function ReportersContainsFilterToJSON(value?: ReportersContainsFilter | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'filter_in': value.filter_in, + }; +} + diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersFieldsFilters.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersFieldsFilters.ts new file mode 100644 index 0000000000..da1ce9f04e --- /dev/null +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersFieldsFilters.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Deepfence ThreatMapper + * Deepfence Runtime API provides programmatic control over Deepfence microservice securing your container, kubernetes and cloud deployments. The API abstracts away underlying infrastructure details like cloud provider, container distros, container orchestrator and type of deployment. This is one uniform API to manage and control security alerts, policies and response to alerts for microservices running anywhere i.e. managed pure greenfield container deployments or a mix of containers, VMs and serverless paradigms like AWS Fargate. + * + * The version of the OpenAPI document: 2.0.0 + * Contact: community@deepfence.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { ReportersContainsFilter } from './ReportersContainsFilter'; +import { + ReportersContainsFilterFromJSON, + ReportersContainsFilterFromJSONTyped, + ReportersContainsFilterToJSON, +} from './ReportersContainsFilter'; + +/** + * + * @export + * @interface ReportersFieldsFilters + */ +export interface ReportersFieldsFilters { + /** + * + * @type {ReportersContainsFilter} + * @memberof ReportersFieldsFilters + */ + contains_filter: ReportersContainsFilter; +} + +/** + * Check if a given object implements the ReportersFieldsFilters interface. + */ +export function instanceOfReportersFieldsFilters(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "contains_filter" in value; + + return isInstance; +} + +export function ReportersFieldsFiltersFromJSON(json: any): ReportersFieldsFilters { + return ReportersFieldsFiltersFromJSONTyped(json, false); +} + +export function ReportersFieldsFiltersFromJSONTyped(json: any, ignoreDiscriminator: boolean): ReportersFieldsFilters { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'contains_filter': ReportersContainsFilterFromJSON(json['contains_filter']), + }; +} + +export function ReportersFieldsFiltersToJSON(value?: ReportersFieldsFilters | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'contains_filter': ReportersContainsFilterToJSON(value.contains_filter), + }; +} + diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersLookupFilter.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersLookupFilter.ts index acdddde2a8..76c31691bc 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersLookupFilter.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersLookupFilter.ts @@ -21,16 +21,16 @@ import { exists, mapValues } from '../runtime'; export interface ReportersLookupFilter { /** * - * @type {{ [key: string]: object; }} + * @type {Array} * @memberof ReportersLookupFilter */ - in_field_filter: { [key: string]: object; } | null; + in_field_filter: Array | null; /** * - * @type {{ [key: string]: object; }} + * @type {Array} * @memberof ReportersLookupFilter */ - node_ids: { [key: string]: object; } | null; + node_ids: Array | null; } /** diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersTopologyFilters.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersTopologyFilters.ts index 9ac13f71ab..f932bd245f 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersTopologyFilters.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ReportersTopologyFilters.ts @@ -13,6 +13,13 @@ */ import { exists, mapValues } from '../runtime'; +import type { ReportersFieldsFilters } from './ReportersFieldsFilters'; +import { + ReportersFieldsFiltersFromJSON, + ReportersFieldsFiltersFromJSONTyped, + ReportersFieldsFiltersToJSON, +} from './ReportersFieldsFilters'; + /** * * @export @@ -25,6 +32,12 @@ export interface ReportersTopologyFilters { * @memberof ReportersTopologyFilters */ cloud_filter: Array | null; + /** + * + * @type {ReportersFieldsFilters} + * @memberof ReportersTopologyFilters + */ + field_filters: ReportersFieldsFilters; /** * * @type {Array} @@ -57,6 +70,7 @@ export interface ReportersTopologyFilters { export function instanceOfReportersTopologyFilters(value: object): boolean { let isInstance = true; isInstance = isInstance && "cloud_filter" in value; + isInstance = isInstance && "field_filters" in value; isInstance = isInstance && "host_filter" in value; isInstance = isInstance && "kubernetes_filter" in value; isInstance = isInstance && "pod_filter" in value; @@ -76,6 +90,7 @@ export function ReportersTopologyFiltersFromJSONTyped(json: any, ignoreDiscrimin return { 'cloud_filter': json['cloud_filter'], + 'field_filters': ReportersFieldsFiltersFromJSON(json['field_filters']), 'host_filter': json['host_filter'], 'kubernetes_filter': json['kubernetes_filter'], 'pod_filter': json['pod_filter'], @@ -93,6 +108,7 @@ export function ReportersTopologyFiltersToJSON(value?: ReportersTopologyFilters return { 'cloud_filter': value.cloud_filter, + 'field_filters': ReportersFieldsFiltersToJSON(value.field_filters), 'host_filter': value.host_filter, 'kubernetes_filter': value.kubernetes_filter, 'pod_filter': value.pod_filter, diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/index.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/index.ts index 78c8a00b0e..682df4241f 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/index.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/index.ts @@ -45,6 +45,8 @@ export * from './ReportColumn'; export * from './ReportMetadataRow'; export * from './ReportRow'; export * from './ReportTable'; +export * from './ReportersContainsFilter'; +export * from './ReportersFieldsFilters'; export * from './ReportersLookupFilter'; export * from './ReportersNodeInfo'; export * from './ReportersProviderThreatGraph'; diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/components/ConnectorHeader.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/components/ConnectorHeader.tsx index f1dc1b2264..7296b6c1cc 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/components/ConnectorHeader.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/components/ConnectorHeader.tsx @@ -10,20 +10,17 @@ type ConnectorHeaderProps = { const canRoute = (pathname: string) => { const path = { - addConnector: '', + addConnector: '/onboard/connectors/add-connectors', scanResult: '', viewResult: '', }; if (pathname.includes('view-scan-results')) { path.viewResult = '/onboard/view-scan-results'; path.scanResult = '/onboard/scan-infrastructure'; - path.addConnector = '/onboard/add-connectors'; } else if (pathname.includes('scan-infrastructure')) { path.scanResult = '/onboard/scan-infrastructure'; - path.addConnector = '/onboard/add-connectors'; path.viewResult = '#'; } else if (pathname.includes('connectors')) { - path.addConnector = '/onboard/add-connectors'; path.scanResult = '#'; path.viewResult = '#'; } @@ -34,7 +31,10 @@ export const ConnectorHeader = ({ title, description }: ConnectorHeaderProps) => const location = useLocation(); const isAddConnectorRoutePath = () => { - return location.pathname.includes('connectors'); + return ( + location.pathname.startsWith('/onboard/connectors') || + location.pathname.includes('/onboard/instructions') + ); }; const isScanRoutePath = () => { diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/AWSTerraform.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/AWSTerraform.tsx index f4029d7d26..dd150ec46a 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/AWSTerraform.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/AWSTerraform.tsx @@ -109,7 +109,7 @@ module "cloud-scanner_example_single-account-ecs" { color="primary" className="ml-auto" onClick={() => { - navigate('/onboard/my-connectors'); + navigate('/onboard/connectors/my-connectors'); }} > Go to connectors diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/AzureConnectorForm.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/AzureConnectorForm.tsx index 0731c2fa97..367b4b5fe2 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/AzureConnectorForm.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/AzureConnectorForm.tsx @@ -109,7 +109,7 @@ export const AzureConnectorForm = () => { color="primary" className="ml-auto" onClick={() => { - navigate('/onboard/my-connectors'); + navigate('/onboard/connectors/my-connectors'); }} > Go to connectors diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/GCPConnectorForm.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/GCPConnectorForm.tsx index caa32bdf4c..598d053bd2 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/GCPConnectorForm.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/clouds/GCPConnectorForm.tsx @@ -114,7 +114,7 @@ export const GCPConnectorForm = () => { color="primary" className="ml-auto" onClick={() => { - navigate('/onboard/my-connectors'); + navigate('/onboard/connectors/my-connectors'); }} > Go to connectors diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/DockerConnectorForm.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/DockerConnectorForm.tsx index 558bac57dc..82a4c78ff9 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/DockerConnectorForm.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/DockerConnectorForm.tsx @@ -60,7 +60,7 @@ export const DockerConnectorForm = () => { color="primary" className="ml-auto" onClick={() => { - navigate('/onboard/my-connectors'); + navigate('/onboard/connectors/my-connectors'); }} > Go to connectors diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/K8ConnectorForm.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/K8ConnectorForm.tsx index 3f24582bfc..81254afe1f 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/K8ConnectorForm.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/K8ConnectorForm.tsx @@ -299,7 +299,7 @@ ${socketMap.containerd.command}="${defaultSocketPath}" \\ color="primary" className="ml-auto" onClick={() => { - navigate('/onboard/my-connectors'); + navigate('/onboard/connectors/my-connectors'); }} > Go to connectors diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/LinuxConnectorForm.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/LinuxConnectorForm.tsx index 0fd52f1939..c373315fb5 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/LinuxConnectorForm.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/hosts/LinuxConnectorForm.tsx @@ -60,7 +60,7 @@ export const LinuxConnectorForm = () => { color="primary" className="ml-auto" onClick={() => { - navigate('/onboard/my-connectors'); + navigate('/onboard/connectors/my-connectors'); }} > Go to connectors diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/registries/AmazonECRConnectionForm.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/registries/AmazonECRConnectionForm.tsx index a573c76964..027da86397 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/registries/AmazonECRConnectionForm.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/components/connectors/registries/AmazonECRConnectionForm.tsx @@ -1,8 +1,5 @@ -import cx from 'classnames'; import { HiViewGridAdd } from 'react-icons/hi'; -import { useCopyToClipboard } from 'react-use'; import { - Accordion, Button, Card, Step, diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/layouts/ConnectorsLayout.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/layouts/ConnectorsLayout.tsx new file mode 100644 index 0000000000..8fefbba5a8 --- /dev/null +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/layouts/ConnectorsLayout.tsx @@ -0,0 +1,57 @@ +import { LoaderFunction, Outlet, redirect, useLocation } from 'react-router-dom'; +import { Tabs } from 'ui-components'; + +import { usePageNavigation } from '../../../utils/usePageNavigation'; +import { ConnectorHeader } from '../components/ConnectorHeader'; + +export const connectorsLoader: LoaderFunction = async ({ request }) => { + const url = new URL(request.url); + if (['/onboard/connectors', '/onboard/connectors/'].includes(url.pathname)) { + throw redirect('/onboard/connectors/add-connectors', 302); + } + return null; +}; + +const tabs = [ + { + label: 'Add Connectors', + value: 'add-connectors', + }, + { + label: 'My Connectors', + value: 'my-connectors', + }, +]; + +export const ConnectorsLayout = () => { + const location = useLocation(); + const { navigate } = usePageNavigation(); + + const tab = location.pathname.startsWith('/onboard/connectors/my-connectors') + ? 'my-connectors' + : 'add-connectors'; + + const onTabChange = (tab: string) => { + navigate(`/onboard/connectors/${tab}`); + }; + + return ( + <> + + +
+ +
+
+ + ); +}; diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/layouts/OnboardLayout.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/layouts/OnboardLayout.tsx index 11af62ed97..2dc2da5c05 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/layouts/OnboardLayout.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/layouts/OnboardLayout.tsx @@ -1,12 +1,11 @@ -import { Outlet, redirect } from 'react-router-dom'; +import { LoaderFunction, Outlet, redirect } from 'react-router-dom'; import { OnboardAppHeader } from '../components/OnBoardAppHeader'; -export const rootOnboardLoader = async ({ request }: any) => { - const index = request.url.lastIndexOf('/onboard'); - const subpath = request.url.substring(index); - if (subpath === '/onboard' || subpath === '/onboard/') { - return redirect('/onboard/add-connectors', 302); +export const rootOnboardLoader: LoaderFunction = async ({ request }) => { + const url = new URL(request.url); + if (['/onboard', '/onboard/'].includes(url.pathname)) { + return redirect('/onboard/connectors', 302); } return null; }; diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/pages/Connector.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/pages/connectors/AddConnectors.tsx similarity index 74% rename from deepfence_frontend/apps/dashboard/src/features/onboard/pages/Connector.tsx rename to deepfence_frontend/apps/dashboard/src/features/onboard/pages/connectors/AddConnectors.tsx index ceced338b5..428dbb27bc 100644 --- a/deepfence_frontend/apps/dashboard/src/features/onboard/pages/Connector.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/pages/connectors/AddConnectors.tsx @@ -1,24 +1,21 @@ import cx from 'classnames'; -import { useEffect, useState } from 'react'; import { IconContext } from 'react-icons'; import { HiOutlineArrowCircleRight } from 'react-icons/hi'; -import { Card, Tabs, Typography } from 'ui-components'; +import { Card, Typography } from 'ui-components'; -import LogoAws from '../../../assets/logo-aws.svg'; -import LogoAwsWhite from '../../../assets/logo-aws-white.svg'; -import LogoAzure from '../../../assets/logo-azure.svg'; -import LogoAzureRegistry from '../../../assets/logo-azure-registry.svg'; -import LogoCloudConnector from '../../../assets/logo-cloud-connector.svg'; -import LogoDocker from '../../../assets/logo-docker.svg'; -import LogoGoogle from '../../../assets/logo-google.svg'; -import LogoHostConnector from '../../../assets/logo-host-connector.svg'; -import LogoK8 from '../../../assets/logo-k8.svg'; -import LogoLinux from '../../../assets/logo-linux.svg'; -import LogoRegistryConnector from '../../../assets/logo-registry-connector.svg'; -import { useTheme } from '../../../theme/ThemeContext'; -import { usePageNavigation } from '../../../utils/usePageNavigation'; -import { ConnectorHeader } from '../components/ConnectorHeader'; -import { NoConnectors } from '../components/connectors/NoConnectors'; +import LogoAws from '../../../../assets/logo-aws.svg'; +import LogoAwsWhite from '../../../../assets/logo-aws-white.svg'; +import LogoAzure from '../../../../assets/logo-azure.svg'; +import LogoAzureRegistry from '../../../../assets/logo-azure-registry.svg'; +import LogoCloudConnector from '../../../../assets/logo-cloud-connector.svg'; +import LogoDocker from '../../../../assets/logo-docker.svg'; +import LogoGoogle from '../../../../assets/logo-google.svg'; +import LogoHostConnector from '../../../../assets/logo-host-connector.svg'; +import LogoK8 from '../../../../assets/logo-k8.svg'; +import LogoLinux from '../../../../assets/logo-linux.svg'; +import LogoRegistryConnector from '../../../../assets/logo-registry-connector.svg'; +import { useTheme } from '../../../../theme/ThemeContext'; +import { usePageNavigation } from '../../../../utils/usePageNavigation'; interface CardConnectProps { path: string; @@ -29,7 +26,7 @@ interface CardConnectProps { const CardConnect = ({ label, path, icon }: CardConnectProps) => { const { navigate } = usePageNavigation(); const handleSelection = () => { - navigate(`${path}`); + navigate(`../../instructions/${path}`); }; return ( @@ -207,12 +204,12 @@ const Registries = () => { { icon: LogoAzureRegistry, label: 'Azure Container Registry', - path: 'registry-azure', + path: 'registry-azure-1', }, { icon: LogoGoogle, label: 'Container Registry | Google Cloud', - path: 'registry-linux', + path: 'registry-linux-1', }, ]; return ( @@ -243,7 +240,7 @@ const Registries = () => { {connectors.map((connector) => { return (
{ ); }; -const tabs = [ - { - label: 'Add Connectors', - value: 'add-connectors', - }, - { - label: 'My Connectors', - value: 'my-connectors', - }, -]; - export const AddConnector = () => { return (
@@ -285,42 +271,3 @@ export const AddConnector = () => {
); }; - -export const Connector = ({ page }: { page: string }) => { - const [tab, setTab] = useState(page); - const { navigate } = usePageNavigation(); - - const onTabChange = (tab: string) => { - navigate(`/onboard/${tab}`); - }; - - useEffect(() => { - if (page) { - setTab(page); - } - }, [page]); - return ( - <> - - -
- {tab === 'add-connectors' && } - {tab === 'my-connectors' && ( - <> - - - )} -
-
- - ); -}; diff --git a/deepfence_frontend/apps/dashboard/src/features/onboard/pages/connectors/MyConnectors.tsx b/deepfence_frontend/apps/dashboard/src/features/onboard/pages/connectors/MyConnectors.tsx new file mode 100644 index 0000000000..9b18b552db --- /dev/null +++ b/deepfence_frontend/apps/dashboard/src/features/onboard/pages/connectors/MyConnectors.tsx @@ -0,0 +1,5 @@ +import { NoConnectors } from '../../components/connectors/NoConnectors'; + +export const MyConnectors = () => { + return ; +}; diff --git a/deepfence_frontend/apps/dashboard/src/routes/private.tsx b/deepfence_frontend/apps/dashboard/src/routes/private.tsx index c45c660405..16ec8fd7c3 100644 --- a/deepfence_frontend/apps/dashboard/src/routes/private.tsx +++ b/deepfence_frontend/apps/dashboard/src/routes/private.tsx @@ -1,5 +1,9 @@ import { Outlet, RouteObject } from 'react-router-dom'; +import { + ConnectorsLayout, + connectorsLoader, +} from '../features/onboard/layouts/ConnectorsLayout'; import { OnboardLayout, rootOnboardLoader, @@ -7,7 +11,8 @@ import { import { AmazonECRConnector } from '../features/onboard/pages/AmazonECRConnector'; import { AWSConnector } from '../features/onboard/pages/AWSConnector'; import { AzureConnector } from '../features/onboard/pages/AzureConnector'; -import { Connector } from '../features/onboard/pages/Connector'; +import { AddConnector } from '../features/onboard/pages/connectors/AddConnectors'; +import { MyConnectors } from '../features/onboard/pages/connectors/MyConnectors'; import { DockerConnector } from '../features/onboard/pages/DockerConnector'; import { GCPConnector } from '../features/onboard/pages/GCPConnector'; import { K8sConnector } from '../features/onboard/pages/K8sConnector'; @@ -20,13 +25,24 @@ export const privateRoutes: RouteObject[] = [ loader: rootOnboardLoader, children: [ { - path: 'add-connectors', - element: , + path: 'connectors', + element: , + loader: connectorsLoader, children: [ { - index: true, - element: , + path: 'add-connectors', + element: , + }, + { + path: 'my-connectors', + element: , }, + ], + }, + { + path: 'instructions', + element: , + children: [ { path: 'cloud/aws', element: , @@ -57,16 +73,6 @@ export const privateRoutes: RouteObject[] = [ }, ], }, - { - path: 'my-connectors', - element: , - children: [ - { - index: true, - element: , - }, - ], - }, ], }, ];