Parcourir la source

allow porter operators to edit non-app node groups from infra tab (#4398)

Feroze Mohideen il y a 2 ans
Parent
commit
6b3c4cd3c1

+ 3 - 0
dashboard/src/assets/information-circle-contained.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11.9999 11.9999L11.9999 16.7999M11.9999 8.44209V8.3999M2.3999 11.9999C2.3999 6.69797 6.69797 2.3999 11.9999 2.3999C17.3018 2.3999 21.5999 6.69797 21.5999 11.9999C21.5999 17.3018 17.3018 21.5999 11.9999 21.5999C6.69797 21.5999 2.3999 17.3018 2.3999 11.9999Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 34 - 0
dashboard/src/components/porter/PorterOperatorComponent.tsx

@@ -0,0 +1,34 @@
+import React from "react";
+import styled from "styled-components";
+
+import Text from "components/porter/Text";
+
+import info from "assets/information-circle-contained.svg";
+
+import Container from "./Container";
+import Icon from "./Icon";
+import Spacer from "./Spacer";
+
+type Props = {
+  children: JSX.Element;
+};
+const PorterOperatorComponent: React.FC<Props> = ({ children }) => {
+  return (
+    <StyledContainer>
+      <Container row>
+        <Icon src={info} height={"14px"} />
+        <Spacer inline x={0.5} />
+        <Text>This is only visible to Porter operators</Text>
+      </Container>
+      <div style={{ marginTop: "10px" }}>{children}</div>
+    </StyledContainer>
+  );
+};
+
+export default PorterOperatorComponent;
+
+const StyledContainer = styled.div`
+  background-color: rgba(128, 128, 128, 0.2);
+  padding: 20px;
+  border-radius: 5px;
+`;

+ 4 - 3
dashboard/src/main/home/infrastructure-dashboard/modals/PreflightChecksModal.tsx

@@ -8,6 +8,7 @@ import Container from "components/porter/Container";
 import { Error as ErrorComponent } from "components/porter/Error";
 import Expandable from "components/porter/Expandable";
 import Modal from "components/porter/Modal";
+import PorterOperatorComponent from "components/porter/PorterOperatorComponent";
 import ShowIntercomButton from "components/porter/ShowIntercomButton";
 import Spacer from "components/porter/Spacer";
 import StatusDot from "components/porter/StatusDot";
@@ -119,16 +120,16 @@ const PreflightChecksModal: React.FC<Props> = ({
             Talk to support
           </ShowIntercomButton>
           {user.email?.endsWith("@porter.run") && (
-            <>
+            <PorterOperatorComponent>
               <Button
                 onClick={async () => {
                   await submitSkippingPreflightChecks();
                 }}
                 color="red"
               >
-                (Porter operators only) Skip preflight checks
+                Skip preflight checks
               </Button>
-            </>
+            </PorterOperatorComponent>
           )}
         </Container>
       </AppearingDiv>

+ 155 - 0
dashboard/src/main/home/infrastructure-dashboard/shared/NodeGroups.tsx

@@ -8,6 +8,7 @@ import Container from "components/porter/Container";
 import Expandable from "components/porter/Expandable";
 import Image from "components/porter/Image";
 import Input from "components/porter/Input";
+import PorterOperatorComponent from "components/porter/PorterOperatorComponent";
 import Select from "components/porter/Select";
 import Spacer from "components/porter/Spacer";
 import Text from "components/porter/Text";
@@ -130,6 +131,160 @@ const NodeGroups: React.FC<Props> = ({
           </Expandable>
         );
       })}
+      <PorterOperatorComponent>
+        <>
+          {displayableNodeGroups.MONITORING?.map((ng) => {
+            return (
+              <Expandable
+                preExpanded={isDefaultExpanded}
+                key={ng.nodeGroup.id}
+                header={
+                  <Container row>
+                    <Image src={world} />
+                    <Spacer inline x={1} />
+                    Monitoring node group
+                  </Container>
+                }
+              >
+                <Controller
+                  name={`cluster.config.nodeGroups.${ng.idx}`}
+                  control={control}
+                  render={({ field: { value, onChange } }) => (
+                    <>
+                      <Select
+                        width="300px"
+                        options={availableMachineTypes
+                          .filter((t) => !t.isGPU)
+                          .map((t) => ({
+                            value: t.name,
+                            label: t.displayName,
+                          }))}
+                        value={value.instanceType}
+                        setValue={(newInstanceType: string) => {
+                          onChange({
+                            ...value,
+                            instanceType: newInstanceType,
+                          });
+                        }}
+                        label="Machine type"
+                      />
+                      <Spacer y={1} />
+                      <Text color="helper">
+                        Minimum number of monitoring nodes
+                      </Text>
+                      <Spacer y={0.5} />
+                      <Input
+                        width="75px"
+                        type="number"
+                        disabled={false}
+                        value={value.minInstances.toString()}
+                        setValue={(newMinInstances: string) => {
+                          onChange({
+                            ...value,
+                            minInstances: parseInt(newMinInstances),
+                          });
+                        }}
+                        placeholder="ex: 1"
+                      />
+                      <Spacer y={1} />
+                      <Text color="helper">
+                        Maximum number of monitoring nodes
+                      </Text>
+                      <Spacer y={0.5} />
+                      <Input
+                        width="75px"
+                        type="number"
+                        disabled={false}
+                        value={value.maxInstances.toString()}
+                        setValue={(newMaxInstances: string) => {
+                          onChange({
+                            ...value,
+                            maxInstances: parseInt(newMaxInstances),
+                          });
+                        }}
+                        placeholder="ex: 10"
+                      />
+                    </>
+                  )}
+                />
+              </Expandable>
+            );
+          })}
+          {displayableNodeGroups.SYSTEM?.map((ng) => {
+            return (
+              <Expandable
+                preExpanded={isDefaultExpanded}
+                key={ng.nodeGroup.id}
+                header={
+                  <Container row>
+                    <Image src={world} />
+                    <Spacer inline x={1} />
+                    System node group
+                  </Container>
+                }
+              >
+                <Controller
+                  name={`cluster.config.nodeGroups.${ng.idx}`}
+                  control={control}
+                  render={({ field: { value, onChange } }) => (
+                    <>
+                      <Select
+                        width="300px"
+                        options={availableMachineTypes
+                          .filter((t) => !t.isGPU)
+                          .map((t) => ({
+                            value: t.name,
+                            label: t.displayName,
+                          }))}
+                        value={value.instanceType}
+                        setValue={(newInstanceType: string) => {
+                          onChange({
+                            ...value,
+                            instanceType: newInstanceType,
+                          });
+                        }}
+                        label="Machine type"
+                      />
+                      <Spacer y={1} />
+                      <Text color="helper">Minimum number of system nodes</Text>
+                      <Spacer y={0.5} />
+                      <Input
+                        width="75px"
+                        type="number"
+                        disabled={false}
+                        value={value.minInstances.toString()}
+                        setValue={(newMinInstances: string) => {
+                          onChange({
+                            ...value,
+                            minInstances: parseInt(newMinInstances),
+                          });
+                        }}
+                        placeholder="ex: 1"
+                      />
+                      <Spacer y={1} />
+                      <Text color="helper">Maximum number of system nodes</Text>
+                      <Spacer y={0.5} />
+                      <Input
+                        width="75px"
+                        type="number"
+                        disabled={false}
+                        value={value.maxInstances.toString()}
+                        setValue={(newMaxInstances: string) => {
+                          onChange({
+                            ...value,
+                            maxInstances: parseInt(newMaxInstances),
+                          });
+                        }}
+                        placeholder="ex: 10"
+                      />
+                    </>
+                  )}
+                />
+              </Expandable>
+            );
+          })}
+        </>
+      </PorterOperatorComponent>
       {displayableNodeGroups.CUSTOM?.map((ng) => {
         return (
           <Expandable