Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SRVKP-7188: Update the Pipelines Dynamic Plugin to use the new Dedicated API endpoints #227

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 36 additions & 53 deletions src/components/catalog/apis/artifactHub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,69 +6,33 @@ import {
} from '@openshift-console/dynamic-plugin-sdk';
import * as _ from 'lodash';
import * as React from 'react';
import { GITHUB_BASE_URL } from '../../../consts';
import { TaskModel, TaskModelV1Beta1 } from '../../../models';
import { ArtifactHubTask, ArtifactHubTaskDetails } from '../../../types';
import { TektonTaskAnnotation } from '../../task-quicksearch/pipeline-quicksearch-utils';
import { consoleProxyFetchJSON } from '../../utils/proxy';
import { ApiResult } from '../hooks/useApiResponse';
import { getTaskDetails, getTaskYAMLFromGithub, searchTasks } from './utils';

export const ARTIFACTHUB_API_BASE_URL = 'https://artifacthub.io/api/v1';
export const ARTIFACTHUB = 'ArtifactHub';

export type ArtifactHubRepository = {
name: string;
kind: number;
url: string;
display_name: string;
repository_id: string;
organization_name: string;
organization_display_name: string;
};

export type ArtifactHubVersion = {
version: string;
contains_security_update: boolean;
prerelease: boolean;
ts: number;
};

export type ArtifactHubTask = {
package_id: string;
name: string;
description: string;
version: string;
display_name: string;
repository: ArtifactHubRepository;
};

export type ArtifactHubTaskDetails = {
package_id: string;
name: string;
description: string;
display_name: string;
keywords: string[];
platforms: string[];
version: ArtifactHubVersion[];
available_versions: [];
content_url: string;
repository: ArtifactHubRepository;
};

const ARTIFACRHUB_TASKS_SEARCH_URL = `${ARTIFACTHUB_API_BASE_URL}/packages/search?offset=0&limit=60&facets=false&kind=7&deprecated=false&sort=relevance`;

export const getArtifactHubTaskDetails = async (
item: CatalogItem,
v?: string,
): Promise<ArtifactHubTaskDetails> => {
const API_BASE_URL = `${ARTIFACTHUB_API_BASE_URL}/packages/tekton-task`;
const { name, data } = item;
const {
task: {
version,
repository: { name: repoName },
},
} = data;
const url = `${API_BASE_URL}/${repoName}/${name}/${v || version}`;
return consoleProxyFetchJSON({ url, method: 'GET' });
return getTaskDetails({
repoName,
name,
version: v || version,
allowAuthHeader: true,
allowInsecure: true,
});
};

