Example plugins

Copy-paste-able starting points. Drop into ~/Library/Application Support/com.buoy.app/plugins/ as .tsx files. Each example assumes /// <reference path="./buoy-sdk.d.ts" /> is in scope (the scaffold writes it).

ConfigMap data viewer

Shows entry count + a table of keys with byte counts.

export default (buoy: Buoy) => {
  buoy.meta({ name: "configmap-data", version: "0.1.0" });

  buoy.addDetailTab({
    match: { group: "", kind: "ConfigMap" },
    id: "data",
    label: "Data",
    render: ({ obj }) => {
      const entries = Object.entries(obj?.data ?? {});
      return (
        <>
          <KeyValue title="Summary">
            <Row label="Entries" value={entries.length} />
            <Row label="Binary" value={Object.keys(obj?.binaryData ?? {}).length} />
          </KeyValue>
          <Table
            rows={entries}
            columns={[
              { header: "KEY", cell: ([k]) => k },
              { header: "BYTES", cell: ([, v]) => (v as string).length },
            ]}
          />
        </>
      );
    },
  });
};

Argo Rollout: pause / resume action

Pauses or resumes a rollout via spec.paused. The when predicates make the two items mutually exclusive in the menu.

export default (buoy: Buoy) => {
  buoy.meta({ name: "rollout-pause" });

  buoy.addAction({
    match: { group: "argoproj.io", kind: "Rollout" },
    id: "pause",
    label: "Pause Rollout",
    when: (obj) => !obj.spec?.paused,
    confirm: { phrase: (obj) => obj.metadata.name },
    run: async (ctx) => {
      await ctx.mergePatch({ spec: { paused: true } });
    },
  });

  buoy.addAction({
    match: { group: "argoproj.io", kind: "Rollout" },
    id: "resume",
    label: "Resume Rollout",
    when: (obj) => obj.spec?.paused === true,
    confirm: { phrase: (obj) => obj.metadata.name },
    run: async (ctx) => {
      await ctx.mergePatch({ spec: { paused: false } });
    },
  });
};

Deployment: owner + peers + rollout history

A custom tab that combines useObject (the owning ReplicaSet) with useList (sibling Pods) and a small replica-set history table.

export default (buoy: Buoy) => {
  buoy.meta({ name: "deployment-overview" });

  buoy.addDetailTab({
    match: { group: "apps", kind: "Deployment" },
    id: "overview",
    label: "Overview+",
    render: ({ obj }) => {
      const peers = useList("pods", {
        labelSelector: obj.spec.selector?.matchLabels,
      });
      const replicaSets = useList("replicasets", {
        labelSelector: obj.spec.selector?.matchLabels,
      });
      const ready = peers.rows.filter((r) => {
        const ready = r.object.status?.containerStatuses ?? [];
        return ready.every((c: any) => c.ready);
      }).length;
      return (
        <>
          <KeyValue title="At a glance">
            <Row label="Image" value={obj.spec.template.spec.containers[0]?.image} mono />
            <Row label="Replicas" value={`${ready}/${obj.spec.replicas}`} />
            <Row label="Strategy" value={obj.spec.strategy?.type ?? "RollingUpdate"} />
          </KeyValue>
          <Table
            title="ReplicaSets"
            rows={replicaSets.rows}
            columns={[
              { header: "NAME", cell: (r) => (
                <CellValue
                  value={r.name}
                  link={{ kind: "ReplicaSet", resource: "replicasets", name: r.name, namespace: r.namespace }}
                />
              ) },
              { header: "DESIRED", cell: (r) => r.object.spec?.replicas ?? 0 },
              { header: "READY", cell: (r) => r.object.status?.readyReplicas ?? 0 },
            ]}
          />
        </>
      );
    },
  });
};

Tell Buoy that whenever you get rollouts, the STRATEGY and STEP columns from the apiserver Table response should always show (instead of being hidden as wide).

export default (buoy: Buoy) => {
  buoy.meta({ name: "rollout-columns" });

  buoy.addListColumns({
    match: { group: "argoproj.io", kind: "Rollout" },
    promotedWide: ["STRATEGY", "STEP"],
    defaults: [
      { kind: "label", key: "app.kubernetes.io/instance", header: "INSTANCE" },
    ],
  });
};

Edit this page on GitLab