Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support plugins #30

Merged
merged 6 commits into from
Dec 27, 2023
Merged

Support plugins #30

merged 6 commits into from
Dec 27, 2023

Conversation

tanbowensg
Copy link
Member

@tanbowensg tanbowensg commented Dec 21, 2023

改动

  1. 添加到 K8s 的部分资源的 Model。(移动到了 d2 中)
  2. 添加了 ModelPlugin。
  3. 添加了 Plugin 机制。
  4. 完善了 RelationPlugin。
  5. 添加了 Plugin 的单测。

review 建议

虽然代码新增很多,但大多数是mock数据和复制的代码。主要关注下面文件即可

  1. data-provider/index.ts
  2. model-plugin/model-plugin.ts
  3. model-plugin/model/pod-model.ts
  4. relation-plugin.ts
  5. global-store.ts
  6. kube-api.ts

Plugin 机制

Plugin作用是在用过 API 获取到数据后,对数据进行一些格式化。经过 Plugin 处理后的数据会进入到 GlobalStore 中缓存。

目前有两个Plugin,分别是ModelPlugin和RelationPlugin。

  • ModelPlugin:格式化 K8s 资源,产生资源对应的 Model。
  • RelationPlugin:给资源添加 metadata.relation 属性(暂时只支持Pod),以便找到关联的资源。

Plugin 的实现

Plugin的接口如下。主要需要实现processDataprocessItem。对于格式化后返回的类型,接口中定义的是 Unstructured & Output,也就是说无论返回什么类型,都要能够兼容 Unstructured

restoreItemrestoreData 可能相对不重要,因为可以通过 model 的 restore 方法直接获得原始数据(rawYaml),以后可能会移除。

export interface IProviderPlugin<Output = Unstructured> {
  _globalStore?: GlobalStore;
  init: (globalStore: GlobalStore) => void;
  processData: (
    res: UnstructuredList
  ) => Promise<DataList<Unstructured & Output>>;
  processItem: (item: Unstructured) => Promise<Unstructured & Output>;
  restoreData: (item: DataList<Unstructured & Output>) => UnstructuredList;
  restoreItem: (item: Unstructured & Output) => Unstructured;
}

Model

Model 是格式化后的 K8s 资源数据结构,用于 UI 展示。它会:

  • 格式化 K8s 资源的字段
  • 处理异步逻辑,比如多个资源的拼接

Model 的继承关系

按照K8s资源的数据结构,大概是这样的关系。

  • Resource(globalStore, label, annotation, name....)
    • ConfigMap
    • Secret
    • WorkloadBaseService(imageNames, containers, initContainers)
      • Pod
      • CronJob
      • Job
      • Workload(Deployment, DaemonSet, StatefulSet)
        • Deployment
        • DaemonSet
        • StatefulSet

Model 的实现

Model 有一些基本规则:

  • 把 k8s 资源本来就有的属性完全复制过来。也就是说,Model 应该是原本资源的超集。
  • Model 的属性是只读的。
  • Model 可以有一些方法,比如 scale 等。但这些方法不应该改变Model的属性,而是返回一个新的对象,而且是K8s资源原始的格式。
  • Model 可以有一个 init 的异步方法。Model plugin 会在 new 之后调用 init 方法。如果有的 Model 有异步的格式化逻辑,可以放在这里,比如Deployment需要查询它的Pod的restarts参数。

最基础的K8s资源长这样。

export class ResourceModel<T extends Unstructured = Unstructured> {
  public id!: string;
  public apiVersion!: T['apiVersion'];
  public kind!: T['kind'];
  public metadata!: T['metadata'];

  constructor(public _rawYaml: T, public _globalStore: GlobalStore) {
    this.id = genResourceId(_rawYaml);
    Object.keys(_rawYaml).forEach(key => {
      Object.defineProperty(this, key, {
        value: _rawYaml[key as keyof T],
        writable: true,
      });
    });
  }

  async init() {}

  get name() {
    return this._rawYaml.metadata?.name;
  }
  get namespace() {
    return this._rawYaml.metadata?.namespace;
  }
  get labels() {
    return this._rawYaml.metadata?.labels;
  }
  get annotations() {
    return this._rawYaml.metadata?.annotations;
  }

  restore() {
    return this._rawYaml;
  }
}

@tanbowensg tanbowensg changed the title Draft: Add model plugin Add model plugin Dec 22, 2023
src/plugins/model-plugin/model/resource-model.ts Outdated Show resolved Hide resolved
src/plugins/type.ts Outdated Show resolved Hide resolved
src/kube-api.ts Outdated Show resolved Hide resolved
export const ProviderPlugins = [
relationPlugin,
modelPlugin,
] as IProviderPlugin[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里需要 assert types 的原因是?

Copy link
Member Author

@tanbowensg tanbowensg Dec 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

因为这两个 Plugin 实际上返回的是两种类型,一个是带relation的Unstructured,另一个是 Model,所以这里要把它们as成一个比较抽象的 IProviderPlugin,也就是返回Unstructured的。在插件内可以定义具体的类型,在插件外应该假设插件返回的都是共通的Unstructured。

src/plugins/index.ts Outdated Show resolved Hide resolved
@tanbowensg
Copy link
Member Author

@Yuyz0112 @MrWindlike 已将 plugins 移动到 d2 中。这个 pr 只有 plugins 机制了。请再 review 一下

@tanbowensg tanbowensg changed the title Add model plugin Support plugins Dec 26, 2023
@Yuyz0112
Copy link
Member

LGTM

@Yuyz0112 Yuyz0112 merged commit c40943a into main Dec 27, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants