From 5057b95f82e5617796cc7f480bac8c539622ddb4 Mon Sep 17 00:00:00 2001 From: sdess09 <37374498+sdess09@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:55:50 -0400 Subject: [PATCH] Fix GCP Preflight Checks (#3613) --- .../src/components/GCPCredentialsForm.tsx | 98 ++++++++++------- .../src/components/GCPProvisionerSettings.tsx | 103 ++++++++++-------- dashboard/src/components/PreflightChecks.tsx | 11 +- dashboard/src/shared/util.ts | 1 + 4 files changed, 126 insertions(+), 87 deletions(-) diff --git a/dashboard/src/components/GCPCredentialsForm.tsx b/dashboard/src/components/GCPCredentialsForm.tsx index 4edf23e8a9..2f6b0761d9 100644 --- a/dashboard/src/components/GCPCredentialsForm.tsx +++ b/dashboard/src/components/GCPCredentialsForm.tsx @@ -12,6 +12,9 @@ import Text from "components/porter/Text"; import Button from "components/porter/Button"; import Spacer from "./porter/Spacer"; import Container from "./porter/Container"; +import VerticalSteps from "./porter/VerticalSteps"; +import Link from "./porter/Link"; +import { Flex } from "main/home/cluster-dashboard/stacks/components/styles"; type Props = { @@ -28,8 +31,7 @@ const GCPCredentialsForm: React.FC = ({ goBack, proceed }) => { const [errorMessage, setErrorMessage] = useState(""); const [detected, setDetected] = useState(undefined); const [gcpCloudProviderCredentialID, setGCPCloudProviderCredentialId] = useState("") - - + const [step, setStep] = useState(0); useEffect(() => { setDetected(undefined); }, []); @@ -133,7 +135,9 @@ const GCPCredentialsForm: React.FC = ({ goBack, proceed }) => { setIsContinueEnabled(true); } - + const incrementStep = () => { + setStep(step + 1) + } return ( <> @@ -146,44 +150,59 @@ const GCPCredentialsForm: React.FC = ({ goBack, proceed }) => { Set GKE credentials - Service account credentials for GCP permissions. - handleLoadJSON(x)} - label="🔒 GCP Key Data (JSON)" - placeholder="Drag a GCP Service Account JSON here, or click to browse." - width="100%" - height="100%" - isRequired={true} - /> - - {detected && serviceAccountKey && (<> - - - <> - - {detected.detected ? ( + + + Create the service account + + + Follow the steps in the Porter docs to generate your service account credentials + + + + , + <> + Upload service account credentials + + handleLoadJSON(x)} + label="🔒 GCP Key Data (JSON)" + placeholder="Drag a GCP Service Account JSON here, or click to browse." + width="100%" + height="100%" + isRequired={true} + /> + + {detected && serviceAccountKey && (<> <> - check + + {detected.detected ? ( + <> + {incrementStep} + check + + ) : ( + error + )} + + + {detected.message} + + + - ) : ( - error + )} - - - {detected.message} - - - - - - )} - - - - + + + + ].filter((x) => x)} + /> ); }; @@ -266,4 +285,5 @@ const StatusIcon = styled.img` top: 20px; right: 20px; height: 18px; - `; \ No newline at end of file + `; + diff --git a/dashboard/src/components/GCPProvisionerSettings.tsx b/dashboard/src/components/GCPProvisionerSettings.tsx index 8e39f5253b..6e927c0bb3 100644 --- a/dashboard/src/components/GCPProvisionerSettings.tsx +++ b/dashboard/src/components/GCPProvisionerSettings.tsx @@ -90,6 +90,7 @@ const GCPProvisionerSettings: React.FC = (props) => { const [preflightFailed, setPreflightFailed] = useState(true) const [isLoading, setIsLoading] = useState(false); const [isExpanded, setIsExpanded] = useState(false); + const [preflightError, setPreflightError] = useState("") const markStepStarted = async (step: string, region?: string) => { try { @@ -218,7 +219,7 @@ const GCPProvisionerSettings: React.FC = (props) => { setIsLoading(true); setIsClicked(true); - + try { window.dataLayer?.push({ @@ -231,7 +232,7 @@ const GCPProvisionerSettings: React.FC = (props) => { } catch (err) { console.log(err); } - + var data = new Contract({ cluster: new Cluster({ projectId: currentProject.id, @@ -384,57 +385,65 @@ const GCPProvisionerSettings: React.FC = (props) => { useEffect(() => { if (statusPreflight() == "" && !props.clusterId) { setStep(1) - setPreflightData(null) + preflightChecks() } }, [props.selectedClusterVersion, clusterNetworking, region]); const preflightChecks = async () => { - setIsLoading(true); - setPreflightData(null); - var data = new PreflightCheckRequest({ - projectId: BigInt(currentProject.id), - cloudProvider: EnumCloudProvider.GCP, - cloudProviderCredentialsId: props.credentialId, - preflightValues: { - case: "gkePreflightValues", - value: new GKEPreflightValues({ - network: new GKENetwork({ - cidrRange: clusterNetworking.cidrRange || defaultClusterNetworking.cidrRange, - controlPlaneCidr: defaultClusterNetworking.controlPlaneCidr, - podCidr: defaultClusterNetworking.podCidr, - serviceCidr: defaultClusterNetworking.serviceCidr, + + try { + setIsLoading(true); + setPreflightData(null); + setPreflightFailed(true) + setPreflightError(""); + var data = new PreflightCheckRequest({ + projectId: BigInt(currentProject.id), + cloudProvider: EnumCloudProvider.GCP, + cloudProviderCredentialsId: props.credentialId, + preflightValues: { + case: "gkePreflightValues", + value: new GKEPreflightValues({ + network: new GKENetwork({ + cidrRange: clusterNetworking.cidrRange || defaultClusterNetworking.cidrRange, + controlPlaneCidr: defaultClusterNetworking.controlPlaneCidr, + podCidr: defaultClusterNetworking.podCidr, + serviceCidr: defaultClusterNetworking.serviceCidr, + }) }) - }) + } + }); + const preflightDataResp = await api.preflightCheck( + "", data, + { + id: currentProject.id, + } + ) + // Check if any of the preflight checks has a message + let hasMessage = false; + let errors = "Preflight Checks Failed : "; + for (let check in preflightDataResp?.data?.Msg.preflight_checks) { + if (preflightDataResp?.data?.Msg.preflight_checks[check]?.message) { + hasMessage = true; + errors = errors + check + ", " + } } - }); - const preflightDataResp = await api.preflightCheck( - "", data, - { - id: currentProject.id, + // If none of the checks have a message, set setPreflightFailed to false + if (hasMessage) { + markStepStarted("provisioning-failed", errors); } - ) - // Check if any of the preflight checks has a message - let hasMessage = false; - let errors = "Preflight Checks Failed : "; - for (let check in preflightDataResp?.data?.Msg.preflight_checks) { - if (preflightDataResp?.data?.Msg.preflight_checks[check]?.message) { - hasMessage = true; - errors = errors + check + ", " + if (!hasMessage) { + setPreflightFailed(false); + setStep(2); } + setPreflightData(preflightDataResp?.data?.Msg); + setIsLoading(false) + } catch (err) { + setPreflightError(err) + setIsLoading(false) + setPreflightFailed(true); } - // If none of the checks have a message, set setPreflightFailed to false - if (hasMessage) { - markStepStarted("provisioning-failed", errors); - } - if (!hasMessage) { - setPreflightFailed(false); - setStep(2); - } - setPreflightData(preflightDataResp?.data?.Msg); - setIsLoading(false) - } const renderForm = () => { @@ -465,13 +474,13 @@ const GCPProvisionerSettings: React.FC = (props) => { , <> - + - {(preflightFailed && preflightData) && + {(preflightFailed && preflightData || preflightError) && <> - + {!preflightError && Preflight checks for the account didn't pass. Please fix the issues and retry. - + } < Button // disabled={isDisabled()} disabled={isLoading} @@ -505,7 +514,7 @@ const GCPProvisionerSettings: React.FC = (props) => { = (props) => { { props.error ? - + props.provider === 'AWS' ? + : + <> + + + + Check to see if billing is enabled on your account + + + : Object.keys(currentMessageConst).map((checkKey) => ( diff --git a/dashboard/src/shared/util.ts b/dashboard/src/shared/util.ts index aaa8e04387..e88a6799b2 100644 --- a/dashboard/src/shared/util.ts +++ b/dashboard/src/shared/util.ts @@ -31,4 +31,5 @@ export const PREFLIGHT_MESSAGE_CONST_AWS = { export const PREFLIGHT_MESSAGE_CONST_GCP = { "apiEnabled": "APIs enabled on service account", "cidrAvailability": "CIDR availability", + "iamPermissions:": "IAM permissions", } \ No newline at end of file