Quellcode durchsuchen

Support Additional Node Policies (#3171)

Stefan McShane vor 2 Jahren
Ursprung
Commit
cc8427219f

+ 2 - 2
api/server/handlers/project_integration/create_azure.go

@@ -52,14 +52,14 @@ func (p *CreateAzureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		AzureIntegration: az.ToAzureIntegrationType(),
 	}
 
-	req := connect.NewRequest(&porterv1.CreateAzureConnectionRequest{
+	req := connect.NewRequest(&porterv1.SaveAzureCredentialsRequest{
 		ProjectId:              int64(project.ID),
 		ClientId:               request.AzureClientID,
 		SubscriptionId:         request.AzureSubscriptionID,
 		TenantId:               request.AzureTenantID,
 		ServicePrincipalSecret: []byte(request.ServicePrincipalKey),
 	})
-	_, err = p.Config().ClusterControlPlaneClient.CreateAzureConnection(r.Context(), req)
+	_, err = p.Config().ClusterControlPlaneClient.SaveAzureCredentials(r.Context(), req)
 
 	if err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))

+ 12 - 20
dashboard/package-lock.json

@@ -12,7 +12,7 @@
         "@loadable/component": "^5.15.2",
         "@material-ui/core": "^4.11.3",
         "@material-ui/lab": "^4.0.0-alpha.61",
-        "@porter-dev/api-contracts": "^0.0.64",
+        "@porter-dev/api-contracts": "^0.0.66",
         "@sentry/react": "^6.13.2",
         "@sentry/tracing": "^6.13.2",
         "@tanstack/react-query": "^4.13.0",
@@ -131,6 +131,14 @@
         "webpack-dev-server": "^3.11.0"
       }
     },
+    "../../api-contracts/generated/js": {
+      "name": "@porter-dev/api-contracts",
+      "version": "0.0.66",
+      "license": "MIT",
+      "dependencies": {
+        "@bufbuild/protobuf": "^1.1.0"
+      }
+    },
     "node_modules/@ampproject/remapping": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
@@ -1935,11 +1943,6 @@
         "node": ">=6.9.0"
       }
     },
-    "node_modules/@bufbuild/protobuf": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.1.1.tgz",
-      "integrity": "sha512-1dS2m3jabfW2XL2K6//41wZkO4XJOZtpe0bKLuta0BvK5LxNRyUBSSN5835n3bIFiNJKFWhDnzZEMrV7QVGFfQ=="
-    },
     "node_modules/@discoveryjs/json-ext": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -2430,12 +2433,8 @@
       }
     },
     "node_modules/@porter-dev/api-contracts": {
-      "version": "0.0.64",
-      "resolved": "https://registry.npmjs.org/@porter-dev/api-contracts/-/api-contracts-0.0.64.tgz",
-      "integrity": "sha512-g9WW8OhBvngMDA7lSLc/7DauJzOG9jGchd2Uzml4c/toycy6etTYpoY04MK1gWuCqKYLiuS+x+x0E91MtX7xPQ==",
-      "dependencies": {
-        "@bufbuild/protobuf": "^1.1.0"
-      }
+      "resolved": "../../api-contracts/generated/js",
+      "link": true
     },
     "node_modules/@sentry/browser": {
       "version": "6.19.7",
@@ -16220,11 +16219,6 @@
         "to-fast-properties": "^2.0.0"
       }
     },
