From 40132bfdb5bcba818a49c3750c1ee98957666703 Mon Sep 17 00:00:00 2001 From: Sanne Raymaekers Date: Thu, 28 Nov 2024 13:22:41 +0100 Subject: [PATCH 1/3] Wizard: Add component to select Azure HyperV generation --- .../Azure/AzureHyperVSelect.tsx | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/Components/CreateImageWizard/steps/TargetEnvironment/Azure/AzureHyperVSelect.tsx diff --git a/src/Components/CreateImageWizard/steps/TargetEnvironment/Azure/AzureHyperVSelect.tsx b/src/Components/CreateImageWizard/steps/TargetEnvironment/Azure/AzureHyperVSelect.tsx new file mode 100644 index 000000000..e69d0374b --- /dev/null +++ b/src/Components/CreateImageWizard/steps/TargetEnvironment/Azure/AzureHyperVSelect.tsx @@ -0,0 +1,68 @@ +import React, { useState } from 'react'; + +import { FormGroup } from '@patternfly/react-core'; +import { + Select, + SelectOption, + SelectVariant, +} from '@patternfly/react-core/deprecated'; + +import { useAppDispatch, useAppSelector } from '../../../../../store/hooks'; +import { + changeAzureHyperVGeneration, + selectAzureHyperVGeneration, +} from '../../../../../store/wizardSlice'; + +export const AzureHyperVSelect = () => { + const hyperVGeneration = useAppSelector(selectAzureHyperVGeneration); + const dispatch = useAppDispatch(); + const [isOpen, setIsOpen] = useState(false); + + const handleSelect = (_event: React.MouseEvent, selection: 'V1' | 'V2') => { + dispatch(changeAzureHyperVGeneration(selection)); + setIsOpen(false); + }; + + const handleToggle = () => { + setIsOpen(!isOpen); + }; + + const selectOptions = [ + , + , + ]; + + return ( + <> + + + + + ); +}; From 0209b13c0cbd4d1f248b6352a3a8c585730131ea Mon Sep 17 00:00:00 2001 From: Sanne Raymaekers Date: Thu, 28 Nov 2024 13:23:23 +0100 Subject: [PATCH 2/3] Wizard: Integrate HyperV selection in Azure target options This determines the generation the image will get registered as in Azure. V2 supports UEFI and more instance types than V1. --- .../steps/TargetEnvironment/Azure/index.tsx | 2 ++ .../CreateImageWizard/utilities/requestMapper.ts | 4 ++++ src/store/wizardSlice.ts | 13 +++++++++++++ 3 files changed, 19 insertions(+) diff --git a/src/Components/CreateImageWizard/steps/TargetEnvironment/Azure/index.tsx b/src/Components/CreateImageWizard/steps/TargetEnvironment/Azure/index.tsx index 00257c236..631629f54 100644 --- a/src/Components/CreateImageWizard/steps/TargetEnvironment/Azure/index.tsx +++ b/src/Components/CreateImageWizard/steps/TargetEnvironment/Azure/index.tsx @@ -14,6 +14,7 @@ import { import { ExternalLinkAltIcon } from '@patternfly/react-icons'; import { AzureAuthButton } from './AzureAuthButton'; +import { AzureHyperVSelect } from './AzureHyperVSelect'; import { AzureResourceGroups } from './AzureResourceGroups'; import { AzureSourcesSelect } from './AzureSourcesSelect'; @@ -91,6 +92,7 @@ const Azure = () => { Learn more about OAuth 2.0 + { return state.wizard.azure.resourceGroup; }; +export const selectAzureHyperVGeneration = (state: RootState) => { + return state.wizard.azure.hyperVGeneration; +}; + export const selectGcpShareMethod = (state: RootState) => { return state.wizard.gcp.shareMethod; }; @@ -406,6 +412,12 @@ export const wizardSlice = createSlice({ changeAzureResourceGroup: (state, action: PayloadAction) => { state.azure.resourceGroup = action.payload; }, + changeAzureHyperVGeneration: ( + state, + action: PayloadAction<'V1' | 'V2'> + ) => { + state.azure.hyperVGeneration = action.payload; + }, reinitializeAzure: (state) => { state.azure.shareMethod = 'sources'; state.azure.tenantId = ''; @@ -690,6 +702,7 @@ export const { changeAzureSubscriptionId, changeAzureSource, changeAzureResourceGroup, + changeAzureHyperVGeneration, reinitializeAzure, changeGcpShareMethod, changeGcpAccountType, From 2af741faba4227bbd9959f960b9e042ae8d07b88 Mon Sep 17 00:00:00 2001 From: Sanne Raymaekers Date: Thu, 28 Nov 2024 13:30:25 +0100 Subject: [PATCH 3/3] src/test: Add test for HyperV generation --- .../TargetEnvironment/AzureTarget.test.tsx | 49 +++++++++++++++++++ src/test/fixtures/composes.ts | 3 ++ src/test/fixtures/editMode.ts | 1 + 3 files changed, 53 insertions(+) diff --git a/src/test/Components/CreateImageWizard/steps/TargetEnvironment/AzureTarget.test.tsx b/src/test/Components/CreateImageWizard/steps/TargetEnvironment/AzureTarget.test.tsx index 6f40783ee..e5db8f214 100644 --- a/src/test/Components/CreateImageWizard/steps/TargetEnvironment/AzureTarget.test.tsx +++ b/src/test/Components/CreateImageWizard/steps/TargetEnvironment/AzureTarget.test.tsx @@ -152,6 +152,19 @@ const enterSubscriptionId = async () => { ); }; +const selectV2 = async () => { + const user = userEvent.setup(); + const hypervMenu = screen.getAllByRole('button', { + name: /options menu/i, + })[0]; + + await waitFor(() => user.click(hypervMenu)); + const v2 = await screen.findByRole('option', { + name: /v2/i, + }); + await waitFor(() => user.click(v2)); +}; + const getResourceGroupInput = async () => { const resourceGroupInput = await screen.findByRole('textbox', { name: /resource group/i, @@ -326,6 +339,7 @@ describe('Azure image type request generated correctly', () => { options: { source_id: '666', resource_group: 'myResourceGroup1', + hyper_v_generation: 'V1', }, type: 'azure', }, @@ -359,6 +373,41 @@ describe('Azure image type request generated correctly', () => { tenant_id: 'b8f86d22-4371-46ce-95e7-65c415f3b1e2', subscription_id: '60631143-a7dc-4d15-988b-ba83f3c99711', resource_group: 'testResourceGroup', + hyper_v_generation: 'V1', + }, + }, + }; + + const expectedRequest: CreateBlueprintRequest = { + ...blueprintRequest, + image_requests: [expectedImageRequest], + }; + + expect(receivedRequest).toEqual(expectedRequest); + }); + + test('manually entering info V2', async () => { + await renderCreateMode(); + await selectAzureTarget(); + await goToAzureStep(); + await selectManuallyEnterInformation(); + await enterTenantGuid(); + await enterSubscriptionId(); + await enterResourceGroup(); + await selectV2(); + await goToReview(); + const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT); + + const expectedImageRequest: ImageRequest = { + architecture: 'x86_64', + image_type: 'azure', + upload_request: { + type: 'azure', + options: { + tenant_id: 'b8f86d22-4371-46ce-95e7-65c415f3b1e2', + subscription_id: '60631143-a7dc-4d15-988b-ba83f3c99711', + resource_group: 'testResourceGroup', + hyper_v_generation: 'V2', }, }, }; diff --git a/src/test/fixtures/composes.ts b/src/test/fixtures/composes.ts index a691f8b17..a3bb2c5c6 100644 --- a/src/test/fixtures/composes.ts +++ b/src/test/fixtures/composes.ts @@ -203,6 +203,7 @@ export const mockComposes: ComposesResponseItem[] = [ type: 'azure', options: { resource_group: 'my_resource_group', + hyper_v_generation: 'V1', }, }, }, @@ -352,6 +353,7 @@ export const mockComposes: ComposesResponseItem[] = [ type: 'azure', options: { resource_group: 'my_resource_group', + hyper_v_generation: 'V1', }, }, }, @@ -648,6 +650,7 @@ export const mockStatus = (composeId: string): ComposeStatus => { type: 'azure', options: { resource_group: 'my_resource_group', + hyper_v_generation: 'V1', }, }, }, diff --git a/src/test/fixtures/editMode.ts b/src/test/fixtures/editMode.ts index 6771438c8..5b8fbdae5 100644 --- a/src/test/fixtures/editMode.ts +++ b/src/test/fixtures/editMode.ts @@ -306,6 +306,7 @@ export const azureImageRequest: ImageRequest = { options: { source_id: '666', resource_group: 'myResourceGroup1', + hyper_v_generation: 'V1', }, type: 'azure', },