Parcourir la source

move logic for go back/next step out of shared status

Alexander Belanger il y a 4 ans
Parent
commit
85e7594655

+ 7 - 5
dashboard/src/main/home/dashboard/Dashboard.tsx

@@ -106,11 +106,13 @@ class Dashboard extends Component<PropsType, StateType> {
 
   renderTabContents = () => {
     if (this.currentTab() === "provisioner") {
-      return <SharedStatus 
-        filter={[]} 
-        project_id={this.props.projectId} 
-        nextFormStep={() => null} 
-      />
+      return (
+        <SharedStatus
+          filter={[]}
+          project_id={this.props.projectId}
+          setInfraStatus={(val: string) => null}
+        />
+      );
     } else if (this.currentTab() === "create-cluster") {
       let helperText = "Create a cluster to link to this project";
       let helperIcon = "info";

+ 55 - 18
dashboard/src/main/home/onboarding/steps/ProvisionResources/ProvisionResources.tsx

@@ -1,7 +1,7 @@
 import Helper from "components/form-components/Helper";
 import SaveButton from "components/SaveButton";
 import TitleSection from "components/TitleSection";
-import React from "react";
+import React, { useState } from "react";
 import { useParams } from "react-router";
 import styled from "styled-components";
 import ProviderSelector, {
@@ -44,6 +44,55 @@ const ProvisionResources: React.FC<Props> = ({
   goBack,
 }) => {
   const { step } = useParams<{ step: any }>();
+  const [infraStatus, setInfraStatus] = useState("creating");
+
+  const renderSaveButton = () => {
+    if (infraStatus == "created") {
+      return (
+        <>
+          <Br height="15px" />
+          <SaveButton
+            text="Continue"
+            disabled={false}
+            onClick={onSuccess}
+            makeFlush={true}
+            clearPosition={true}
+            statusPosition="right"
+            saveText=""
+          />
+        </>
+      );
+    } else if (infraStatus == "error") {
+      return (
+        <>
+          <Br height="15px" />
+          <SaveButton
+            text="Resolve Errors"
+            status="Encountered errors while provisioning."
+            disabled={false}
+            onClick={goBack}
+            makeFlush={true}
+            clearPosition={true}
+            statusPosition="right"
+            saveText=""
+          />
+        </>
+      );
+    }
+  };
+
+  const getFilterOpts = (): string[] => {
+    switch (provider) {
+      case "aws":
+        return ["eks", "ecr"];
+      case "gcp":
+        return ["gke", "gcr"];
+      case "do":
+        return ["doks", "docr"];
+    }
+
+    return [];
+  };
 
   const Content = () => {
     switch (step) {
@@ -64,24 +113,12 @@ const ProvisionResources: React.FC<Props> = ({
           <>
             <SharedStatus
               project_id={project?.id}
-              filter={[]}
-              nextFormStep={onSuccess}
-              goBack={goBack}
+              filter={getFilterOpts()}
+              setInfraStatus={setInfraStatus}
             />
             <Br />
-            <Helper>
-              Note: Provisioning can take up to 15 minutes.
-            </Helper>
-            <Br height="15px" />
-            <SaveButton
-              text="Continue"
-              disabled={false}
-              onClick={() => alert("continue")}
-              makeFlush={true}
-              clearPosition={true}
-              statusPosition="right"
-              saveText=""
-            />
+            <Helper>Note: Provisioning can take up to 15 minutes.</Helper>
+            {renderSaveButton()}
           </>
         );
       case "connect_own_cluster":
@@ -134,7 +171,7 @@ export default ProvisionResources;
 
 const Br = styled.div<{ height?: string }>`
   width: 100%;
-  height: ${props => props.height || "1px"};
+  height: ${(props) => props.height || "1px"};
   margin-top: -3px;
 `;
 

+ 61 - 11
dashboard/src/main/home/onboarding/steps/ProvisionResources/forms/SharedStatus.tsx

@@ -8,11 +8,10 @@ import api from "shared/api";
 import { useWebsockets } from "shared/hooks/useWebsockets";
 
 export const SharedStatus: React.FC<{
-  nextFormStep: () => void;
+  setInfraStatus: (status: string) => void;
   project_id: number;
   filter: string[];
-  goBack?: any;
-}> = ({ nextFormStep, project_id, filter, goBack }) => {
+}> = ({ setInfraStatus, project_id, filter }) => {
   const {
     newWebsocket,
     openWebsocket,
@@ -81,6 +80,65 @@ export const SharedStatus: React.FC<{
     setTFModules([...tfModules]);
   };
 
+  useEffect(() => {
+    setInfraStatus("created");
+
+    // recompute tf module state each time, to see if infra is ready
+    if (tfModules.length > 0) {
+      // see if all tf modules are in a "created" state
+      if (
+        tfModules.filter((val) => val.status == "created").length ==
+        tfModules.length
+      ) {
+        setInfraStatus("created");
+        return;
+      }
+
+      if (
+        tfModules.filter((val) => val.status == "error").length ==
+        tfModules.length
+      ) {
+        setInfraStatus("error");
+        return;
+      }
+
+      // otherwise, check that all resources in each module are provisioned. Each module
+      // must have more than one resource
+      let numModulesSuccessful = 0;
+      let numModulesErrored = 0;
+
+      for (let tfModule of tfModules) {
+        if (tfModule.status == "created") {
+          numModulesSuccessful++;
+        } else if (tfModule.status == "error") {
+          numModulesErrored++;
+        } else {
+          let resLength = tfModule.resources?.length;
+          if (resLength > 0) {
+            numModulesSuccessful +=
+              tfModule.resources.filter((resource) => resource.provisioned)
+                .length == resLength
+                ? 1
+                : 0;
+
+            numModulesErrored +=
+              tfModule.resources.filter(
+                (resource) => resource.errored?.errored_out
+              ).length > 0
+                ? 1
+                : 0;
+          }
+        }
+      }
+
+      if (numModulesSuccessful == tfModules.length) {
+        setInfraStatus("created");
+      } else if (numModulesErrored == tfModules.length) {
+        setInfraStatus("error");
+      }
+    }
+  }, [tfModules]);
+
   const setupInfraWebsocket = (
     websocketID: string,
     module: TFModule,
@@ -218,7 +276,6 @@ export const SharedStatus: React.FC<{
   useEffect(() => {
     api.getInfra("<token>", {}, { project_id: project_id }).then((res) => {
       var matchedInfras: Map<string, any> = new Map();
-      var numCreated = 0;
 
       res.data.forEach((infra: any) => {
         // if filter list is empty, add infra automatically
@@ -230,15 +287,8 @@ export const SharedStatus: React.FC<{
         ) {
           matchedInfras.set(infra.kind, infra);
         }
-
-        numCreated += infra?.status == "created" ? 1 : 0;
       });
 
-      // if all created, call next form step
-      if (numCreated == res.data.length) {
-        nextFormStep();
-      }
-
       // query for desired and current state, and convert to tf module
       matchedInfras.forEach((infra: any) => {
         var module: TFModule = {

+ 0 - 13
dashboard/src/main/home/onboarding/steps/ProvisionResources/forms/_AWSProvisionerForm.tsx

@@ -279,19 +279,6 @@ export const SettingsForm: React.FC<{
   );
 };
 
-export const Status: React.FC<{
-  nextFormStep: () => void;
-  project: any;
-}> = ({ nextFormStep, project }) => {
-  return (
-    <SharedStatus
-      nextFormStep={nextFormStep}
-      project_id={project?.id}
-      filter={["eks", "ecr"]}
-    />
-  );
-};
-
 const Br = styled.div`
   width: 100%;
   height: 15px;

+ 0 - 13
dashboard/src/main/home/onboarding/steps/ProvisionResources/forms/_DOProvisionerForm.tsx

@@ -235,19 +235,6 @@ export const SettingsForm: React.FC<{
   );
 };
 
-export const Status: React.FC<{
-  nextFormStep: () => void;
-  project: any;
-}> = ({ nextFormStep, project }) => {
-  return (
-    <SharedStatus
-      nextFormStep={nextFormStep}
-      project_id={project?.id}
-      filter={["doks", "docr"]}
-    />
-  );
-};
-
 const Br = styled.div`
   width: 100%;
   height: 15px;

+ 0 - 13
dashboard/src/main/home/onboarding/steps/ProvisionResources/forms/_GCPProvisionerForm.tsx

@@ -252,19 +252,6 @@ export const SettingsForm: React.FC<{
   );
 };
 
-export const Status: React.FC<{
-  nextFormStep: () => void;
-  project: any;
-}> = ({ nextFormStep, project }) => {
-  return (
-    <SharedStatus
-      nextFormStep={nextFormStep}
-      project_id={project?.id}
-      filter={["gke", "gcr"]}
-    />
-  );
-};
-
 const Br = styled.div`
   width: 100%;
   height: 15px;