|
|
@@ -15,10 +15,11 @@ import Button from "./porter/Button";
|
|
|
import Link from "./porter/Link";
|
|
|
import Container from "./porter/Container";
|
|
|
import Step from "./porter/Step";
|
|
|
-import { Box, Step as MuiStep, StepContent, StepLabel, Stepper, ThemeProvider, Typography, createTheme } from "@material-ui/core";
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
import Modal from "./porter/Modal";
|
|
|
import theme from "shared/themes/midnight";
|
|
|
+import VerticalSteps from "./porter/VerticalSteps";
|
|
|
+import PreflightChecks from "./PreflightChecks";
|
|
|
|
|
|
type Props = {
|
|
|
goBack: () => void;
|
|
|
@@ -26,36 +27,6 @@ type Props = {
|
|
|
switchToCredentialFlow: () => void;
|
|
|
};
|
|
|
|
|
|
-const stepperTheme = createTheme({
|
|
|
- palette: {
|
|
|
- background: {
|
|
|
- paper: 'none',
|
|
|
- },
|
|
|
- text: {
|
|
|
- primary: '#DFDFE1',
|
|
|
- secondary: '#aaaabb',
|
|
|
- },
|
|
|
- action: {
|
|
|
- active: '#001E3C',
|
|
|
- },
|
|
|
- },
|
|
|
- typography: {
|
|
|
- fontFamily: "Work Sans, sans-serif",
|
|
|
- },
|
|
|
- overrides: {
|
|
|
- MuiStepIcon: {
|
|
|
- root: {
|
|
|
- '&$completed': {
|
|
|
- color: theme.button,
|
|
|
- },
|
|
|
- '&$active': {
|
|
|
- color: theme.button,
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
-});
|
|
|
-
|
|
|
const CloudFormationForm: React.FC<Props> = ({
|
|
|
goBack,
|
|
|
proceed,
|
|
|
@@ -65,6 +36,7 @@ const CloudFormationForm: React.FC<Props> = ({
|
|
|
const [currentStep, setCurrentStep] = useState<number>(0);
|
|
|
const [hasClickedCloudformationButton, setHasClickedCloudformationButton] = useState(false);
|
|
|
const [showNeedHelpModal, setShowNeedHelpModal] = useState(false);
|
|
|
+ const [preflightData, setPreflightData] = useState<any>(undefined);
|
|
|
|
|
|
const { currentProject, user } = useContext(Context);
|
|
|
const markStepStarted = async (
|
|
|
@@ -116,10 +88,17 @@ const CloudFormationForm: React.FC<Props> = ({
|
|
|
id: currentProject.id,
|
|
|
}
|
|
|
);
|
|
|
+ setPreflightData({
|
|
|
+ "Msg": {
|
|
|
+ "preflight_checks": {
|
|
|
+ cloudFormation: {},
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
return true;
|
|
|
},
|
|
|
{
|
|
|
- enabled: currentStep === 2,
|
|
|
+ enabled: currentStep === 3,
|
|
|
retry: (failureCount, err) => {
|
|
|
// if they've waited over 35 seconds notify us on slack. Cloudformation stack should only take around 20-25 seconds to create
|
|
|
if (failureCount === 7 && hasClickedCloudformationButton) {
|
|
|
@@ -203,6 +182,7 @@ const CloudFormationForm: React.FC<Props> = ({
|
|
|
}
|
|
|
|
|
|
const directToCloudFormation = () => {
|
|
|
+ setCurrentStep(3)
|
|
|
const externalId = getExternalId();
|
|
|
let trustArn = process.env.TRUST_ARN ? process.env.TRUST_ARN : "arn:aws:iam::108458755588:role/CAPIManagement";
|
|
|
const cloudformation_url = `https://console.aws.amazon.com/cloudformation/home?#/stacks/create/review?templateURL=https://porter-role.s3.us-east-2.amazonaws.com/cloudformation-policy.json&stackName=PorterRole¶m_ExternalIdParameter=${externalId}¶m_TrustArnParameter=${trustArn}`
|
|
|
@@ -216,150 +196,168 @@ const CloudFormationForm: React.FC<Props> = ({
|
|
|
<>
|
|
|
<Text>Grant Porter permissions to create infrastructure in your AWS account by following 3 simple steps.</Text>
|
|
|
<Spacer y={1} />
|
|
|
- <ThemeProvider theme={stepperTheme} >
|
|
|
- <Stepper activeStep={currentStep} orientation="vertical" style={{ padding: 0 }}>
|
|
|
- <MuiStep>
|
|
|
- <StepLabel>Log in to your AWS Account.</StepLabel>
|
|
|
- <StepContent>
|
|
|
- <Text color="helper">Return to Porter after successful login.</Text>
|
|
|
- <Spacer y={0.5} />
|
|
|
- <AWSButtonContainer>
|
|
|
- <ButtonImg src={aws} />
|
|
|
- <Button
|
|
|
- width={"170px"}
|
|
|
- onClick={directToAWSLogin}
|
|
|
- color="linear-gradient(180deg, #26292e, #24272c)"
|
|
|
- withBorder
|
|
|
- >
|
|
|
- Log in
|
|
|
- </Button>
|
|
|
- </AWSButtonContainer>
|
|
|
- <Spacer y={0.5} />
|
|
|
- <StepChangeButtonsContainer>
|
|
|
- <Button onClick={() => setCurrentStep(1)}>Continue</Button>
|
|
|
- </StepChangeButtonsContainer>
|
|
|
- </StepContent>
|
|
|
- </MuiStep>
|
|
|
- <MuiStep>
|
|
|
- <StepLabel>Enter your AWS Account ID.</StepLabel>
|
|
|
- <StepContent>
|
|
|
- <Text color="helper">Make sure this is the ID of the account you are currently logged into and would like to provision resources in.</Text>
|
|
|
- <Spacer y={0.5} />
|
|
|
- <Input
|
|
|
- label={
|
|
|
- <Flex>
|
|
|
- 👤 AWS account ID
|
|
|
- <i
|
|
|
- className="material-icons"
|
|
|
- onClick={() => {
|
|
|
- window.open("https://us-east-1.console.aws.amazon.com/billing/home?region=us-east-1#/account", "_blank")
|
|
|
- }}
|
|
|
- >
|
|
|
- help_outline
|
|
|
- </i>
|
|
|
- </Flex>
|
|
|
- }
|
|
|
- value={AWSAccountID}
|
|
|
- setValue={handleAWSAccountIDChange}
|
|
|
- placeholder="ex: 915037676314"
|
|
|
- error={awsAccountIdInputError}
|
|
|
- />
|
|
|
- <Spacer y={0.5} />
|
|
|
- <StepChangeButtonsContainer>
|
|
|
- <Button onClick={handleContinueWithAWSAccountId} disabled={awsAccountIdInputError != null || AWSAccountID.length === 0}>Continue</Button>
|
|
|
- <Spacer inline x={0.5} />
|
|
|
- <Button onClick={() => setCurrentStep(0)} color="#121212">Back</Button>
|
|
|
- </StepChangeButtonsContainer>
|
|
|
- </StepContent>
|
|
|
- </MuiStep>
|
|
|
- <MuiStep>
|
|
|
- <StepLabel optional={<Typography variant="caption" color="textSecondary">This grants Porter permissions to create infrastructure in your account.</Typography>}>Create an AWS Cloudformation Stack.</StepLabel>
|
|
|
- <StepContent>
|
|
|
- <Text color="helper">Clicking the button below will take you to the AWS CloudFormation console. Return to Porter after clicking 'Create stack' in the bottom right corner.</Text>
|
|
|
- <Spacer y={0.5} />
|
|
|
- <AWSButtonContainer>
|
|
|
- <ButtonImg src={aws} />
|
|
|
- <Button
|
|
|
- width={"170px"}
|
|
|
- onClick={directToCloudFormation}
|
|
|
- color="linear-gradient(180deg, #26292e, #24272c)"
|
|
|
- withBorder
|
|
|
- disabled={canProceed}
|
|
|
- disabledTooltipMessage={"Porter can already access your account!"}
|
|
|
- >
|
|
|
- Grant permissions
|
|
|
- </Button>
|
|
|
- </AWSButtonContainer>
|
|
|
- <Spacer y={0.5} />
|
|
|
- <Text color="helper">
|
|
|
- Once the CloudFormation stack has status{" "}
|
|
|
- <Box component="span" color="#1d8102">
|
|
|
- CREATE_COMPLETE
|
|
|
- </Box>, you may proceed.
|
|
|
- </Text>
|
|
|
- <Spacer y={0.25} />
|
|
|
- <Text color="helper">This may take 1 - 2 minutes.</Text>
|
|
|
- <Spacer y={0.5} />
|
|
|
- <StepChangeButtonsContainer>
|
|
|
- <Button onClick={handleProceedToProvisionStep} disabled={!canProceed}>Continue</Button>
|
|
|
- <Spacer inline x={0.5} />
|
|
|
- <Button
|
|
|
- onClick={() => setCurrentStep(1)}
|
|
|
- color="#121212"
|
|
|
- status={canProceed ? "success" : hasClickedCloudformationButton ? "loading" : undefined}
|
|
|
- loadingText={`Checking if Porter can access AWS account ID ${AWSAccountID}...`}
|
|
|
- successText={`Porter can access AWS account ID ${AWSAccountID}`}
|
|
|
- >
|
|
|
- Back
|
|
|
- </Button>
|
|
|
- </StepChangeButtonsContainer>
|
|
|
- <Spacer y={0.5} />
|
|
|
- <Link hasunderline onClick={() => setShowNeedHelpModal(true)}>
|
|
|
+ <VerticalSteps
|
|
|
+ onlyShowCurrentStep={true}
|
|
|
+ currentStep={currentStep}
|
|
|
+ steps={[
|
|
|
+ <>
|
|
|
+ <Text size={16}>Log in to your AWS account</Text>
|
|
|
+ <Spacer y={.5} />
|
|
|
+ <Text color="helper">
|
|
|
+ Return to Porter after successful login.
|
|
|
+ </Text>
|
|
|
+ <Spacer y={.5} />
|
|
|
+ <AWSButtonContainer>
|
|
|
+ <ButtonImg src={aws} />
|
|
|
+ <Button
|
|
|
+ width={"170px"}
|
|
|
+ onClick={directToAWSLogin}
|
|
|
+ color="linear-gradient(180deg, #26292e, #24272c)"
|
|
|
+ withBorder
|
|
|
+ >
|
|
|
+ Log in
|
|
|
+ </Button>
|
|
|
+ </AWSButtonContainer>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Button onClick={() => setCurrentStep(1)}>
|
|
|
+ Continue
|
|
|
+ </Button>
|
|
|
+ </>,
|
|
|
+ <>
|
|
|
+ <Text size={16}>Enter your AWS account ID</Text>
|
|
|
+ <Spacer y={.5} />
|
|
|
+ <Text color="helper">
|
|
|
+ Make sure this is the ID of the account you are currently logged into and would like to provision resources in.
|
|
|
+ </Text>
|
|
|
+ <Spacer y={.5} />
|
|
|
+ <Input
|
|
|
+ label={
|
|
|
+ <Flex>
|
|
|
+ 👤 AWS account ID
|
|
|
+ <i
|
|
|
+ className="material-icons"
|
|
|
+ onClick={() => {
|
|
|
+ window.open("https://us-east-1.console.aws.amazon.com/billing/home?region=us-east-1#/account", "_blank")
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ help_outline
|
|
|
+ </i>
|
|
|
+ </Flex>
|
|
|
+ }
|
|
|
+ value={AWSAccountID}
|
|
|
+ setValue={handleAWSAccountIDChange}
|
|
|
+ placeholder="ex: 915037676314"
|
|
|
+ error={awsAccountIdInputError}
|
|
|
+ />
|
|
|
+ <Spacer y={1} />
|
|
|
+ <StepChangeButtonsContainer>
|
|
|
+ <Button onClick={handleContinueWithAWSAccountId} disabled={awsAccountIdInputError != null || AWSAccountID.length === 0}>Continue</Button>
|
|
|
+ <Spacer inline x={0.5} />
|
|
|
+ <Button onClick={() => setCurrentStep(0)} color="#222222">Back</Button>
|
|
|
+ </StepChangeButtonsContainer>
|
|
|
+ </>,
|
|
|
+ <>
|
|
|
+ <Text size={16}>Create an AWS CloudFormation stack</Text>
|
|
|
+ <Spacer y={.5} />
|
|
|
+ <Text color="helper">
|
|
|
+ This grants Porter permissions to create infrastructure in your account.
|
|
|
+ </Text>
|
|
|
+ <Spacer y={.5} />
|
|
|
+ <Text color="helper">
|
|
|
+ Clicking the button below will take you to the AWS CloudFormation console. Return to Porter after clicking 'Create stack' in the bottom right corner.
|
|
|
+ </Text>
|
|
|
+ <Spacer y={.5} />
|
|
|
+ <AWSButtonContainer>
|
|
|
+ <ButtonImg src={aws} />
|
|
|
+ <Button
|
|
|
+ width={"170px"}
|
|
|
+ onClick={directToCloudFormation}
|
|
|
+ color="linear-gradient(180deg, #26292e, #24272c)"
|
|
|
+ withBorder
|
|
|
+ disabled={canProceed || preflightData}
|
|
|
+ disabledTooltipMessage={"Porter can already access your account!"}
|
|
|
+ >
|
|
|
+ Grant permissions
|
|
|
+ </Button>
|
|
|
+ </AWSButtonContainer>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <StepChangeButtonsContainer>
|
|
|
+ <Button onClick={() => setCurrentStep(3)}>Continue</Button>
|
|
|
+ <Spacer inline x={0.5} />
|
|
|
+ <Button
|
|
|
+ onClick={() => setCurrentStep(1)}
|
|
|
+ color="#222222"
|
|
|
+ // status={canProceed ? "success" : hasClickedCloudformationButton ? "loading" : undefined}
|
|
|
+ loadingText={`Checking if Porter can access AWS account ID ${AWSAccountID}...`}
|
|
|
+ successText={`Porter can access AWS account ID ${AWSAccountID}`}
|
|
|
+ >
|
|
|
+ Back
|
|
|
+ </Button>
|
|
|
+ </StepChangeButtonsContainer>
|
|
|
+ </>,
|
|
|
+ <>
|
|
|
+ <Text size={16}>Check permissions</Text>
|
|
|
+ <Spacer y={.5} />
|
|
|
+ <Text color="helper">
|
|
|
+ Checking if Porter can access AWS account with ID {AWSAccountID}. This can take up to a minute.<Spacer inline width="10px" /><Link hasunderline onClick={() => setShowNeedHelpModal(true)}>
|
|
|
Need help?
|
|
|
</Link>
|
|
|
- </StepContent>
|
|
|
- </MuiStep>
|
|
|
- {showNeedHelpModal &&
|
|
|
- <Modal closeModal={() => setShowNeedHelpModal(false)} width={"800px"}>
|
|
|
- <Text size={16}>Granting Porter access to AWS</Text>
|
|
|
- <Spacer y={1} />
|
|
|
- <Text color="helper">
|
|
|
- Porter needs access to your AWS account in order to create infrastructure. You can grant Porter access to AWS by following these steps:
|
|
|
- </Text>
|
|
|
- <Spacer y={1} />
|
|
|
- <Step number={1}>
|
|
|
- <Link to="https://aws.amazon.com/resources/create-account/" target="_blank">
|
|
|
- Create an AWS account
|
|
|
- </Link>
|
|
|
- <Spacer inline width="5px" />
|
|
|
- if you don't already have one.
|
|
|
- </Step>
|
|
|
- <Spacer y={1} />
|
|
|
- <Step number={2}>
|
|
|
- Once you are logged in to your AWS account,
|
|
|
- <Spacer inline width="5px" />
|
|
|
- <Link to="https://console.aws.amazon.com/billing/home?region=us-east-1#/account" target="_blank">
|
|
|
- copy your account ID
|
|
|
- </Link>.
|
|
|
- </Step>
|
|
|
- <Spacer y={1} />
|
|
|
- <Step number={3}>Fill in your account ID on Porter and select "Grant permissions".</Step>
|
|
|
- <Spacer y={1} />
|
|
|
- <Step number={4}>After being redirected to AWS CloudFormation, select "Create stack" on the bottom right.</Step>
|
|
|
- <Spacer y={1} />
|
|
|
- <Step number={5}>The stack will start to create. Refresh until the stack status has changed from "CREATE_IN_PROGRESS" to "CREATE_COMPLETE":</Step>
|
|
|
- <Spacer y={1} />
|
|
|
- <ImageDiv>
|
|
|
- <img src={cloudformationStatus} height="250px" />
|
|
|
- </ImageDiv>
|
|
|
- <Spacer y={1} />
|
|
|
- <Step number={6}>Return to Porter and select "Continue".</Step>
|
|
|
- <Spacer y={1} />
|
|
|
- <Step number={7}>If you continue to see issues, <a href="mailto:support@porter.run">email support.</a></Step>
|
|
|
- </Modal>
|
|
|
- }
|
|
|
- </Stepper>
|
|
|
- </ThemeProvider>
|
|
|
+ </Text>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <PreflightChecks preflightData={preflightData} provider={"DEFAULT"} />
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Container row>
|
|
|
+ <Button
|
|
|
+ onClick={handleProceedToProvisionStep}
|
|
|
+ disabled={!canProceed}
|
|
|
+ >
|
|
|
+ Continue
|
|
|
+ </Button>
|
|
|
+ <Spacer inline x={0.5} />
|
|
|
+ <Button onClick={() => setCurrentStep(2)} color="#222222">Back</Button>
|
|
|
+ </Container>
|
|
|
+ </>,
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ {showNeedHelpModal &&
|
|
|
+ <Modal closeModal={() => setShowNeedHelpModal(false)} width={"800px"}>
|
|
|
+ <Text size={16}>Granting Porter access to AWS</Text>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Text color="helper">
|
|
|
+ Porter needs access to your AWS account in order to create infrastructure. You can grant Porter access to AWS by following these steps:
|
|
|
+ </Text>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Step number={1}>
|
|
|
+ <Link to="https://aws.amazon.com/resources/create-account/" target="_blank">
|
|
|
+ Create an AWS account
|
|
|
+ </Link>
|
|
|
+ <Spacer inline width="5px" />
|
|
|
+ if you don't already have one.
|
|
|
+ </Step>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Step number={2}>
|
|
|
+ Once you are logged in to your AWS account,
|
|
|
+ <Spacer inline width="5px" />
|
|
|
+ <Link to="https://console.aws.amazon.com/billing/home?region=us-east-1#/account" target="_blank">
|
|
|
+ copy your account ID
|
|
|
+ </Link>.
|
|
|
+ </Step>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Step number={3}>Fill in your account ID on Porter and select "Grant permissions".</Step>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Step number={4}>After being redirected to AWS CloudFormation, select "Create stack" on the bottom right.</Step>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Step number={5}>The stack will start to create. Refresh until the stack status has changed from "CREATE_IN_PROGRESS" to "CREATE_COMPLETE":</Step>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <ImageDiv>
|
|
|
+ <img src={cloudformationStatus} height="250px" />
|
|
|
+ </ImageDiv>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Step number={6}>Return to Porter and select "Continue".</Step>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Step number={7}>If you continue to see issues, <a href="mailto:support@porter.run">email support.</a></Step>
|
|
|
+ </Modal>
|
|
|
+ }
|
|
|
</>
|
|
|
);
|
|
|
}
|