1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Merge branch 'master' into upgrade-typedoc-to-0.20

This commit is contained in:
Jari Kolehmainen 2021-04-19 13:23:04 +03:00
commit fa2f145600
10 changed files with 55 additions and 42 deletions

View File

@ -20,6 +20,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Add the current IP address, long hostname and short hostname record to /etc/hosts file
if: runner.os == 'Linux'
run: |
echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts
- name: Using Node.js ${{ matrix.node-version }} - name: Using Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:

View File

@ -1,9 +1,9 @@
import { LensRendererExtension, Store, Interface, Component } from "@k8slens/extensions"; import { LensRendererExtension, Interface, Component, Catalog} from "@k8slens/extensions";
import { MetricsFeature } from "./src/metrics-feature"; import { MetricsFeature } from "./src/metrics-feature";
export default class ClusterMetricsFeatureExtension extends LensRendererExtension { export default class ClusterMetricsFeatureExtension extends LensRendererExtension {
onActivate() { onActivate() {
const category = Store.catalogCategories.getForGroupKind<Store.KubernetesClusterCategory>("entity.k8slens.dev", "KubernetesCluster"); const category = Catalog.catalogCategories.getForGroupKind<Catalog.KubernetesClusterCategory>("entity.k8slens.dev", "KubernetesCluster");
if (!category) { if (!category) {
return; return;
@ -12,7 +12,7 @@ export default class ClusterMetricsFeatureExtension extends LensRendererExtensio
category.on("contextMenuOpen", this.clusterContextMenuOpen.bind(this)); category.on("contextMenuOpen", this.clusterContextMenuOpen.bind(this));
} }
async clusterContextMenuOpen(cluster: Store.KubernetesCluster, ctx: Interface.CatalogEntityContextMenuContext) { async clusterContextMenuOpen(cluster: Catalog.KubernetesCluster, ctx: Interface.CatalogEntityContextMenuContext) {
if (!cluster.status.active) { if (!cluster.status.active) {
return; return;
} }

View File

@ -1,4 +1,4 @@
import { ClusterFeature, Store, K8sApi } from "@k8slens/extensions"; import { ClusterFeature, Catalog, K8sApi } from "@k8slens/extensions";
import semver from "semver"; import semver from "semver";
import * as path from "path"; import * as path from "path";
@ -49,7 +49,7 @@ export class MetricsFeature extends ClusterFeature.Feature {
storageClass: null, storageClass: null,
}; };
async install(cluster: Store.KubernetesCluster): Promise<void> { async install(cluster: Catalog.KubernetesCluster): Promise<void> {
// Check if there are storageclasses // Check if there are storageclasses
const storageClassApi = K8sApi.forCluster(cluster, K8sApi.StorageClass); const storageClassApi = K8sApi.forCluster(cluster, K8sApi.StorageClass);
const scs = await storageClassApi.list(); const scs = await storageClassApi.list();
@ -62,11 +62,11 @@ export class MetricsFeature extends ClusterFeature.Feature {
super.applyResources(cluster, path.join(__dirname, "../resources/")); super.applyResources(cluster, path.join(__dirname, "../resources/"));
} }
async upgrade(cluster: Store.KubernetesCluster): Promise<void> { async upgrade(cluster: Catalog.KubernetesCluster): Promise<void> {
return this.install(cluster); return this.install(cluster);
} }
async updateStatus(cluster: Store.KubernetesCluster): Promise<ClusterFeature.FeatureStatus> { async updateStatus(cluster: Catalog.KubernetesCluster): Promise<ClusterFeature.FeatureStatus> {
try { try {
const statefulSet = K8sApi.forCluster(cluster, K8sApi.StatefulSet); const statefulSet = K8sApi.forCluster(cluster, K8sApi.StatefulSet);
const prometheus = await statefulSet.get({name: "prometheus", namespace: "lens-metrics"}); const prometheus = await statefulSet.get({name: "prometheus", namespace: "lens-metrics"});
@ -87,7 +87,7 @@ export class MetricsFeature extends ClusterFeature.Feature {
return this.status; return this.status;
} }
async uninstall(cluster: Store.KubernetesCluster): Promise<void> { async uninstall(cluster: Catalog.KubernetesCluster): Promise<void> {
const namespaceApi = K8sApi.forCluster(cluster, K8sApi.Namespace); const namespaceApi = K8sApi.forCluster(cluster, K8sApi.Namespace);
const clusterRoleBindingApi = K8sApi.forCluster(cluster, K8sApi.ClusterRoleBinding); const clusterRoleBindingApi = K8sApi.forCluster(cluster, K8sApi.ClusterRoleBinding);
const clusterRoleApi = K8sApi.forCluster(cluster, K8sApi.ClusterRole); const clusterRoleApi = K8sApi.forCluster(cluster, K8sApi.ClusterRole);

View File

@ -1,4 +1,4 @@
import { EventBus, Util, Store, App } from "@k8slens/extensions"; import { EventBus, Util, Catalog, App } from "@k8slens/extensions";
import ua from "universal-analytics"; import ua from "universal-analytics";
import Analytics from "analytics-node"; import Analytics from "analytics-node";
import { machineIdSync } from "node-machine-id"; import { machineIdSync } from "node-machine-id";
@ -102,7 +102,7 @@ export class Tracker extends Util.Singleton {
} }
protected reportData() { protected reportData() {
const clustersList = Store.catalogEntities.getItemsForApiKind<Store.KubernetesCluster>("entity.k8slens.dev/v1alpha1", "KubernetesCluster"); const clustersList = Catalog.catalogEntities.getItemsForApiKind<Catalog.KubernetesCluster>("entity.k8slens.dev/v1alpha1", "KubernetesCluster");
this.event("generic-data", "report", { this.event("generic-data", "report", {
appVersion: App.version, appVersion: App.version,
@ -117,7 +117,7 @@ export class Tracker extends Util.Singleton {
}); });
} }
protected reportClusterData(cluster: Store.KubernetesCluster) { protected reportClusterData(cluster: Catalog.KubernetesCluster) {
this.event("cluster-data", "report", { this.event("cluster-data", "report", {
id: cluster.metadata.id, id: cluster.metadata.id,
managed: cluster.metadata.source !== "local", managed: cluster.metadata.source !== "local",

View File

@ -3,7 +3,7 @@ import path from "path";
import hb from "handlebars"; import hb from "handlebars";
import { observable } from "mobx"; import { observable } from "mobx";
import { ResourceApplier } from "../main/resource-applier"; import { ResourceApplier } from "../main/resource-applier";
import { KubernetesCluster } from "./core-api/stores"; import { KubernetesCluster } from "./core-api/catalog";
import logger from "../main/logger"; import logger from "../main/logger";
import { app } from "electron"; import { app } from "electron";
import { requestMain } from "../common/ipc"; import { requestMain } from "../common/ipc";

View File

@ -3,6 +3,9 @@ import { computed } from "mobx";
import { CatalogEntity } from "../../common/catalog-entity"; import { CatalogEntity } from "../../common/catalog-entity";
import { catalogEntityRegistry as registry } from "../../common/catalog-entity-registry"; import { catalogEntityRegistry as registry } from "../../common/catalog-entity-registry";
export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog-category-registry";
export * from "../../common/catalog-entities";
export class CatalogEntityRegistry { export class CatalogEntityRegistry {
@computed getItemsForApiKind<T extends CatalogEntity>(apiVersion: string, kind: string): T[] { @computed getItemsForApiKind<T extends CatalogEntity>(apiVersion: string, kind: string): T[] {
return registry.getItemsForApiKind<T>(apiVersion, kind); return registry.getItemsForApiKind<T>(apiVersion, kind);

View File

@ -9,10 +9,12 @@ import * as Store from "./stores";
import * as Util from "./utils"; import * as Util from "./utils";
import * as ClusterFeature from "./cluster-feature"; import * as ClusterFeature from "./cluster-feature";
import * as Interface from "../interfaces"; import * as Interface from "../interfaces";
import * as Catalog from "./catalog";
export { export {
App, App,
EventBus, EventBus,
Catalog,
ClusterFeature, ClusterFeature,
Interface, Interface,
Store, Store,

View File

@ -1,4 +1 @@
export { ExtensionStore } from "../extension-store"; export { ExtensionStore } from "../extension-store";
export { KubernetesCluster, KubernetesClusterCategory } from "../../common/catalog-entities/kubernetes-cluster";
export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog-category-registry";
export { catalogEntities } from "./catalog";

View File

@ -15,8 +15,14 @@ export interface KubeObjectListLayoutProps extends ItemListLayoutProps {
dependentStores?: KubeObjectStore[]; dependentStores?: KubeObjectStore[];
} }
const defaultProps: Partial<KubeObjectListLayoutProps> = {
onDetails: (item: KubeObject) => showDetails(item.selfLink),
};
@observer @observer
export class KubeObjectListLayout extends React.Component<KubeObjectListLayoutProps> { export class KubeObjectListLayout extends React.Component<KubeObjectListLayoutProps> {
static defaultProps = defaultProps as object;
@computed get selectedItem() { @computed get selectedItem() {
return this.props.store.getByPath(kubeSelectedUrlParam.get()); return this.props.store.getByPath(kubeSelectedUrlParam.get());
} }
@ -33,14 +39,6 @@ export class KubeObjectListLayout extends React.Component<KubeObjectListLayoutPr
]); ]);
} }
onDetails = (item: KubeObject) => {
if (this.props.onDetails) {
this.props.onDetails(item);
} else {
showDetails(item.selfLink);
}
};
render() { render() {
const { className, store, items = store.contextItems, ...layoutProps } = this.props; const { className, store, items = store.contextItems, ...layoutProps } = this.props;
@ -52,10 +50,7 @@ export class KubeObjectListLayout extends React.Component<KubeObjectListLayoutPr
items={items} items={items}
preloadStores={false} // loading handled in kubeWatchApi.subscribeStores() preloadStores={false} // loading handled in kubeWatchApi.subscribeStores()
detailsItem={this.selectedItem} detailsItem={this.selectedItem}
onDetails={this.onDetails} renderItemMenu={(item: KubeObject) => <KubeObjectMenu object={item} />} // safe because we are dealing with KubeObjects here
renderItemMenu={(item) => {
return <KubeObjectMenu object={item}/>;
}}
/> />
); );
} }

View File

@ -7,13 +7,13 @@ import { hideDetails } from "./kube-object-details";
import { apiManager } from "../../api/api-manager"; import { apiManager } from "../../api/api-manager";
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry"; import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
export interface KubeObjectMenuProps<T extends KubeObject = any> extends MenuActionsProps { export interface KubeObjectMenuProps<T> extends MenuActionsProps {
object: T; object: T | null | undefined;
editable?: boolean; editable?: boolean;
removable?: boolean; removable?: boolean;
} }
export class KubeObjectMenu extends React.Component<KubeObjectMenuProps> { export class KubeObjectMenu<T extends KubeObject> extends React.Component<KubeObjectMenuProps<T>> {
get store() { get store() {
const { object } = this.props; const { object } = this.props;
@ -52,23 +52,35 @@ export class KubeObjectMenu extends React.Component<KubeObjectMenuProps> {
@autobind() @autobind()
renderRemoveMessage() { renderRemoveMessage() {
const { object } = this.props; const { object } = this.props;
const resourceKind = object.kind;
const resourceName = object.getName(); if (!object) {
return null;
}
return ( return (
<p>Remove {resourceKind} <b>{resourceName}</b>?</p> <p>Remove {object.kind} <b>{object.getName()}</b>?</p>
); );
} }
getMenuItems(object: T): React.ReactChild[] {
if (!object) {
return [];
}
return kubeObjectMenuRegistry
.getItemsForKind(object.kind, object.apiVersion)
.map(({components: { MenuItem }}, index) => (
<MenuItem
object={object}
key={`menu-item-${index}`}
toolbar={toolbar}
/>
));
}
render() { render() {
const { remove, update, renderRemoveMessage, isEditable, isRemovable } = this; const { remove, update, renderRemoveMessage, isEditable, isRemovable } = this;
const { className, object, editable, removable, toolbar, ...menuProps } = this.props; const { className, object, editable, removable, ...menuProps } = this.props;
if (!object) return null;
const menuItems = kubeObjectMenuRegistry.getItemsForKind(object.kind, object.apiVersion).map((item, index) => {
return <item.components.MenuItem object={object} key={`menu-item-${index}`} toolbar={toolbar} />;
});
return ( return (
<MenuActions <MenuActions
@ -76,10 +88,9 @@ export class KubeObjectMenu extends React.Component<KubeObjectMenuProps> {
updateAction={isEditable ? update : undefined} updateAction={isEditable ? update : undefined}
removeAction={isRemovable ? remove : undefined} removeAction={isRemovable ? remove : undefined}
removeConfirmationMessage={renderRemoveMessage} removeConfirmationMessage={renderRemoveMessage}
toolbar={toolbar}
{...menuProps} {...menuProps}
> >
{menuItems} {this.getMenuItems(object)}
</MenuActions> </MenuActions>
); );
} }