diff --git a/workspaces/orchestrator/.changeset/polite-chicken-applaud.md b/workspaces/orchestrator/.changeset/polite-chicken-applaud.md new file mode 100644 index 00000000..d71e3cb1 --- /dev/null +++ b/workspaces/orchestrator/.changeset/polite-chicken-applaud.md @@ -0,0 +1,5 @@ +--- +'@red-hat-developer-hub/backstage-plugin-orchestrator-common': patch +--- + +generate openapi spec api-doc diff --git a/workspaces/orchestrator/package.json b/workspaces/orchestrator/package.json index 0d50ac54..99ae38d8 100644 --- a/workspaces/orchestrator/package.json +++ b/workspaces/orchestrator/package.json @@ -21,7 +21,7 @@ "prettier:check": "prettier --check .", "prettier:fix": "prettier --write .", "new": "backstage-cli new --scope @red-hat-developer-hub", - "postinstall": "cd ../../ && yarn install" + "postinstall": "./scripts/postinstall" }, "workspaces": { "packages": [ diff --git a/workspaces/orchestrator/plugins/orchestrator-common/scripts/openapi.sh b/workspaces/orchestrator/plugins/orchestrator-common/scripts/openapi.sh index 64c714d6..1b43cd1d 100755 --- a/workspaces/orchestrator/plugins/orchestrator-common/scripts/openapi.sh +++ b/workspaces/orchestrator/plugins/orchestrator-common/scripts/openapi.sh @@ -8,6 +8,8 @@ API_FOLDER="${GENERATED_FOLDER}/api" DEFINITION_FILE="${API_FOLDER}/definition.ts" METADATA_FILE="${GENERATED_FOLDER}/.METADATA.sha1" CLIENT_FOLDER="${GENERATED_FOLDER}/client" +APIDOC_TEMPLATE_FILE="./src/openapi/api-doc-template.yaml" +APIDOC_GENERATED_FILE=${GENERATED_FOLDER}/docs/api-doc/orchestrator-api.yaml openapi_generate() { # TypeScript Client generation @@ -15,9 +17,13 @@ openapi_generate() { openapi-generator-cli generate -g typescript-axios -i ${OPENAPI_SPEC_FILE} -o ${CLIENT_FOLDER} # Docs generation - rm -rf ./src/generated/docs/markdown ./src/generated/docs/html + rm -rf ./src/generated/docs/markdown ./src/generated/docs/html ./src/generated/docs/api-doc openapi-generator-cli generate -g markdown -i ${OPENAPI_SPEC_FILE} -o ./src/generated/docs/markdown/ openapi-generator-cli generate -g html2 -i ${OPENAPI_SPEC_FILE} -o ./src/generated/docs/html + mkdir ./src/generated/docs/api-doc + cp $APIDOC_TEMPLATE_FILE $APIDOC_GENERATED_FILE + cat $OPENAPI_SPEC_FILE | sed 's/^/ /g' >> $APIDOC_GENERATED_FILE + yaml2json -f ${OPENAPI_SPEC_FILE} diff --git a/workspaces/orchestrator/plugins/orchestrator-common/src/generated/docs/api-doc/orchestrator-api.yaml b/workspaces/orchestrator/plugins/orchestrator-common/src/generated/docs/api-doc/orchestrator-api.yaml new file mode 100644 index 00000000..01047f9b --- /dev/null +++ b/workspaces/orchestrator/plugins/orchestrator-common/src/generated/docs/api-doc/orchestrator-api.yaml @@ -0,0 +1,739 @@ +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: orchestrator-backend + description: The Orchestrator backend plugin API + tags: + - orchestrator +spec: + type: openapi + lifecycle: experimental + owner: development + definition: | + openapi: 3.1.0 + info: + title: Orchestrator plugin + description: API to interact with orchestrator plugin + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + version: 0.0.1 + servers: + - url: / + paths: + /v2/workflows/overview: + post: + operationId: getWorkflowsOverview + description: Returns the key fields of the workflow including data on the last run instance + requestBody: + required: false + description: Pagination and filters + content: + application/json: + schema: + $ref: '#/components/schemas/SearchRequest' + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/WorkflowOverviewListResultDTO' + '500': + description: Error fetching workflow overviews + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/{workflowId}/overview: + get: + operationId: getWorkflowOverviewById + description: Returns the key fields of the workflow including data on the last run instance + parameters: + - name: workflowId + in: path + required: true + description: Unique identifier of the workflow + schema: + type: string + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/WorkflowOverviewDTO' + '500': + description: Error fetching workflow overview + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/{workflowId}/source: + get: + operationId: getWorkflowSourceById + description: Get the workflow's definition + parameters: + - name: workflowId + in: path + description: ID of the workflow to fetch + required: true + schema: + type: string + responses: + '200': + description: Success + content: + text/plain: + schema: + type: string + '500': + description: Error fetching workflow source by id + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/{workflowId}/inputSchema: + get: + operationId: getWorkflowInputSchemaById + description: Get the workflow input schema. It defines the input fields of the workflow + parameters: + - name: workflowId + in: path + description: ID of the workflow to fetch + required: true + schema: + type: string + - name: instanceId + in: query + description: ID of instance + schema: + type: string + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/InputSchemaResponseDTO' + '500': + description: Error fetching workflow input schema by id + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/instances: + post: + operationId: getInstances + summary: Get instances + description: Retrieve an array of workflow executions (instances) + requestBody: + required: false + description: Parameters for retrieving instances + content: + application/json: + schema: + $ref: '#/components/schemas/GetInstancesRequest' + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/ProcessInstanceListResultDTO' + '500': + description: Error fetching instances + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/{workflowId}/instances: + post: + operationId: getWorkflowInstances + summary: Get instances for a specific workflow + description: Retrieve an array of workflow executions (instances) for the given workflow + parameters: + - name: workflowId + in: path + required: true + description: ID of the workflow + schema: + type: string + requestBody: + required: false + description: Parameters for retrieving workflow instances + content: + application/json: + schema: + $ref: '#/components/schemas/SearchRequest' + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/ProcessInstanceListResultDTO' + '500': + description: Error fetching instances + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/instances/{instanceId}: + get: + summary: Get Workflow Instance by ID + description: Get a workflow execution/run (instance) + operationId: getInstanceById + parameters: + - name: instanceId + in: path + required: true + description: ID of the workflow instance + schema: + type: string + - name: includeAssessment + in: query + required: false + description: Whether to include assessment + schema: + type: boolean + default: false + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/AssessedProcessInstanceDTO' + '500': + description: Error fetching instance + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/instances/statuses: + get: + operationId: getWorkflowStatuses + summary: Get workflow status list + description: Retrieve array with the status of all instances + responses: + '200': + description: Success + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/WorkflowRunStatusDTO' + '500': + description: Error fetching workflow statuses + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/{workflowId}/execute: + post: + summary: Execute a workflow + description: Execute a workflow + operationId: executeWorkflow + parameters: + - name: workflowId + in: path + description: ID of the workflow to execute + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExecuteWorkflowRequestDTO' + responses: + '200': + description: Successful execution + content: + application/json: + schema: + $ref: '#/components/schemas/ExecuteWorkflowResponseDTO' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/{workflowId}/{instanceId}/retrigger: + post: + summary: Retrigger an instance + description: Retrigger an instance + operationId: retriggerInstance + parameters: + - name: workflowId + in: path + description: ID of the workflow + required: true + schema: + type: string + - name: instanceId + in: path + description: ID of the instance to retrigger + required: true + schema: + type: string + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v2/workflows/instances/{instanceId}/abort: + delete: + summary: Abort a workflow instance + operationId: abortWorkflow + description: Aborts a workflow instance identified by the provided instanceId. + parameters: + - name: instanceId + in: path + required: true + description: The identifier of the workflow instance to abort. + schema: + type: string + responses: + '200': + description: Successful operation + content: + text/plain: + schema: + type: string + '500': + description: Error aborting workflow + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + components: + schemas: + ErrorResponse: + description: + The ErrorResponse object represents a common structure for handling errors in API responses. + It includes essential information about the error, such as the error message and additional optional details. + type: object + properties: + message: + description: + A string providing a concise and human-readable description of the encountered error. + This field is required in the ErrorResponse object. + type: string + default: internal server error + additionalInfo: + description: + An optional field that can contain additional information or context about the error. + It provides flexibility for including extra details based on specific error scenarios. + type: string + required: + - message + GetInstancesRequest: + type: object + properties: + paginationInfo: + $ref: '#/components/schemas/PaginationInfoDTO' + filters: + $ref: '#/components/schemas/SearchRequest' + GetOverviewsRequestParams: + type: object + properties: + paginationInfo: + $ref: '#/components/schemas/PaginationInfoDTO' + filters: + $ref: '#/components/schemas/SearchRequest' + WorkflowOverviewListResultDTO: + type: object + properties: + overviews: + type: array + items: + $ref: '#/components/schemas/WorkflowOverviewDTO' + minItems: 0 + paginationInfo: + $ref: '#/components/schemas/PaginationInfoDTO' + WorkflowOverviewDTO: + type: object + properties: + workflowId: + type: string + description: Workflow unique identifier + minLength: 1 + name: + type: string + description: Workflow name + minLength: 1 + format: + $ref: '#/components/schemas/WorkflowFormatDTO' + lastRunId: + type: string + lastTriggeredMs: + type: number + minimum: 0 + lastRunStatus: + $ref: '#/components/schemas/ProcessInstanceStatusDTO' + category: + $ref: '#/components/schemas/WorkflowCategoryDTO' + avgDurationMs: + type: number + minimum: 0 + description: + type: string + required: + - workflowId + - format + PaginationInfoDTO: + type: object + properties: + pageSize: + type: number + offset: + type: number + totalCount: + type: number + orderDirection: + enum: + - ASC + - DESC + orderBy: + type: string + additionalProperties: false + WorkflowFormatDTO: + type: string + description: Format of the workflow definition + enum: + - yaml + - json + WorkflowCategoryDTO: + type: string + description: Category of the workflow + enum: + - assessment + - infrastructure + WorkflowListResultDTO: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/WorkflowDTO' + paginationInfo: + $ref: '#/components/schemas/PaginationInfoDTO' + required: + - items + - paginationInfo + WorkflowDTO: + type: object + properties: + id: + type: string + description: Workflow unique identifier + minLength: 1 + name: + type: string + description: Workflow name + minLength: 1 + format: + $ref: '#/components/schemas/WorkflowFormatDTO' + category: + $ref: '#/components/schemas/WorkflowCategoryDTO' + description: + type: string + description: Description of the workflow + annotations: + type: array + items: + type: string + required: + - id + - category + - format + ProcessInstanceListResultDTO: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/ProcessInstanceDTO' + paginationInfo: + $ref: '#/components/schemas/PaginationInfoDTO' + AssessedProcessInstanceDTO: + type: object + properties: + instance: + $ref: '#/components/schemas/ProcessInstanceDTO' + assessedBy: + $ref: '#/components/schemas/ProcessInstanceDTO' + required: + - instance + ProcessInstanceDTO: + type: object + properties: + id: + type: string + processId: + type: string + processName: + type: string + status: + $ref: '#/components/schemas/ProcessInstanceStatusDTO' + endpoint: + type: string + serviceUrl: + type: string + start: + type: string + end: + type: string + duration: + type: string + category: + $ref: '#/components/schemas/WorkflowCategoryDTO' + description: + type: string + workflowdata: + $ref: '#/components/schemas/WorkflowDataDTO' + businessKey: + type: string + nodes: + type: array + items: + $ref: '#/components/schemas/NodeInstanceDTO' + error: + $ref: '#/components/schemas/ProcessInstanceErrorDTO' + required: + - id + - processId + - nodes + WorkflowDataDTO: + type: object + properties: + result: + $ref: '#/components/schemas/WorkflowResultDTO' + additionalProperties: true + WorkflowResultDTO: + # Based on https://github.com/parodos-dev/serverless-workflows/blob/main/shared/schemas/workflow-result-schema.json + description: Result of a workflow execution + type: object + properties: + completedWith: + description: The state of workflow completion. + type: string + enum: + - error + - success + message: + description: High-level summary of the current status, free-form text, human readable. + type: string + nextWorkflows: + description: List of workflows suggested to run next. Items at lower indexes are of higher priority. + type: array + items: + type: object + properties: + id: + description: Workflow identifier + type: string + name: + description: Human readable title describing the workflow. + type: string + required: + - id + - name + outputs: + description: Additional structured output of workflow processing. This can contain identifiers of created resources, links to resources, logs or other output. + type: array + items: + type: object + properties: + key: + description: Unique identifier of the option. Preferably human-readable. + type: string + value: + description: Free form value of the option. + anyOf: + - type: string + - type: number + format: + description: More detailed type of the 'value' property. Defaults to 'text'. + enum: + - text + - number + - link + required: + - key + - value + ProcessInstanceStatusDTO: + type: string + description: Status of the workflow run + enum: + - Active + - Error + - Completed + - Aborted + - Suspended + - Pending + WorkflowRunStatusDTO: + type: object + properties: + key: + type: string + value: + type: string + ExecuteWorkflowRequestDTO: + type: object + properties: + inputData: + type: object + additionalProperties: true + required: + - inputData + ExecuteWorkflowResponseDTO: + type: object + properties: + id: + type: string + required: + - id + WorkflowProgressDTO: + allOf: + - $ref: '#/components/schemas/NodeInstanceDTO' + - type: object + properties: + status: + $ref: '#/components/schemas/ProcessInstanceStatusDTO' + error: + $ref: '#/components/schemas/ProcessInstanceErrorDTO' + NodeInstanceDTO: + type: object + properties: + __typename: + type: string + default: 'NodeInstance' + description: Type name + id: + type: string + description: Node instance ID + name: + type: string + description: Node name + type: + type: string + description: Node type + enter: + type: string + description: Date when the node was entered + exit: + type: string + description: Date when the node was exited (optional) + definitionId: + type: string + description: Definition ID + nodeId: + type: string + description: Node ID + required: + - id + ProcessInstanceErrorDTO: + type: object + properties: + __typename: + type: string + default: 'ProcessInstanceError' + description: Type name + nodeDefinitionId: + type: string + description: Node definition ID + message: + type: string + description: Error message (optional) + required: + - nodeDefinitionId + SearchRequest: + type: object + properties: + filters: + $ref: '#/components/schemas/Filter' + paginationInfo: + $ref: '#/components/schemas/PaginationInfoDTO' + Filter: + oneOf: + - $ref: '#/components/schemas/LogicalFilter' + - $ref: '#/components/schemas/FieldFilter' + LogicalFilter: + type: object + required: + - operator + - filters + properties: + operator: + type: string + enum: [AND, OR, NOT] + filters: + type: array + items: + $ref: '#/components/schemas/Filter' + + FieldFilter: + type: object + required: + - field + - operator + - value + properties: + field: + type: string + operator: + type: string + enum: + [ + EQ, + GT, + GTE, + LT, + LTE, + IN, + IS_NULL, + CONTAINS, + CONTAINS_ALL, + CONTAINS_ANY, + LIKE, + BETWEEN, + ] + # The `value` field should be defined as follows. However, due to a bug (open since May 2023), + # https://github.com/OpenAPITools/openapi-generator/issues/15701 + # using `oneOf` to specify enum values for a property in the schema doesn't generate the enums correctly. + value: + oneOf: + - type: string + - type: number + - type: boolean + - type: array + items: + oneOf: + - type: string + - type: number + - type: boolean + # - type: string + # enum: + # - A + # - B + + InputSchemaResponseDTO: + type: object + properties: + inputSchema: + type: object + data: + type: object diff --git a/workspaces/orchestrator/plugins/orchestrator-common/src/openapi/api-doc-template.yaml b/workspaces/orchestrator/plugins/orchestrator-common/src/openapi/api-doc-template.yaml new file mode 100644 index 00000000..b0bec622 --- /dev/null +++ b/workspaces/orchestrator/plugins/orchestrator-common/src/openapi/api-doc-template.yaml @@ -0,0 +1,12 @@ +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: orchestrator-backend + description: The Orchestrator backend plugin API + tags: + - orchestrator +spec: + type: openapi + lifecycle: experimental + owner: development + definition: | diff --git a/workspaces/orchestrator/scripts/postinstall b/workspaces/orchestrator/scripts/postinstall new file mode 100755 index 00000000..93b568c3 --- /dev/null +++ b/workspaces/orchestrator/scripts/postinstall @@ -0,0 +1,6 @@ +#!/bin/bash +mydir=`pwd` +cd ../../ && yarn install +cd $mydir +cd plugins/orchestrator-common +yarn openapi:check