Enforce semicolons in eslint

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
This commit is contained in:
Panu Horsmalahti committed 2020-11-19 16:35:04 +02:00
1 parent 0f3f5611ba
commit 1477bb8274
531 files changed
+3979 -3975

No files matched your search

+2 -2
View File
@@ -24,7 +24,7 @@ export class ApiManager {
}
protected resolveApi(api: string | KubeApi): KubeApi {
if (typeof api === "string") return this.getApi(api)
if (typeof api === "string") return this.getApi(api);
return api;
}
@@ -41,7 +41,7 @@ export class ApiManager {
registerStore(store: KubeObjectStore, apis: KubeApi[] = [store.api]) {
apis.forEach(api => {
this.stores.set(api, store);
})
});
}
getStore(api: string | KubeApi): KubeObjectStore {
+1 -1
View File
@@ -8,7 +8,7 @@ export class ClusterApi extends KubeApi<Cluster> {
async getMetrics(nodeNames: string[], params?: IMetricsReqParams): Promise<IClusterMetrics> {
const nodes = nodeNames.join("|");
const opts = { category: "cluster", nodes: nodes }
const opts = { category: "cluster", nodes: nodes };
return metricsApi.getMetrics({
memoryUsage: opts,
+6 -6
View File
@@ -70,25 +70,25 @@ export class CustomResourceDefinition extends KubeObject {
group: this.getGroup(),
name: this.getPluralName(),
}
})
});
}
getResourceApiBase() {
const { group } = this.spec;
return `/apis/${group}/${this.getVersion()}/${this.getPluralName()}`
return `/apis/${group}/${this.getVersion()}/${this.getPluralName()}`;
}
getPluralName() {
return this.getNames().plural
return this.getNames().plural;
}
getResourceKind() {
return this.spec.names.kind
return this.spec.names.kind;
}
getResourceTitle() {
const name = this.getPluralName();
return name[0].toUpperCase() + name.substr(1)
return name[0].toUpperCase() + name.substr(1);
}
getGroup() {
@@ -141,7 +141,7 @@ export class CustomResourceDefinition extends KubeObject {
...condition,
isReady: status === "True",
tooltip: `${message || reason} (${lastTransitionTime})`
}
};
});
}
}
+5 -5
View File
@@ -65,17 +65,17 @@ export class CronJob extends KubeObject {
}
getSuspendFlag() {
return this.spec.suspend.toString()
return this.spec.suspend.toString();
}
getLastScheduleTime() {
if (!this.status.lastScheduleTime) return "-"
const diff = moment().diff(this.status.lastScheduleTime)
return formatDuration(diff, true)
if (!this.status.lastScheduleTime) return "-";
const diff = moment().diff(this.status.lastScheduleTime);
return formatDuration(diff, true);
}
getSchedule() {
return this.spec.schedule
return this.spec.schedule;
}
isNeverRun() {
+3 -3
View File
@@ -64,9 +64,9 @@ export class DaemonSet extends WorkloadKubeObject {
}
getImages() {
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", [])
const initContainers: IPodContainer[] = get(this, "spec.template.spec.initContainers", [])
return [...containers, ...initContainers].map(container => container.image)
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", []);
const initContainers: IPodContainer[] = get(this, "spec.template.spec.initContainers", []);
return [...containers, ...initContainers].map(container => container.image);
}
}
+9 -9
View File
@@ -6,13 +6,13 @@ import { KubeApi } from "../kube-api";
export class DeploymentApi extends KubeApi<Deployment> {
protected getScaleApiUrl(params: { namespace: string; name: string }) {
return this.getUrl(params) + "/scale"
return this.getUrl(params) + "/scale";
}
getReplicas(params: { namespace: string; name: string }): Promise<number> {
return this.request
.get(this.getScaleApiUrl(params))
.then(({ status }: any) => status?.replicas)
.then(({ status }: any) => status?.replicas);
}
scale(params: { namespace: string; name: string }, replicas: number) {
@@ -23,7 +23,7 @@ export class DeploymentApi extends KubeApi<Deployment> {
replicas: replicas
}
}
})
});
}
restart(params: { namespace: string; name: string }) {
@@ -42,7 +42,7 @@ export class DeploymentApi extends KubeApi<Deployment> {
headers: {
'content-type': 'application/strategic-merge-patch+json'
}
})
});
}
}
@@ -170,16 +170,16 @@ export class Deployment extends WorkloadKubeObject {
}
getConditions(activeOnly = false) {
const { conditions } = this.status
if (!conditions) return []
const { conditions } = this.status;
if (!conditions) return [];
if (activeOnly) {
return conditions.filter(c => c.status === "True")
return conditions.filter(c => c.status === "True");
}
return conditions
return conditions;
}
getConditionsText(activeOnly = true) {
return this.getConditions(activeOnly).map(({ type }) => type).join(" ")
return this.getConditions(activeOnly).map(({ type }) => type).join(" ");
}
getReplicas() {
+13 -13
View File
@@ -42,22 +42,22 @@ export class EndpointAddress implements IEndpointAddress {
};
constructor(data: IEndpointAddress) {
Object.assign(this, data)
Object.assign(this, data);
}
getId() {
return this.ip
return this.ip;
}
getName() {
return this.hostname
return this.hostname;
}
getTargetRef(): ITargetRef {
if (this.targetRef) {
return Object.assign(this.targetRef, {apiVersion: "v1"})
return Object.assign(this.targetRef, {apiVersion: "v1"});
} else {
return null
return null;
}
}
}
@@ -68,7 +68,7 @@ export class EndpointSubset implements IEndpointSubset {
ports: IEndpointPort[];
constructor(data: IEndpointSubset) {
Object.assign(this, data)
Object.assign(this, data);
}
getAddresses(): EndpointAddress[] {
@@ -83,16 +83,16 @@ export class EndpointSubset implements IEndpointSubset {
toString(): string {
if(!this.addresses) {
return ""
return "";
}
return this.addresses.map(address => {
if (!this.ports) {
return address.ip
return address.ip;
}
return this.ports.map(port => {
return `${address.ip}:${port.port}`
}).join(", ")
}).join(", ")
return `${address.ip}:${port.port}`;
}).join(", ");
}).join(", ");
}
}
@@ -111,9 +111,9 @@ export class Endpoint extends KubeObject {
toString(): string {
if(this.subsets) {
return this.getEndpointSubsets().map(es => es.toString()).join(", ")
return this.getEndpointSubsets().map(es => es.toString()).join(", ");
} else {
return "<none>"
return "<none>";
}
}
+7 -7
View File
@@ -38,21 +38,21 @@ export class KubeEvent extends KubeObject {
}
getSource() {
const { component, host } = this.source
return `${component} ${host || ""}`
const { component, host } = this.source;
return `${component} ${host || ""}`;
}
getFirstSeenTime() {
const diff = moment().diff(this.firstTimestamp)
return formatDuration(diff, true)
const diff = moment().diff(this.firstTimestamp);
return formatDuration(diff, true);
}
getLastSeenTime() {
const diff = moment().diff(this.lastTimestamp)
return formatDuration(diff, true)
const diff = moment().diff(this.lastTimestamp);
return formatDuration(diff, true);
}
}
export const eventApi = new KubeApi({
objectConstructor: KubeEvent,
})
});
@@ -41,7 +41,7 @@ export const helmChartsApi = {
return {
readme,
versions,
}
};
});
},
@@ -82,7 +82,7 @@ export const helmReleasesApi = {
return {
...details,
resources
}
};
});
},
@@ -156,12 +156,12 @@ export class HelmRelease implements ItemObject {
}
getChart(withVersion = false) {
let chart = this.chart
let chart = this.chart;
if(!withVersion && this.getVersion() != "" ) {
const search = new RegExp(`-${this.getVersion()}`)
const search = new RegExp(`-${this.getVersion()}`);
chart = chart.replace(search, "");
}
return chart
return chart;
}
getRevision() {
@@ -173,12 +173,12 @@ export class HelmRelease implements ItemObject {
}
getVersion() {
const versions = this.chart.match(/(v?\d+)[^-].*$/)
const versions = this.chart.match(/(v?\d+)[^-].*$/);
if (versions) {
return versions[0]
return versions[0];
}
else {
return ""
return "";
}
}
+3 -3
View File
@@ -86,7 +86,7 @@ export class HorizontalPodAutoscaler extends KubeObject {
...condition,
isReady: status === "True",
tooltip: `${message || reason} (${lastTransitionTime})`
}
};
});
}
@@ -102,7 +102,7 @@ export class HorizontalPodAutoscaler extends KubeObject {
const { type, resource, pods, object, external } = metric;
switch (type) {
case HpaMetricType.Resource:
return resource.name
return resource.name;
case HpaMetricType.Pods:
return pods.metricName;
case HpaMetricType.Object:
@@ -128,7 +128,7 @@ export class HorizontalPodAutoscaler extends KubeObject {
}
if (target) {
targetValue = target.targetAverageUtilization || target.targetAverageValue || target.targetValue;
if (target.targetAverageUtilization) targetValue += "%"
if (target.targetAverageUtilization) targetValue += "%";
}
return `${currentValue} / ${targetValue}`;
}
+32 -32
View File
@@ -1,35 +1,35 @@
// Kubernetes apis
// Docs: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/
export * from "./cluster.api"
export * from "./cluster-role.api"
export * from "./cluster-role-binding.api"
export * from "./configmap.api"
export * from "./crd.api"
export * from "./cron-job.api"
export * from "./daemon-set.api"
export * from "./deployment.api"
export * from "./endpoint.api"
export * from "./events.api"
export * from "./hpa.api"
export * from "./ingress.api"
export * from "./job.api"
export * from "./namespaces.api"
export * from "./network-policy.api"
export * from "./nodes.api"
export * from "./persistent-volume.api"
export * from "./persistent-volume-claims.api"
export * from "./pods.api"
export * from "./poddisruptionbudget.api"
export * from "./pod-metrics.api"
export * from "./podsecuritypolicy.api"
export * from "./replica-set.api"
export * from "./resource-quota.api"
export * from "./role.api"
export * from "./role-binding.api"
export * from "./secret.api"
export * from "./selfsubjectrulesreviews.api"
export * from "./service.api"
export * from "./service-accounts.api"
export * from "./stateful-set.api"
export * from "./storage-class.api"
export * from "./cluster.api";
export * from "./cluster-role.api";
export * from "./cluster-role-binding.api";
export * from "./configmap.api";
export * from "./crd.api";
export * from "./cron-job.api";
export * from "./daemon-set.api";
export * from "./deployment.api";
export * from "./endpoint.api";
export * from "./events.api";
export * from "./hpa.api";
export * from "./ingress.api";
export * from "./job.api";
export * from "./namespaces.api";
export * from "./network-policy.api";
export * from "./nodes.api";
export * from "./persistent-volume.api";
export * from "./persistent-volume-claims.api";
export * from "./pods.api";
export * from "./poddisruptionbudget.api";
export * from "./pod-metrics.api";
export * from "./podsecuritypolicy.api";
export * from "./replica-set.api";
export * from "./resource-quota.api";
export * from "./role.api";
export * from "./role-binding.api";
export * from "./secret.api";
export * from "./selfsubjectrulesreviews.api";
export * from "./service.api";
export * from "./service-accounts.api";
export * from "./stateful-set.api";
export * from "./storage-class.api";
+22 -22
View File
@@ -5,7 +5,7 @@ import { KubeApi } from "../kube-api";
export class IngressApi extends KubeApi<Ingress> {
getMetrics(ingress: string, namespace: string): Promise<IIngressMetrics> {
const opts = { category: "ingress", ingress }
const opts = { category: "ingress", ingress };
return metricsApi.getMetrics({
bytesSentSuccess: opts,
bytesSentFailure: opts,
@@ -63,51 +63,51 @@ export class Ingress extends KubeObject {
}
getRoutes() {
const { spec: { tls, rules } } = this
if (!rules) return []
const { spec: { tls, rules } } = this;
if (!rules) return [];
let protocol = "http"
const routes: string[] = []
let protocol = "http";
const routes: string[] = [];
if (tls && tls.length > 0) {
protocol += "s"
protocol += "s";
}
rules.map(rule => {
const host = rule.host ? rule.host : "*"
const host = rule.host ? rule.host : "*";
if (rule.http && rule.http.paths) {
rule.http.paths.forEach(path => {
routes.push(protocol + "://" + host + (path.path || "/") + " ⇢ " + path.backend.serviceName + ":" + path.backend.servicePort)
})
routes.push(protocol + "://" + host + (path.path || "/") + " ⇢ " + path.backend.serviceName + ":" + path.backend.servicePort);
});
}
})
});
return routes;
}
getHosts() {
const { spec: { rules } } = this
if (!rules) return []
return rules.filter(rule => rule.host).map(rule => rule.host)
const { spec: { rules } } = this;
if (!rules) return [];
return rules.filter(rule => rule.host).map(rule => rule.host);
}
getPorts() {
const ports: number[] = []
const { spec: { tls, rules, backend } } = this
const httpPort = 80
const tlsPort = 443
const ports: number[] = [];
const { spec: { tls, rules, backend } } = this;
const httpPort = 80;
const tlsPort = 443;
if (rules && rules.length > 0) {
if (rules.some(rule => rule.hasOwnProperty("http"))) {
ports.push(httpPort)
ports.push(httpPort);
}
}
else {
if (backend && backend.servicePort) {
ports.push(backend.servicePort)
ports.push(backend.servicePort);
}
}
if (tls && tls.length > 0) {
ports.push(tlsPort)
ports.push(tlsPort);
}
return ports.join(", ")
return ports.join(", ");
}
getLoadBalancers() {
@@ -115,7 +115,7 @@ export class Ingress extends KubeObject {
return (loadBalancer.ingress ?? []).map(address => (
address.hostname || address.ip
))
));
}
}
+4 -4
View File
@@ -91,15 +91,15 @@ export class Job extends WorkloadKubeObject {
}
getImages() {
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", [])
return [...containers].map(container => container.image)
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", []);
return [...containers].map(container => container.image);
}
delete() {
const params: JsonApiParams = {
query: { propagationPolicy: "Background" }
}
return super.delete(params)
};
return super.delete(params);
}
}
+3 -3
View File
@@ -66,7 +66,7 @@ export function normalizeMetrics(metrics: IMetrics, frames = 60): IMetrics {
} as IMetricsResult],
},
status: "",
}
};
}
const { result } = metrics.data;
@@ -78,7 +78,7 @@ export function normalizeMetrics(metrics: IMetrics, frames = 60): IMetrics {
if (!res.values || !res.values.length) return;
while (res.values.length < frames) {
const timestamp = moment.unix(res.values[0][0]).subtract(1, "minute").unix();
res.values.unshift([timestamp, "0"])
res.values.unshift([timestamp, "0"]);
}
});
}
@@ -103,7 +103,7 @@ export function getItemMetrics(metrics: { [key: string]: IMetrics }, itemName: s
const itemMetrics = { ...metrics };
for (const metric in metrics) {
if (!metrics[metric]?.data?.result) {
continue
continue;
}
const results = metrics[metric].data.result;
const result = results.find(res => Object.values(res.metric)[0] == itemName);
@@ -57,7 +57,7 @@ export class NetworkPolicy extends KubeObject {
if (!this.spec.podSelector || !this.spec.podSelector.matchLabels) return [];
return Object
.entries(this.spec.podSelector.matchLabels)
.map(data => data.join(":"))
.map(data => data.join(":"));
}
getTypes(): string[] {
+17 -17
View File
@@ -5,7 +5,7 @@ import { KubeApi } from "../kube-api";
export class NodesApi extends KubeApi<Node> {
getMetrics(): Promise<INodeMetrics> {
const opts = { category: "nodes"}
const opts = { category: "nodes"};
return metricsApi.getMetrics({
memoryUsage: opts,
@@ -86,12 +86,12 @@ export class Node extends KubeObject {
}
getNodeConditionText() {
const { conditions } = this.status
if (!conditions) return ""
const { conditions } = this.status;
if (!conditions) return "";
return conditions.reduce((types, current) => {
if (current.status !== "True") return ""
return types += ` ${current.type}`
}, "")
if (current.status !== "True") return "";
return types += ` ${current.type}`;
}, "");
}
getTaints() {
@@ -101,23 +101,23 @@ export class Node extends KubeObject {
getRoleLabels() {
const roleLabels = Object.keys(this.metadata.labels).filter(key =>
key.includes("node-role.kubernetes.io")
).map(key => key.match(/([^/]+$)/)[0]) // all after last slash
).map(key => key.match(/([^/]+$)/)[0]); // all after last slash
if (this.metadata.labels["kubernetes.io/role"] != undefined) {
roleLabels.push(this.metadata.labels["kubernetes.io/role"])
roleLabels.push(this.metadata.labels["kubernetes.io/role"]);
}
return roleLabels.join(", ")
return roleLabels.join(", ");
}
getCpuCapacity() {
if (!this.status.capacity || !this.status.capacity.cpu) return 0
return cpuUnitsToNumber(this.status.capacity.cpu)
if (!this.status.capacity || !this.status.capacity.cpu) return 0;
return cpuUnitsToNumber(this.status.capacity.cpu);
}
getMemoryCapacity() {
if (!this.status.capacity || !this.status.capacity.memory) return 0
return unitsToBytes(this.status.capacity.memory)
if (!this.status.capacity || !this.status.capacity.memory) return 0;
return unitsToBytes(this.status.capacity.memory);
}
getConditions() {
@@ -144,16 +144,16 @@ export class Node extends KubeObject {
}
getOperatingSystem(): string {
const label = this.getLabels().find(label => label.startsWith("kubernetes.io/os="))
const label = this.getLabels().find(label => label.startsWith("kubernetes.io/os="));
if (label) {
return label.split("=", 2)[1]
return label.split("=", 2)[1];
}
return "linux"
return "linux";
}
isUnschedulable() {
return this.spec.unschedulable
return this.spec.unschedulable;
}
}
@@ -51,13 +51,13 @@ export class PersistentVolumeClaim extends KubeObject {
}
getPods(allPods: Pod[]): Pod[] {
const pods = allPods.filter(pod => pod.getNs() === this.getNs())
const pods = allPods.filter(pod => pod.getNs() === this.getNs());
return pods.filter(pod => {
return pod.getVolumes().filter(volume =>
volume.persistentVolumeClaim &&
volume.persistentVolumeClaim.claimName === this.getName()
).length > 0
})
).length > 0;
});
}
getStorage(): string {
@@ -78,7 +78,7 @@ export class PersistentVolumeClaim extends KubeObject {
getStatus(): string {
if (this.status) return this.status.phase;
return "-"
return "-";
}
}
@@ -48,7 +48,7 @@ export class PersistentVolume extends KubeObject {
getCapacity(inBytes = false) {
const capacity = this.spec.capacity;
if (capacity) {
if (inBytes) return unitsToBytes(capacity.storage)
if (inBytes) return unitsToBytes(capacity.storage);
return capacity.storage;
}
return 0;
+19 -19
View File
@@ -11,7 +11,7 @@ export class PodsApi extends KubeApi<Pod> {
getMetrics(pods: Pod[], namespace: string, selector = "pod, namespace"): Promise<IPodMetrics> {
const podSelector = pods.map(pod => pod.getName()).join("|");
const opts = { category: "pods", pods: podSelector, namespace, selector }
const opts = { category: "pods", pods: podSelector, namespace, selector };
return metricsApi.getMetrics({
cpuUsage: opts,
@@ -246,11 +246,11 @@ export class Pod extends WorkloadKubeObject {
}
getRunningContainers() {
const statuses = this.getContainerStatuses()
const statuses = this.getContainerStatuses();
return this.getAllContainers().filter(container => {
return statuses.find(status => status.name === container.name && !!status.state["running"])
return statuses.find(status => status.name === container.name && !!status.state["running"]);
}
)
);
}
getContainerStatuses(includeInitContainers = true) {
@@ -323,7 +323,7 @@ export class Pod extends WorkloadKubeObject {
const { reason } = state.terminated;
message = reason ? reason : "Terminated";
}
})
});
}
if (message) return message;
return this.getStatusPhase();
@@ -348,32 +348,32 @@ export class Pod extends WorkloadKubeObject {
}
getNodeSelectors(): string[] {
const { nodeSelector } = this.spec
if (!nodeSelector) return []
return Object.entries(nodeSelector).map(values => values.join(": "))
const { nodeSelector } = this.spec;
if (!nodeSelector) return [];
return Object.entries(nodeSelector).map(values => values.join(": "));
}
getTolerations() {
return this.spec.tolerations || []
return this.spec.tolerations || [];
}
getAffinity(): IAffinity {
return this.spec.affinity
return this.spec.affinity;
}
hasIssues() {
const notReady = !!this.getConditions().find(condition => {
return condition.type == "Ready" && condition.status !== "True"
return condition.type == "Ready" && condition.status !== "True";
});
const crashLoop = !!this.getContainerStatuses().find(condition => {
const waiting = condition.state.waiting
return (waiting && waiting.reason == "CrashLoopBackOff")
})
const waiting = condition.state.waiting;
return (waiting && waiting.reason == "CrashLoopBackOff");
});
return (
notReady ||
crashLoop ||
this.getStatusPhase() !== "Running"
)
);
}
getLivenessProbe(container: IPodContainer) {
@@ -418,14 +418,14 @@ export class Pod extends WorkloadKubeObject {
}
getNodeName() {
return this.spec?.nodeName
return this.spec?.nodeName;
}
getSelectedNodeOs() {
if (!this.spec.nodeSelector) return
if (!this.spec.nodeSelector["kubernetes.io/os"] && !this.spec.nodeSelector["beta.kubernetes.io/os"]) return
if (!this.spec.nodeSelector) return;
if (!this.spec.nodeSelector["kubernetes.io/os"] && !this.spec.nodeSelector["beta.kubernetes.io/os"]) return;
return this.spec.nodeSelector["kubernetes.io/os"] || this.spec.nodeSelector["beta.kubernetes.io/os"]
return this.spec.nodeSelector["kubernetes.io/os"] || this.spec.nodeSelector["beta.kubernetes.io/os"];
}
}
@@ -47,8 +47,8 @@ export class ReplicaSet extends WorkloadKubeObject {
}
getImages() {
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", [])
return [...containers].map(container => container.image)
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", []);
return [...containers].map(container => container.image);
}
}
@@ -1,4 +1,4 @@
import jsYaml from "js-yaml"
import jsYaml from "js-yaml";
import { KubeObject } from "../kube-object";
import { KubeJsonApiData } from "../kube-json-api";
import { apiBase } from "../index";
@@ -21,7 +21,7 @@ export const resourceApplierApi = {
if (api) {
return new api.objectConstructor(obj);
} else {
return new KubeObject(obj)
return new KubeObject(obj);
}
});
return items.length === 1 ? items[0] : items;
@@ -37,7 +37,7 @@ export class ResourceQuota extends KubeObject {
constructor(data: KubeJsonApiData) {
super(data);
this.spec = this.spec || {} as any
this.spec = this.spec || {} as any;
}
spec: {
@@ -27,7 +27,7 @@ export class RoleBinding extends KubeObject {
}
getSubjectNames(): string {
return this.getSubjects().map(subject => subject.name).join(", ")
return this.getSubjects().map(subject => subject.name).join(", ");
}
}
@@ -58,7 +58,7 @@ export class SelfSubjectRulesReview extends KubeObject {
const separator = apiGroup == "" ? "" : ".";
return resource + separator + apiGroup;
})
}
};
}
}
+2 -2
View File
@@ -17,7 +17,7 @@ export class ServicePort implements IServicePort {
nodePort?: number;
constructor(data: IServicePort) {
Object.assign(this, data)
Object.assign(this, data);
}
toString() {
@@ -62,7 +62,7 @@ export class Service extends KubeObject {
getExternalIps() {
const lb = this.getLoadBalancer();
if (lb && lb.ingress) {
return lb.ingress.map(val => val.ip || val.hostname)
return lb.ingress.map(val => val.ip || val.hostname);
}
return this.spec.externalIPs || [];
}
@@ -73,8 +73,8 @@ export class StatefulSet extends WorkloadKubeObject {
}
getImages() {
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", [])
return [...containers].map(container => container.image)
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", []);
return [...containers].map(container => container.image);
}
}
@@ -21,15 +21,15 @@ export class StorageClass extends KubeObject {
return (
annotations["storageclass.kubernetes.io/is-default-class"] === "true" ||
annotations["storageclass.beta.kubernetes.io/is-default-class"] === "true"
)
);
}
getVolumeBindingMode() {
return this.volumeBindingMode || "-"
return this.volumeBindingMode || "-";
}
getReclaimPolicy() {
return this.reclaimPolicy || "-"
return this.reclaimPolicy || "-";
}
}
+6 -6
View File
@@ -110,23 +110,23 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
} else {
const error = new JsonApiErrorParsed(data, this.parseError(data, res));
this.onError.emit(error, res);
this.writeLog({ ...log, error })
this.writeLog({ ...log, error });
throw error;
}
})
});
}
protected parseError(error: JsonApiError | string, res: Response): string[] {
if (typeof error === "string") {
return [error]
return [error];
}
else if (Array.isArray(error.errors)) {
return error.errors.map(error => error.title)
return error.errors.map(error => error.title);
}
else if (error.message) {
return [error.message]
return [error.message];
}
return [res.statusText || "Error!"]
return [res.statusText || "Error!"];
}
protected writeLog(log: JsonApiLog) {
+10 -10
View File
@@ -51,7 +51,7 @@ export function parseKubeApi(path: string): IKubeApiParsed {
} else {
switch (left.length) {
case 4:
[apiGroup, apiVersion, resource, name] = left
[apiGroup, apiVersion, resource, name] = left;
break;
case 2:
resource = left.pop();
@@ -79,11 +79,11 @@ export function parseKubeApi(path: string): IKubeApiParsed {
*/
if (left[0].includes('.') || left[1].match(/^v[0-9]/)) {
[apiGroup, apiVersion] = left;
resource = left.slice(2).join("/")
resource = left.slice(2).join("/");
} else {
apiGroup = "";
apiVersion = left[0];
[resource, name] = left.slice(1)
[resource, name] = left.slice(1);
}
break;
}
@@ -93,7 +93,7 @@ export function parseKubeApi(path: string): IKubeApiParsed {
const apiBase = [apiPrefix, apiGroup, apiVersion, resource].filter(v => v).join("/");
if (!apiBase) {
throw new Error(`invalid apiPath: ${path}`)
throw new Error(`invalid apiPath: ${path}`);
}
return {
@@ -108,11 +108,11 @@ export function createKubeApiURL(ref: IKubeApiLinkRef): string {
const { apiPrefix = "/apis", resource, apiVersion, name } = ref;
let { namespace } = ref;
if (namespace) {
namespace = `namespaces/${namespace}`
namespace = `namespaces/${namespace}`;
}
return [apiPrefix, apiVersion, namespace, resource, name]
.filter(v => v)
.join("/")
.join("/");
}
export function lookupApiLink(ref: IKubeObjectRef, parentObject: KubeObject): string {
@@ -124,9 +124,9 @@ export function lookupApiLink(ref: IKubeObjectRef, parentObject: KubeObject): st
if (!kind) return "";
// search in registered apis by 'kind' & 'apiVersion'
const api = apiManager.getApi(api => api.kind === kind && api.apiVersionWithGroup == apiVersion)
const api = apiManager.getApi(api => api.kind === kind && api.apiVersionWithGroup == apiVersion);
if (api) {
return api.getUrl({ namespace, name })
return api.getUrl({ namespace, name });
}
// lookup api by generated resource link
@@ -142,10 +142,10 @@ export function lookupApiLink(ref: IKubeObjectRef, parentObject: KubeObject): st
// resolve by kind only (hpa's might use refs to older versions of resources for example)
const apiByKind = apiManager.getApi(api => api.kind === kind);
if (apiByKind) {
return apiByKind.getUrl({ name, namespace })
return apiByKind.getUrl({ name, namespace });
}
// otherwise generate link with default prefix
// resource still might exists in k8s, but api is not registered in the app
return createKubeApiURL({ apiVersion, name, namespace, resource })
return createKubeApiURL({ apiVersion, name, namespace, resource });
}
+12 -12
View File
@@ -1,6 +1,6 @@
// Base class for building all kubernetes apis
import merge from "lodash/merge"
import merge from "lodash/merge";
import { stringify } from "querystring";
import { IKubeObjectConstructor, KubeObject } from "./kube-object";
import { KubeJsonApi, KubeJsonApiData, KubeJsonApiDataList } from "./kube-json-api";
@@ -51,7 +51,7 @@ export function forCluster<T extends KubeObject>(cluster: IKubeApiCluster, kubeC
return new KubeApi({
objectConstructor: kubeClass,
request: request
})
});
}
export class KubeApi<T extends KubeObject = any> {
@@ -83,7 +83,7 @@ export class KubeApi<T extends KubeObject = any> {
isNamespaced = options.objectConstructor?.namespaced
} = options || {};
if (!options.apiBase) {
options.apiBase = objectConstructor.apiBase
options.apiBase = objectConstructor.apiBase;
}
const { apiBase, apiPrefix, apiGroup, apiVersion, apiVersionWithGroup, resource } = KubeApi.parseApi(options.apiBase);
@@ -105,7 +105,7 @@ export class KubeApi<T extends KubeObject = any> {
get apiVersionWithGroup() {
return [this.apiGroup, this.apiVersionPreferred ?? this.apiVersion]
.filter(Boolean)
.join("/")
.join("/");
}
protected async checkPreferredVersion() {
@@ -116,7 +116,7 @@ export class KubeApi<T extends KubeObject = any> {
});
if (this.apiVersionPreferred) {
Object.defineProperty(this, "apiBase", { value: this.getUrl() })
Object.defineProperty(this, "apiBase", { value: this.getUrl() });
apiManager.registerApi(this.apiBase, this);
}
}
@@ -147,10 +147,10 @@ export class KubeApi<T extends KubeObject = any> {
protected normalizeQuery(query: Partial<IKubeApiQueryParams> = {}) {
if (query.labelSelector) {
query.labelSelector = [query.labelSelector].flat().join(",")
query.labelSelector = [query.labelSelector].flat().join(",");
}
if (query.fieldSelector) {
query.fieldSelector = [query.fieldSelector].flat().join(",")
query.fieldSelector = [query.fieldSelector].flat().join(",");
}
return query;
}
@@ -170,7 +170,7 @@ export class KubeApi<T extends KubeObject = any> {
kind: this.kind,
apiVersion: apiVersion,
...item,
}))
}));
}
// custom apis might return array for list response, e.g. users, groups, etc.
@@ -218,13 +218,13 @@ export class KubeApi<T extends KubeObject = any> {
const apiUrl = this.getUrl({ namespace, name });
return this.request
.put(apiUrl, { data })
.then(this.parseResponse)
.then(this.parseResponse);
}
async delete({ name = "", namespace = "default" }) {
await this.checkPreferredVersion();
const apiUrl = this.getUrl({ namespace, name });
return this.request.del(apiUrl)
return this.request.del(apiUrl);
}
getWatchUrl(namespace = "", query: IKubeApiQueryParams = {}) {
@@ -232,7 +232,7 @@ export class KubeApi<T extends KubeObject = any> {
watch: 1,
resourceVersion: this.getResourceVersion(namespace),
...query,
})
});
}
watch(): () => void {
@@ -240,4 +240,4 @@ export class KubeApi<T extends KubeObject = any> {
}
}
export * from "./kube-api-parse"
export * from "./kube-api-parse";
@@ -1 +1 @@
export { kubeObjectDetailRegistry } from "../../extensions/registries/kube-object-detail-registry"
export { kubeObjectDetailRegistry } from "../../extensions/registries/kube-object-detail-registry";
+5 -5
View File
@@ -65,7 +65,7 @@ export class KubeObject implements ItemObject {
static stringifyLabels(labels: { [name: string]: string }): string[] {
if (!labels) return [];
return Object.entries(labels).map(([name, value]) => `${name}=${value}`)
return Object.entries(labels).map(([name, value]) => `${name}=${value}`);
}
constructor(data: KubeJsonApiData) {
@@ -78,7 +78,7 @@ export class KubeObject implements ItemObject {
status?: any; // todo: type-safety support
get selfLink() {
return this.metadata.selfLink
return this.metadata.selfLink;
}
getId() {
@@ -131,18 +131,18 @@ export class KubeObject implements ItemObject {
return refs.map(ownerRef => ({
...ownerRef,
namespace: this.getNs(),
}))
}));
}
getSearchFields() {
const { getName, getId, getNs, getAnnotations, getLabels } = this
const { getName, getId, getNs, getAnnotations, getLabels } = this;
return [
getName(),
getNs(),
getId(),
...getLabels(),
...getAnnotations(true),
]
];
}
toPlainObject(): object {
+7 -7
View File
@@ -1,7 +1,7 @@
// Kubernetes watch-api consumer
import { computed, observable, reaction } from "mobx";
import { stringify } from "querystring"
import { stringify } from "querystring";
import { autobind, EventEmitter } from "../utils";
import { KubeJsonApiData } from "./kube-json-api";
import type { KubeObjectStore } from "../kube-object.store";
@@ -61,13 +61,13 @@ export class KubeWatchApi {
}
protected getQuery(): Partial<IKubeWatchRouteQuery> {
const { isAdmin, allowedNamespaces } = getHostedCluster()
const { isAdmin, allowedNamespaces } = getHostedCluster();
return {
api: this.activeApis.map(api => {
if (isAdmin) return api.getWatchUrl();
return allowedNamespaces.map(namespace => api.getWatchUrl(namespace))
return allowedNamespaces.map(namespace => api.getWatchUrl(namespace));
}).flat()
}
};
}
// todo: maybe switch to websocket to avoid often reconnects
@@ -119,11 +119,11 @@ export class KubeWatchApi {
await api.refreshResourceVersion({ namespace });
this.reconnect();
} catch (error) {
console.error("failed to refresh resource version", error)
console.error("failed to refresh resource version", error);
if (this.subscribers.size > 0) {
setTimeout(() => {
this.onRouteEvent(event)
}, 1000)
this.onRouteEvent(event);
}, 1000);
}
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
import { stringify } from "querystring";
import { autobind, base64, EventEmitter } from "../utils";
import { WebSocketApi } from "./websocket-api";
import isEqual from "lodash/isEqual"
import isEqual from "lodash/isEqual";
import { isDevelopment } from "../../common/vars";
export enum TerminalChannels {
@@ -51,7 +51,7 @@ export class TerminalApi extends WebSocketApi {
const wss = `ws${protocol === "https:" ? "s" : ""}://`;
const query: TerminalApiQuery = { id };
if (port) {
port = `:${port}`
port = `:${port}`;
}
if (node) {
query.node = node;
+1 -1
View File
@@ -146,7 +146,7 @@ export class WebSocketApi {
}
protected _onError(evt: Event) {
this.writeLog('%cERROR', 'color:red;font-weight:bold;', evt)
this.writeLog('%cERROR', 'color:red;font-weight:bold;', evt);
}
protected _onClose(evt: CloseEvent) {
+5 -5
View File
@@ -65,16 +65,16 @@ export class WorkloadKubeObject extends KubeObject {
}
getTolerations(): IToleration[] {
return get(this, "spec.template.spec.tolerations", [])
return get(this, "spec.template.spec.tolerations", []);
}
getAffinity(): IAffinity {
return get(this, "spec.template.spec.affinity")
return get(this, "spec.template.spec.affinity");
}
getAffinityNumber() {
const affinity = this.getAffinity()
if (!affinity) return 0
return Object.keys(affinity).length
const affinity = this.getAffinity();
if (!affinity) return 0;
return Object.keys(affinity).length;
}
}
+13 -13
View File
@@ -1,9 +1,9 @@
import "./components/app.scss"
import "./components/app.scss";
import React from "react";
import * as Mobx from "mobx"
import * as MobxReact from "mobx-react"
import * as LensExtensions from "../extensions/extension-api"
import * as Mobx from "mobx";
import * as MobxReact from "mobx-react";
import * as LensExtensions from "../extensions/extension-api";
import { App } from "./components/app";
import { LensApp } from "./lens-app";
import { render, unmountComponentAtNode } from "react-dom";
@@ -25,13 +25,13 @@ export {
Mobx,
MobxReact,
LensExtensions
}
};
export async function bootstrap(App: AppComponent) {
const rootElem = document.getElementById("app")
const rootElem = document.getElementById("app");
rootElem.classList.toggle("is-mac", isMac);
extensionLoader.init()
extensionLoader.init();
// preload common stores
await Promise.all([
@@ -53,13 +53,13 @@ export async function bootstrap(App: AppComponent) {
}
window.addEventListener("message", (ev: MessageEvent) => {
if (ev.data === "teardown") {
userStore.unregisterIpcListener()
workspaceStore.unregisterIpcListener()
clusterStore.unregisterIpcListener()
unmountComponentAtNode(rootElem)
window.location.href = "about:blank"
userStore.unregisterIpcListener();
workspaceStore.unregisterIpcListener();
clusterStore.unregisterIpcListener();
unmountComponentAtNode(rootElem);
window.location.href = "about:blank";
}
})
});
render(<>
{isMac && <div id="draggable-top" />}
<App />
+1 -1
View File
@@ -1 +1 @@
export * from "./not-found"
export * from "./not-found";
@@ -3,6 +3,6 @@ import { buildURL } from "../../../common/utils/buildUrl";
export const addClusterRoute: RouteProps = {
path: "/add-cluster"
}
};
export const addClusterURL = buildURL(addClusterRoute.path)
export const addClusterURL = buildURL(addClusterRoute.path);
@@ -1,4 +1,4 @@
import "./add-cluster.scss"
import "./add-cluster.scss";
import os from "os";
import React, { Fragment } from "react";
import { observer } from "mobx-react";
@@ -16,7 +16,7 @@ import { WizardLayout } from "../layout/wizard-layout";
import { kubeConfigDefaultPath, loadConfig, splitConfig, validateConfig, validateKubeConfig } from "../../../common/kube-helpers";
import { ClusterModel, ClusterStore, clusterStore } from "../../../common/cluster-store";
import { workspaceStore } from "../../../common/workspace-store";
import { v4 as uuid } from "uuid"
import { v4 as uuid } from "uuid";
import { navigate } from "../../navigation";
import { userStore } from "../../../common/user-store";
import { clusterViewURL } from "../cluster-manager/cluster-view.route";
@@ -84,7 +84,7 @@ export class AddCluster extends React.Component {
break;
case KubeConfigSourceTab.TEXT:
try {
this.error = ""
this.error = "";
const contexts = this.getContexts(loadConfig(this.customConfig || "{}"));
this.kubeContexts.replace(contexts);
} catch (err) {
@@ -94,7 +94,7 @@ export class AddCluster extends React.Component {
}
if (this.kubeContexts.size === 1) {
this.selectedContexts.push(this.kubeContexts.keys().next().value)
this.selectedContexts.push(this.kubeContexts.keys().next().value);
}
}
@@ -102,8 +102,8 @@ export class AddCluster extends React.Component {
const contexts = new Map();
splitConfig(config).forEach(config => {
contexts.set(config.currentContext, config);
})
return contexts
});
return contexts;
}
selectKubeConfigDialog = async () => {
@@ -124,11 +124,11 @@ export class AddCluster extends React.Component {
let newClusters: ClusterModel[] = [];
try {
if (!this.selectedContexts.length) {
this.error = <Trans>Please select at least one cluster context</Trans>
this.error = <Trans>Please select at least one cluster context</Trans>;
return;
}
this.error = ""
this.isWaiting = true
this.error = "";
this.isWaiting = true;
newClusters = this.selectedContexts.filter(context => {
try {
@@ -136,7 +136,7 @@ export class AddCluster extends React.Component {
validateKubeConfig(kubeConfig);
return true;
} catch (err) {
this.error = String(err.message)
this.error = String(err.message);
if (err instanceof ExecValidationNotFoundError ) {
Notifications.error(<Trans>Error while adding cluster(s): {this.error}</Trans>);
return false;
@@ -159,8 +159,8 @@ export class AddCluster extends React.Component {
clusterName: kubeConfig.currentContext,
httpsProxy: this.proxyServer || undefined,
},
}
})
};
});
runInAction(() => {
clusterStore.addClusters(...newClusters);
@@ -175,7 +175,7 @@ export class AddCluster extends React.Component {
);
}
}
})
});
this.refreshContexts();
} catch (err) {
this.error = String(err);
@@ -218,7 +218,7 @@ export class AddCluster extends React.Component {
Lens app might not have all login shell env variables set automatically.
</p>
</Fragment>
)
);
}
renderKubeConfigSource() {
@@ -281,7 +281,7 @@ export class AddCluster extends React.Component {
</>
)}
</>
)
);
}
renderContextSelector() {
@@ -302,7 +302,7 @@ export class AddCluster extends React.Component {
noOptionsMessage={() => _i18n._(t`No contexts available or they have been added already`)}
onChange={({ value: ctx }: SelectOption<string>) => {
if (this.selectedContexts.includes(ctx)) {
this.selectedContexts.remove(ctx)
this.selectedContexts.remove(ctx);
} else {
this.selectedContexts.push(ctx);
}
@@ -315,7 +315,7 @@ export class AddCluster extends React.Component {
</small>
)}
</>
)
);
}
onKubeConfigInputBlur = (evt: React.FocusEvent<HTMLInputElement>) => {
@@ -345,11 +345,11 @@ export class AddCluster extends React.Component {
{isNew && <Icon small material="fiber_new" />}
{isSelected && <Icon small material="check" className="box right" />}
</div>
)
);
};
render() {
const addDisabled = this.selectedContexts.length === 0
const addDisabled = this.selectedContexts.length === 0;
return (
<WizardLayout
@@ -361,12 +361,12 @@ export class AddCluster extends React.Component {
onDragLeave: event => this.dropAreaActive = false,
onDragOver: event => {
event.preventDefault(); // enable onDrop()-callback
event.dataTransfer.dropEffect = "move"
event.dataTransfer.dropEffect = "move";
},
onDrop: event => {
this.sourceTab = KubeConfigSourceTab.FILE;
this.dropAreaActive = false
this.setKubeConfig(event.dataTransfer.files[0].path)
this.dropAreaActive = false;
this.setKubeConfig(event.dataTransfer.files[0].path);
}
}}
>
@@ -407,6 +407,6 @@ export class AddCluster extends React.Component {
/>
</div>
</WizardLayout>
)
);
}
}
@@ -1,2 +1,2 @@
export * from "./add-cluster"
export * from "./add-cluster.route"
export * from "./add-cluster";
export * from "./add-cluster.route";
@@ -35,16 +35,16 @@ export class HelmChartDetails extends Component<Props> {
}
chartUpdater = autorun(() => {
this.selectedChart = null
const { chart: { name, repo, version } } = this.props
this.selectedChart = null;
const { chart: { name, repo, version } } = this.props;
helmChartsApi.get(repo, name, version).then(result => {
this.readme = result.readme
this.chartVersions = result.versions
this.selectedChart = result.versions[0]
this.readme = result.readme;
this.chartVersions = result.versions;
this.selectedChart = result.versions[0];
},
error => {
this.error = error;
})
});
});
@autobind()
@@ -55,7 +55,7 @@ export class HelmChartDetails extends Component<Props> {
try {
this.chartPromise?.cancel();
const { chart: { name, repo } } = this.props;
const { readme } = await (this.chartPromise = helmChartsApi.get(repo, name, version))
const { readme } = await (this.chartPromise = helmChartsApi.get(repo, name, version));
this.readme = readme;
} catch (error) {
this.error = error;
@@ -65,7 +65,7 @@ export class HelmChartDetails extends Component<Props> {
@autobind()
install() {
createInstallChartTab(this.selectedChart);
this.props.hideDetails()
this.props.hideDetails();
}
renderIntroduction() {
@@ -112,14 +112,14 @@ export class HelmChartDetails extends Component<Props> {
renderReadme() {
if (this.readme === null) {
return <Spinner center />
return <Spinner center />;
}
return (
<div className="chart-description">
<MarkdownViewer markdown={this.readme} />
</div>
)
);
}
renderContent() {
@@ -132,7 +132,7 @@ export class HelmChartDetails extends Component<Props> {
<div className="box grow">
<p className="error">{this.error}</p>
</div>
)
);
}
return (
@@ -1,9 +1,9 @@
import semver from "semver"
import semver from "semver";
import { observable } from "mobx";
import { autobind } from "../../utils";
import { HelmChart, helmChartsApi } from "../../api/endpoints/helm-charts.api";
import { ItemStore } from "../../item.store";
import flatten from "lodash/flatten"
import flatten from "lodash/flatten";
export interface IChartVersion {
repo: string;
@@ -24,7 +24,7 @@ export class HelmChartStore extends ItemStore<HelmChart> {
protected sortVersions = (versions: IChartVersion[]) => {
return versions.sort((first, second) => {
return semver.compare(second.version, first.version)
return semver.compare(second.version, first.version);
});
};
@@ -38,8 +38,8 @@ export class HelmChartStore extends ItemStore<HelmChart> {
return versions.map(chart => ({
repo: repo,
version: chart.getVersion()
}))
})
}));
});
};
if (!this.isLoaded) {
await this.loadAll();
@@ -4,11 +4,11 @@ import { appsRoute } from "../+apps/apps.route";
export const helmChartsRoute: RouteProps = {
path: appsRoute.path + "/charts/:repo?/:chartName?"
}
};
export interface IHelmChartsRouteParams {
chartName?: string;
repo?: string;
}
export const helmChartsURL = buildURL<IHelmChartsRouteParams>(helmChartsRoute.path)
export const helmChartsURL = buildURL<IHelmChartsRouteParams>(helmChartsRoute.path);
@@ -28,13 +28,13 @@ export class HelmCharts extends Component<Props> {
}
get selectedChart() {
const { match: { params: { chartName, repo } } } = this.props
const { match: { params: { chartName, repo } } } = this.props;
return helmChartStore.getByName(chartName, repo);
}
showDetails = (chart: HelmChart) => {
if (!chart) {
navigation.merge(helmChartsURL())
navigation.merge(helmChartsURL());
}
else {
navigation.merge(helmChartsURL({
@@ -42,7 +42,7 @@ export class HelmCharts extends Component<Props> {
chartName: chart.getName(),
repo: chart.getRepository(),
}
}))
}));
}
}
@@ -77,7 +77,7 @@ export class ReleaseDetails extends Component<Props> {
updateValues = async () => {
const { release } = this.props;
const name = release.getName();
const namespace = release.getNs()
const namespace = release.getNs();
const data = {
chart: release.getChart(),
repo: await release.getRepo(),
@@ -121,7 +121,7 @@ export class ReleaseDetails extends Component<Props> {
/>
</div>
</div>
)
);
}
renderNotes() {
@@ -222,13 +222,13 @@ export class ReleaseDetails extends Component<Props> {
<DrawerTitle title={_i18n._(t`Resources`)}/>
{this.renderResources()}
</div>
)
);
}
render() {
const { release, hideDetails } = this.props
const title = release ? <Trans>Release: {release.getName()}</Trans> : ""
const toolbar = <HelmReleaseMenu release={release} toolbar hideDetails={hideDetails}/>
const { release, hideDetails } = this.props;
const title = release ? <Trans>Release: {release.getName()}</Trans> : "";
const toolbar = <HelmReleaseMenu release={release} toolbar hideDetails={hideDetails}/>;
return (
<Drawer
className={cssNames("ReleaseDetails", themeStore.activeTheme.type)}
@@ -240,6 +240,6 @@ export class ReleaseDetails extends Component<Props> {
>
{this.renderContent()}
</Drawer>
)
);
}
}
@@ -46,7 +46,7 @@ export class HelmReleaseMenu extends React.Component<Props> {
</MenuItem>
)}
</>
)
);
}
render() {
@@ -10,7 +10,7 @@ import { HelmRelease, helmReleasesApi, IReleaseRevision } from "../../api/endpoi
import { releaseStore } from "./release.store";
import { Select, SelectOption } from "../select";
import { Notifications } from "../notifications";
import orderBy from "lodash/orderBy"
import orderBy from "lodash/orderBy";
interface Props extends DialogProps {
}
@@ -65,7 +65,7 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
renderContent() {
const { revision, revisions } = this;
if (!revision) {
return <p><Trans>No revisions to rollback.</Trans></p>
return <p><Trans>No revisions to rollback.</Trans></p>;
}
return (
<div className="flex gaps align-center">
@@ -78,13 +78,13 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
onChange={({ value }: SelectOption<IReleaseRevision>) => this.revision = value}
/>
</div>
)
);
}
render() {
const { ...dialogProps } = this.props;
const releaseName = this.release ? this.release.getName() : "";
const header = <h5><Trans>Rollback <b>{releaseName}</b></Trans></h5>
const header = <h5><Trans>Rollback <b>{releaseName}</b></Trans></h5>;
return (
<Dialog
{...dialogProps}
@@ -104,6 +104,6 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
</WizardStep>
</Wizard>
</Dialog>
)
);
}
}
@@ -4,7 +4,7 @@ import { appsRoute } from "../+apps/apps.route";
export const releaseRoute: RouteProps = {
path: appsRoute.path + "/releases/:namespace?/:name?"
}
};
export interface IReleaseRouteParams {
name?: string;
@@ -33,7 +33,7 @@ export class ReleaseStore extends ItemStore<HelmRelease> {
this.loadAll();
}
this.releaseSecrets = [...secrets];
})
});
}
unwatch() {
@@ -48,7 +48,7 @@ export class ReleaseStore extends ItemStore<HelmRelease> {
const labels = {
owner: "helm",
name: release.getName()
}
};
return secretsStore.getByLabel(labels)
.filter(secret => secret.getNs() == release.getNs())[0];
}
@@ -58,7 +58,7 @@ export class ReleaseStore extends ItemStore<HelmRelease> {
this.isLoading = true;
let items;
try {
const { isAdmin, allowedNamespaces } = getHostedCluster()
const { isAdmin, allowedNamespaces } = getHostedCluster();
items = await this.loadItems(!isAdmin ? allowedNamespaces : null);
} finally {
if (items) {
@@ -48,7 +48,7 @@ export class HelmReleases extends Component<Props> {
showDetails = (item: HelmRelease) => {
if (!item) {
navigation.merge(releaseURL())
navigation.merge(releaseURL());
}
else {
navigation.merge(releaseURL({
@@ -56,7 +56,7 @@ export class HelmReleases extends Component<Props> {
name: item.getName(),
namespace: item.getNs()
}
}))
}));
}
}
@@ -73,7 +73,7 @@ export class HelmReleases extends Component<Props> {
<Trans>Note: StatefulSet Volumes won't be deleted automatically</Trans>
</p>
</div>
)
);
}
render() {
@@ -122,7 +122,7 @@ export class HelmReleases extends Component<Props> {
release.appVersion,
{ title: release.getStatus(), className: kebabCase(release.getStatus()) },
release.getUpdated(),
]
];
}}
renderItemMenu={(release: HelmRelease) => {
return (
@@ -130,7 +130,7 @@ export class HelmReleases extends Component<Props> {
release={release}
removeConfirmationMessage={this.renderRemoveDialogMessage([release])}
/>
)
);
}}
customizeRemoveDialog={(selectedItems: HelmRelease[]) => ({
message: this.renderRemoveDialogMessage(selectedItems)
+2 -2
View File
@@ -23,12 +23,12 @@ export class Apps extends React.Component {
url: releaseURL({ query }),
routePath: releaseRoute.path.toString(),
},
]
];
}
render() {
return (
<TabLayout className="Apps" tabs={Apps.tabRoutes}/>
)
);
}
}
@@ -7,6 +7,6 @@ export interface IClusterSettingsRouteParams extends IClusterViewRouteParams {
export const clusterSettingsRoute: RouteProps = {
path: `/cluster/:clusterId/settings`,
}
};
export const clusterSettingsURL = buildURL<IClusterSettingsRouteParams>(clusterSettingsRoute.path)
export const clusterSettingsURL = buildURL<IClusterSettingsRouteParams>(clusterSettingsRoute.path);
@@ -14,7 +14,7 @@ import { IClusterSettingsRouteParams } from "./cluster-settings.route";
import { clusterStore } from "../../../common/cluster-store";
import { PageLayout } from "../layout/page-layout";
import { requestMain } from "../../../common/ipc";
import { clusterActivateHandler, clusterRefreshHandler } from "../../../common/cluster-ipc"
import { clusterActivateHandler, clusterRefreshHandler } from "../../../common/cluster-ipc";
interface Props extends RouteComponentProps<IClusterSettingsRouteParams> {
}
@@ -22,7 +22,7 @@ interface Props extends RouteComponentProps<IClusterSettingsRouteParams> {
@observer
export class ClusterSettings extends React.Component<Props> {
get clusterId() {
return this.props.match.params.clusterId
return this.props.match.params.clusterId;
}
get cluster(): Cluster {
@@ -37,18 +37,18 @@ export class ClusterSettings extends React.Component<Props> {
reaction(() => this.clusterId, clusterId => clusterStore.setActive(clusterId), {
fireImmediately: true,
})
])
]);
}
refreshCluster = async () => {
if (this.cluster) {
await requestMain(clusterActivateHandler, this.cluster.id)
await requestMain(clusterRefreshHandler, this.cluster.id)
await requestMain(clusterActivateHandler, this.cluster.id);
await requestMain(clusterRefreshHandler, this.cluster.id);
}
}
render() {
const cluster = this.cluster
const cluster = this.cluster;
if (!cluster) return null;
const header = (
<>
@@ -35,14 +35,14 @@ export class ClusterIconSetting extends React.Component<Props> {
cluster.preferences.icon = undefined;
}
} catch (e) {
this.errorText = e.toString()
this.status = GeneralInputStatus.ERROR
this.errorText = e.toString();
this.status = GeneralInputStatus.ERROR;
}
}
getClearButton() {
if (this.props.cluster.preferences.icon) {
return <Button tooltip="Revert back to default icon" accent onClick={() => this.onIconPick([])}>Clear</Button>
return <Button tooltip="Revert back to default icon" accent onClick={() => this.onIconPick([])}>Clear</Button>;
}
}
@@ -59,7 +59,7 @@ export class ClusterPrometheusSetting extends React.Component<Props> {
service: parsed[1],
port: parseInt(parsed[2]),
prefix: apiPrefix
}
};
}
onSaveProvider = () => {
@@ -19,21 +19,21 @@ export class InstallFeature extends React.Component<Props> {
@observable message = "";
componentDidMount() {
const feature = this.props.feature
const cluster = this.props.cluster
const feature = this.props.feature;
const cluster = this.props.cluster;
const statusUpdate = interval(20, () => {
feature.updateStatus(cluster)
})
statusUpdate.start(true)
feature.updateStatus(cluster);
});
statusUpdate.start(true);
disposeOnUnmount(this, () => {
statusUpdate.stop()
})
statusUpdate.stop();
});
disposeOnUnmount(this,
reaction(() => feature.status.installed, () => {
this.loading = false;
this.message = ""
this.message = "";
}, { equals: comparer.structural })
);
}
@@ -60,8 +60,8 @@ export class InstallFeature extends React.Component<Props> {
accent
disabled={disabled}
onClick={this.runAction(async () => {
this.message = "Uninstalling feature ..."
feature.uninstall(cluster)
this.message = "Uninstalling feature ...";
feature.uninstall(cluster);
})}
>
Uninstall
@@ -72,8 +72,8 @@ export class InstallFeature extends React.Component<Props> {
primary
disabled={disabled}
onClick={this.runAction(async () =>{
this.message = "Installing feature ..."
feature.install(cluster)
this.message = "Installing feature ...";
feature.install(cluster);
})}
>
Install
@@ -23,7 +23,7 @@ export class RemoveClusterButton extends React.Component<Props> {
ok: async () => {
await clusterStore.removeById(cluster.id);
}
})
});
}
render() {
@@ -22,7 +22,7 @@ export class Features extends React.Component<Props> {
<p><f.components.Description /></p>
</>
</InstallFeature>
)
);
})}
</div>
);
@@ -1,2 +1,2 @@
export * from "./cluster-settings.route"
export * from "./cluster-settings"
export * from "./cluster-settings.route";
export * from "./cluster-settings";
@@ -14,7 +14,7 @@ export class Status extends React.Component<Props> {
@autobind()
openKubeconfig() {
const { cluster } = this.props;
shell.showItemInFolder(cluster.kubeConfigPath)
shell.showItemInFolder(cluster.kubeConfigPath);
}
renderStatusRows() {
@@ -1,4 +1,4 @@
import "./cluster-issues.scss"
import "./cluster-issues.scss";
import React from "react";
import { observer } from "mobx-react";
@@ -43,7 +43,7 @@ export class ClusterIssues extends React.Component<Props> {
// Node bad conditions
nodesStore.items.forEach(node => {
const { kind, selfLink, getId, getName } = node
const { kind, selfLink, getId, getName } = node;
node.getWarningConditions().forEach(({ message }) => {
warnings.push({
kind,
@@ -51,8 +51,8 @@ export class ClusterIssues extends React.Component<Props> {
getName,
selfLink,
message,
})
})
});
});
});
// Warning events for Workloads
@@ -67,7 +67,7 @@ export class ClusterIssues extends React.Component<Props> {
kind,
selfLink: lookupApiLink(involvedObject, error),
});
})
});
return warnings;
}
@@ -72,7 +72,7 @@ export const ClusterMetrics = observer(() => {
return <Spinner center/>;
}
if (!memoryCapacity || !cpuCapacity) {
return <ClusterNoMetrics className="empty"/>
return <ClusterNoMetrics className="empty"/>;
}
return (
<BarChart
@@ -24,7 +24,7 @@ export const ClusterPieCharts = observer(() => {
<p><Trans>Specified limits are higher than node capacity!</Trans></p>
</div>
);
}
};
const renderCharts = () => {
const data = getMetricLastPoints(clusterStore.metrics);
@@ -168,7 +168,7 @@ export const ClusterPieCharts = observer(() => {
</div>
</div>
);
}
};
const renderContent = () => {
const { masterNodes, workerNodes } = nodesStore;
@@ -194,11 +194,11 @@ export const ClusterPieCharts = observer(() => {
return <ClusterNoMetrics className="empty"/>;
}
return renderCharts();
}
};
return (
<div className="ClusterPieCharts flex">
{renderContent()}
</div>
);
})
});
@@ -3,6 +3,6 @@ import { buildURL } from "../../../common/utils/buildUrl";
export const clusterRoute: RouteProps = {
path: "/cluster"
}
};
export const clusterURL = buildURL(clusterRoute.path)
export const clusterURL = buildURL(clusterRoute.path);
@@ -35,7 +35,7 @@ export class ClusterStore extends KubeObjectStore<Cluster> {
Object.assign(this, storage.get());
reaction(() => {
const { metricType, metricNodeRole } = this;
return { metricType, metricNodeRole }
return { metricType, metricNodeRole };
},
settings => storage.set(settings)
);
@@ -85,9 +85,9 @@ export class ClusterStore extends KubeObjectStore<Cluster> {
getMetricsValues(source: Partial<IClusterMetrics>): [number, string][] {
switch (this.metricType) {
case MetricType.CPU:
return normalizeMetrics(source.cpuUsage).data.result[0].values
return normalizeMetrics(source.cpuUsage).data.result[0].values;
case MetricType.MEMORY:
return normalizeMetrics(source.memoryUsage).data.result[0].values
return normalizeMetrics(source.memoryUsage).data.result[0].values;
default:
return [];
}
+7 -7
View File
@@ -1,4 +1,4 @@
import "./cluster.scss"
import "./cluster.scss";
import React from "react";
import { computed, reaction } from "mobx";
@@ -21,19 +21,19 @@ export class Cluster extends React.Component {
private dependentStores = [nodesStore, podsStore];
private watchers = [
interval(60, () => { getHostedCluster().available && clusterStore.getMetrics()}),
interval(20, () => { getHostedCluster().available && eventStore.loadAll()})
interval(60, () => { getHostedCluster().available && clusterStore.getMetrics();}),
interval(20, () => { getHostedCluster().available && eventStore.loadAll();})
];
@computed get isLoaded() {
return nodesStore.isLoaded && podsStore.isLoaded
return nodesStore.isLoaded && podsStore.isLoaded;
}
// todo: refactor
async componentDidMount() {
const { dependentStores } = this;
if (!isAllowedResource("nodes")) {
dependentStores.splice(dependentStores.indexOf(nodesStore), 1)
dependentStores.splice(dependentStores.indexOf(nodesStore), 1);
}
this.watchers.forEach(watcher => watcher.start(true));
@@ -49,7 +49,7 @@ export class Cluster extends React.Component {
() => clusterStore.metricNodeRole,
() => this.watchers.forEach(watcher => watcher.restart())
)
])
]);
}
render() {
@@ -67,6 +67,6 @@ export class Cluster extends React.Component {
)}
</div>
</TabLayout>
)
);
}
}
+1 -1
View File
@@ -1,2 +1,2 @@
export * from "./cluster.route"
export * from "./cluster.route";
@@ -51,7 +51,7 @@ export class HpaDetails extends React.Component<Props> {
</Trans>
);
}
}
};
return (
<Table>
@@ -68,7 +68,7 @@ export class HpaDetails extends React.Component<Props> {
<TableCell className="name">{name}</TableCell>
<TableCell className="metrics">{values}</TableCell>
</TableRow>
)
);
})
}
</Table>
@@ -113,7 +113,7 @@ export class HpaDetails extends React.Component<Props> {
tooltip={tooltip}
className={cssNames({ [type.toLowerCase()]: isReady })}
/>
)
);
})}
</DrawerItem>
@@ -132,7 +132,7 @@ kubeObjectDetailRegistry.add({
components: {
Details: (props) => <HpaDetails {...props} />
}
})
});
kubeObjectDetailRegistry.add({
kind: "HorizontalPodAutoscaler",
@@ -141,4 +141,4 @@ kubeObjectDetailRegistry.add({
components: {
Details: (props) => <KubeEventDetails {...props} />
}
})
});
@@ -3,9 +3,9 @@ import { buildURL } from "../../../common/utils/buildUrl";
export const hpaRoute: RouteProps = {
path: "/hpa"
}
};
export interface IHpaRouteParams {
}
export const hpaURL = buildURL<IHpaRouteParams>(hpaRoute.path)
export const hpaURL = buildURL<IHpaRouteParams>(hpaRoute.path);
@@ -1,4 +1,4 @@
import "./hpa.scss"
import "./hpa.scss";
import React from "react";
import { observer } from "mobx-react";
@@ -78,7 +78,7 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
tooltip={tooltip}
className={cssNames(type.toLowerCase())}
/>
)
);
})
]}
/>
@@ -1,3 +1,3 @@
export * from "./hpa"
export * from "./hpa-details"
export * from "./hpa.route"
export * from "./hpa";
export * from "./hpa-details";
export * from "./hpa.route";
@@ -31,7 +31,7 @@ export class ConfigMapDetails extends React.Component<Props> {
this.data.replace(configMap.data); // refresh
}
})
])
]);
}
save = async () => {
@@ -75,7 +75,7 @@ export class ConfigMapDetails extends React.Component<Props> {
/>
</div>
</div>
)
);
})
}
<Button
@@ -98,7 +98,7 @@ kubeObjectDetailRegistry.add({
components: {
Details: (props) => <ConfigMapDetails {...props} />
}
})
});
kubeObjectDetailRegistry.add({
kind: "ConfigMap",
@@ -107,6 +107,6 @@ kubeObjectDetailRegistry.add({
components: {
Details: (props) => <KubeEventDetails {...props} />
}
})
});
@@ -3,7 +3,7 @@ import { buildURL } from "../../../common/utils/buildUrl";
export const configMapsRoute: RouteProps = {
path: "/configmaps"
}
};
export interface IConfigMapsRouteParams {
}
@@ -1,4 +1,4 @@
import "./config-maps.scss"
import "./config-maps.scss";
import React from "react";
import { observer } from "mobx-react";
@@ -1,3 +1,3 @@
export * from "./config-maps.route"
export * from "./config-maps"
export * from "./config-map-details"
export * from "./config-maps.route";
export * from "./config-maps";
export * from "./config-map-details";
@@ -1,3 +1,3 @@
export * from "./pod-disruption-budgets.route"
export * from "./pod-disruption-budgets"
export * from "./pod-disruption-budgets-details"
export * from "./pod-disruption-budgets.route";
export * from "./pod-disruption-budgets";
export * from "./pod-disruption-budgets-details";
@@ -18,8 +18,8 @@ export class PodDisruptionBudgetDetails extends React.Component<Props> {
render() {
const { object: pdb } = this.props;
if (!pdb) return null
const { status, spec } = pdb
if (!pdb) return null;
const { status, spec } = pdb;
const selectors = pdb.getSelectors();
return (
<div className="PdbDetails">
@@ -50,7 +50,7 @@ export class PodDisruptionBudgetDetails extends React.Component<Props> {
</DrawerItem>
</div>
)
);
}
}
@@ -60,4 +60,4 @@ kubeObjectDetailRegistry.add({
components: {
Details: (props) => <PodDisruptionBudgetDetails {...props} />
}
})
});
@@ -3,9 +3,9 @@ import { buildURL } from "../../../common/utils/buildUrl";
export const pdbRoute: RouteProps = {
path: "/poddisruptionbudgets"
}
};
export interface IPodDisruptionBudgetsRouteParams {
}
export const pdbURL = buildURL<IPodDisruptionBudgetsRouteParams>(pdbRoute.path)
export const pdbURL = buildURL<IPodDisruptionBudgetsRouteParams>(pdbRoute.path);
@@ -1,4 +1,4 @@
import "./pod-disruption-budgets.scss"
import "./pod-disruption-budgets.scss";
import * as React from "react";
import { observer } from "mobx-react";
@@ -65,7 +65,7 @@ export class PodDisruptionBudgets extends React.Component<Props> {
pdb.getCurrentHealthy(),
pdb.getDesiredHealthy(),
pdb.getAge(),
]
];
}}
/>
);
@@ -193,12 +193,12 @@ export class AddQuotaDialog extends React.Component<Props> {
<div className="value">{value}</div>
<Icon material="clear" onClick={() => this.quotas[quota] = ""} />
</div>
)
);
})}
</div>
</WizardStep>
</Wizard>
</Dialog>
)
);
}
}
@@ -1,3 +1,3 @@
export * from "./resource-quotas.route"
export * from "./resource-quotas"
export * from "./resource-quota-details"
export * from "./resource-quotas.route";
export * from "./resource-quotas";
export * from "./resource-quota-details";
@@ -20,24 +20,24 @@ const onlyNumbers = /$[0-9]*^/g;
function transformUnit(name: string, value: string): number {
if (name.includes("memory") || name.includes("storage")) {
return unitsToBytes(value)
return unitsToBytes(value);
}
if (name.includes("cpu")) {
return cpuUnitsToNumber(value)
return cpuUnitsToNumber(value);
}
return metricUnitsToNumber(value);
}
function renderQuotas(quota: ResourceQuota): JSX.Element[] {
const { hard = {}, used = {} } = quota.status
const { hard = {}, used = {} } = quota.status;
return Object.entries(hard)
.filter(([name]) => used[name])
.map(([name, value]) => {
const current = transformUnit(name, used[name])
const max = transformUnit(name, value)
const current = transformUnit(name, used[name]);
const max = transformUnit(name, value);
const usage = max === 0 ? 100 : Math.ceil(current / max * 100); // special case 0 max as always 100% usage
return (
@@ -52,8 +52,8 @@ function renderQuotas(quota: ResourceQuota): JSX.Element[] {
}
/>
</div>
)
})
);
});
}
@observer
@@ -104,4 +104,4 @@ kubeObjectDetailRegistry.add({
components: {
Details: (props) => <ReplicaSetDetails {...props} />
}
})
});
@@ -3,7 +3,7 @@ import { buildURL } from "../../../common/utils/buildUrl";
export const resourceQuotaRoute: RouteProps = {
path: "/resourcequotas"
}
};
export interface IResourceQuotaRouteParams {
}
@@ -1,4 +1,4 @@
import "./add-secret-dialog.scss"
import "./add-secret-dialog.scss";
import React from "react";
import { observable } from "mobx";
@@ -85,7 +85,7 @@ export class AddSecretDialog extends React.Component<Props> {
data[key] = processValue ? processValue(value) : value;
}
return data;
}, {})
}, {});
}
createSecret = async () => {
@@ -100,7 +100,7 @@ export class AddSecretDialog extends React.Component<Props> {
annotations: this.getDataFromFields(annotations),
labels: this.getDataFromFields(labels),
} as IKubeObjectMetadata
}
};
try {
const newSecret = await secretsApi.create({ namespace, name }, secret);
showDetails(newSecret.selfLink);
@@ -163,11 +163,11 @@ export class AddSecretDialog extends React.Component<Props> {
onClick={() => this.removeField(field, index)}
/>
</div>
)
);
})}
</div>
</>
)
);
}
render() {
@@ -216,6 +216,6 @@ export class AddSecretDialog extends React.Component<Props> {
</WizardStep>
</Wizard>
</Dialog>
)
);
}
}
@@ -1,4 +1,4 @@
export * from "./secrets.route"
export * from "./secrets"
export * from "./secret-details"
export * from "./secrets.route";
export * from "./secrets";
export * from "./secret-details";
@@ -36,7 +36,7 @@ export class SecretDetails extends React.Component<Props> {
this.revealSecret = {};
}
})
])
]);
}
saveSecret = async () => {
@@ -97,7 +97,7 @@ export class SecretDetails extends React.Component<Props> {
}
</div>
</div>
)
);
})
}
<Button
@@ -119,4 +119,4 @@ kubeObjectDetailRegistry.add({
components: {
Details: (props) => <SecretDetails {...props} />
}
})
});
@@ -3,7 +3,7 @@ import { buildURL } from "../../../common/utils/buildUrl";
export const secretsRoute: RouteProps = {
path: "/secrets"
}
};
export interface ISecretsRouteParams {
}
@@ -1,4 +1,4 @@
import "./secrets.scss"
import "./secrets.scss";
import React from "react";
import { observer } from "mobx-react";
@@ -5,8 +5,8 @@ import { configMapsURL } from "../+config-maps/config-maps.route";
export const configRoute: RouteProps = {
get path() {
return Config.tabRoutes.map(({ routePath }) => routePath).flat()
return Config.tabRoutes.map(({ routePath }) => routePath).flat();
}
}
};
export const configURL = (params?: IURLParams) => configMapsURL(params);
+9 -9
View File
@@ -8,20 +8,20 @@ import { namespaceStore } from "../+namespaces/namespace.store";
import { resourceQuotaRoute, ResourceQuotas, resourceQuotaURL } from "../+config-resource-quotas";
import { pdbRoute, pdbURL, PodDisruptionBudgets } from "../+config-pod-disruption-budgets";
import { HorizontalPodAutoscalers, hpaRoute, hpaURL } from "../+config-autoscalers";
import { isAllowedResource } from "../../../common/rbac"
import { isAllowedResource } from "../../../common/rbac";
@observer
export class Config extends React.Component {
static get tabRoutes(): TabLayoutRoute[] {
const query = namespaceStore.getContextParams()
const routes: TabLayoutRoute[] = []
const query = namespaceStore.getContextParams();
const routes: TabLayoutRoute[] = [];
if (isAllowedResource("configmaps")) {
routes.push({
title: <Trans>ConfigMaps</Trans>,
component: ConfigMaps,
url: configMapsURL({ query }),
routePath: configMapsRoute.path.toString(),
})
});
}
if (isAllowedResource("secrets")) {
routes.push({
@@ -29,7 +29,7 @@ export class Config extends React.Component {
component: Secrets,
url: secretsURL({ query }),
routePath: secretsRoute.path.toString(),
})
});
}
if (isAllowedResource("resourcequotas")) {
routes.push({
@@ -37,7 +37,7 @@ export class Config extends React.Component {
component: ResourceQuotas,
url: resourceQuotaURL({ query }),
routePath: resourceQuotaRoute.path.toString(),
})
});
}
if (isAllowedResource("horizontalpodautoscalers")) {
routes.push({
@@ -45,7 +45,7 @@ export class Config extends React.Component {
component: HorizontalPodAutoscalers,
url: hpaURL({ query }),
routePath: hpaRoute.path.toString(),
})
});
}
if (isAllowedResource("poddisruptionbudgets")) {
routes.push({
@@ -53,7 +53,7 @@ export class Config extends React.Component {
component: PodDisruptionBudgets,
url: pdbURL({ query }),
routePath: pdbRoute.path.toString(),
})
});
}
return routes;
}
@@ -61,6 +61,6 @@ export class Config extends React.Component {
render() {
return (
<TabLayout className="Config" tabs={Config.tabRoutes}/>
)
);
}
}
+2 -2
View File
@@ -1,2 +1,2 @@
export * from "./config.route"
export * from "./config"
export * from "./config.route";
export * from "./config";
@@ -60,7 +60,7 @@ export class CRDDetails extends React.Component<Props> {
<DrawerItem name={<Trans>Conditions</Trans>} className="conditions" labelsOnly>
{
crd.getConditions().map(condition => {
const { type, message, lastTransitionTime, status } = condition
const { type, message, lastTransitionTime, status } = condition;
return (
<Badge
key={type}
@@ -112,7 +112,7 @@ export class CRDDetails extends React.Component<Props> {
<Badge label={jsonPath}/>
</TableCell>
</TableRow>
)
);
})
}
</Table>
@@ -130,7 +130,7 @@ export class CRDDetails extends React.Component<Props> {
</>
}
</div>
)
);
}
}
@@ -140,4 +140,4 @@ kubeObjectDetailRegistry.add({
components: {
Details: (props) => <CRDDetails {...props} />
}
})
});
@@ -1,4 +1,4 @@
import "./crd-list.scss"
import "./crd-list.scss";
import React from "react";
import { Trans } from "@lingui/macro";
@@ -24,7 +24,7 @@ enum sortBy {
@observer
export class CrdList extends React.Component {
@computed get groups() {
return navigation.searchParams.getAsArray("groups")
return navigation.searchParams.getAsArray("groups");
}
onGroupChange(group: string) {
@@ -32,7 +32,7 @@ export class CrdList extends React.Component {
const index = groups.findIndex(item => item == group);
if (index !== -1) groups.splice(index, 1);
else groups.push(group);
setQueryParams({ groups })
setQueryParams({ groups });
}
render() {
@@ -52,14 +52,14 @@ export class CrdList extends React.Component {
searchFilters={Object.values(sortingCallbacks)}
filterItems={[
(items: CustomResourceDefinition[]) => {
return selectedGroups.length ? items.filter(item => selectedGroups.includes(item.getGroup())) : items
return selectedGroups.length ? items.filter(item => selectedGroups.includes(item.getGroup())) : items;
}
]}
renderHeaderTitle={<Trans>Custom Resources</Trans>}
customizeHeader={() => {
let placeholder = <Trans>All groups</Trans>;
if (selectedGroups.length == 1) placeholder = <><Trans>Group</Trans>: {selectedGroups[0]}</>
if (selectedGroups.length >= 2) placeholder = <><Trans>Groups</Trans>: {selectedGroups.join(", ")}</>
if (selectedGroups.length == 1) placeholder = <><Trans>Group</Trans>: {selectedGroups[0]}</>;
if (selectedGroups.length >= 2) placeholder = <><Trans>Groups</Trans>: {selectedGroups.join(", ")}</>;
return {
// todo: move to global filters
filters: (
@@ -77,11 +77,11 @@ export class CrdList extends React.Component {
<span>{group}</span>
{isSelected && <Icon small material="check" className="box right"/>}
</div>
)
);
}}
/>
)
}
};
}}
renderTableHeader={[
{ title: <Trans>Resource</Trans>, className: "kind", sortBy: sortBy.kind },
@@ -99,10 +99,10 @@ export class CrdList extends React.Component {
crd.getVersion(),
crd.getScope(),
crd.getAge(),
]
];
}}
/>
)
);
}
}
@@ -19,7 +19,7 @@ interface Props extends KubeObjectDetailsProps<CustomResourceDefinition> {
function convertSpecValue(value: any): any {
if (Array.isArray(value)) {
return value.map(convertSpecValue)
return value.map(convertSpecValue);
}
if (typeof value === "object") {
@@ -31,10 +31,10 @@ function convertSpecValue(value: any): any {
className="box grow"
value={JSON.stringify(value, null, 2)}
/>
)
);
}
return value
return value;
}
@observer
@@ -48,13 +48,13 @@ export class CrdResourceDetails extends React.Component<Props> {
<DrawerItem key={name} name={name} renderBoolean>
{convertSpecValue(jsonPath.value(crd, jp.slice(1)))}
</DrawerItem>
))
));
}
renderStatus(crd: CustomResourceDefinition, columns: AdditionalPrinterColumnsV1[]) {
const showStatus = !columns.find(column => column.name == "Status") && crd.status?.conditions;
if (!showStatus) {
return null
return null;
}
const conditions = crd.status.conditions
@@ -66,13 +66,13 @@ export class CrdResourceDetails extends React.Component<Props> {
className={cssNames({ disabled: status === "False" }, kind.toLowerCase())}
tooltip={message}
/>
))
));
return (
<DrawerItem name={<Trans>Status</Trans>} className="status" labelsOnly>
{conditions}
</DrawerItem>
)
);
}
render() {
@@ -90,6 +90,6 @@ export class CrdResourceDetails extends React.Component<Props> {
{this.renderAdditionalColumns(object, extraColumns)}
{this.renderStatus(object, extraColumns)}
</div>
)
);
}
}
@@ -32,7 +32,7 @@ export class CrdResources extends React.Component<Props> {
store.loadAll();
}
})
])
]);
}
@computed get crd() {
@@ -41,7 +41,7 @@ export class CrdResources extends React.Component<Props> {
}
@computed get store() {
if (!this.crd) return null
if (!this.crd) return null;
return apiManager.getStore(this.crd.getResourceApiBase());
}
@@ -54,10 +54,10 @@ export class CrdResources extends React.Component<Props> {
[sortBy.name]: (item: KubeObject) => item.getName(),
[sortBy.namespace]: (item: KubeObject) => item.getNs(),
[sortBy.age]: (item: KubeObject) => item.metadata.creationTimestamp,
}
};
extraColumns.forEach(column => {
sortingCallbacks[column.name] = (item: KubeObject) => jsonPath.value(item, column.jsonPath.slice(1))
})
sortingCallbacks[column.name] = (item: KubeObject) => jsonPath.value(item, column.jsonPath.slice(1));
});
return (
<KubeObjectListLayout
@@ -78,7 +78,7 @@ export class CrdResources extends React.Component<Props> {
title: name,
className: name.toLowerCase(),
sortBy: name
}
};
}),
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
]}
@@ -92,6 +92,6 @@ export class CrdResources extends React.Component<Props> {
crdInstance.getAge(),
]}
/>
)
);
}
}
@@ -3,15 +3,15 @@ import { buildURL } from "../../../common/utils/buildUrl";
export const crdRoute: RouteProps = {
path: "/crd"
}
};
export const crdDefinitionsRoute: RouteProps = {
path: crdRoute.path + "/definitions"
}
};
export const crdResourcesRoute: RouteProps = {
path: crdRoute.path + "/:group/:name"
}
};
export interface ICRDListQuery {
groups?: string;
@@ -26,14 +26,14 @@ export class CRDStore extends KubeObjectStore<CustomResourceDefinition> {
super();
// auto-init stores for crd-s
reaction(() => this.items.toJS(), items => items.forEach(initStore))
reaction(() => this.items.toJS(), items => items.forEach(initStore));
}
protected sortItems(items: CustomResourceDefinition[]) {
return super.sortItems(items, [
crd => crd.getGroup(),
crd => crd.getName(),
])
]);
}
@computed get groups() {
@@ -43,7 +43,7 @@ export class CRDStore extends KubeObjectStore<CustomResourceDefinition> {
if (!groups[group]) groups[group] = [];
groups[group].push(crd);
return groups;
}, groups)
}, groups);
}
getByGroup(group: string, pluralName: string) {
@@ -53,12 +53,12 @@ export class CRDStore extends KubeObjectStore<CustomResourceDefinition> {
}
getByObject(obj: KubeObject) {
if (!obj) return null
if (!obj) return null;
const { kind, apiVersion } = obj;
return this.items.find(crd => (
kind === crd.getResourceKind() && apiVersion === `${crd.getGroup()}/${crd.getVersion()}`
))
));
}
}
@@ -17,7 +17,7 @@ export class CustomResources extends React.Component {
url: crdURL(),
routePath: crdRoute.path.toString(),
}
]
];
}
render() {
Loaded 100 of 531 files, more files were not shown because too many files have changed in this diff. Show more