Skip to content

Commit

Permalink
fetch node pods
Browse files Browse the repository at this point in the history
  • Loading branch information
maciaszczykm committed Apr 2, 2024
1 parent f41fdef commit 91f8ad8
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 70 deletions.
188 changes: 119 additions & 69 deletions assets/src/components/kubernetes/cluster/Node.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactElement, useMemo } from 'react'
import React, { ReactElement, useMemo } from 'react'
import {
Card,
ChipList,
Expand All @@ -14,9 +14,14 @@ import {
Common_Event as EventT,
NodeEventsQuery,
NodeEventsQueryVariables,
NodePodsQuery,
NodePodsQueryVariables,
NodeQueryVariables,
Node_NodeDetail as NodeT,
Pod_PodList as PodListT,
Pod_Pod as PodT,
useNodeEventsQuery,
useNodePodsQuery,
useNodeQuery,
} from '../../../generated/graphql-kubernetes'
import { KubernetesClient } from '../../../helpers/kubernetes.client'
Expand All @@ -32,12 +37,17 @@ import { SubTitle } from '../../cluster/nodes/SubTitle'

import { ResourceInfoCardEntry } from '../common/ResourceInfoCard'

import { GaugeWrap, ResourceGauge } from '../../cluster/Gauges'

import { usePodColumns } from '../workloads/Pods'

import { getBreadcrumbs } from './Nodes'
import { useEventsColumns } from './Events'
import { NodeReadyChip } from './utils'

const directory: Array<TabEntry> = [
{ path: '', label: 'Info' },
{ path: 'pods', label: 'Pods' },
{ path: 'events', label: 'Events' },
{ path: 'raw', label: 'Raw' },
] as const
Expand Down Expand Up @@ -95,74 +105,114 @@ export function NodeInfo(): ReactElement {
const node = useOutletContext() as NodeT

return (
<section>
<SubTitle>Node information</SubTitle>
<Card
css={{
display: 'flex',
gap: theme.spacing.large,
padding: theme.spacing.medium,
}}
>
<ResourceInfoCardEntry heading="Provider ID">
{node?.providerID}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Unschedulable">
{node?.unschedulable ? 'True' : 'False'}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Pod CIDR">
{node?.podCIDR}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Addresses">
<ChipList
size="small"
limit={5}
values={node.addresses || []}
transformValue={(a) => `${a?.type}: ${a?.address}`}
emptyState={<div>None</div>}
/>
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Taints">
<ChipList
size="small"
limit={5}
values={node.taints || []}
transformValue={(t) => `${t?.key}=${t?.value}:${t?.effect}`}
emptyState={<div>None</div>}
/>
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Machine ID">
{node?.nodeInfo.machineID}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="System UUID">
{node?.nodeInfo.systemUUID}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Boot ID">
{node?.nodeInfo.bootID}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Kernel version">
{node?.nodeInfo.kernelVersion}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="OS image">
{node?.nodeInfo.osImage}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Container runtime version">
{node?.nodeInfo.containerRuntimeVersion}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="kubelet version">
{node?.nodeInfo.kubeletVersion}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="kube-proxy version">
{node?.nodeInfo.kubeProxyVersion}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Operating system">
{node?.nodeInfo.operatingSystem}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Architecture">
{node?.nodeInfo.architecture}
</ResourceInfoCardEntry>
</Card>
</section>
<>
<section>
<SubTitle>Allocated resources</SubTitle>
<Card>
<GaugeWrap
heading="Memory reservation"
width="auto"
height="auto"
>
<ResourceGauge
limits={node.allocatedResources.memoryLimits}
requests={node.allocatedResources.memoryRequests}
total={node.allocatedResources.memoryCapacity}
type="memory"
/>
</GaugeWrap>
TODO
</Card>
</section>
<section>
<SubTitle>Node information</SubTitle>
<Card
css={{
display: 'flex',
gap: theme.spacing.large,
padding: theme.spacing.medium,
}}
>
<ResourceInfoCardEntry heading="Provider ID">
{node?.providerID}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Unschedulable">
{node?.unschedulable ? 'True' : 'False'}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Pod CIDR">
{node?.podCIDR}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Addresses">
<ChipList
size="small"
limit={5}
values={node.addresses || []}
transformValue={(a) => `${a?.type}: ${a?.address}`}
emptyState={<div>None</div>}
/>
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Taints">
<ChipList
size="small"
limit={5}
values={node.taints || []}
transformValue={(t) => `${t?.key}=${t?.value}:${t?.effect}`}
emptyState={<div>None</div>}
/>
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Machine ID">
{node?.nodeInfo.machineID}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="System UUID">
{node?.nodeInfo.systemUUID}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Boot ID">
{node?.nodeInfo.bootID}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Kernel version">
{node?.nodeInfo.kernelVersion}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="OS image">
{node?.nodeInfo.osImage}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Container runtime version">
{node?.nodeInfo.containerRuntimeVersion}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="kubelet version">
{node?.nodeInfo.kubeletVersion}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="kube-proxy version">
{node?.nodeInfo.kubeProxyVersion}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Operating system">
{node?.nodeInfo.operatingSystem}
</ResourceInfoCardEntry>
<ResourceInfoCardEntry heading="Architecture">
{node?.nodeInfo.architecture}
</ResourceInfoCardEntry>
</Card>
</section>
</>
)
}

export function NodePods(): ReactElement {
const { name } = useParams()
const columns = usePodColumns()

// TODO: Pagination etc.
return (
<ResourceList<PodListT, PodT, NodePodsQuery, NodePodsQueryVariables>
namespaced
columns={columns}
query={useNodePodsQuery}
queryOptions={{
variables: { name } as NodePodsQueryVariables,
}}
queryName="handleGetNodePods"
itemsKey="pods"
disableOnRowClick
/>
)
}

Expand Down
62 changes: 61 additions & 1 deletion assets/src/generated/graphql-kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4737,7 +4737,15 @@ export type NodeQueryVariables = Exact<{
}>;


export type NodeQuery = { __typename?: 'Query', handleGetNodeDetail?: { __typename?: 'node_NodeDetail', providerID: string, containerImages: Array<string | null>, podCIDR: string, phase: string, unschedulable: boolean, ready: string, errors: Array<any | null>, typeMeta: { __typename?: 'types_TypeMeta', kind?: string | null, restartable?: boolean | null, scalable?: boolean | null }, objectMeta: { __typename?: 'types_ObjectMeta', uid?: string | null, name?: string | null, namespace?: string | null, labels?: any | null, annotations?: any | null, creationTimestamp?: string | null }, nodeInfo: { __typename?: 'v1_NodeSystemInfo', architecture: string, bootID: string, containerRuntimeVersion: string, kernelVersion: string, kubeletVersion: string, kubeProxyVersion: string, machineID: string, operatingSystem: string, osImage: string, systemUUID: string }, addresses?: Array<{ __typename?: 'v1_NodeAddress', type: string, address: string } | null> | null, taints?: Array<{ __typename?: 'v1_Taint', key: string, value?: string | null, effect: string } | null> | null } | null };
export type NodeQuery = { __typename?: 'Query', handleGetNodeDetail?: { __typename?: 'node_NodeDetail', providerID: string, containerImages: Array<string | null>, podCIDR: string, phase: string, unschedulable: boolean, ready: string, errors: Array<any | null>, typeMeta: { __typename?: 'types_TypeMeta', kind?: string | null, restartable?: boolean | null, scalable?: boolean | null }, objectMeta: { __typename?: 'types_ObjectMeta', uid?: string | null, name?: string | null, namespace?: string | null, labels?: any | null, annotations?: any | null, creationTimestamp?: string | null }, nodeInfo: { __typename?: 'v1_NodeSystemInfo', architecture: string, bootID: string, containerRuntimeVersion: string, kernelVersion: string, kubeletVersion: string, kubeProxyVersion: string, machineID: string, operatingSystem: string, osImage: string, systemUUID: string }, allocatedResources: { __typename?: 'node_NodeAllocatedResources', cpuRequests: any, cpuRequestsFraction: number, cpuCapacity: any, memoryRequests: any, memoryRequestsFraction: number, memoryCapacity: any, allocatedPods: number, podFraction: number, podCapacity: any }, addresses?: Array<{ __typename?: 'v1_NodeAddress', type: string, address: string } | null> | null, taints?: Array<{ __typename?: 'v1_Taint', key: string, value?: string | null, effect: string } | null> | null } | null };

export type NodePodsQueryVariables = Exact<{
namespace: Scalars['String']['input'];
name: Scalars['String']['input'];
}>;


export type NodePodsQuery = { __typename?: 'Query', handleGetNodePods?: { __typename?: 'pod_PodList', listMeta: { __typename?: 'types_ListMeta', totalItems: number }, pods: Array<{ __typename?: 'pod_Pod', status: string, containerImages: Array<string | null>, nodeName: string, restartCount: number, typeMeta: { __typename?: 'types_TypeMeta', kind?: string | null, restartable?: boolean | null, scalable?: boolean | null }, objectMeta: { __typename?: 'types_ObjectMeta', uid?: string | null, name?: string | null, namespace?: string | null, labels?: any | null, annotations?: any | null, creationTimestamp?: string | null }, warnings: Array<{ __typename?: 'common_Event', message: string } | null> } | null> } | null };

export type NodeEventsQueryVariables = Exact<{
name: Scalars['String']['input'];
Expand Down Expand Up @@ -6392,6 +6400,17 @@ export const NodeDocument = gql`
osImage
systemUUID
}
allocatedResources {
cpuRequests
cpuRequestsFraction
cpuCapacity
memoryRequests
memoryRequestsFraction
memoryCapacity
allocatedPods
podFraction
podCapacity
}
addresses {
type
address
Expand Down Expand Up @@ -6445,6 +6464,47 @@ export type NodeQueryHookResult = ReturnType<typeof useNodeQuery>;
export type NodeLazyQueryHookResult = ReturnType<typeof useNodeLazyQuery>;
export type NodeSuspenseQueryHookResult = ReturnType<typeof useNodeSuspenseQuery>;
export type NodeQueryResult = Apollo.QueryResult<NodeQuery, NodeQueryVariables>;
export const NodePodsDocument = gql`
query NodePods($namespace: String!, $name: String!) {
handleGetNodePods(name: $name) @rest(type: "pod_PodList", path: "node/{args.name}/pod") {
...PodList
}
}
${PodListFragmentDoc}`;

/**
* __useNodePodsQuery__
*
* To run a query within a React component, call `useNodePodsQuery` and pass it any options that fit your needs.
* When your component renders, `useNodePodsQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useNodePodsQuery({
* variables: {
* namespace: // value for 'namespace'
* name: // value for 'name'
* },
* });
*/
export function useNodePodsQuery(baseOptions: Apollo.QueryHookOptions<NodePodsQuery, NodePodsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<NodePodsQuery, NodePodsQueryVariables>(NodePodsDocument, options);
}
export function useNodePodsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<NodePodsQuery, NodePodsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<NodePodsQuery, NodePodsQueryVariables>(NodePodsDocument, options);
}
export function useNodePodsSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions<NodePodsQuery, NodePodsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useSuspenseQuery<NodePodsQuery, NodePodsQueryVariables>(NodePodsDocument, options);
}
export type NodePodsQueryHookResult = ReturnType<typeof useNodePodsQuery>;
export type NodePodsLazyQueryHookResult = ReturnType<typeof useNodePodsLazyQuery>;
export type NodePodsSuspenseQueryHookResult = ReturnType<typeof useNodePodsSuspenseQuery>;
export type NodePodsQueryResult = Apollo.QueryResult<NodePodsQuery, NodePodsQueryVariables>;
export const NodeEventsDocument = gql`
query NodeEvents($name: String!, $filterBy: String, $sortBy: String, $itemsPerPage: String, $page: String) {
handleGetNodeEvents(
Expand Down
15 changes: 15 additions & 0 deletions assets/src/graph-kubernetes/cluster/node.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,21 @@ query Node($name: String!) {
}
}

query NodePods(
$namespace: String!
$name: String!
) {
handleGetNodePods(
name: $name
)
@rest(
type: "pod_PodList"
path: "node/{args.name}/pod"
) {
...PodList
}
}

query NodeEvents(
$name: String!
$filterBy: String
Expand Down
5 changes: 5 additions & 0 deletions assets/src/routes/kubernetesRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import Nodes from '../components/kubernetes/cluster/Nodes'
import Node, {
NodeEvents,
NodeInfo,
NodePods,
} from '../components/kubernetes/cluster/Node'
import Events from '../components/kubernetes/cluster/Events'
import Namespaces from '../components/kubernetes/cluster/Namespaces'
Expand Down Expand Up @@ -517,6 +518,10 @@ export const kubernetesRoutes = [
path=""
element={<NodeInfo />}
/>
<Route
path="pods"
element={<NodePods />}
/>
<Route
path="events"
element={<NodeEvents />}
Expand Down

0 comments on commit 91f8ad8

Please sign in to comment.