API: Add programatically generated Image Builder API slice definitions

These definitions were generated using the RTKQ code generation tool and
will replace the existing definitions.
This commit is contained in:
lucasgarfield 2023-07-25 19:35:24 +02:00 committed by Lucas Garfield
parent 87b97b830f
commit 1894a9dcb2
10 changed files with 329 additions and 31 deletions

View file

@ -0,0 +1,13 @@
import type { ConfigFile } from '@rtk-query/codegen-openapi'
const config: ConfigFile = {
schemaFile: '../schema/image-builder.json',
apiFile: '../../src/store/emptyImageBuilderApi.ts',
apiImport: 'emptyImageBuilderApi',
outputFile: '../../src/store/imageBuilderApi.ts',
exportName: 'imageBuilderApi',
hooks: true,
filterEndpoints: ['getComposes', 'getComposeStatus', 'getComposeClones', 'getCloneStatus', 'getArchitectures'],
}
export default config

File diff suppressed because one or more lines are too long

View file

@ -112,6 +112,7 @@
"test": "TZ=UTC jest --verbose --no-cache",
"test:single": "jest --verbose -w 1",
"build": "webpack --config config/prod.webpack.config.js",
"api": "npx @rtk-query/codegen-openapi ./api/config/image-builder.ts",
"verify": "npm-run-all build lint test"
},
"insights": {

View file

@ -29,8 +29,8 @@ import {
import './CreateImageWizard.scss';
import api from '../../api';
import { UNIT_GIB, UNIT_KIB, UNIT_MIB } from '../../constants';
import { useGetArchitecturesByDistributionQuery } from '../../store/apiSlice';
import { composeAdded } from '../../store/composesSlice';
import { useGetArchitecturesQuery } from '../../store/imageBuilderApi';
import isRhel from '../../Utilities/isRhel';
import { resolveRelPath } from '../../Utilities/path';
import { useGetEnvironment } from '../../Utilities/useGetEnvironment';
@ -502,8 +502,8 @@ const CreateImageWizard = () => {
const composeRequest = compose?.request;
// TODO: This causes an annoying re-render when using Recreate image
const { data: distroInfo } = useGetArchitecturesByDistributionQuery(
composeRequest?.distribution,
const { data: distroInfo } = useGetArchitecturesQuery(
{ distribution: composeRequest?.distribution },
{
// distroInfo is only needed when recreating an image, skip otherwise
skip: composeId ? false : true,

View file

@ -5,7 +5,7 @@ import WizardContext from '@data-driven-forms/react-form-renderer/wizard-context
import { Button } from '@patternfly/react-core';
import PropTypes from 'prop-types';
import { usePrefetch } from '../../../store/apiSlice';
import { imageBuilderApi } from '../../../store/imageBuilderApi';
// FileSystemconfigButtons are defined separately to display errors inside of the button footer
const FileSystemConfigButtons = ({ handleNext, handlePrev, nextStep }) => {
@ -15,7 +15,7 @@ const FileSystemConfigButtons = ({ handleNext, handlePrev, nextStep }) => {
getState()?.errors?.['file-system-configuration'] ? true : false
);
const [nextHasBeenClicked, setNextHasBeenClicked] = useState(false);
const prefetchArchitectures = usePrefetch('getArchitecturesByDistribution');
const prefetchArchitectures = imageBuilderApi.usePrefetch('getArchitectures');
useEffect(() => {
const errors = getState()?.errors?.['file-system-configuration'];
@ -38,7 +38,7 @@ const FileSystemConfigButtons = ({ handleNext, handlePrev, nextStep }) => {
const handleMouseEnter = () => {
const distribution = getState()?.values?.release;
prefetchArchitectures(distribution);
prefetchArchitectures({ distribution });
};
return (

View file

@ -30,7 +30,7 @@ import {
import PropTypes from 'prop-types';
import api from '../../../api';
import { useGetArchitecturesByDistributionQuery } from '../../../store/apiSlice';
import { useGetArchitecturesQuery } from '../../../store/imageBuilderApi';
const ExactMatch = ({
pkgList,
@ -61,7 +61,7 @@ export const RedHatPackages = ({ defaultArch }) => {
const { getState } = useFormApi();
const distribution = getState()?.values?.release;
const { data: distributionInformation, isSuccess: isSuccessDistroInfo } =
useGetArchitecturesByDistributionQuery(distribution);
useGetArchitecturesQuery({ distribution });
const getAllPackages = async (packagesSearchName) => {
// if the env is stage beta then use content-sources api

View file

@ -1,6 +1,6 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { ActivationKeys, Architectures, ClonesResponse, ComposeStatus, ComposesResponse, RepositoryCollectionResponse, SourceResponse, SourceUploadInfoResponse, UploadStatus, } from '../../types';
import { ActivationKeys, RepositoryCollectionResponse, SourceResponse, SourceUploadInfoResponse } from '../../types';
type GetRepositoriesArgs = { available_for_arch: string, available_for_version: string, limit: number, offset: number }
@ -11,7 +11,6 @@ enum Provider {
import {
CONTENT_SOURCES,
IMAGE_BUILDER_API,
PROVISIONING_SOURCES_ENDPOINT,
RHSM_API,
} from '../constants';
@ -27,10 +26,6 @@ export const apiSlice = createApi({
query: (sourceId) =>
`${PROVISIONING_SOURCES_ENDPOINT}/sources/${sourceId}/upload_info`
}),
getArchitecturesByDistribution: builder.query<Architectures, string>({
query: (distribution) =>
`${IMAGE_BUILDER_API}/architectures/${distribution}`,
}),
getActivationKeys: builder.query<ActivationKeys[], void>({
query: () => `${RHSM_API}/activation_keys`,
}),
@ -40,29 +35,13 @@ export const apiSlice = createApi({
getRepositories: builder.query<RepositoryCollectionResponse, GetRepositoriesArgs>({
query: ({available_for_arch, available_for_version, limit, offset}) => `${CONTENT_SOURCES}/repositories/?available_for_arch=${available_for_arch}&available_for_version=${available_for_version}&limit=${limit}&offset=${offset}`,
}),
getClones: builder.query<ClonesResponse, string>({
query: (composeId) => `${IMAGE_BUILDER_API}/composes/${composeId}/clones`,
}),
getCloneStatus: builder.query<UploadStatus, string>({
query: (cloneId) => `${IMAGE_BUILDER_API}/clones/${cloneId}`,
}),
getComposes: builder.query<ComposesResponse, void>({
query: () => `${IMAGE_BUILDER_API}/composes`,
}),
getComposeStatus: builder.query<ComposeStatus, string>({
query: (composeId) => `${IMAGE_BUILDER_API}/composes/${composeId}`,
}),
}),
});
export const {
useGetArchitecturesByDistributionQuery,
useGetActivationKeysQuery,
useGetActivationKeyInformationQuery,
useGetRepositoriesQuery,
useGetClonesQuery,
useGetCloneStatusQuery,
useGetComposeStatusQuery,
useGetSourcesQuery,
useGetSourceDetailQuery,
usePrefetch,

View file

@ -0,0 +1,9 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import {IMAGE_BUILDER_API} from '../constants'
// initialize an empty api service that we'll inject endpoints into later as needed
export const emptyImageBuilderApi = createApi({
reducerPath: 'imageBuilderApi',
baseQuery: fetchBaseQuery({ baseUrl: IMAGE_BUILDER_API }),
endpoints: () => ({}),
})

View file

@ -0,0 +1,290 @@
import { emptyImageBuilderApi as api } from "./emptyImageBuilderApi";
const injectedRtkApi = api.injectEndpoints({
endpoints: (build) => ({
getArchitectures: build.query<
GetArchitecturesApiResponse,
GetArchitecturesApiArg
>({
query: (queryArg) => ({ url: `/architectures/${queryArg.distribution}` }),
}),
getCloneStatus: build.query<
GetCloneStatusApiResponse,
GetCloneStatusApiArg
>({
query: (queryArg) => ({ url: `/clones/${queryArg.id}` }),
}),
getComposes: build.query<GetComposesApiResponse, GetComposesApiArg>({
query: (queryArg) => ({
url: `/composes`,
params: { limit: queryArg.limit, offset: queryArg.offset },
}),
}),
getComposeStatus: build.query<
GetComposeStatusApiResponse,
GetComposeStatusApiArg
>({
query: (queryArg) => ({ url: `/composes/${queryArg.composeId}` }),
}),
getComposeClones: build.query<
GetComposeClonesApiResponse,
GetComposeClonesApiArg
>({
query: (queryArg) => ({
url: `/composes/${queryArg.composeId}/clones`,
params: { limit: queryArg.limit, offset: queryArg.offset },
}),
}),
}),
overrideExisting: false,
});
export { injectedRtkApi as imageBuilderApi };
export type GetArchitecturesApiResponse =
/** status 200 a list of available architectures and their associated image types */ Architectures;
export type GetArchitecturesApiArg = {
/** distribution for which to look up available architectures */
distribution: string;
};
export type GetCloneStatusApiResponse =
/** status 200 clone status */ UploadStatus;
export type GetCloneStatusApiArg = {
/** Id of clone status to get */
id: string;
};
export type GetComposesApiResponse =
/** status 200 a list of composes */ ComposesResponse;
export type GetComposesApiArg = {
/** max amount of composes, default 100 */
limit?: number;
/** composes page offset, default 0 */
offset?: number;
};
export type GetComposeStatusApiResponse =
/** status 200 compose status */ ComposeStatus;
export type GetComposeStatusApiArg = {
/** Id of compose */
composeId: string;
};
export type GetComposeClonesApiResponse =
/** status 200 compose clones */ ClonesResponse;
export type GetComposeClonesApiArg = {
/** Id of compose to get the clones of */
composeId: string;
/** max amount of clones, default 100 */
limit?: number;
/** clones page offset, default 0 */
offset?: number;
};
export type Repository = {
baseurl?: string;
check_gpg?: boolean;
check_repo_gpg?: boolean;
gpgkey?: string;
ignore_ssl?: boolean;
metalink?: string;
mirrorlist?: string;
rhsm: boolean;
};
export type ArchitectureItem = {
arch: string;
image_types: string[];
repositories: Repository[];
};
export type Architectures = ArchitectureItem[];
export type AwsUploadStatus = {
ami: string;
region: string;
};
export type Awss3UploadStatus = {
url: string;
};
export type GcpUploadStatus = {
image_name: string;
project_id: string;
};
export type AzureUploadStatus = {
image_name: string;
};
export type UploadTypes = "aws" | "gcp" | "azure" | "aws.s3";
export type UploadStatus = {
options:
| AwsUploadStatus
| Awss3UploadStatus
| GcpUploadStatus
| AzureUploadStatus;
status: "success" | "failure" | "pending" | "running";
type: UploadTypes;
};
export type ComposesResponseItem = {
created_at: string;
id: string;
image_name?: string;
request: any;
};
export type ComposesResponse = {
data: ComposesResponseItem[];
links: {
first: string;
last: string;
};
meta: {
count: number;
};
};
export type ComposeStatusError = {
details?: any;
id: number;
reason: string;
};
export type ImageStatus = {
error?: ComposeStatusError;
status:
| "success"
| "failure"
| "pending"
| "building"
| "uploading"
| "registering";
upload_status?: UploadStatus;
};
export type CustomRepository = {
baseurl?: string[];
check_gpg?: boolean;
check_repo_gpg?: boolean;
enabled?: boolean;
filename?: string;
gpgkey?: string[];
id: string;
metalink?: string;
mirrorlist?: string;
name?: string;
priority?: number;
ssl_verify?: boolean;
};
export type Filesystem = {
min_size: any;
mountpoint: string;
};
export type OpenScap = {
profile_id: string;
};
export type Subscription = {
"activation-key": string;
"base-url": string;
insights: boolean;
organization: number;
rhc?: boolean;
"server-url": string;
};
export type User = {
name: string;
ssh_key: string;
};
export type Customizations = {
custom_repositories?: CustomRepository[];
filesystem?: Filesystem[];
openscap?: OpenScap;
packages?: string[];
payload_repositories?: Repository[];
subscription?: Subscription;
users?: User[];
};
export type Distributions =
| "rhel-8"
| "rhel-8-nightly"
| "rhel-84"
| "rhel-85"
| "rhel-86"
| "rhel-87"
| "rhel-88"
| "rhel-9"
| "rhel-9-nightly"
| "rhel-90"
| "rhel-91"
| "rhel-92"
| "centos-8"
| "centos-9"
| "fedora-37"
| "fedora-38"
| "fedora-39";
export type ImageTypes =
| "aws"
| "azure"
| "edge-commit"
| "edge-installer"
| "gcp"
| "guest-image"
| "image-installer"
| "vsphere"
| "vsphere-ova"
| "ami"
| "rhel-edge-commit"
| "rhel-edge-installer"
| "vhd";
export type OsTree = {
contenturl?: string;
parent?: string;
ref?: string;
rhsm?: boolean;
url?: string;
};
export type AwsUploadRequestOptions = {
share_with_accounts?: string[];
share_with_sources?: string[];
};
export type Awss3UploadRequestOptions = object;
export type GcpUploadRequestOptions = {
share_with_accounts: string[];
};
export type AzureUploadRequestOptions = {
image_name?: string;
resource_group: string;
source_id?: string;
subscription_id?: string;
tenant_id?: string;
};
export type UploadRequest = {
options:
| AwsUploadRequestOptions
| Awss3UploadRequestOptions
| GcpUploadRequestOptions
| AzureUploadRequestOptions;
type: UploadTypes;
};
export type ImageRequest = {
architecture: "x86_64" | "aarch64";
image_type: ImageTypes;
ostree?: OsTree;
upload_request: UploadRequest;
};
export type ComposeRequest = {
customizations?: Customizations;
distribution: Distributions;
image_name?: string;
image_requests: ImageRequest[];
};
export type ComposeStatus = {
image_status: ImageStatus;
request: ComposeRequest;
};
export type ClonesResponseItem = {
created_at: string;
id: string;
request: any;
};
export type ClonesResponse = {
data: ClonesResponseItem[];
links: {
first: string;
last: string;
};
meta: {
count: number;
};
};
export const {
useGetArchitecturesQuery,
useGetCloneStatusQuery,
useGetComposesQuery,
useGetComposeStatusQuery,
useGetComposeClonesQuery,
} = injectedRtkApi;

View file

@ -5,15 +5,20 @@ import promiseMiddleware from 'redux-promise-middleware';
import { apiSlice } from './apiSlice';
import clonesSlice from './clonesSlice';
import composesSlice from './composesSlice';
import { imageBuilderApi } from './imageBuilderApi';
export const reducer = {
[apiSlice.reducerPath]: apiSlice.reducer,
clones: clonesSlice,
composes: composesSlice,
[imageBuilderApi.reducerPath]: imageBuilderApi.reducer,
notifications: notificationsReducer,
};
export const middleware = (getDefaultMiddleware) =>
getDefaultMiddleware().concat(promiseMiddleware).concat(apiSlice.middleware);
getDefaultMiddleware()
.concat(promiseMiddleware)
.concat(apiSlice.middleware)
.concat(imageBuilderApi.middleware);
export const store = configureStore({ reducer, middleware });