export const useGetArtifactHubTasks = (
Expand All @@ -81,11 +45,8 @@ export const useGetArtifactHubTasks = (
React.useEffect(() => {
let mounted = true;
if (hasPermission) {
consoleProxyFetchJSON<{ packages: ArtifactHubTask[] }>({
url: ARTIFACRHUB_TASKS_SEARCH_URL,
method: 'GET',
})
.then(({ packages }) => {
searchTasks({ allowAuthHeader: true, allowInsecure: true })
.then((packages) => {
if (mounted) {
setLoaded(true);
setResult(packages);
Expand All @@ -112,7 +73,18 @@ export const createArtifactHubTask = (
namespace: string,
version: string,
) => {
return consoleProxyFetchJSON({ url, method: 'GET' })
const yamlPath = url.startsWith(GITHUB_BASE_URL)
? url.slice(GITHUB_BASE_URL.length)
: null;
if (!yamlPath) {
throw new Error('Not a valid GitHub URL');
}

return getTaskYAMLFromGithub({
yamlPath,
allowAuthHeader: true,
allowInsecure: true,
})
.then((task: K8sResourceKind) => {
task.metadata.namespace = namespace;
task.metadata.annotations = {
Expand Down Expand Up @@ -140,7 +112,18 @@ export const updateArtifactHubTask = async (
name: string,
version: string,
) => {
return consoleProxyFetchJSON({ url, method: 'GET' })
const yamlPath = url.startsWith(GITHUB_BASE_URL)
? url.slice(GITHUB_BASE_URL.length)
: null;
if (!yamlPath) {
throw new Error('Not a valid GitHub raw URL');
}

return getTaskYAMLFromGithub({
yamlPath,
allowAuthHeader: true,
allowInsecure: true,
})
.then((task: K8sResourceKind) => {
task.metadata.namespace = namespace;
task.metadata.annotations = {
Expand Down
118 changes: 118 additions & 0 deletions src/components/catalog/apis/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import {
consoleFetchJSON,
K8sResourceKind,
} from '@openshift-console/dynamic-plugin-sdk';
import { HttpError } from '@openshift-console/dynamic-plugin-sdk/lib/utils/error/http-error';
import { load } from 'js-yaml';
import {
ARTIFACTHUB_SEARCH_URL,
ARTIFACTHUB_TASK_DETAILS_URL,
GITHUB_ARTIFACTHUB_TASK_YAML_URL,
} from '../../../consts';
import {
ArtifactHubTask,
ArtifactHubTaskDetails,
DevConsoleEndpointResponse,
TaskDetailsRequest,
TaskSearchRequest,
TaskYAMLRequest,
} from '../../../types';

/**
* Fetches the YAML content of a task from GitHub.
* @param taskYAMLRequest The request object containing the path to the task YAML file.
* @returns The parsed YAML content of the task.
*/
export const getTaskYAMLFromGithub = async (
taskYAMLRequest: TaskYAMLRequest,
): Promise<K8sResourceKind> => {
const taskYAMLResponse: DevConsoleEndpointResponse =
await consoleFetchJSON.post(
GITHUB_ARTIFACTHUB_TASK_YAML_URL,
taskYAMLRequest,
);

if (!taskYAMLResponse.statusCode) {
throw new Error('Unexpected proxy response: Status code is missing!');
}

if (taskYAMLResponse.statusCode < 200 || taskYAMLResponse.statusCode >= 300) {
throw new HttpError(
`Unexpected status code: ${taskYAMLResponse.statusCode}`,
taskYAMLResponse.statusCode,
null,
taskYAMLResponse,
);
}

try {
// Parse the YAML response body
return load(taskYAMLResponse.body);
} catch (e) {
throw new Error('Failed to parse task YAML response body as YAML');
}
};

/**
* Fetches the details of a task from ArtifactHub.
* @param taskDetailsRequest The request object containing the task details.
* @returns The details of the task.
*/
export const getTaskDetails = async (
taskDetailsRequest: TaskDetailsRequest,
): Promise<ArtifactHubTaskDetails> => {
const taskDetailsResponse: DevConsoleEndpointResponse =
await consoleFetchJSON.post(
ARTIFACTHUB_TASK_DETAILS_URL,
taskDetailsRequest,
);
if (!taskDetailsResponse.statusCode) {
throw new Error('Unexpected proxy response: Status code is missing!');
}
if (
taskDetailsResponse.statusCode < 200 ||
taskDetailsResponse.statusCode >= 300
) {
throw new HttpError(
`Unexpected status code: ${taskDetailsResponse.statusCode}`,
taskDetailsResponse.statusCode,
null,
taskDetailsResponse,
);
}

try {
return JSON.parse(taskDetailsResponse.body) as ArtifactHubTaskDetails;
} catch (e) {
throw new Error('Failed to parse task details response body as JSON');
}
};

/**
* Fetches the tasks from ArtifactHub.
* @param (optional) searchrequest The search request object.
* @returns The array of tasks matching the search request.
*/
export const searchTasks = async (
searchrequest?: TaskSearchRequest,
): Promise<ArtifactHubTask[]> => {
const searchResponse: DevConsoleEndpointResponse =
await consoleFetchJSON.post(ARTIFACTHUB_SEARCH_URL, searchrequest || {});
if (!searchResponse.statusCode) {
throw new Error('Unexpected proxy response: Status code is missing!');
}
if (searchResponse.statusCode < 200 || searchResponse.statusCode >= 300) {
throw new HttpError(
`Unexpected status code: ${searchResponse.statusCode}`,
searchResponse.statusCode,
null,
searchResponse,
);
}

try {
return JSON.parse(searchResponse.body).packages as ArtifactHubTask[];
} catch (e) {
throw new Error('Failed to parse search response body as JSON');
}
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import * as React from 'react';
import {
ARTIFACTHUB,
ArtifactHubTask,
useGetArtifactHubTasks,
} from '../apis/artifactHub';
import { ARTIFACTHUB, useGetArtifactHubTasks } from '../apis/artifactHub';
import { TektonHubTask } from '../apis/tektonHub';
import {
CatalogItem,
Expand All @@ -16,6 +12,7 @@ import { TaskModel } from '../../../models';
import { getReferenceForModel } from '../../pipelines-overview/utils';
import { useTektonHubIntegration } from '../catalog-utils';
import { t } from '../../utils/common-utils';
import { ArtifactHubTask } from '../../../types';

const normalizeArtifactHubTasks = (
artifactHubTasks: ArtifactHubTask[],
Expand Down
5 changes: 4 additions & 1 deletion src/components/hooks/useTektonResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import {
RepositoryLabels,
TektonResourceLabel,
} from '../../consts';
import { PipelineRunKind, TaskRunKind } from '../../types';
import {
PipelineRunKind,
RecordsList,
TaskRunKind,
TektonResultsOptions,
} from '../../types';
import {
getPipelineRuns,
getTaskRunLog,
getTaskRuns,
Expand Down
8 changes: 4 additions & 4 deletions src/components/hooks/useTektonResults.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk';
import * as React from 'react';
import { PipelineRunKind, TaskRunKind } from '../../types';
import {
PipelineRunKind,
RecordsList,
TaskRunKind,
TektonResultsOptions,
getPipelineRuns,
getTaskRuns,
} from '../utils/tekton-results';
} from '../../types';
import { getPipelineRuns, getTaskRuns } from '../utils/tekton-results';

export type GetNextPage = () => void | undefined;

Expand Down
4 changes: 2 additions & 2 deletions src/components/pipelines-metrics/PipelinesAverageDuration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import {
timeToMinutes,
} from '../pipelines-overview/dateTime';
import { ALL_NAMESPACES_KEY } from '../../consts';
import { DataType } from '../utils/tekton-results';
import { SummaryResponse, getResultsSummary } from '../utils/summary-api';
import { getResultsSummary } from '../utils/summary-api';
import { getFilter, useInterval } from '../pipelines-overview/utils';
import { DataType, SummaryResponse } from '../../types';

interface PipelinesAverageDurationProps {
timespan?: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@patternfly/react-core';
import { SummaryProps, getFilter, useInterval } from './utils';
import { getResultsSummary } from '../utils/summary-api';
import { DataType } from '../utils/tekton-results';
import { DataType } from '../../types';
import { ALL_NAMESPACES_KEY } from '../../consts';
import { formatTime, getDropDownDate } from './dateTime';
import { LoadingInline } from '../Loading';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import {
parsePrometheusDuration,
monthYear,
} from './dateTime';
import { DataType } from '../utils/tekton-results';
import { SummaryResponse, getResultsSummary } from '../utils/summary-api';
import { getResultsSummary } from '../utils/summary-api';
import { DataType, SummaryResponse } from '../../types';
import { ALL_NAMESPACES_KEY } from '../../consts';
import { getFilter, useInterval } from './utils';
import { LoadingInline } from '../Loading';
Expand Down
4 changes: 2 additions & 2 deletions src/components/pipelines-overview/PipelineRunsStatusCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ import {
monthYear,
} from './dateTime';
import { getFilter, useInterval } from './utils';
import { SummaryResponse, getResultsSummary } from '../utils/summary-api';
import { DataType } from '../utils/tekton-results';
import { getResultsSummary } from '../utils/summary-api';
import './PipelinesOverview.scss';
import { LoadingInline } from '../Loading';
import { ALL_NAMESPACES_KEY } from '../../consts';
import { DataType, SummaryResponse } from '../../types';
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';

interface PipelinesRunsStatusCardProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import {
import { SummaryProps, useInterval } from './utils';
import { PipelineModel, RepositoryModel } from '../../models';
import { getResultsSummary } from '../utils/summary-api';
import { DataType } from '../utils/tekton-results';
import { ALL_NAMESPACES_KEY } from '../../consts';
import { getDropDownDate } from './dateTime';
import { LoadingInline } from '../Loading';
import { DataType } from '../../types';

import './PipelineRunsTotalCard.scss';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import PipelineRunsForPipelinesList from './PipelineRunsForPipelinesList';
import SearchInputField from '../SearchInput';
import { SummaryProps, useInterval, useQueryParams } from '../utils';
import { getResultsSummary } from '../../../components/utils/summary-api';
import { DataType } from '../../../components/utils/tekton-results';
import { DataType } from '../../../types';
import { getDropDownDate } from '../dateTime';
import { ALL_NAMESPACES_KEY } from '../../../consts';

Expand Down
Loading