-    "@bufbuild/protobuf": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.1.1.tgz",
-      "integrity": "sha512-1dS2m3jabfW2XL2K6//41wZkO4XJOZtpe0bKLuta0BvK5LxNRyUBSSN5835n3bIFiNJKFWhDnzZEMrV7QVGFfQ=="
-    },
     "@discoveryjs/json-ext": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -16564,9 +16558,7 @@
       "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw=="
     },
     "@porter-dev/api-contracts": {
-      "version": "0.0.64",
-      "resolved": "https://registry.npmjs.org/@porter-dev/api-contracts/-/api-contracts-0.0.64.tgz",
-      "integrity": "sha512-g9WW8OhBvngMDA7lSLc/7DauJzOG9jGchd2Uzml4c/toycy6etTYpoY04MK1gWuCqKYLiuS+x+x0E91MtX7xPQ==",
+      "version": "file:../../api-contracts/generated/js",
       "requires": {
         "@bufbuild/protobuf": "^1.1.0"
       }

+ 1 - 1
dashboard/package.json

@@ -7,7 +7,7 @@
     "@loadable/component": "^5.15.2",
     "@material-ui/core": "^4.11.3",
     "@material-ui/lab": "^4.0.0-alpha.61",
-    "@porter-dev/api-contracts": "^0.0.64",
+    "@porter-dev/api-contracts": "^0.0.66",
     "@sentry/react": "^6.13.2",
     "@sentry/tracing": "^6.13.2",
     "@tanstack/react-query": "^4.13.0",

+ 0 - 1
dashboard/src/components/ProvisionerForm.tsx

@@ -7,7 +7,6 @@ import azure from "assets/azure.png";
 import Heading from "components/form-components/Heading";
 import Helper from "./form-components/Helper";
 import ProvisionerSettings from "./ProvisionerSettings";
-import ProvisionerSettingsOld from "./ProvisionerSettingsOld";
 import Text from "./porter/Text";
 import Spacer from "./porter/Spacer";
 import Container from "./porter/Container";

+ 22 - 12
dashboard/src/components/ProvisionerSettings.tsx

@@ -89,6 +89,7 @@ const ProvisionerSettings: React.FC<Props> = (props) => {
   const [isExpanded, setIsExpanded] = useState(false);
   const [minInstances, setMinInstances] = useState(1);
   const [maxInstances, setMaxInstances] = useState(10);
+  const [additionalNodePolicies, setAdditionalNodePolicies] = useState<string[]>([]);
   const [cidrRange, setCidrRange] = useState("10.78.0.0/16");
   const [clusterVersion, setClusterVersion] = useState("v1.24.0");
   const [loadBalancer, setLoadBalancer] = useState<LoadBalancer | undefined>();
@@ -156,6 +157,7 @@ const ProvisionerSettings: React.FC<Props> = (props) => {
                 maxInstances: 5,
                 nodeGroupType: NodeGroupType.SYSTEM,
                 isStateful: false,
+                additionalPolicies: additionalNodePolicies,
               }),
               new EKSNodeGroup({
                 instanceType: "t3.large",
@@ -163,6 +165,7 @@ const ProvisionerSettings: React.FC<Props> = (props) => {
                 maxInstances: 1,
                 nodeGroupType: NodeGroupType.MONITORING,
                 isStateful: true,
+                additionalPolicies: additionalNodePolicies,
               }),
               new EKSNodeGroup({
                 instanceType: machineType,
@@ -170,6 +173,7 @@ const ProvisionerSettings: React.FC<Props> = (props) => {
                 maxInstances: maxInstances || 10,
                 nodeGroupType: NodeGroupType.APPLICATION,
                 isStateful: false,
+                additionalPolicies: additionalNodePolicies,
               }),
             ],
           }),
