Skip to content

Commit

Permalink
misc status footer refactors (#3624)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feroze Mohideen authored Sep 21, 2023
1 parent 61fb431 commit 7d1280c
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 63 deletions.
6 changes: 3 additions & 3 deletions api/server/handlers/porter_app/latest_app_revisions.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/porter-dev/porter/internal/telemetry"
)

// LatestAppRevisionsHandler handles requests to the /apps/{porter_app_name}/revisions endpoint
// LatestAppRevisionsHandler handles requests to the /apps/revisions endpoint
type LatestAppRevisionsHandler struct {
handlers.PorterHandlerReadWriter
}
Expand All @@ -31,7 +31,7 @@ func NewLatestAppRevisionsHandler(
}
}

// LatestAppRevisionsRequest represents the response from the /apps/{porter_app_name}/revisions endpoint
// LatestAppRevisionsRequest represents the response from the /apps/revisions endpoint
type LatestAppRevisionsRequest struct{}

// LatestRevisionWithSource is an app revision and its source porter app
Expand All @@ -40,7 +40,7 @@ type LatestRevisionWithSource struct {
Source types.PorterApp `json:"source"`
}

// LatestAppRevisionsResponse represents the response from the /apps/{porter_app_name}/revisions endpoint
// LatestAppRevisionsResponse represents the response from the /apps/revisions endpoint
type LatestAppRevisionsResponse struct {
AppRevisions []LatestRevisionWithSource `json:"app_revisions"`
}
Expand Down
16 changes: 13 additions & 3 deletions api/server/handlers/porter_app/pod_status.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package porter_app

