🚚 New Routes for resources
This commit is contained in:
parent
74ebe0b925
commit
fe3dcd2165
16
classes/CustomResourceDefinition.ts
Normal file
16
classes/CustomResourceDefinition.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import type { Metadata } from "./Metadata";
|
||||||
|
|
||||||
|
export class CustomResourceDefinition
|
||||||
|
{
|
||||||
|
constructor (
|
||||||
|
public metadata: Metadata,
|
||||||
|
public spec: Spec
|
||||||
|
) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Spec
|
||||||
|
{
|
||||||
|
constructor (
|
||||||
|
public group: string
|
||||||
|
) { }
|
||||||
|
}
|
||||||
@ -2,5 +2,7 @@ import type { Metadata } from "./Metadata";
|
|||||||
|
|
||||||
export class Namespace
|
export class Namespace
|
||||||
{
|
{
|
||||||
metadata?: Metadata;
|
constructor (
|
||||||
|
public metadata: Metadata
|
||||||
|
) { }
|
||||||
}
|
}
|
||||||
55
classes/ResourceRepo.ts
Normal file
55
classes/ResourceRepo.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export class ResourceRepo<T>
|
||||||
|
{
|
||||||
|
private resources: Ref<T[] | undefined> = ref(undefined);
|
||||||
|
private interval: NodeJS.Timeout | undefined = undefined;
|
||||||
|
|
||||||
|
static init<T>()
|
||||||
|
{
|
||||||
|
return new ResourceRepo<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
load(resourceType: string)
|
||||||
|
{
|
||||||
|
this.refresh(resourceType);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear()
|
||||||
|
{
|
||||||
|
clearTimeout(this.interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
get()
|
||||||
|
{
|
||||||
|
return computed(() => {
|
||||||
|
return this.resources.value;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private refresh(resourceType: string)
|
||||||
|
{
|
||||||
|
const namespace = this.getNamespace();
|
||||||
|
let url = useRuntimeConfig().public.apiBase + '/resources/' + resourceType
|
||||||
|
if (namespace)
|
||||||
|
{
|
||||||
|
url = url + "/" + namespace;
|
||||||
|
}
|
||||||
|
axios.get<T[]>(url)
|
||||||
|
.then((response) => {
|
||||||
|
this.resources.value = undefined;
|
||||||
|
this.resources.value = response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getNamespace()
|
||||||
|
{
|
||||||
|
const namespace = useRoute().params.namespace as string;
|
||||||
|
if (namespace !== "_all")
|
||||||
|
{
|
||||||
|
return namespace as string;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,20 +3,12 @@
|
|||||||
<div class="content-l">
|
<div class="content-l">
|
||||||
<h2>Kubooboo</h2>
|
<h2>Kubooboo</h2>
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<NuxtLink class="resources" to="/account/inspect/nodes">Nodes</NuxtLink>
|
<NuxtLink class="resources" v-for="[key, value] of resources" :to="'/account/inspect/' + key + '/_all'" :class="{ 'router-link-active': useRoute().params.resource === key }">{{ value }}</NuxtLink>
|
||||||
<NuxtLink class="resources" to="/account/inspect/ingresses">Ingresses</NuxtLink>
|
|
||||||
<NuxtLink class="resources" to="/account/inspect/services">Services</NuxtLink>
|
|
||||||
<NuxtLink class="resources" to="/account/inspect/deployments">Deployments</NuxtLink>
|
|
||||||
<NuxtLink class="resources" to="/account/inspect/pods">Pods</NuxtLink>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="divider" :class="{ hide: !inNamespaceScopedResource }"></div>
|
<div class="divider" :class="{ hide: !inNamespaceScopedResource }"></div>
|
||||||
<div :class="{ hide: !inNamespaceScopedResource }">
|
<div class="nav" :class="{ hide: !inNamespaceScopedResource }">
|
||||||
<div class="namespace" :class="{ active: currentNamespace === undefined }" @click="() => namespaceStore.selectNamespace(undefined)">
|
<NuxtLink class="namespace" :to="base + '/_all'">Alle</NuxtLink>
|
||||||
<p>Alle</p>
|
<NuxtLink v-for="namespace in namespaces" class="namespace" :to="base + '/' + namespace.metadata.name">{{ namespace.metadata.name }}</NuxtLink>
|
||||||
</div>
|
|
||||||
<div class="namespace" v-for="namespace in namespaces" @click="() => namespaceStore.selectNamespace(namespace)" :class="{ active: namespace.metadata?.name === currentNamespace?.metadata?.name }">
|
|
||||||
<p v-if="namespace.metadata">{{ namespace.metadata.name }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="left-center" v-if="user" @click="() => accountPopup.open()">
|
<div class="left-center" v-if="user" @click="() => accountPopup.open()">
|
||||||
@ -31,6 +23,8 @@ import SidebarTemplate from './SidebarTemplate.vue';
|
|||||||
|
|
||||||
import { useNamespaceStore } from '#imports';
|
import { useNamespaceStore } from '#imports';
|
||||||
|
|
||||||
|
const resources = new Map<string, string>([["nodes", "Nodes"], ["ingresses", "Ingresses"], ["services", "Services"], ["deployments", "Deployments"], ["pods", "Pods"], ["custom-resource-definitions", "CDRs"]]);
|
||||||
|
|
||||||
const namespaceStore = useNamespaceStore();
|
const namespaceStore = useNamespaceStore();
|
||||||
|
|
||||||
const namespaces = computed(namespaceStore.getNamespaces);
|
const namespaces = computed(namespaceStore.getNamespaces);
|
||||||
@ -41,8 +35,18 @@ const user = getUser();
|
|||||||
|
|
||||||
const accountPopup = ref();
|
const accountPopup = ref();
|
||||||
|
|
||||||
|
const base = computed(() => {
|
||||||
|
const resource = useRoute().params.resource as string;
|
||||||
|
if (resource)
|
||||||
|
{
|
||||||
|
return '/account/inspect/' + resource;
|
||||||
|
}
|
||||||
|
throw new Error();
|
||||||
|
})
|
||||||
|
|
||||||
const inNamespaceScopedResource: ComputedRef<boolean> = computed(() => {
|
const inNamespaceScopedResource: ComputedRef<boolean> = computed(() => {
|
||||||
if(useRoute().fullPath.startsWith('/account/inspect/nodes'))
|
const resource = useRoute().params.resource as string;
|
||||||
|
if(['custom-resource-definitions', 'nodes'].includes(resource))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,5 +35,7 @@ defineExpose({
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -24,10 +24,8 @@
|
|||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.namespace.active, .resources.router-link-active {
|
.router-link-active {
|
||||||
background-color: var(--primary-color)
|
background-color: var(--primary-color);
|
||||||
}
|
|
||||||
.namespace.active *, .resources.router-link-active {
|
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
.divider {
|
.divider {
|
||||||
|
|||||||
32
components/TableComponent.vue
Normal file
32
components/TableComponent.vue
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<div class="table">
|
||||||
|
<slot v-if="!loading"></slot>
|
||||||
|
<div class="loading center" v-if="loading">
|
||||||
|
<UiLoadingIcon></UiLoadingIcon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
loading: boolean
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.table {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
.loading {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.grid-element {
|
||||||
|
height: 2.25rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Deployment } from '~/classes/Deployment';
|
import { Deployment } from '~/classes/Deployment';
|
||||||
import { rescaleDeployment } from '~/requests/deployments';
|
|
||||||
import RescaleDeploymentPopup from '../RescaleDeploymentPopup.vue';
|
import RescaleDeploymentPopup from '../RescaleDeploymentPopup.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<TableComponent :loading="customResourceDefinitions == null">
|
||||||
|
<div class="resource-container crd-container">
|
||||||
|
<div class="header">
|
||||||
|
<p>Name</p>
|
||||||
|
<p>Gruppe</p>
|
||||||
|
</div>
|
||||||
|
<div v-for="customResourceDefinition, index in customResourceDefinitions" class="resource" :class="{ even: index % 2 }">
|
||||||
|
<p class="grid-element">{{ customResourceDefinition.metadata.name }}</p>
|
||||||
|
<p class="grid-element">{{ customResourceDefinition.spec.group }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TableComponent>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { CustomResourceDefinition } from '~/classes/CustomResourceDefinition';
|
||||||
|
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||||
|
|
||||||
|
const customResourceDefinitions = ResourceRepo.init<CustomResourceDefinition>().load('custom-resource-definitions').get();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.crd-container {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
27
components/inspect/resources/DeploymentComponent.vue
Normal file
27
components/inspect/resources/DeploymentComponent.vue
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<TableComponent :loading="deployments == null">
|
||||||
|
<div class="resource-container deployment-container">
|
||||||
|
<div class="header">
|
||||||
|
<p>Name</p>
|
||||||
|
<p>Namespace</p>
|
||||||
|
<p>Replicas</p>
|
||||||
|
<p>Aktionen</p>
|
||||||
|
</div>
|
||||||
|
<DeploymentComponent :deployment="deployment" v-for="deployment, index in deployments" class="resource" :class="{ even: index % 2 }"></DeploymentComponent>
|
||||||
|
</div>
|
||||||
|
</TableComponent>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Deployment } from '~/classes/Deployment';
|
||||||
|
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||||
|
import DeploymentComponent from '~/components/deployments/DeploymentComponent.vue';
|
||||||
|
|
||||||
|
const deployments = ResourceRepo.init<Deployment>().load('deployments').get();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.deployment-container {
|
||||||
|
grid-template-columns: auto 1fr 1fr auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
24
components/inspect/resources/IngressComponent.vue
Normal file
24
components/inspect/resources/IngressComponent.vue
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<template>
|
||||||
|
<TableComponent :loading="ingresses == null">
|
||||||
|
<div class="resource-container ingress-container">
|
||||||
|
<div class="header">
|
||||||
|
<p>Name</p>
|
||||||
|
<p>Namespace</p>
|
||||||
|
</div>
|
||||||
|
<IngressComponent :ingress="ingress" v-for="ingress, index in ingresses" class="resource" :class="{ even: index % 2 }"></IngressComponent>
|
||||||
|
</div>
|
||||||
|
</TableComponent>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Ingress } from '~/classes/Ingress';
|
||||||
|
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||||
|
|
||||||
|
const ingresses = ResourceRepo.init<Ingress>().load('ingresses').get();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.ingress-container {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
28
components/inspect/resources/NodeComponent.vue
Normal file
28
components/inspect/resources/NodeComponent.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<TableComponent :loading="node == null">
|
||||||
|
<div class="resource-container node-container">
|
||||||
|
<div class="header">
|
||||||
|
<p>Name</p>
|
||||||
|
<p>Alter</p>
|
||||||
|
<p>Status</p>
|
||||||
|
<p>CPU</p>
|
||||||
|
<p>RAM</p>
|
||||||
|
</div>
|
||||||
|
<NodeComponent :node-stats="ns" v-for="ns, index in node" class="resource" :class="{ even: index % 2 }"></NodeComponent>
|
||||||
|
</div>
|
||||||
|
</TableComponent>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { NodeStats } from '~/classes/Node';
|
||||||
|
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||||
|
import NodeComponent from '~/components/NodeComponent.vue';
|
||||||
|
|
||||||
|
const node = ResourceRepo.init<NodeStats>().load('nodes').get();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.node-container {
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
23
components/inspect/resources/PodComponent.vue
Normal file
23
components/inspect/resources/PodComponent.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<TableComponent :loading="pods == null">
|
||||||
|
<div class="resource-container pod-container">
|
||||||
|
<div class="header">
|
||||||
|
<p>Pod</p>
|
||||||
|
<p>Namespace</p>
|
||||||
|
<p>Alter</p>
|
||||||
|
<p>Node</p>
|
||||||
|
<p>Status</p>
|
||||||
|
<p>Aktionen</p>
|
||||||
|
</div>
|
||||||
|
<PodComponent v-for="pod, index in pods" :pod="pod" class="resource" :class="{ even: index % 2 }"></PodComponent>
|
||||||
|
</div>
|
||||||
|
</TableComponent>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Pod } from '~/classes/Pod';
|
||||||
|
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||||
|
import PodComponent from '~/components/pod/PodComponent.vue';
|
||||||
|
|
||||||
|
const pods = ResourceRepo.init<Pod>().load('pods').get();
|
||||||
|
</script>
|
||||||
26
components/inspect/resources/ServiceComponent.vue
Normal file
26
components/inspect/resources/ServiceComponent.vue
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<TableComponent :loading="services == null">
|
||||||
|
<div class="resource-container service-container">
|
||||||
|
<div class="header">
|
||||||
|
<p>Service</p>
|
||||||
|
<p>Namespace</p>
|
||||||
|
<p>Type</p>
|
||||||
|
<p>Aktionen</p>
|
||||||
|
</div>
|
||||||
|
<ServiceComponent :service="service" v-for="service, index in services" class="resource" :class="{ even: index % 2 }"></ServiceComponent>
|
||||||
|
</div>
|
||||||
|
</TableComponent>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||||
|
import type { Service } from '~/classes/Service';
|
||||||
|
|
||||||
|
const services = ResourceRepo.init<Service>().load('services').get();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.service-container {
|
||||||
|
grid-template-columns: auto auto 1fr auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -9,6 +9,7 @@ import UiIcon from './UiIcon.vue';
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.rotate{
|
.rotate{
|
||||||
animation: rotate 1s linear infinite;
|
animation: rotate 1s linear infinite;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
@keyframes rotate{
|
@keyframes rotate{
|
||||||
to{ transform: rotate(360deg); }
|
to{ transform: rotate(360deg); }
|
||||||
|
|||||||
10
pages/account/inspect/[resource].vue
Normal file
10
pages/account/inspect/[resource].vue
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<template>
|
||||||
|
<NuxtPage></NuxtPage>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
20
pages/account/inspect/[resource]/[namespace].vue
Normal file
20
pages/account/inspect/[resource]/[namespace].vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<PodComponent v-if="resource === 'pods'"></PodComponent>
|
||||||
|
<CustomResourceDefinitionComponent v-else-if="resource === 'custom-resource-definitions'"></CustomResourceDefinitionComponent>
|
||||||
|
<IngressComponent v-else-if="resource === 'ingresses'"></IngressComponent>
|
||||||
|
<ServiceComponent v-else-if="resource === 'services'"></ServiceComponent>
|
||||||
|
<DeploymentComponent v-else-if="resource === 'deployments'"></DeploymentComponent>
|
||||||
|
<NodeComponent v-else-if="resource === 'nodes'"></NodeComponent>
|
||||||
|
<p v-else>Invalid resource</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import PodComponent from '~/components/inspect/resources/PodComponent.vue';
|
||||||
|
import CustomResourceDefinitionComponent from '~/components/inspect/resources/CustomResourceDefinitionComponent.vue';
|
||||||
|
import IngressComponent from '~/components/inspect/resources/IngressComponent.vue';
|
||||||
|
import ServiceComponent from '~/components/inspect/resources/ServiceComponent.vue';
|
||||||
|
import DeploymentComponent from '~/components/inspect/resources/DeploymentComponent.vue';
|
||||||
|
import NodeComponent from '~/components/inspect/resources/NodeComponent.vue';
|
||||||
|
|
||||||
|
const resource = useRoute().params.resource as string;
|
||||||
|
</script>
|
||||||
@ -1,50 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="resource-container deployment-container">
|
|
||||||
<div class="header">
|
|
||||||
<p>Name</p>
|
|
||||||
<p>Namespace</p>
|
|
||||||
<p>Replicas</p>
|
|
||||||
<p>Aktionen</p>
|
|
||||||
</div>
|
|
||||||
<DeploymentComponent :deployment="deployment" v-for="deployment, index in deployments" class="resource" :class="{ even: index % 2 }"></DeploymentComponent>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { Deployment } from '~/classes/Deployment';
|
|
||||||
import { useNamespaceStore } from '#imports';
|
|
||||||
import type { Namespace } from '~/classes/Namespace';
|
|
||||||
import { getDeployments } from '~/requests/deployments';
|
|
||||||
import DeploymentComponent from '~/components/deployments/DeploymentComponent.vue';
|
|
||||||
|
|
||||||
const deployments: Ref<Deployment[] | undefined> = ref(undefined);
|
|
||||||
|
|
||||||
const namespace = computed(useNamespaceStore().getCurrentNamespace);
|
|
||||||
|
|
||||||
let interval: NodeJS.Timeout | undefined = undefined;
|
|
||||||
onMounted(() => {
|
|
||||||
watch(namespace, (newNamespace) => {
|
|
||||||
loadDeployments(newNamespace);
|
|
||||||
clearInterval(interval);
|
|
||||||
interval = setInterval(() => {
|
|
||||||
loadDeployments(newNamespace);
|
|
||||||
}, 10000);
|
|
||||||
}, { immediate: true })
|
|
||||||
})
|
|
||||||
onUnmounted(() => {
|
|
||||||
clearInterval(interval);
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadDeployments(namespace?: Namespace)
|
|
||||||
{
|
|
||||||
getDeployments(namespace?.metadata?.name, (_deployments: Deployment[]) => {
|
|
||||||
deployments.value = _deployments;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.deployment-container {
|
|
||||||
grid-template-columns: 1fr 1fr 1fr auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="resource-container ingress-container">
|
|
||||||
<div class="header">
|
|
||||||
<p>Name</p>
|
|
||||||
<p>Namespace</p>
|
|
||||||
</div>
|
|
||||||
<IngressComponent :ingress="ingress" v-for="ingress, index in ingresses" class="resource" :class="{ even: index % 2 }"></IngressComponent>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import type { Ingress } from '~/classes/Ingress';
|
|
||||||
import IngressComponent from '~/components/IngressComponent.vue';
|
|
||||||
import { getIngresses } from '~/requests/ingresses';
|
|
||||||
|
|
||||||
const ingresses: Ref<Ingress[] | undefined> = ref(undefined);
|
|
||||||
|
|
||||||
const namespace = computed(useNamespaceStore().getCurrentNamespace);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
watch(namespace, (newNamespace) => {
|
|
||||||
getIngresses(newNamespace?.metadata?.name, (_ingresses: Ingress[]) => {
|
|
||||||
ingresses.value = _ingresses;
|
|
||||||
});
|
|
||||||
}, { immediate: true })
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.ingress-container {
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="resource-container node-container">
|
|
||||||
<div class="header">
|
|
||||||
<p>Name</p>
|
|
||||||
<p>Alter</p>
|
|
||||||
<p>Status</p>
|
|
||||||
<p>CPU</p>
|
|
||||||
<p>RAM</p>
|
|
||||||
</div>
|
|
||||||
<NodeComponent :node-stats="ns" v-for="ns, index in nodeStats" class="resource" :class="{ even: index % 2 }"></NodeComponent>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { NodeStats } from '~/classes/Node';
|
|
||||||
import { getNodes } from '~/requests/nodes';
|
|
||||||
|
|
||||||
const nodeStats: Ref<NodeStats[] | undefined> = ref(undefined);
|
|
||||||
|
|
||||||
let interval: NodeJS.Timeout | undefined = undefined;
|
|
||||||
onMounted(() => {
|
|
||||||
loadNodes();
|
|
||||||
interval = setInterval(() => {
|
|
||||||
loadNodes();
|
|
||||||
}, 10000)
|
|
||||||
})
|
|
||||||
onUnmounted(() => {
|
|
||||||
clearInterval(interval);
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadNodes()
|
|
||||||
{
|
|
||||||
getNodes((_nodes: NodeStats[]) => {
|
|
||||||
nodeStats.value = _nodes;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.node-container {
|
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
|
||||||
}
|
|
||||||
.action-buttons {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="resource-container pod-container">
|
|
||||||
<div class="header">
|
|
||||||
<p>Pod</p>
|
|
||||||
<p>Namespace</p>
|
|
||||||
<p>Alter</p>
|
|
||||||
<p>Node</p>
|
|
||||||
<p>Status</p>
|
|
||||||
<p>Aktionen</p>
|
|
||||||
</div>
|
|
||||||
<PodComponent v-for="pod, index in pods" :pod="pod" class="resource" :class="{ even: index % 2 }"></PodComponent>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { type Pod } from '~/classes/Pod';
|
|
||||||
import { getPods } from '~/requests/pod';
|
|
||||||
import { useNamespaceStore } from '#imports';
|
|
||||||
import type { Namespace } from '~/classes/Namespace';
|
|
||||||
|
|
||||||
const pods: Ref<Pod[] | undefined> = ref(undefined);
|
|
||||||
|
|
||||||
const namespace = computed(useNamespaceStore().getCurrentNamespace);
|
|
||||||
|
|
||||||
let interval: NodeJS.Timeout | undefined = undefined;
|
|
||||||
onMounted(() => {
|
|
||||||
watch(namespace, (newNamespace) => {
|
|
||||||
loadPods(newNamespace);
|
|
||||||
clearInterval(interval);
|
|
||||||
interval = setInterval(() => {
|
|
||||||
loadPods(newNamespace);
|
|
||||||
}, 10000);
|
|
||||||
}, { immediate: true })
|
|
||||||
})
|
|
||||||
onUnmounted(() => {
|
|
||||||
clearInterval(interval);
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadPods(namespace?: Namespace)
|
|
||||||
{
|
|
||||||
getPods(namespace?.metadata?.name, (_pods: Pod[]) => {
|
|
||||||
pods.value = _pods;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.pod-container {
|
|
||||||
grid-template-columns: auto auto auto 1fr auto auto;
|
|
||||||
}
|
|
||||||
.action-buttons {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="resource-container service-container">
|
|
||||||
<div class="header">
|
|
||||||
<p>Service</p>
|
|
||||||
<p>Namespace</p>
|
|
||||||
<p>Type</p>
|
|
||||||
<p>Aktionen</p>
|
|
||||||
</div>
|
|
||||||
<ServiceComponent :service="service" v-for="service, index in services" class="resource" :class="{ even: index % 2 }"></ServiceComponent>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { useNamespaceStore } from '#imports';
|
|
||||||
import type { Namespace } from '~/classes/Namespace';
|
|
||||||
import type { Service } from '~/classes/Service';
|
|
||||||
import { getServices } from '~/requests/services';
|
|
||||||
|
|
||||||
const services: Ref<Service[] | undefined> = ref(undefined);
|
|
||||||
|
|
||||||
const namespace = computed(useNamespaceStore().getCurrentNamespace);
|
|
||||||
|
|
||||||
let interval: NodeJS.Timeout | undefined = undefined;
|
|
||||||
onMounted(() => {
|
|
||||||
watch(namespace, (newNamespace) => {
|
|
||||||
loadServices(newNamespace);
|
|
||||||
clearInterval(interval);
|
|
||||||
interval = setInterval(() => {
|
|
||||||
loadServices(newNamespace);
|
|
||||||
}, 10000);
|
|
||||||
}, { immediate: true })
|
|
||||||
})
|
|
||||||
onUnmounted(() => {
|
|
||||||
clearInterval(interval);
|
|
||||||
})
|
|
||||||
|
|
||||||
function loadServices(namespace?: Namespace)
|
|
||||||
{
|
|
||||||
getServices(namespace?.metadata?.name, (_services: Service[]) => {
|
|
||||||
services.value = _services;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.service-container {
|
|
||||||
grid-template-columns: auto auto 1fr auto;
|
|
||||||
}
|
|
||||||
.action-buttons {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
<template>
|
|
||||||
<p>{{ namespace }}</p>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
const namespace = computed(() => {
|
|
||||||
const namespace = useRoute().params.namespace;
|
|
||||||
if (namespace)
|
|
||||||
{
|
|
||||||
return namespace;
|
|
||||||
}
|
|
||||||
return "Alle";
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
<template>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
@ -42,7 +42,7 @@ function doLogin()
|
|||||||
const decode = jwtDecode(token) as any;
|
const decode = jwtDecode(token) as any;
|
||||||
getUser(decode.upn, token, (user: User) => {
|
getUser(decode.upn, token, (user: User) => {
|
||||||
setSessionCookie(new Session(user, token), decode.exp as number);
|
setSessionCookie(new Session(user, token), decode.exp as number);
|
||||||
useRouter().push('/account/inspect');
|
useRouter().push('/account/inspect/nodes/_all');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,9 @@ export const useNamespaceStore = defineStore('namespace', {
|
|||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getNamespaces: (state) => {
|
getNamespaces: (state) => {
|
||||||
return (): Namespace[] | undefined => state.namespaces;
|
return (): Namespace[] | undefined => {
|
||||||
|
return state.namespaces;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getCurrentNamespace: (state) => {
|
getCurrentNamespace: (state) => {
|
||||||
return (): Namespace | undefined => state.currentNamespace;
|
return (): Namespace | undefined => state.currentNamespace;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user