API: Add programatically generated Provisioning 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-27 14:13:43 +02:00 committed by Lucas Garfield
parent 74528356fa
commit 702b667dc5
20 changed files with 2020 additions and 89 deletions

View file

@ -0,0 +1,13 @@
import type { ConfigFile } from '@rtk-query/codegen-openapi'
const config: ConfigFile = {
schemaFile: '../schema/provisioning.json',
apiFile: '../../src/store/emptyProvisioningApi.ts',
apiImport: 'emptyProvisioningApi',
outputFile: '../../src/store/provisioningApi.ts',
exportName: 'provisioningApi',
hooks: true,
filterEndpoints: ['getSourceList', 'getSourceUploadInfo'],
}
export default config

1870
api/schema/provisioning.json Normal file

File diff suppressed because it is too large Load diff

View file

@ -112,7 +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 & npx @rtk-query/codegen-openapi ./api/config/rhsm.ts & npx @rtk-query/codegen-openapi ./api/config/contentSources.ts",
"api": "npx @rtk-query/codegen-openapi ./api/config/image-builder.ts & npx @rtk-query/codegen-openapi ./api/config/rhsm.ts & npx @rtk-query/codegen-openapi ./api/config/contentSources.ts & npx @rtk-query/codegen-openapi ./api/config/provisioning.ts",
"verify": "npm-run-all build lint test"
},
"insights": {

View file

@ -1,10 +0,0 @@
import {useGetSourceDetailQuery} from "../../../store/apiSlice";
type AWSAccountIdProps = {
sourceId: string
}
export const AWSAccountId = ({ sourceId }: AWSAccountIdProps) => {
const { data } = useGetSourceDetailQuery(sourceId);
return <>{data?.aws?.account_id}</>;
};

View file

@ -14,9 +14,9 @@ import {
import PropTypes from 'prop-types';
import {
useGetSourceDetailQuery,
useGetSourcesQuery,
} from '../../../store/apiSlice';
useGetSourceListQuery,
useGetSourceUploadInfoQuery,
} from '../../../store/provisioningApi';
export const AWSSourcesSelect = ({
label,
@ -37,16 +37,19 @@ export const AWSSourcesSelect = ({
isSuccess,
isError,
refetch,
} = useGetSourcesQuery('aws');
} = useGetSourceListQuery({ provider: 'aws' });
const {
data: sourceDetails,
isFetching: isFetchingDetails,
isSuccess: isSuccessDetails,
isError: isErrorDetails,
} = useGetSourceDetailQuery(selectedSourceId, {
skip: !selectedSourceId,
});
} = useGetSourceUploadInfoQuery(
{ id: selectedSourceId },
{
skip: !selectedSourceId,
}
);
useEffect(() => {
if (isFetchingDetails || !isSuccessDetails) return;

View file

@ -0,0 +1,12 @@
import React from 'react';
import {useGetSourceUploadInfoQuery} from "../../../store/provisioningApi";
type AwsAccountIdProps = {
sourceId: number
}
export const AwsAccountId = ({ sourceId }: AwsAccountIdProps) => {
const { data } = useGetSourceUploadInfoQuery({ id: sourceId });
return <>{data?.aws?.account_id}</>;
};

View file

@ -12,7 +12,7 @@ import {
} from '@patternfly/react-core';
import PropTypes from 'prop-types';
import { useGetSourceDetailQuery } from '../../../store/apiSlice';
import { useGetSourceUploadInfoQuery } from '../../../store/provisioningApi';
const AzureResourceGroups = ({ label, isRequired, className, ...props }) => {
const { change, getState } = useFormApi();
@ -25,8 +25,8 @@ const AzureResourceGroups = ({ label, isRequired, className, ...props }) => {
setSourceId(values['azure-sources-select']);
};
const { data: sourceDetails, isFetching } = useGetSourceDetailQuery(
sourceId,
const { data: sourceDetails, isFetching } = useGetSourceUploadInfoQuery(
{ id: sourceId },
{
skip: !sourceId,
}

View file

@ -14,9 +14,9 @@ import {
import PropTypes from 'prop-types';
import {
useGetSourcesQuery,
useGetSourceDetailQuery,
} from '../../../store/apiSlice';
useGetSourceListQuery,
useGetSourceUploadInfoQuery,
} from '../../../store/provisioningApi';
const AzureSourcesSelect = ({ label, isRequired, className, ...props }) => {
const { change } = useFormApi();
@ -30,16 +30,19 @@ const AzureSourcesSelect = ({ label, isRequired, className, ...props }) => {
isSuccess,
isError,
refetch,
} = useGetSourcesQuery('azure');
} = useGetSourceListQuery({ provider: 'azure' });
const {
data: sourceDetails,
isFetching: isFetchingDetails,
isSuccess: isSuccessDetails,
isError: isErrorDetails,
} = useGetSourceDetailQuery(selectedSourceId, {
skip: !selectedSourceId,
});
} = useGetSourceUploadInfoQuery(
{ id: selectedSourceId },
{
skip: !selectedSourceId,
}
);
useEffect(() => {
if (isFetchingDetails || !isSuccessDetails) return;

View file

@ -18,7 +18,7 @@ import { ExclamationTriangleIcon, HelpIcon } from '@patternfly/react-icons';
import PropTypes from 'prop-types';
import ActivationKeyInformation from './ActivationKeyInformation';
import { AWSAccountId } from './AWSAccountId';
import { AwsAccountId } from './AwsAccountId';
import {
FSReviewTable,
PackagesTable,
@ -26,7 +26,7 @@ import {
} from './ReviewStepTables';
import { RELEASES, UNIT_GIB } from '../../../constants';
import { useGetSourcesQuery } from '../../../store/apiSlice';
import { useGetSourceListQuery } from '../../../store/provisioningApi';
import { useShowActivationKeyQuery } from '../../../store/rhsmApi';
import { useGetEnvironment } from '../../../Utilities/useGetEnvironment';
import { googleAccType } from '../steps/googleCloud';
@ -64,7 +64,9 @@ export const ImageOutputList = () => {
};
export const TargetEnvAWSList = () => {
const { data: awsSources, isSuccess } = useGetSourcesQuery();
const { data: awsSources, isSuccess } = useGetSourceListQuery({
provider: 'aws',
});
const { isBeta } = useGetEnvironment();
const { getState } = useFormApi();
@ -92,7 +94,7 @@ export const TargetEnvAWSList = () => {
getState()?.values?.['aws-target-type'] ===
'aws-target-type-source' &&
isSuccess && (
<AWSAccountId
<AwsAccountId
sourceId={getState()?.values?.['aws-sources-select']}
/>
)}
@ -169,7 +171,7 @@ export const TargetEnvGCPList = () => {
export const TargetEnvAzureList = () => {
const { getState } = useFormApi();
const { data: azureSources, isSuccess: isSuccessAzureSources } =
useGetSourcesQuery('azure');
useGetSourceListQuery({ provider: 'azure' });
return (
<TextContent>
<Text component={TextVariants.h3}>Microsoft Azure</Text>

View file

@ -15,7 +15,7 @@ import {
import { HelpIcon } from '@patternfly/react-icons';
import PropTypes from 'prop-types';
import { usePrefetch } from '../../../store/apiSlice';
import { provisioningApi } from '../../../store/provisioningApi';
const TargetEnvironment = ({ label, isRequired, ...props }) => {
const { getState, change } = useFormApi();
@ -29,7 +29,7 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
'guest-image': false,
'image-installer': false,
});
const prefetchSources = usePrefetch('getSources');
const prefetchSources = provisioningApi.usePrefetch('getSourceList');
useEffect(() => {
if (getState()?.values?.[input.name]) {
@ -76,7 +76,7 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
}
onClick={() => handleSetEnvironment('aws', !environment.aws)}
onKeyDown={(e) => handleKeyDown(e, 'aws', !environment.aws)}
onMouseEnter={() => prefetchSources('aws')}
onMouseEnter={() => prefetchSources({ provider: 'aws' })}
isSelected={environment.aws}
isStacked
isDisplayLarge
@ -96,6 +96,7 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
onClick={() => handleSetEnvironment('gcp', !environment.gcp)}
isSelected={environment.gcp}
onKeyDown={(e) => handleKeyDown(e, 'gcp', !environment.gcp)}
onMouseEnter={() => prefetchSources({ provider: 'gcp' })}
isStacked
isDisplayLarge
/>
@ -113,7 +114,7 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
}
onClick={() => handleSetEnvironment('azure', !environment.azure)}
onKeyDown={(e) => handleKeyDown(e, 'azure', !environment.azure)}
onMouseEnter={() => prefetchSources('azure')}
onMouseEnter={() => prefetchSources({ provider: 'azure' })}
isSelected={environment.azure}
isStacked
isDisplayLarge

View file

@ -17,7 +17,7 @@ import { useSelector } from 'react-redux';
import ClonesTable from './ClonesTable';
import { useGetSourcesQuery } from '../../store/apiSlice';
import { useGetSourceListQuery } from '../../store/provisioningApi';
const sourceNotFoundPopover = () => {
return (
@ -59,7 +59,9 @@ const sourceNotFoundPopover = () => {
};
const getAzureSourceName = (id) => {
const { data: sources, isSuccess } = useGetSourcesQuery('azure');
const { data: sources, isSuccess } = useGetSourceListQuery({
provider: 'azure',
});
if (isSuccess) {
const sourcename = sources.find((source) => source.id === id);
@ -74,7 +76,9 @@ const getAzureSourceName = (id) => {
};
const getAWSSourceName = (id) => {
const { data: sources, isSuccess } = useGetSourcesQuery('aws');
const { data: sources, isSuccess } = useGetSourceListQuery({
provider: 'aws',
});
if (isSuccess) {
const sourcename = sources.find((source) => source.id === id);

View file

@ -1,7 +1,7 @@
export const IMAGE_BUILDER_API = '/api/image-builder/v1';
export const RHSM_API = '/api/rhsm/v2';
export const CONTENT_SOURCES_API = '/api/content-sources/v1';
export const PROVISIONING_SOURCES_ENDPOINT = '/api/provisioning/v1';
export const PROVISIONING_API = '/api/provisioning/v1';
export const RHEL_8 = 'rhel-88';
export const RHEL_9 = 'rhel-92';
export const CENTOS_8 = 'centos-8';

View file

@ -1,32 +0,0 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { SourceResponse, SourceUploadInfoResponse } from '../../types';
enum Provider {
'azure',
'aws'
}
import {
PROVISIONING_SOURCES_ENDPOINT,
} from '../constants';
export const apiSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: '' }),
endpoints: (builder) => ({
getSources: builder.query<SourceResponse[], Provider>({
query: (provider) => `${PROVISIONING_SOURCES_ENDPOINT}/sources?provider=${provider}`,
}),
getSourceDetail: builder.query<SourceUploadInfoResponse, string>({
query: (sourceId) =>
`${PROVISIONING_SOURCES_ENDPOINT}/sources/${sourceId}/upload_info`
}),
}),
});
export const {
useGetSourcesQuery,
useGetSourceDetailQuery,
usePrefetch,
} = apiSlice;

View file

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

View file

@ -2,29 +2,29 @@ import { notificationsReducer } from '@redhat-cloud-services/frontend-components
import { configureStore } from '@reduxjs/toolkit';
import promiseMiddleware from 'redux-promise-middleware';
import { apiSlice } from './apiSlice';
import clonesSlice from './clonesSlice';
import composesSlice from './composesSlice';
import { contentSourcesApi } from './contentSourcesApi';
import { imageBuilderApi } from './imageBuilderApi';
import { provisioningApi } from './provisioningApi';
import { rhsmApi } from './rhsmApi';
export const reducer = {
[apiSlice.reducerPath]: apiSlice.reducer,
clones: clonesSlice,
composes: composesSlice,
[contentSourcesApi.reducerPath]: contentSourcesApi.reducer,
[imageBuilderApi.reducerPath]: imageBuilderApi.reducer,
[rhsmApi.reducerPath]: rhsmApi.reducer,
[provisioningApi.reducerPath]: provisioningApi.reducer,
notifications: notificationsReducer,
};
export const middleware = (getDefaultMiddleware) =>
getDefaultMiddleware()
.concat(promiseMiddleware)
.concat(apiSlice.middleware)
.concat(contentSourcesApi.middleware)
.concat(imageBuilderApi.middleware)
.concat(rhsmApi.middleware);
.concat(rhsmApi.middleware)
.concat(provisioningApi.middleware);
export const store = configureStore({ reducer, middleware });

View file

@ -0,0 +1,59 @@
import { emptyProvisioningApi as api } from "./emptyProvisioningApi";
const injectedRtkApi = api.injectEndpoints({
endpoints: (build) => ({
getSourceList: build.query<GetSourceListApiResponse, GetSourceListApiArg>({
query: (queryArg) => ({
url: `/sources`,
params: { provider: queryArg.provider },
}),
}),
getSourceUploadInfo: build.query<
GetSourceUploadInfoApiResponse,
GetSourceUploadInfoApiArg
>({
query: (queryArg) => ({ url: `/sources/${queryArg.id}/upload_info` }),
}),
}),
overrideExisting: false,
});
export { injectedRtkApi as provisioningApi };
export type GetSourceListApiResponse =
/** status 200 Returned on success. */ V1SourceResponse[];
export type GetSourceListApiArg = {
provider?: "aws" | "azure" | "gcp";
};
export type GetSourceUploadInfoApiResponse =
/** status 200 Return on success. */ V1SourceUploadInfoResponse;
export type GetSourceUploadInfoApiArg = {
/** Source ID from Sources Database */
id: number;
};
export type V1SourceResponse = {
id?: string;
name?: string;
source_type_id?: string;
uid?: string;
};
export type V1ResponseError = {
build_time?: string;
edge_id?: string;
environment?: string;
error?: string;
msg?: string;
trace_id?: string;
version?: string;
};
export type V1SourceUploadInfoResponse = {
aws?: {
account_id?: string;
} | null;
azure?: {
resource_groups?: string[];
subscription_id?: string;
tenant_id?: string;
} | null;
gcp?: any | null;
provider?: string;
};
export const { useGetSourceListQuery, useGetSourceUploadInfoQuery } =
injectedRtkApi;

View file

@ -4,7 +4,7 @@ import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { rest } from 'msw';
import { PROVISIONING_SOURCES_ENDPOINT } from '../../../constants.js';
import { PROVISIONING_API } from '../../../constants.js';
import { server } from '../../mocks/server.js';
import { renderWithReduxRouter } from '../../testUtils';
@ -161,7 +161,7 @@ describe('Step Upload to Azure', () => {
test('component renders error state correctly', async () => {
setUp();
server.use(
rest.get(`${PROVISIONING_SOURCES_ENDPOINT}/sources`, (req, res, ctx) =>
rest.get(`${PROVISIONING_API}/sources`, (req, res, ctx) =>
res(ctx.status(500))
)
);

View file

@ -11,11 +11,7 @@ import userEvent from '@testing-library/user-event';
import { rest } from 'msw';
import api from '../../../api.js';
import {
RHEL_8,
RHEL_9,
PROVISIONING_SOURCES_ENDPOINT,
} from '../../../constants.js';
import { RHEL_8, RHEL_9, PROVISIONING_API } from '../../../constants.js';
import { mockComposesEmpty } from '../../fixtures/composes.js';
import { customizations, ids } from '../../fixtures/customizations.js';
import { mockPkgResultAlphaContentSources } from '../../fixtures/packages.js';
@ -127,7 +123,7 @@ describe('Step Upload to AWS', () => {
test('component renders error state correctly', async () => {
setUp();
server.use(
rest.get(`${PROVISIONING_SOURCES_ENDPOINT}/sources`, (req, res, ctx) =>
rest.get(`${PROVISIONING_API}/sources`, (req, res, ctx) =>
res(ctx.status(500))
)
);

View file

@ -3,7 +3,7 @@ import { rest } from 'msw';
import {
CONTENT_SOURCES_API,
IMAGE_BUILDER_API,
PROVISIONING_SOURCES_ENDPOINT,
PROVISIONING_API,
RHSM_API,
} from '../../constants';
import {
@ -25,12 +25,12 @@ import { mockRepositoryResults } from '../fixtures/repositories';
import { mockSourcesByProvider, mockUploadInfo } from '../fixtures/sources';
export const handlers = [
rest.get(`${PROVISIONING_SOURCES_ENDPOINT}/sources`, (req, res, ctx) => {
rest.get(`${PROVISIONING_API}/sources`, (req, res, ctx) => {
const provider = req.url.searchParams.get('provider');
return res(ctx.status(200), ctx.json(mockSourcesByProvider(provider)));
}),
rest.get(
`${PROVISIONING_SOURCES_ENDPOINT}/sources/:sourceId/upload_info`,
`${PROVISIONING_API}/sources/:sourceId/upload_info`,
(req, res, ctx) => {
const { sourceId } = req.params;
if (sourceId === '666' || sourceId === '667' || sourceId === '123') {

View file

@ -7,6 +7,7 @@
"jsx": "react-jsx",
"allowJs": true,
"moduleResolution": "node",
"strictNullChecks": true
"strictNullChecks": true,
"allowSyntheticDefaultImports": true
}
}