import (
"fmt"
"net/http"

"connectrpc.com/connect"
Expand All @@ -10,6 +11,7 @@ import (
"github.com/porter-dev/porter/api/server/shared"
"github.com/porter-dev/porter/api/server/shared/apierrors"
"github.com/porter-dev/porter/api/server/shared/config"
"github.com/porter-dev/porter/api/server/shared/requestutils"
"github.com/porter-dev/porter/api/types"
"github.com/porter-dev/porter/internal/models"
"github.com/porter-dev/porter/internal/telemetry"
Expand Down Expand Up @@ -37,7 +39,7 @@ func NewPodStatusHandler(
// PodStatusRequest is the expected format for a request body on GET /apps/pods
type PodStatusRequest struct {
DeploymentTargetID string `schema:"deployment_target_id"`
Selectors string `schema:"selectors"`
ServiceName string `schema:"service"`
}

func (c *PodStatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Expand All @@ -51,10 +53,17 @@ func (c *PodStatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

appName, reqErr := requestutils.GetURLParamString(r, types.URLParamPorterAppName)
if reqErr != nil {
err := telemetry.Error(ctx, span, reqErr, "porter app name not found in request")
c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
return
}

cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
project, _ := r.Context().Value(types.ProjectScope).(*models.Project)

telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "selectors", Value: request.Selectors})
telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "service-name", Value: request.ServiceName}, telemetry.AttributeKV{Key: "app-name", Value: appName})

if request.DeploymentTargetID == "" {
err := telemetry.Error(ctx, span, nil, "must provide deployment target id")
Expand Down Expand Up @@ -99,7 +108,8 @@ func (c *PodStatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

pods := []v1.Pod{}

podsList, err := agent.GetPodsByLabel(request.Selectors, namespace)
selectors := fmt.Sprintf("porter.run/service-name=%s,porter.run/deployment-target-id=%s,porter.run/app-name=%s", request.ServiceName, request.DeploymentTargetID, appName)
podsList, err := agent.GetPodsByLabel(selectors, namespace)
if err != nil {
err = telemetry.Error(ctx, span, err, "unable to get pods by label")
c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
Expand Down
4 changes: 2 additions & 2 deletions api/server/router/porter_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -980,14 +980,14 @@ func getPorterAppRoutes(
Router: r,
})

// GET /api/projects/{project_id}/clusters/{cluster_id}/apps/pods -> cluster.NewPodStatusHandler
// GET /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/pods -> cluster.NewPodStatusHandler
appPodStatusEndpoint := factory.NewAPIEndpoint(
&types.APIRequestMetadata{
Verb: types.APIVerbGet,
Method: types.HTTPVerbGet,
Path: &types.Path{
Parent: basePath,
RelativePath: fmt.Sprintf("%s/pods", relPathV2),
RelativePath: fmt.Sprintf("%s/{%s}/pods", relPathV2, types.URLParamPorterAppName),
},
Scopes: []types.PermissionScope{
types.UserScope,
Expand Down
18 changes: 9 additions & 9 deletions dashboard/src/lib/hooks/useAppStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import _ from "lodash";
import { useEffect, useMemo, useState } from "react";
import api from "shared/api";
import { NewWebsocketOptions, useWebsockets } from "shared/hooks/useWebsockets";
import { useRevisionIdToNumber } from "./useRevisionList";
import { useRevisionList } from "./useRevisionList";
import { valueExists } from "shared/util";

export type PorterAppVersionStatus = {
Expand Down Expand Up @@ -38,7 +38,7 @@ export const useAppStatus = (
) => {
const [servicePodMap, setServicePodMap] = useState<Record<string, ClientPod[]>>({});

const revisionIdToNumber = useRevisionIdToNumber(appName, deploymentTargetId);
const { revisionIdToNumber } = useRevisionList({ appName, deploymentTargetId, projectId, clusterId });

const {
newWebsocket,
Expand Down Expand Up @@ -76,18 +76,17 @@ export const useAppStatus = (
};

const updatePods = async (serviceName: string) => {
const selectors = `porter.run/service-name=${serviceName},porter.run/deployment-target-id=${deploymentTargetId}`;

try {
const res = await api.appPodStatus(
"<token>",
{
deployment_target_id: deploymentTargetId,
selectors,
service: serviceName,
},
{
id: projectId,
project_id: projectId,
cluster_id: clusterId,
app_name: appName,
}
);
// TODO: type the response
Expand Down Expand Up @@ -143,7 +142,7 @@ export const useAppStatus = (
setupWebsocket(serviceName);
}
return () => closeAllWebsockets();
}, [projectId, clusterId, deploymentTargetId, appName, JSON.stringify(revisionIdToNumber)]);
}, [projectId, clusterId, deploymentTargetId, appName]);

const processReplicaSetArray = (replicaSetArray: ClientPod[][]): PorterAppVersionStatus[] => {
return replicaSetArray.map((replicaSet, i) => {
Expand All @@ -161,7 +160,8 @@ export const useAppStatus = (
message = `${replicaSet.length} replica${replicaSet.length === 1 ? "" : "s"} ${replicaSet.length === 1 ? "is" : "are"
} failing to run Version ${version}`;
} else if (
i > 0 && replicaSetArray[i - 1].every(p => !p.isFailing)
// last check ensures that we don't say 'spinning down' unless there exists a version status above it
i > 0 && replicaSetArray[i - 1].every(p => !p.isFailing) && revisionIdToNumber[replicaSetArray[i - 1][0].revisionId] != null
) {
status = "spinningDown";
message = `${replicaSet.length} replica${replicaSet.length === 1 ? "" : "s"} ${replicaSet.length === 1 ? "is" : "are"
Expand Down Expand Up @@ -207,7 +207,7 @@ export const useAppStatus = (
}));

return serviceReplicaSetMap;
}, [JSON.stringify(servicePodMap)]);
}, [JSON.stringify(servicePodMap), JSON.stringify(revisionIdToNumber)]);

return {
serviceVersionStatus,
Expand Down
55 changes: 24 additions & 31 deletions dashboard/src/lib/hooks/useRevisionList.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
import { useQuery } from "@tanstack/react-query";
import { useContext, useEffect, useState } from "react";
import { Context } from "shared/Context";
import { useEffect, useState } from "react";
import api from "shared/api";
import { z } from "zod";
import { AppRevision, appRevisionValidator } from "../revisions/types";
import { useLatestRevision } from "../../main/home/app-dashboard/app-view/LatestRevisionContext";

export function useRevisionList(appName: string, deploymentTargetId: string) {
const { currentProject, currentCluster } = useContext(Context);
const { latestRevision } = useLatestRevision();

import { useLatestRevision } from "main/home/app-dashboard/app-view/LatestRevisionContext";

export function useRevisionList({
appName,
deploymentTargetId,
projectId,
clusterId,
}: {
appName: string,
deploymentTargetId: string,
projectId: number,
clusterId: number
}): { revisionList: AppRevision[], revisionIdToNumber: Record<string, number> } {
const [
revisionList,
setRevisionList,
] = useState<AppRevision[]>([]);

if (currentProject == null || currentCluster == null) {
return [];
}
const [revisionIdToNumber, setRevisionIdToNumber] = useState<Record<string, number>>({});
const { latestRevision } = useLatestRevision();

const { data } = useQuery(
["listAppRevisions", currentProject.id, currentCluster.id, appName, deploymentTargetId, latestRevision],
["listAppRevisions", projectId, clusterId, appName, deploymentTargetId, latestRevision],
async () => {
const res = await api.listAppRevisions(
"<token>",
{
deployment_target_id: deploymentTargetId,
},
{
project_id: currentProject.id,
cluster_id: currentCluster.id,
project_id: projectId,
cluster_id: clusterId,
porter_app_name: appName,
}
);
Expand All @@ -39,32 +43,21 @@ export function useRevisionList(appName: string, deploymentTargetId: string) {
app_revisions: z.array(appRevisionValidator),
})
.parseAsync(res.data);

return revisions;
},
{
enabled: !!currentProject && !!currentCluster,
refetchInterval: 5000,
refetchOnWindowFocus: false,
}
);

useEffect(() => {
if (data) {
setRevisionList(data.app_revisions);
const revisionList = data.app_revisions
setRevisionList(revisionList);
setRevisionIdToNumber(Object.fromEntries(revisionList.map(r => ([r.id, r.revision_number]))))
}
}, [data]);

return revisionList;
}

export function useRevisionIdToNumber(appName: string, deploymentTargetId: string) {
const revisionList = useRevisionList(appName, deploymentTargetId);
const revisionIdToNumber: Record<string, number> = Object.fromEntries(revisionList.map(r => ([r.id, r.revision_number])))

return revisionIdToNumber;
}

export function useLatestRevisionNumber(appName: string, deploymentTargetId: string) {
const revisionList = useRevisionList(appName, deploymentTargetId);
return revisionList.map((revision) => revision.revision_number).reduce((a, b) => Math.max(a, b), 0)
return { revisionList, revisionIdToNumber };
}
4 changes: 2 additions & 2 deletions dashboard/src/main/home/app-dashboard/app-view/AppHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const AppHeader: React.FC = () => {
[]
);

return domains.length === 1 ? prefixSubdomain(domains[0]) : "";
return domains.length === 1 ? domains[0] : "";
}, [latestProto]);

return (
Expand Down Expand Up @@ -125,7 +125,7 @@ const AppHeader: React.FC = () => {
<>
<Container>
<Text>
<a href={displayDomain} target="_blank">
<a href={prefixSubdomain(displayDomain)} target="_blank">
{displayDomain}
</a>
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ export const LatestRevisionProvider = ({
app_revision: appRevisionValidator,
})
.parseAsync(res.data);

return revisionData.app_revision;
},
{
enabled: appParamsExist,
refetchInterval: 5000,
refetchOnWindowFocus: false,
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@ import { PorterAppDeployEvent } from "../types";
import AnimateHeight from "react-animate-height";
import ServiceStatusDetail from "./ServiceStatusDetail";
import { useLatestRevision } from "main/home/app-dashboard/app-view/LatestRevisionContext";
import { useRevisionIdToNumber } from "lib/hooks/useRevisionList";
import { useRevisionList } from "lib/hooks/useRevisionList";

type Props = {
event: PorterAppDeployEvent;
appName: string;
showServiceStatusDetail?: boolean;
deploymentTargetId: string;
projectId: number;
clusterId: number;
};

const DeployEventCard: React.FC<Props> = ({ event, appName, deploymentTargetId, showServiceStatusDetail = false }) => {
const DeployEventCard: React.FC<Props> = ({ event, appName, deploymentTargetId, projectId, clusterId, showServiceStatusDetail = false }) => {
const { latestRevision } = useLatestRevision();
const [diffModalVisible, setDiffModalVisible] = useState(false);
const [revertModalVisible, setRevertModalVisible] = useState(false);
const [serviceStatusVisible, setServiceStatusVisible] = useState(showServiceStatusDetail);

const revisionIdToNumber = useRevisionIdToNumber(appName, deploymentTargetId);
const { revisionIdToNumber } = useRevisionList({ appName, deploymentTargetId, projectId, clusterId });

const renderStatusText = () => {
switch (event.status) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const EventCard: React.FC<Props> = ({ event, deploymentTargetId, isLatestDeployE
return match(event)
.with({ type: "APP_EVENT" }, (ev) => <AppEventCard event={ev} deploymentTargetId={deploymentTargetId} projectId={projectId} clusterId={clusterId} appName={appName} />)
.with({ type: "BUILD" }, (ev) => <BuildEventCard event={ev} projectId={projectId} clusterId={clusterId} appName={appName} />)
.with({ type: "DEPLOY" }, (ev) => <DeployEventCard event={ev} appName={appName} showServiceStatusDetail={isLatestDeployEvent} deploymentTargetId={deploymentTargetId} appName={appName} />)
.with({ type: "DEPLOY" }, (ev) => <DeployEventCard event={ev} appName={appName} showServiceStatusDetail={isLatestDeployEvent} deploymentTargetId={deploymentTargetId} projectId={projectId} clusterId={clusterId} />)
.with({ type: "PRE_DEPLOY" }, (ev) => <PreDeployEventCard event={ev} appName={appName} projectId={projectId} clusterId={clusterId} />)
.exhaustive();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ import Container from "components/porter/Container";
import Button from "components/porter/Button";
import LogFilterContainer from "../../expanded-app/logs/LogFilterContainer";
import StyledLogs from "../../expanded-app/logs/StyledLogs";
import { useLatestRevisionNumber, useRevisionIdToNumber } from "lib/hooks/useRevisionList";
import { useRevisionList } from "lib/hooks/useRevisionList";
import { useLocation } from "react-router";
import { useLatestRevision } from "../../app-view/LatestRevisionContext";

type Props = {
projectId: number;
Expand Down Expand Up @@ -81,8 +82,8 @@ const Logs: React.FC<Props> = ({
output_stream: logQueryParamOpts.output_stream ?? GenericLogFilter.getDefaultOption("output_stream").value,
});

const revisionIdToNumber = useRevisionIdToNumber(appName, deploymentTargetId)
const latestRevisionNumber = useLatestRevisionNumber(appName, deploymentTargetId)
const { revisionIdToNumber } = useRevisionList({ appName, deploymentTargetId, projectId, clusterId });
const { latestRevision: { revision_number: latestRevisionNumber } } = useLatestRevision();

const isAgentVersionUpdated = (agentImage: string | undefined) => {
if (agentImage == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ export const useLogs = ({
setDate,
JSON.stringify(selectedFilterValues),
JSON.stringify(timeRange?.endTime),
filterPredeploy
filterPredeploy,
]);

useEffect(() => {
Expand Down
8 changes: 4 additions & 4 deletions dashboard/src/shared/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,11 @@ const appJobs = baseApi<
const appPodStatus = baseApi<
{
deployment_target_id: string;
selectors: string;
service: string;
},
{ id: number; cluster_id: number }
>("GET", (pathParams) => {
return `/api/projects/${pathParams.id}/clusters/${pathParams.cluster_id}/apps/pods`;
{ project_id: number; cluster_id: number, app_name: string }
>("GET", ({ project_id, cluster_id, app_name }) => {
return `/api/projects/${project_id}/clusters/${cluster_id}/apps/${app_name}/pods`;
});

const getFeedEvents = baseApi<
Expand Down

0 comments on commit 7d1280c

Please sign in to comment.