Explorar el Código

Merge branch 'belanger/agent-v3-integration' into dev

Alexander Belanger hace 3 años
padre
commit
bf492a28e7

+ 1 - 1
dashboard/src/components/porter-form/PorterFormWrapper.tsx

@@ -109,8 +109,8 @@ const PorterFormWrapper: React.FC<PropsType> = ({
           saveValuesStatus={saveValuesStatus}
           currentTab={currentTab}
           setCurrentTab={(newTab) => {
-            setCurrentTab(newTab);
             onTabChange(newTab);
+            setCurrentTab(newTab);
           }}
           isLaunch={isLaunch}
           hideSpacer={hideBottomSpacer}

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx

@@ -885,7 +885,7 @@ const ExpandedChart: React.FC<Props> = (props) => {
                     margin_left={"0px"}
                   />
                   */}
-                  <DeployStatusSection chart={currentChart} />
+                  <DeployStatusSection chart={currentChart} setLogData={renderLogsAtTimestamp} />
                   <LastDeployed>
                     <Dot>•</Dot>Last deployed
                     {" " + getReadableDate(currentChart.info.last_deployed)}

+ 25 - 16
dashboard/src/main/home/cluster-dashboard/expanded-chart/deploy-status-section/ControllerTab.tsx

@@ -13,7 +13,7 @@ import _ from "lodash";
 type Props = {
   controller: any;
   selectedPod: any;
-  selectPod: (newPod: any) => unknown;
+  selectPod: (newPod: any, userSelected: boolean) => unknown;
   selectors: any;
   isLast?: boolean;
   isFirst?: boolean;
@@ -161,11 +161,11 @@ const ControllerTabFC: React.FunctionComponent<Props> = ({
    * @param rawList A rawList of pods in case we don't want to use the state one. Useful to
    * avoid problems with reactivity
    */
-  const handleSelectPod = (pod: ControllerTabPodType, rawList?: any[]) => {
+  const handleSelectPod = (pod: ControllerTabPodType, rawList?: any[], userSelected?: boolean) => {
     const rawPod = [...rawPodList, ...(rawList || [])].find(
       (rawPod) => rawPod?.metadata?.name === pod?.name
     );
-    selectPod(rawPod);
+    selectPod(rawPod, !!userSelected);
   };
 
   const currentSelectedPod = useMemo(() => {
@@ -224,18 +224,23 @@ const ControllerTabFC: React.FunctionComponent<Props> = ({
   };
 
   const replicaSetArray = useMemo(() => {
-    const podsDividedByReplicaSet = _.sortBy(pods, ["revisionNumber"]).reverse().reduce<
-      Array<Array<ControllerTabPodType>>
-    >(function (prev, currentPod, i) {
-      if (
-        !i ||
-        prev[prev.length - 1][0].replicaSetName !== currentPod.replicaSetName
+    const podsDividedByReplicaSet = _.sortBy(pods, ["revisionNumber"])
+      .reverse()
+      .reduce<Array<Array<ControllerTabPodType>>>(function (
+        prev,
+        currentPod,
+        i
       ) {
-        return prev.concat([[currentPod]]);
-      }
-      prev[prev.length - 1].push(currentPod);
-      return prev;
-    }, []);
+        if (
+          !i ||
+          prev[prev.length - 1][0].replicaSetName !== currentPod.replicaSetName
+        ) {
+          return prev.concat([[currentPod]]);
+        }
+        prev[prev.length - 1].push(currentPod);
+        return prev;
+      },
+      []);
 
     return podsDividedByReplicaSet.length === 1 ? [] : podsDividedByReplicaSet;
   }, [pods]);
@@ -303,10 +308,14 @@ const ControllerTabFC: React.FunctionComponent<Props> = ({
             status === "failed" &&
               pod.status?.message &&
               setPodError(pod.status?.message);
-            handleSelectPod(pod);
+            handleSelectPod(pod, true);
             setUserSelectedPod(true);
           }}
-          onDeleteClick={() => setPodPendingDelete(pod)}
+          onDeleteClick={(e: MouseEvent) => {
+            e.preventDefault();
+            e.stopPropagation();
+            setPodPendingDelete(pod);
+          }}
         />
       );
     });

+ 13 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/deploy-status-section/DeployStatusSection.tsx

@@ -3,9 +3,11 @@ import PodDropdown from "./PodDropdown";
 
 import styled from "styled-components";
 import { getPodStatus } from "./util";
+import { InitLogData } from "../logs-section/LogsSection";
 
 type Props = {
   chart?: any;
+  setLogData: (initLogData: InitLogData) => void;
 };
 
 type DeployStatus = "Deploying" | "Deployed" | "Failed";
@@ -94,7 +96,17 @@ const DeployStatusSection: React.FC<Props> = (props) => {
       </StyledDeployStatusSection>
       <DropdownWrapper expanded={isExpanded}>
         <Dropdown ref={wrapperRef}>
-          <PodDropdown currentChart={props.chart} onUpdate={onUpdate} />
+          <PodDropdown
+            currentChart={props.chart}
+            onUpdate={onUpdate}
+            // Allow users to navigate to pod logs upon clicking the pod
+            onSelectPod={(pod: any) => {
+              props.setLogData({
+                podName: pod?.metadata?.name,
+                revision: pod?.metadata?.annotations?.["helm.sh/revision"],
+              });
+            }}
+          />
         </Dropdown>
       </DropdownWrapper>
     </>

+ 12 - 10
dashboard/src/main/home/cluster-dashboard/expanded-chart/deploy-status-section/PodDropdown.tsx

@@ -12,12 +12,14 @@ type Props = {
   selectors?: string[];
   currentChart: ChartType;
   onUpdate: (props: any) => void;
+  onSelectPod: (pod: any) => void;
 };
 
 const PodDropdown: React.FunctionComponent<Props> = ({
   currentChart,
   selectors,
   onUpdate,
+  onSelectPod,
 }) => {
   const [selectedPod, setSelectedPod] = useState<any>({});
   const [controllers, setControllers] = useState<any[]>([]);
@@ -73,7 +75,13 @@ const PodDropdown: React.FunctionComponent<Props> = ({
           // handle CronJob case
           key={c.metadata?.uid || c.uid}
           selectedPod={selectedPod}
-          selectPod={setSelectedPod}
+          selectPod={(pod: any, userSelected) => {
+            setSelectedPod(pod);
+
+            if (userSelected) {
+              onSelectPod(pod);
+            }
+          }}
           selectors={selectors ? [selectors[i]] : null}
           controller={c}
           isLast={i === controllers?.length - 1}
@@ -94,9 +102,7 @@ const PodDropdown: React.FunctionComponent<Props> = ({
       );
     }
     if (controllers?.length > 0) {
-      return (
-        <TabWrapper>{renderTabs()}</TabWrapper>
-      );
+      return <TabWrapper>{renderTabs()}</TabWrapper>;
     }
 
     return (
@@ -108,17 +114,13 @@ const PodDropdown: React.FunctionComponent<Props> = ({
     );
   };
 
-  return (
-    <StyledStatusSection>
-      {renderStatusSection()}
-    </StyledStatusSection>
-  );
+  return <StyledStatusSection>{renderStatusSection()}</StyledStatusSection>;
 };
 
 export default PodDropdown;
 
 const TabWrapper = styled.div`
-  width: 100%; 
+  width: 100%;
   min-height: 50px;
 `;
 

+ 3 - 2
dashboard/src/main/home/cluster-dashboard/expanded-chart/deploy-status-section/PodRow.tsx

@@ -22,7 +22,7 @@ const PodRow: React.FunctionComponent<PodRowProps> = ({
   const [showTooltip, setShowTooltip] = useState(false);
 
   return (
-    <Tab key={pod?.name}>
+    <Tab key={pod?.name} onClick={onTabClick}>
       <Gutter>
         <Rail />
         <Circle />
@@ -30,7 +30,7 @@ const PodRow: React.FunctionComponent<PodRowProps> = ({
       </Gutter>
       <Name
         onMouseOver={() => {
-          // setShowTooltip(true);
+          setShowTooltip(true);
         }}
         onMouseOut={() => {
           setShowTooltip(false);
@@ -145,6 +145,7 @@ const Tab = styled.div`
   padding: 20px 18px 20px 42px;
   text-shadow: 0px 0px 8px none;
   overflow: visible;
+  cursor: pointer;
 `;
 
 const Rail = styled.div`

+ 11 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/logs-section/LogsSection.tsx

@@ -152,7 +152,7 @@ const LogsSection: React.FC<Props> = ({
           setPodFilter(res.data[0]);
         }
       });
-  }, []);
+  }, [initData]);
 
   useEffect(() => {
     if (!loading && scrollToBottomRef.current && scrollToBottomEnabled) {
@@ -163,6 +163,16 @@ const LogsSection: React.FC<Props> = ({
     }
   }, [loading, logs, scrollToBottomRef, scrollToBottomEnabled]);
 
+  useEffect(() => {
+    if (initData.podName) {
+      setPodFilter(initData.podName);
+    }
+
+    if (initData.timestamp) {
+      setSelectedDate(dayjs(initData.timestamp).toDate());
+    }
+  }, [initData]);
+
   const renderLogs = () => {
     return logs?.map((log, i) => {
       return (

+ 14 - 74
dashboard/src/main/home/cluster-dashboard/expanded-chart/metrics/JobMetricsSection.tsx

@@ -38,8 +38,6 @@ const JobMetricsSection: React.FunctionComponent<PropsType> = ({
   jobChart: currentChart,
   jobRun,
 }) => {
-  const [pods, setPods] = useState([]);
-  const [selectedPod, setSelectedPod] = useState("");
   const [controllerOptions, setControllerOptions] = useState([]);
   const [selectedController, setSelectedController] = useState(null);
   const [ingressOptions, setIngressOptions] = useState([]);
@@ -99,48 +97,6 @@ const JobMetricsSection: React.FunctionComponent<PropsType> = ({
       });
   }, [currentChart, currentCluster, currentProject]);
 
-  useEffect(() => {
-    getPods();
-  }, [selectedController]);
-
-  const getPods = () => {
-    const jobName = jobRun?.metadata?.name;
-    const selector = `job-name=${jobName}`;
-
-    setIsLoading((prev) => prev + 1);
-
-    api
-      .getMatchingPods(
-        "<token>",
-        {
-          namespace: selectedController?.metadata?.namespace,
-          selectors: [selector],
-        },
-        {
-          id: currentProject.id,
-          cluster_id: currentCluster.id,
-        }
-      )
-      .then((res) => {
-        const pods = res?.data?.map((pod: any) => {
-          let name = pod?.metadata?.name;
-          return { value: name, label: name };
-        });
-
-        setPods(pods);
-        setSelectedPod(pods[0].value);
-
-        getMetrics();
-      })
-      .catch((err) => {
-        setCurrentError(JSON.stringify(err));
-        return;
-      })
-      .finally(() => {
-        setIsLoading((prev) => prev - 1);
-      });
-  };
-
   const getAutoscalingThreshold = async (
     metricType: "cpu_hpa_threshold" | "memory_hpa_threshold",
     shouldsum: boolean,
@@ -184,9 +140,6 @@ const JobMetricsSection: React.FunctionComponent<PropsType> = ({
   };
 
   const getMetrics = async () => {
-    if (pods?.length == 0) {
-      return;
-    }
     try {
       let namespace = currentChart.namespace;
 
@@ -202,8 +155,6 @@ const JobMetricsSection: React.FunctionComponent<PropsType> = ({
         end = Math.round(new Date().getTime() / 1000);
       }
 
-      let podNames = [selectedPod] as string[];
-
       setIsLoading((prev) => prev + 1);
       setData([]);
 
@@ -211,14 +162,14 @@ const JobMetricsSection: React.FunctionComponent<PropsType> = ({
         "<token>",
         {
           metric: selectedMetric,
-          shouldsum: false,
-          kind: selectedController?.kind,
-          name: selectedController?.metadata.name,
+          shouldsum: true,
+          kind: "job",
+          name: jobRun?.metadata?.name,
           namespace: namespace,
           startrange: start,
           endrange: end,
           resolution: resolutions[selectedRange],
-          pods: podNames,
+          // pods: podNames,
         },
         {
           id: currentProject.id,
@@ -226,13 +177,15 @@ const JobMetricsSection: React.FunctionComponent<PropsType> = ({
         }
       );
 
-      const metrics = new MetricNormalizer(
-        res.data,
-        selectedMetric as AvailableMetrics
-      );
+      if (res.data.length > 0) {
+        const metrics = new MetricNormalizer(
+          res.data,
+          selectedMetric as AvailableMetrics
+        );
 
-      // transform the metrics to expected form
-      setData(metrics.getParsedData());
+        // transform the metrics to expected form
+        setData(metrics.getParsedData());
+      }
     } catch (error) {
       setCurrentError(JSON.stringify(error));
     } finally {
@@ -241,16 +194,10 @@ const JobMetricsSection: React.FunctionComponent<PropsType> = ({
   };
 
   useEffect(() => {
-    if (selectedMetric && selectedRange && selectedPod && selectedController) {
+    if (selectedMetric && selectedRange && selectedController) {
       getMetrics();
     }
-  }, [
-    selectedMetric,
-    selectedRange,
-    selectedPod,
-    selectedController,
-    selectedIngress,
-  ]);
+  }, [selectedMetric, selectedRange, selectedController, selectedIngress]);
 
   const renderMetricsSettings = () => {
     if (showMetricsSettings && true) {
@@ -284,13 +231,6 @@ const JobMetricsSection: React.FunctionComponent<PropsType> = ({
               options={controllerOptions}
               width="100%"
             />
-            <SelectRow
-              label="Target Pod"
-              value={selectedPod}
-              setActiveValue={(x: any) => setSelectedPod(x)}
-              options={pods}
-              width="100%"
-            />
           </DropdownAlt>
         </>
       );

+ 5 - 0
internal/kubernetes/prometheus/metrics.go

@@ -211,6 +211,11 @@ func QueryPrometheus(
 	rawQuery, err := resp.DoRaw(context.TODO())
 
 	if err != nil {
+		// in this case, it's very likely that prometheus doesn't contain any data for the given labels
+		if strings.Contains(err.Error(), "rejected our request for an unknown reason") {
+			return []*promParsedSingletonQuery{}, nil
+		}
+
 		return nil, err
 	}