|
|
@@ -1,15 +1,4 @@
|
|
|
-import React, {useContext, useEffect, useState} from "react";
|
|
|
-import styled from "styled-components";
|
|
|
-import {type RouteComponentProps, withRouter} from "react-router";
|
|
|
-
|
|
|
-import {OFState} from "main/home/onboarding/state";
|
|
|
-import api from "shared/api";
|
|
|
-import {Context} from "shared/Context";
|
|
|
-import {pushFiltered} from "shared/routing";
|
|
|
-
|
|
|
-import SelectRow from "components/form-components/SelectRow";
|
|
|
-import Heading from "components/form-components/Heading";
|
|
|
-import InputRow from "./form-components/InputRow";
|
|
|
+import React, { useContext, useEffect, useState } from "react";
|
|
|
import {
|
|
|
AKS,
|
|
|
AKSNodePool,
|
|
|
@@ -18,53 +7,46 @@ import {
|
|
|
Contract,
|
|
|
EnumCloudProvider,
|
|
|
EnumKubernetesKind,
|
|
|
- NodePoolType
|
|
|
+ NodePoolType,
|
|
|
} from "@porter-dev/api-contracts";
|
|
|
-import {type ClusterType} from "shared/types";
|
|
|
+import { Label } from "@tanstack/react-query-devtools/build/lib/Explorer";
|
|
|
+import { withRouter, type RouteComponentProps } from "react-router";
|
|
|
+import styled from "styled-components";
|
|
|
+
|
|
|
+import Heading from "components/form-components/Heading";
|
|
|
+import SelectRow from "components/form-components/SelectRow";
|
|
|
+import { OFState } from "main/home/onboarding/state";
|
|
|
+import { useIntercom } from "lib/hooks/useIntercom";
|
|
|
+
|
|
|
+import api from "shared/api";
|
|
|
+import { Context } from "shared/Context";
|
|
|
+import { pushFiltered } from "shared/routing";
|
|
|
+import { type ClusterType } from "shared/types";
|
|
|
+import dotVertical from "assets/dot-vertical.svg";
|
|
|
+
|
|
|
+import {
|
|
|
+ AzureLocationOptions,
|
|
|
+ azureSupportedMachineTypes,
|
|
|
+ type MachineTypeOption,
|
|
|
+} from "./azureUtils";
|
|
|
+import InputRow from "./form-components/InputRow";
|
|
|
import Button from "./porter/Button";
|
|
|
import Error from "./porter/Error";
|
|
|
+import Icon from "./porter/Icon";
|
|
|
+import Link from "./porter/Link";
|
|
|
import Spacer from "./porter/Spacer";
|
|
|
import Step from "./porter/Step";
|
|
|
-import Link from "./porter/Link";
|
|
|
import Text from "./porter/Text";
|
|
|
-import {useIntercom} from "lib/hooks/useIntercom";
|
|
|
-import Icon from "./porter/Icon";
|
|
|
-import dotVertical from "assets/dot-vertical.svg";
|
|
|
-import {Label} from "@tanstack/react-query-devtools/build/lib/Explorer";
|
|
|
-
|
|
|
-const locationOptions = [
|
|
|
- { value: "eastus", label: "East US" },
|
|
|
- { value: "eastus2", label: "East US 2" },
|
|
|
- { value: "westus2", label: "West US 2" },
|
|
|
- { value: "westus3", label: "West US 3" },
|
|
|
- { value: "centralus", label: "Central US" },
|
|
|
- { value: "southcentralus", label: "South Central US" },
|
|
|
- { value: "australiaeast", label: "Australia East" },
|
|
|
- { value: "brazilsouth", label: "Brazil South" },
|
|
|
- { value: "centralindia", label: "Central India" },
|
|
|
- { value: "southcentralus", label: "South Central US" },
|
|
|
- { value: "eastasia", label: "East Asia" },
|
|
|
- { value: "francecentral", label: "France Central" },
|
|
|
- { value: "northeurope", label: "North Europe" },
|
|
|
- { value: "norwayeast", label: "Norway East" },
|
|
|
- { value: "swedencentral", label: "Sweden Central" },
|
|
|
- { value: "switzerlandnorth", label: "Switzerland North" },
|
|
|
- { value: "uksouth", label: "UK South" },
|
|
|
- { value: "westeurope", label: "West Europe" },
|
|
|
-];
|
|
|
-
|
|
|
-const machineTypeOptions = [
|
|
|
- { value: "Standard_B2als_v2", label: "Standard_B2als_v2"},
|
|
|
- { value: "Standard_A2_v2", label: "Standard_A2_v2" },
|
|
|
- { value: "Standard_A4_v2", label: "Standard_A4_v2" },
|
|
|
-];
|
|
|
|
|
|
const skuTierOptions = [
|
|
|
{ value: AksSkuTier.FREE, label: "Free" },
|
|
|
- { value: AksSkuTier.STANDARD, label: "Standard (for production workloads, +$73/month)" },
|
|
|
+ {
|
|
|
+ value: AksSkuTier.STANDARD,
|
|
|
+ label: "Standard (for production workloads, +$73/month)",
|
|
|
+ },
|
|
|
];
|
|
|
|
|
|
-const clusterVersionOptions = [{ value: "v1.27.3", label: "v1.27" }, { value: "v1.24.9", label: "v1.24" }];
|
|
|
+const clusterVersionOptions = [{ value: "v1.27.3", label: "v1.27" }];
|
|
|
|
|
|
type Props = RouteComponentProps & {
|
|
|
selectedClusterVersion?: Contract;
|
|
|
@@ -73,7 +55,8 @@ type Props = RouteComponentProps & {
|
|
|
clusterId?: number;
|
|
|
};
|
|
|
|
|
|
-const VALID_CIDR_RANGE_PATTERN = /^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.0\.0\/16$/;
|
|
|
+const VALID_CIDR_RANGE_PATTERN =
|
|
|
+ /^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.0\.0\/16$/;
|
|
|
|
|
|
const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
const {
|
|
|
@@ -94,18 +77,35 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
const [cidrRange, setCidrRange] = useState("10.78.0.0/16");
|
|
|
const [clusterVersion, setClusterVersion] = useState("v1.27.3");
|
|
|
const [isReadOnly, setIsReadOnly] = useState(false);
|
|
|
- const [skuTier, setSkuTier] = useState(AksSkuTier.FREE)
|
|
|
+ const [skuTier, setSkuTier] = useState(AksSkuTier.FREE);
|
|
|
const [errorMessage, setErrorMessage] = useState<string>("");
|
|
|
const [errorDetails, setErrorDetails] = useState<string>("");
|
|
|
const [isClicked, setIsClicked] = useState(false);
|
|
|
+ const [
|
|
|
+ regionFilteredMachineTypeOptions,
|
|
|
+ setRegionFilteredMachineTypeOptions,
|
|
|
+ ] = useState<MachineTypeOption[]>(azureSupportedMachineTypes(azureLocation));
|
|
|
|
|
|
const { showIntercomWithMessage } = useIntercom();
|
|
|
|
|
|
- const markStepStarted = async (step: string, {region, error_message}: {region?: string; error_message?: string}) => {
|
|
|
+ useEffect(() => {
|
|
|
+ setRegionFilteredMachineTypeOptions(
|
|
|
+ azureSupportedMachineTypes(azureLocation)
|
|
|
+ );
|
|
|
+ }, [azureLocation]);
|
|
|
+
|
|
|
+ const markStepStarted = async (
|
|
|
+ step: string,
|
|
|
+ { region, error_message }: { region?: string; error_message?: string }
|
|
|
+ ) => {
|
|
|
try {
|
|
|
- await api.updateOnboardingStep("<token>", { step, region, error_message, provider: "azure" }, {
|
|
|
- project_id: currentProject.id,
|
|
|
- });
|
|
|
+ await api.updateOnboardingStep(
|
|
|
+ "<token>",
|
|
|
+ { step, region, error_message, provider: "azure" },
|
|
|
+ {
|
|
|
+ project_id: currentProject.id,
|
|
|
+ }
|
|
|
+ );
|
|
|
} catch (err) {
|
|
|
console.log(err);
|
|
|
}
|
|
|
@@ -117,7 +117,11 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
} else if (errorMessage !== "") {
|
|
|
return (
|
|
|
<Error
|
|
|
- message={errorDetails !== "" ? errorMessage + " (" + errorDetails + ")" : errorMessage}
|
|
|
+ message={
|
|
|
+ errorDetails !== ""
|
|
|
+ ? errorMessage + " (" + errorDetails + ")"
|
|
|
+ : errorMessage
|
|
|
+ }
|
|
|
ctaText={
|
|
|
errorMessage !== DEFAULT_ERROR_MESSAGE
|
|
|
? "Troubleshooting steps"
|
|
|
@@ -132,15 +136,14 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
|
|
|
const isDisabled = () => {
|
|
|
return (
|
|
|
- (!clusterName && true)
|
|
|
- || (isReadOnly && props.provisionerError === "")
|
|
|
- || currentCluster?.status === "UPDATING"
|
|
|
- || isClicked
|
|
|
- || (!currentProject?.enable_reprovision && props.clusterId)
|
|
|
- )
|
|
|
+ (!clusterName && true) ||
|
|
|
+ (isReadOnly && props.provisionerError === "") ||
|
|
|
+ currentCluster?.status === "UPDATING" ||
|
|
|
+ isClicked ||
|
|
|
+ (!currentProject?.enable_reprovision && props.clusterId)
|
|
|
+ );
|
|
|
};
|
|
|
|
|
|
-
|
|
|
const validateInputs = (): string => {
|
|
|
if (!clusterName) {
|
|
|
return "Cluster name is required";
|
|
|
@@ -162,29 +165,29 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
}
|
|
|
|
|
|
return "";
|
|
|
- }
|
|
|
+ };
|
|
|
const createCluster = async () => {
|
|
|
const err = validateInputs();
|
|
|
if (err !== "") {
|
|
|
- setErrorMessage(err)
|
|
|
- setErrorDetails("")
|
|
|
+ setErrorMessage(err);
|
|
|
+ setErrorDetails("");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
setIsClicked(true);
|
|
|
-
|
|
|
+
|
|
|
try {
|
|
|
window.dataLayer?.push({
|
|
|
- event: 'provision-attempt',
|
|
|
+ event: "provision-attempt",
|
|
|
data: {
|
|
|
- cloud: 'azure',
|
|
|
- email: user?.email
|
|
|
- }
|
|
|
+ cloud: "azure",
|
|
|
+ email: user?.email,
|
|
|
+ },
|
|
|
});
|
|
|
} catch (err) {
|
|
|
console.log(err);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
const data = new Contract({
|
|
|
cluster: new Cluster({
|
|
|
projectId: currentProject.id,
|
|
|
@@ -234,7 +237,7 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
try {
|
|
|
setIsReadOnly(true);
|
|
|
setErrorMessage("");
|
|
|
- setErrorDetails("")
|
|
|
+ setErrorDetails("");
|
|
|
|
|
|
if (!props.clusterId) {
|
|
|
markStepStarted("provisioning-started", { region: azureLocation });
|
|
|
@@ -266,11 +269,14 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
});
|
|
|
// }
|
|
|
setErrorMessage("");
|
|
|
- setErrorDetails("")
|
|
|
+ setErrorDetails("");
|
|
|
} catch (err) {
|
|
|
- showIntercomWithMessage({ message: "I am running into an issue provisioning a cluster." });
|
|
|
+ showIntercomWithMessage({
|
|
|
+ message: "I am running into an issue provisioning a cluster.",
|
|
|
+ });
|
|
|
let errorMessage = DEFAULT_ERROR_MESSAGE;
|
|
|
- const errorDetails = err.response?.data?.error?.replace("unknown: ", "") ?? "";
|
|
|
+ const errorDetails =
|
|
|
+ err.response?.data?.error?.replace("unknown: ", "") ?? "";
|
|
|
// hacky, need to standardize error contract with backend
|
|
|
setIsClicked(false);
|
|
|
if (errorDetails.includes("resource provider")) {
|
|
|
@@ -283,7 +289,9 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
setErrorDetails("");
|
|
|
}
|
|
|
setErrorMessage(errorMessage);
|
|
|
- markStepStarted("provisioning-failed", { error_message: `Error message: ${errorMessage}; Error details: ${errorDetails}` });
|
|
|
+ markStepStarted("provisioning-failed", {
|
|
|
+ error_message: `Error message: ${errorMessage}; Error details: ${errorDetails}`,
|
|
|
+ });
|
|
|
} finally {
|
|
|
setIsReadOnly(false);
|
|
|
setIsClicked(false);
|
|
|
@@ -294,25 +302,29 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
if (!currentProject) return;
|
|
|
setIsReadOnly(
|
|
|
!!props.clusterId &&
|
|
|
- (currentCluster?.status === "UPDATING" ||
|
|
|
- currentCluster?.status === "UPDATING_UNAVAILABLE")
|
|
|
+ (currentCluster?.status === "UPDATING" ||
|
|
|
+ currentCluster?.status === "UPDATING_UNAVAILABLE")
|
|
|
);
|
|
|
setClusterName(
|
|
|
- `${currentProject?.name.substring(0,16)}-cluster-${Math.random()
|
|
|
+ `${currentProject?.name.substring(0, 16)}-cluster-${Math.random()
|
|
|
.toString(36)
|
|
|
.substring(2, 8)}`
|
|
|
);
|
|
|
}, []);
|
|
|
|
|
|
useEffect(() => {
|
|
|
-
|
|
|
if (!props.selectedClusterVersion) return;
|
|
|
|
|
|
// TODO: pass in contract as the already parsed object, rather than JSON (requires changes to AWS/GCP provisioning)
|
|
|
- const contract = Contract.fromJsonString(JSON.stringify(props.selectedClusterVersion))
|
|
|
+ const contract = Contract.fromJsonString(
|
|
|
+ JSON.stringify(props.selectedClusterVersion)
|
|
|
+ );
|
|
|
|
|
|
- if (contract?.cluster?.kindValues && contract.cluster.kindValues.case === "aksKind") {
|
|
|
- const aksValues = contract.cluster.kindValues.value
|
|
|
+ if (
|
|
|
+ contract?.cluster?.kindValues &&
|
|
|
+ contract.cluster.kindValues.case === "aksKind"
|
|
|
+ ) {
|
|
|
+ const aksValues = contract.cluster.kindValues.value;
|
|
|
aksValues.nodePools.map((nodePool: AKSNodePool) => {
|
|
|
if (nodePool.nodePoolType === NodePoolType.APPLICATION) {
|
|
|
setMachineType(nodePool.instanceType);
|
|
|
@@ -326,112 +338,77 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
setClusterVersion(aksValues.clusterVersion);
|
|
|
setCidrRange(aksValues.cidrRange);
|
|
|
if (aksValues.skuTier !== AksSkuTier.UNSPECIFIED) {
|
|
|
- setSkuTier(aksValues.skuTier)
|
|
|
+ setSkuTier(aksValues.skuTier);
|
|
|
}
|
|
|
}
|
|
|
}, [props.selectedClusterVersion]);
|
|
|
|
|
|
- const renderForm = () => {
|
|
|
- // Render simplified form if initial create
|
|
|
- if (!props.clusterId) {
|
|
|
- return (
|
|
|
- <>
|
|
|
- <Text size={16}>Select an Azure location and tier</Text>
|
|
|
- <Spacer y={1} />
|
|
|
- <Text color="helper">
|
|
|
- Porter will automatically provision your infrastructure with the
|
|
|
- specified configuration.
|
|
|
- </Text>
|
|
|
- <Spacer height="10px" />
|
|
|
- <SelectRow
|
|
|
- options={locationOptions}
|
|
|
- width="350px"
|
|
|
- disabled={isReadOnly}
|
|
|
- value={azureLocation}
|
|
|
- scrollBuffer={true}
|
|
|
- dropdownMaxHeight="240px"
|
|
|
- setActiveValue={setAzureLocation}
|
|
|
- label="📍 Azure location"
|
|
|
- />
|
|
|
- <Spacer y={.75} />
|
|
|
- <div style={{display: "flex", alignItems: "center"}}>
|
|
|
- <Spacer inline x={.05}/>
|
|
|
- <Icon src={dotVertical} height={"15px"}/>
|
|
|
- <Spacer inline x={.1}/>
|
|
|
- <Label>Azure Tier</Label>
|
|
|
- </div>
|
|
|
- <SelectRow
|
|
|
- options={skuTierOptions}
|
|
|
- width="350px"
|
|
|
- disabled={isReadOnly}
|
|
|
- value={skuTier}
|
|
|
- scrollBuffer={true}
|
|
|
- dropdownMaxHeight="240px"
|
|
|
- setActiveValue={setSkuTier}
|
|
|
- />
|
|
|
- </>
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- // If settings, update full form
|
|
|
+ const renderSimpleSettings = (): JSX.Element => {
|
|
|
return (
|
|
|
<>
|
|
|
- <Heading isAtTop>AKS configuration</Heading>
|
|
|
- <Spacer y={0.75} />
|
|
|
<SelectRow
|
|
|
- options={locationOptions}
|
|
|
+ options={AzureLocationOptions}
|
|
|
width="350px"
|
|
|
- disabled={isReadOnly || true}
|
|
|
+ disabled={props.clusterId ? props.clusterId !== 0 : false}
|
|
|
value={azureLocation}
|
|
|
scrollBuffer={true}
|
|
|
dropdownMaxHeight="240px"
|
|
|
setActiveValue={setAzureLocation}
|
|
|
label="📍 Azure location"
|
|
|
/>
|
|
|
- <Spacer y={.75} />
|
|
|
- <div style={{display: "flex", alignItems: "center"}}>
|
|
|
- <Spacer inline x={.05}/>
|
|
|
- <Icon src={dotVertical} height={"15px"}/>
|
|
|
- <Spacer inline x={.1}/>
|
|
|
+ <Spacer y={0.75} />
|
|
|
+ <div style={{ display: "flex", alignItems: "center" }}>
|
|
|
+ <Spacer inline x={0.05} />
|
|
|
+ <Icon src={dotVertical} height={"15px"} />
|
|
|
+ <Spacer inline x={0.2} />
|
|
|
<Label>Azure Tier</Label>
|
|
|
</div>
|
|
|
<SelectRow
|
|
|
- options={skuTierOptions}
|
|
|
- width="350px"
|
|
|
- disabled={isReadOnly}
|
|
|
- value={skuTier}
|
|
|
- scrollBuffer={true}
|
|
|
- dropdownMaxHeight="240px"
|
|
|
- setActiveValue={setSkuTier}
|
|
|
+ options={skuTierOptions}
|
|
|
+ width="350px"
|
|
|
+ disabled={isReadOnly}
|
|
|
+ value={skuTier}
|
|
|
+ scrollBuffer={true}
|
|
|
+ dropdownMaxHeight="240px"
|
|
|
+ setActiveValue={setSkuTier}
|
|
|
/>
|
|
|
- {user?.isPorterUser && (
|
|
|
- <Heading>
|
|
|
- <ExpandHeader
|
|
|
- onClick={() => { setIsExpanded(!isExpanded); }}
|
|
|
- isExpanded={isExpanded}
|
|
|
- >
|
|
|
- <i className="material-icons">arrow_drop_down</i>
|
|
|
- Advanced settings
|
|
|
- </ExpandHeader>
|
|
|
- </Heading>
|
|
|
- )}
|
|
|
+ </>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const renderAdvancedSettings = (): JSX.Element => {
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <Heading>
|
|
|
+ <ExpandHeader
|
|
|
+ onClick={() => {
|
|
|
+ setIsExpanded(!isExpanded);
|
|
|
+ }}
|
|
|
+ isExpanded={isExpanded}
|
|
|
+ >
|
|
|
+ <i className="material-icons">arrow_drop_down</i>
|
|
|
+ Advanced settings
|
|
|
+ </ExpandHeader>
|
|
|
+ </Heading>
|
|
|
+ <Spacer y={0.5} />
|
|
|
+
|
|
|
{isExpanded && (
|
|
|
<>
|
|
|
<SelectRow
|
|
|
options={clusterVersionOptions}
|
|
|
width="350px"
|
|
|
- disabled={isReadOnly}
|
|
|
+ disabled={true}
|
|
|
value={clusterVersion}
|
|
|
scrollBuffer={true}
|
|
|
dropdownMaxHeight="240px"
|
|
|
setActiveValue={setClusterVersion}
|
|
|
label="Cluster version"
|
|
|
/>
|
|
|
- <Spacer y={.75} />
|
|
|
+ <Spacer y={0.75} />
|
|
|
<SelectRow
|
|
|
- options={machineTypeOptions}
|
|
|
+ options={regionFilteredMachineTypeOptions}
|
|
|
width="350px"
|
|
|
- disabled={isReadOnly}
|
|
|
+ disabled={true}
|
|
|
value={machineType}
|
|
|
scrollBuffer={true}
|
|
|
dropdownMaxHeight="240px"
|
|
|
@@ -443,16 +420,20 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
type="number"
|
|
|
disabled={isReadOnly}
|
|
|
value={maxInstances}
|
|
|
- setValue={(x: number) => { setMaxInstances(x); }}
|
|
|
+ setValue={(x: number) => {
|
|
|
+ setMaxInstances(x);
|
|
|
+ }}
|
|
|
label="Maximum number of application nodes"
|
|
|
placeholder="ex: 1"
|
|
|
/>
|
|
|
<InputRow
|
|
|
width="350px"
|
|
|
type="string"
|
|
|
- disabled={isReadOnly}
|
|
|
+ disabled={true}
|
|
|
value={cidrRange}
|
|
|
- setValue={(x: string) => { setCidrRange(x); }}
|
|
|
+ setValue={(x: string) => {
|
|
|
+ setCidrRange(x);
|
|
|
+ }}
|
|
|
label="VPC CIDR range"
|
|
|
placeholder="ex: 10.78.0.0/16"
|
|
|
/>
|
|
|
@@ -462,6 +443,34 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
);
|
|
|
};
|
|
|
|
|
|
+ const renderForm = () => {
|
|
|
+ // Render simplified form if initial create
|
|
|
+ if (!props.clusterId) {
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <Text size={16}>Select an Azure location and tier</Text>
|
|
|
+ <Spacer y={1} />
|
|
|
+ <Text color="helper">
|
|
|
+ Porter will automatically provision your infrastructure with the
|
|
|
+ specified configuration.
|
|
|
+ </Text>
|
|
|
+ <Spacer height="10px" />
|
|
|
+ {renderSimpleSettings()}
|
|
|
+ </>
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // If settings, update full form
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <Heading isAtTop>AKS configuration</Heading>
|
|
|
+ <Spacer y={0.75} />
|
|
|
+ {renderSimpleSettings()}
|
|
|
+ {renderAdvancedSettings()}
|
|
|
+ </>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
return (
|
|
|
<>
|
|
|
<StyledForm>{renderForm()}</StyledForm>
|
|
|
@@ -472,27 +481,25 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
|
|
|
>
|
|
|
Provision
|
|
|
</Button>
|
|
|
- {
|
|
|
- (!currentProject?.enable_reprovision && currentCluster) &&
|
|
|
+ {!currentProject?.enable_reprovision && currentCluster && (
|
|
|
<>
|
|
|
<Spacer y={1} />
|
|
|
- <Text>Updates to the cluster are disabled on this project. Enable re-provisioning by contacting <a href="mailto:support@porter.run">Porter Support</a>.</Text>
|
|
|
+ <Text>
|
|
|
+ Updates to the cluster are disabled on this project. Enable
|
|
|
+ re-provisioning by contacting{" "}
|
|
|
+ <a href="mailto:support@porter.run">Porter Support</a>.
|
|
|
+ </Text>
|
|
|
</>
|
|
|
- }
|
|
|
- {user.isPorterUser &&
|
|
|
+ )}
|
|
|
+ {user.isPorterUser && (
|
|
|
<>
|
|
|
-
|
|
|
<Spacer y={1} />
|
|
|
<Text color="yellow">Visible to Admin Only</Text>
|
|
|
- <Button
|
|
|
- color="red"
|
|
|
- onClick={createCluster}
|
|
|
- status={getStatus()}
|
|
|
- >
|
|
|
+ <Button color="red" onClick={createCluster} status={getStatus()}>
|
|
|
Override Provision
|
|
|
</Button>
|
|
|
</>
|
|
|
- }
|
|
|
+ )}
|
|
|
</>
|
|
|
);
|
|
|
};
|
|
|
@@ -507,7 +514,7 @@ const ExpandHeader = styled.div<{ isExpanded: boolean }>`
|
|
|
margin-right: 7px;
|
|
|
margin-left: -7px;
|
|
|
transform: ${(props) =>
|
|
|
- props.isExpanded ? "rotate(0deg)" : "rotate(-90deg)"};
|
|
|
+ props.isExpanded ? "rotate(0deg)" : "rotate(-90deg)"};
|
|
|
transition: transform 0.1s ease;
|
|
|
}
|
|
|
`;
|
|
|
@@ -545,10 +552,7 @@ const errorMessageToModal = (errorMessage: string) => {
|
|
|
<Step number={1}>
|
|
|
Log into
|
|
|
<Spacer inline width="5px" />
|
|
|
- <Link
|
|
|
- to="https://login.microsoftonline.com/"
|
|
|
- target="_blank"
|
|
|
- >
|
|
|
+ <Link to="https://login.microsoftonline.com/" target="_blank">
|
|
|
your Azure account
|
|
|
</Link>
|
|
|
.
|
|
|
@@ -572,11 +576,14 @@ const errorMessageToModal = (errorMessage: string) => {
|
|
|
</Step>
|
|
|
<Spacer y={1} />
|
|
|
<Step number={4}>
|
|
|
- Select "Compute" and search for the quotas that have reached usage limits in your region. Request an increase by clicking the pencil icon on the far right.
|
|
|
+ Select "Compute" and search for the quotas that have reached usage
|
|
|
+ limits in your region. Request an increase by clicking the pencil
|
|
|
+ icon on the far right.
|
|
|
</Step>
|
|
|
<Spacer y={1} />
|
|
|
<Text color="helper">
|
|
|
- We recommend an initial quota of 20 vCPUs for both Total Regional Cores and Standard Basv2 Family.
|
|
|
+ We recommend an initial quota of 20 vCPUs for both Total Regional
|
|
|
+ Cores and Standard Basv2 Family.
|
|
|
</Text>
|
|
|
<Spacer y={1} />
|
|
|
<Step number={5}>
|
|
|
@@ -585,7 +592,9 @@ const errorMessageToModal = (errorMessage: string) => {
|
|
|
</Step>
|
|
|
<Spacer y={1} />
|
|
|
<Text color="helper">
|
|
|
- Quota increases can take several minutes to process. If Azure is unable to automatically increase the quota, create a support request as prompted by Azure. Requests are usually fulfilled in a few hours.
|
|
|
+ Quota increases can take several minutes to process. If Azure is
|
|
|
+ unable to automatically increase the quota, create a support request
|
|
|
+ as prompted by Azure. Requests are usually fulfilled in a few hours.
|
|
|
</Text>
|
|
|
</>
|
|
|
);
|
|
|
@@ -597,16 +606,17 @@ const errorMessageToModal = (errorMessage: string) => {
|
|
|
</Text>
|
|
|
<Spacer y={1} />
|
|
|
<Text color="helper">
|
|
|
- You will need to register all of the following resource providers to your Azure subscription before provisioning: Capacity, Compute, ContainerRegistry, ContainerService, ManagedIdentity, Network, OperationalInsights, OperationsManagement, ResourceGraph, Resources, Storage
|
|
|
+ You will need to register all of the following resource providers to
|
|
|
+ your Azure subscription before provisioning: Capacity, Compute,
|
|
|
+ ContainerRegistry, ContainerService, ManagedIdentity, Network,
|
|
|
+ OperationalInsights, OperationsManagement, ResourceGraph, Resources,
|
|
|
+ Storage
|
|
|
</Text>
|
|
|
<Spacer y={1} />
|
|
|
<Step number={1}>
|
|
|
Log into
|
|
|
<Spacer inline width="5px" />
|
|
|
- <Link
|
|
|
- to="https://login.microsoftonline.com/"
|
|
|
- target="_blank"
|
|
|
- >
|
|
|
+ <Link to="https://login.microsoftonline.com/" target="_blank">
|
|
|
your Azure account
|
|
|
</Link>
|
|
|
.
|
|
|
@@ -630,16 +640,17 @@ const errorMessageToModal = (errorMessage: string) => {
|
|
|
</Step>
|
|
|
<Spacer y={1} />
|
|
|
<Step number={4}>
|
|
|
- Search for each required resource provider and select "Register" from the top menu bar if it is not already registered.
|
|
|
+ Search for each required resource provider and select "Register"
|
|
|
+ from the top menu bar if it is not already registered.
|
|
|
</Step>
|
|
|
<Spacer y={1} />
|
|
|
<Step number={5}>
|
|
|
- After confirming that all providers are registered, return to Porter and retry the
|
|
|
- provision.
|
|
|
+ After confirming that all providers are registered, return to Porter
|
|
|
+ and retry the provision.
|
|
|
</Step>
|
|
|
</>
|
|
|
);
|
|
|
default:
|
|
|
return null;
|
|
|
}
|
|
|
-};
|
|
|
+};
|