@@ -271,13 +275,19 @@ const ProvisionerSettings: React.FC<Props> = (props) => {
       if (eksValues == null) {
         return
       }
-      eksValues.nodeGroups.map((nodeGroup: any) => {
-        if (nodeGroup.nodeGroupType === "NODE_GROUP_TYPE_APPLICATION") {
+      eksValues.nodeGroups.map((nodeGroup: EKSNodeGroup) => {
+        if (nodeGroup.nodeGroupType === NodeGroupType.APPLICATION) {
           setMachineType(nodeGroup.instanceType);
           setMinInstances(nodeGroup.minInstances);
           setMaxInstances(nodeGroup.maxInstances);
         }
+
+        if (nodeGroup.additionalPolicies?.length > 0) {
+          // this shares policies across all node groups, but there is no reason that this can be specific policies per node group
+          setAdditionalNodePolicies(nodeGroup.additionalPolicies);
+        }
       });
+
       setCreateStatus("");
       setClusterName(eksValues.clusterName);
       setAwsRegion(eksValues.region);
@@ -327,16 +337,16 @@ const ProvisionerSettings: React.FC<Props> = (props) => {
           setActiveValue={setAwsRegion}
           label="📍 AWS region"
         />
-        
-          <Heading>
-            <ExpandHeader
-              onClick={() => setIsExpanded(!isExpanded)}
-              isExpanded={isExpanded}
-            >
-              <i className="material-icons">arrow_drop_down</i>
-              Advanced settings
-            </ExpandHeader>
-          </Heading>
+
+        <Heading>
+          <ExpandHeader
+            onClick={() => setIsExpanded(!isExpanded)}
+            isExpanded={isExpanded}
+          >
+            <i className="material-icons">arrow_drop_down</i>
+            Advanced settings
+          </ExpandHeader>
+        </Heading>
 
         {isExpanded && (
           <>

+ 0 - 345
dashboard/src/components/ProvisionerSettingsOld.tsx

@@ -1,345 +0,0 @@
-import React, { useEffect, useState, useContext } from "react";
-import styled from "styled-components";
-import { 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 Helper from "components/form-components/Helper";
-import InputRow from "./form-components/InputRow";
-import SaveButton from "./SaveButton";
-import {
-  Contract,
-  EnumKubernetesKind,
-  EnumCloudProvider,
-  NodeGroupType,
-  EKSNodeGroup,
-  EKS,
-  Cluster,
-} from "@porter-dev/api-contracts";
-import { ClusterType } from "shared/types";
-import Text from "./porter/Text";
-import Spacer from "./porter/Spacer";
-
-const regionOptions = [
-  { value: "us-east-1", label: "US East (N. Virginia) us-east-1" },
-  { value: "us-east-2", label: "US East (Ohio) us-east-2" },
-  { value: "us-west-1", label: "US West (N. California) us-west-1" },
-  { value: "us-west-2", label: "US West (Oregon) us-west-2" },
-  { value: "af-south-1", label: "Africa (Cape Town) af-south-1" },
-  { value: "ap-east-1", label: "Asia Pacific (Hong Kong) ap-east-1" },
-  { value: "ap-south-1", label: "Asia Pacific (Mumbai) ap-south-1" },
-  { value: "ap-northeast-2", label: "Asia Pacific (Seoul) ap-northeast-2" },
-  { value: "ap-southeast-1", label: "Asia Pacific (Singapore) ap-southeast-1" },
-  { value: "ap-southeast-2", label: "Asia Pacific (Sydney) ap-southeast-2" },
-  { value: "ap-northeast-1", label: "Asia Pacific (Tokyo) ap-northeast-1" },
-  { value: "ca-central-1", label: "Canada (Central) ca-central-1" },
-  { value: "eu-central-1", label: "Europe (Frankfurt) eu-central-1" },
-  { value: "eu-west-1", label: "Europe (Ireland) eu-west-1" },
-  { value: "eu-west-2", label: "Europe (London) eu-west-2" },
-  { value: "eu-south-1", label: "Europe (Milan) eu-south-1" },
-  { value: "eu-west-3", label: "Europe (Paris) eu-west-3" },
-  { value: "eu-north-1", label: "Europe (Stockholm) eu-north-1" },
-  { value: "me-south-1", label: "Middle East (Bahrain) me-south-1" },
-  { value: "sa-east-1", label: "South America (São Paulo) sa-east-1" },
-];
-
-const machineTypeOptions = [
-  { value: "t3.medium", label: "t3.medium" },
-  { value: "t3.large", label: "t3.large" },
-  { value: "t3.xlarge", label: "t3.xlarge" },
-  { value: "t3.2xlarge", label: "t3.2xlarge" },
-];
-
-const clusterVersionOptions = [
-  { value: "v1.24.0", label: "1.24.0" },
-  { value: "v1.25.0", label: "1.25.0" },
-];
-
-type Props = RouteComponentProps & {
-  selectedClusterVersion?: Contract;
-  credentialId: string;
-  clusterId?: number;
-};
-
-const ProvisionerSettingsOld: React.FC<Props> = (props) => {
-  const {
-    user,
-    currentProject,
-    currentCluster,
-    setCurrentCluster,
-    setShouldRefreshClusters,
-    setHasFinishedOnboarding,
-  } = useContext(Context);
-  const [createStatus, setCreateStatus] = useState("");
-  const [clusterName, setClusterName] = useState("");
-  const [awsRegion, setAwsRegion] = useState("us-east-1");
-  const [machineType, setMachineType] = useState("t3.xlarge");
-  const [isExpanded, setIsExpanded] = useState(false);
-  const [minInstances, setMinInstances] = useState(1);
-  const [maxInstances, setMaxInstances] = useState(10);
-  const [cidrRange, setCidrRange] = useState("10.78.0.0/16");
-  const [clusterVersion, setClusterVersion] = useState("v1.24.0");
-  const [isReadOnly, setIsReadOnly] = useState(false);
-
-  const markProvisioningStarted = async () => {
-    try {
-      const res = await api.updateOnboardingStep(
-        "<token>",
-        { step: "provisioning-started" },
-        {}
-      );
-    } catch (err) {
-      console.log(err);
-    }
-  };
-
-  const createCluster = async () => {
-    markProvisioningStarted();
-
-    var data = new Contract({
-      cluster: new Cluster({
-        projectId: currentProject.id,
-        kind: EnumKubernetesKind.EKS,
-        cloudProvider: EnumCloudProvider.AWS,
-        cloudProviderCredentialsId: String(props.credentialId),
-        kindValues: {
-          case: "eksKind",
-          value: new EKS({
-            clusterName,
-            clusterVersion: clusterVersion || "v1.24.0",
-            cidrRange: cidrRange || "10.78.0.0/16",
-            region: awsRegion,
-            nodeGroups: [
-              new EKSNodeGroup({
-                instanceType: "t3.medium",
-                minInstances: 1,
-                maxInstances: 5,
-                nodeGroupType: NodeGroupType.SYSTEM,
-                isStateful: false,
-              }),
-              new EKSNodeGroup({
-                instanceType: "t3.large",
-                minInstances: 1,
-                maxInstances: 5,
-                nodeGroupType: NodeGroupType.MONITORING,
-                isStateful: false,
-              }),
-              new EKSNodeGroup({
-                instanceType: machineType,
-                minInstances: minInstances || 1,
-                maxInstances: maxInstances || 10,
-                nodeGroupType: NodeGroupType.APPLICATION,
-                isStateful: false,
-              }),
-            ],
-          }),
-        },
-      }),
-    });
-
-    if (props.clusterId) {
-      data["cluster"]["clusterId"] = props.clusterId;
-    }
-
-    try {
-      const res = await api.createContract("<token>", data, {
-        project_id: currentProject.id,
-      });
-
-      // Only refresh and set clusters on initial create
-      if (!props.clusterId) {
-        setShouldRefreshClusters(true);
-        api
-          .getClusters("<token>", {}, { id: currentProject.id })
-          .then(({ data }) => {
-            data.forEach((cluster: ClusterType) => {
-              if (cluster.id === res.data.contract_revision?.cluster_id) {
-                // setHasFinishedOnboarding(true);
-                setCurrentCluster(cluster);
-                OFState.actions.goTo("clean_up");
-                pushFiltered(props, "/cluster-dashboard", ["project_id"], {
-                  cluster: cluster.name,
-                });
-              }
-            });
-          })
-          .catch((err) => {
-            console.error(err);
-          });
-      }
-    } catch (err) {
-      console.log(err);
-    }
-  };
-
-  useEffect(() => {
-    setIsReadOnly(
-      props.clusterId &&
-        (currentCluster.status === "UPDATING" ||
-          currentCluster.status === "UPDATING_UNAVAILABLE")
-    );
-    setClusterName(
-      `${currentProject.name}-cluster-${Math.random()
-        .toString(36)
-        .substring(2, 8)}`
-    );
-  }, []);
-
-  useEffect(() => {
-    const contract = props.selectedClusterVersion as any;
-    if (contract?.cluster) {
-      contract.cluster.eksKind.nodeGroups.map((nodeGroup: any) => {
-        if (nodeGroup.nodeGroupType === "NODE_GROUP_TYPE_APPLICATION") {
-          setMachineType(nodeGroup.instanceType);
-          setMinInstances(nodeGroup.minInstances);
-          setMaxInstances(nodeGroup.maxInstances);
-        }
-      });
-      setCreateStatus("");
-      setClusterName(contract.cluster.eksKind.clusterName);
-      setAwsRegion(contract.cluster.eksKind.region);
-      setClusterVersion(contract.cluster.eksKind.clusterVersion);
-      setCidrRange(contract.cluster.eksKind.cidrRange);
-    }
-  }, [props.selectedClusterVersion]);
-
-  const renderForm = () => {
-    // Render simplified form if initial create
-    if (!props.clusterId) {
-      return (
-        <>
-          <Text size={16}>Select an AWS region</Text>
-          <Spacer y={1} />
-          <Text color="helper">
-            Porter will automatically provision your infrastructure in the
-            specified region.
-          </Text>
-          <Spacer height="10px" />
-          <SelectRow
-            options={regionOptions}
-            width="350px"
-            disabled={isReadOnly}
-            value={awsRegion}
-            scrollBuffer={true}
-            dropdownMaxHeight="240px"
-            setActiveValue={setAwsRegion}
-            label="📍 AWS region"
-          />
-        </>
-      );
-    }
-
-    // If settings, update full form
-    return (
-      <>
-        <Heading isAtTop>EKS configuration</Heading>
-        <SelectRow
-          options={regionOptions}
-          width="350px"
-          disabled={isReadOnly || true}
-          value={awsRegion}
-          scrollBuffer={true}
-          dropdownMaxHeight="240px"
-          setActiveValue={setAwsRegion}
-          label="📍 AWS region"
-        />
-        { 
-          <Heading>
-            <ExpandHeader
-              onClick={() => setIsExpanded(!isExpanded)}
-              isExpanded={isExpanded}
-            >
-              <i className="material-icons">arrow_drop_down</i>
-              Advanced settings
-            </ExpandHeader>
-          </Heading>
-        }
-        {isExpanded && (
-          <>
- {user?.isPorterUser && (<SelectRow
-              options={clusterVersionOptions}
-              width="350px"
-              disabled={isReadOnly}
-              value={clusterVersion}
-              scrollBuffer={true}
-              dropdownMaxHeight="240px"
-              setActiveValue={setClusterVersion}
-              label="Cluster version"
-            />)}
-            <SelectRow
-              options={machineTypeOptions}
-              width="350px"
-              disabled={isReadOnly}
-              value={machineType}
-              scrollBuffer={true}
-              dropdownMaxHeight="240px"
-              setActiveValue={setMachineType}
-              label="Machine type"
-            />
-            <InputRow
-              width="350px"
-              type="number"
-              disabled={isReadOnly}
-              value={maxInstances}
-              setValue={(x: number) => setMaxInstances(x)}
-              label="Maximum number of application EC2 instances"
-              placeholder="ex: 1"
-            />
-            <InputRow
-              width="350px"
-              type="string"
-              disabled={isReadOnly}
-              value={cidrRange}
-              setValue={(x: string) => setCidrRange(x)}
-              label="VPC CIDR range"
-              placeholder="ex: 10.78.0.0/16"
-            />
-          </>
-        )}
-      </>
-    );
-  };
-
-  return (
-    <>
-      <StyledForm>{renderForm()}</StyledForm>
-      <SaveButton
-        disabled={(!clusterName && true) || isReadOnly}
-        onClick={createCluster}
-        clearPosition
-        text="Provision"
-        statusPosition="right"
-        status={isReadOnly && "Provisioning is still in progress"}
-      />
-    </>
-  );
-};
-
-export default withRouter(ProvisionerSettingsOld);
-
-const ExpandHeader = styled.div<{ isExpanded: boolean }>`
-  display: flex;
-  align-items: center;
-  cursor: pointer;
-  > i {
-    margin-right: 7px;
-    margin-left: -7px;
-    transform: ${(props) =>
-      props.isExpanded ? "rotate(0deg)" : "rotate(-90deg)"};
-  }
-`;
-
-const StyledForm = styled.div`
-  position: relative;
-  padding: 30px 30px 25px;
-  border-radius: 5px;
-  background: #26292e;
-  border: 1px solid #494b4f;
-  font-size: 13px;
-  margin-bottom: 30px;
-`;

+ 1 - 1
go.mod

@@ -76,7 +76,7 @@ require (
 	github.com/honeycombio/otel-launcher-go v0.2.0
 	github.com/nats-io/nats.go v1.24.0
 	github.com/open-policy-agent/opa v0.44.0
-	github.com/porter-dev/api-contracts v0.0.64
+	github.com/porter-dev/api-contracts v0.0.66
 	github.com/riandyrn/otelchi v0.5.1
 	github.com/santhosh-tekuri/jsonschema/v5 v5.0.1
 	github.com/stefanmcshane/helm v0.0.0-20221213002717-88a4a2c6e77d

+ 2 - 4
go.sum

@@ -1490,10 +1490,8 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/polyfloyd/go-errorlint v0.0.0-20210722154253-910bb7978349/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=
-github.com/porter-dev/api-contracts v0.0.64 h1:mMtc4lumSAEW6+o/bEGjuwQwZNNCKHk1n9aBcSb3rCw=
-github.com/porter-dev/api-contracts v0.0.64/go.mod h1:qr2L58mJLr5DUGV5OPw3REiSrQvJq6TgkKyEWP95dyU=
-github.com/porter-dev/api-contracts v0.0.63 h1:ZC2uURhfPmuknnNm9atM+7y3yW6YBCaR1vRQ9EvHCQc=
-github.com/porter-dev/api-contracts v0.0.63/go.mod h1:qr2L58mJLr5DUGV5OPw3REiSrQvJq6TgkKyEWP95dyU=
+github.com/porter-dev/api-contracts v0.0.66 h1:sqK6Xu6QtC6cvhXoI1NbsdaruQK23yw07llbn14CWbc=
+github.com/porter-dev/api-contracts v0.0.66/go.mod h1:qr2L58mJLr5DUGV5OPw3REiSrQvJq6TgkKyEWP95dyU=
 github.com/porter-dev/switchboard v0.0.0-20221019155755-67ff2bf04935 h1:hfb3nt3AJXIBbevu6ARTg9SdOkMP6WLbKBiG5hT5rcc=
 github.com/porter-dev/switchboard v0.0.0-20221019155755-67ff2bf04935/go.mod h1:xSPzqSFMQ6OSbp42fhCi4AbGbQbsm6nRvOkrblFeXU4=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=

+ 0 - 6
package-lock.json

@@ -1,6 +0,0 @@
-{
-  "name": "porter",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {}
-}