velero icon indicating copy to clipboard operation
velero copied to clipboard

Enhanced Plugin Management — Design Proposal

Open abendrothj opened this issue 5 months ago • 2 comments

Status: Draft
Author: Jake Abendroth (abendrothj)
Related issue: https://github.com/vmware-tanzu/velero/issues/3210
Related implementation PR: https://github.com/vmware-tanzu/velero/pull/9352
Target release: v1.19 (note: v1.18 feature freeze is near)

Summary

This proposal improves Velero's CLI/plugin UX by clearly indicating which plugins are built into the Velero server binary and by allowing velero plugin remove <plugin-name> semantics that map user-facing plugin names (e.g., velero.io/aws) to init-container images/names. The changes are intentionally limited to CLI/API metadata and removal UX; they do not change plugin discovery or plugin runtime registration.

The implementation work is in vmware-tanzu/velero#9352 and this design PR is intended to let maintainers review the design independent of the implementation.

Motivation

  • Users see plugins via velero plugin get but cannot tell which plugins are built-in (and therefore cannot be removed).
  • velero plugin remove currently requires the init container name or image string; users expect to use plugin names shown in velero plugin get instead.
  • Provide clearer diagnostics and safer removal workflows.

Goals

  • Add plugin metadata indicating built-in status and registering command for diagnostics.
  • Display built-in status in CLI output.
  • Allow velero plugin remove <plugin-name> that resolves to an init container image/name and refuses removal of built-in plugins.
  • Preserve existing velero plugin remove <image|container> behavior for backwards compatibility.

Non-Goals

  • Changing plugin registration/discovery mechanisms.
  • Adding package/registry systems for plugins.
  • Major runtime or packaging redesign.

Proposed API changes

Modify the ServerStatusRequest API plugin information to carry additional optional fields:

File: pkg/apis/velero/v1/server_status_request_types.go

  • Add fields to PluginInfo:
type PluginInfo struct {
  Name    string `json:"name"`
  Kind    string `json:"kind"`
  // Command is the command/binary that registered the plugin on the server.
  // +optional
  Command string `json:"command,omitempty"`
  // BuiltIn indicates whether the plugin is provided by the Velero server
  // binary (i.e. a system plugin that cannot be removed by changing init containers).
  // +optional
  BuiltIn bool `json:"builtIn,omitempty"`
}

These fields are optional to preserve API compatibility with older clients.

Server-side behavior

File: internal/velero/serverstatusrequest.go

  • GetInstalledPluginInfo should set PluginInfo.Command (the registering process/binary) and PluginInfo.BuiltIn.
  • Heuristic for BuiltIn: plugin.Command == os.Args[0] OR another reliable indicator that the plugin was registered by the Velero server binary.

CLI output

File: pkg/cmd/util/output/plugin_printer.go

  • Add a "BuiltIn" column to the plugin table output. This gives operators a clear, at-a-glance indicator of mandatory built-in plugins vs external ones.

Plugin removal command

File: pkg/cmd/cli/plugin/remove.go

  • Accept plugin names (e.g., velero.io/aws) as input in addition to existing image/container names.

  • Workflow:

    1. Query server status (ServerStatusRequest) to check whether specified plugin name exists and whether it has BuiltIn==true. If built-in — refuse removal with a clear error message.
    2. If not built-in, resolve the plugin name to an init container via heuristics:
      • Exact init container name match.
      • Exact init container image match.
      • Sanitized plugin name match (e.g., convert velero.io/aws -> aws) to container name or image substring.
      • Substring match on init container image or name.
    3. If zero matches, error with a message listing the available init containers and their images.
    4. If multiple matches, error asking for disambiguation (or accept a --image/--container flag).
    5. If a single match, remove that init container as existing behavior does (patch the Velero Deployment).
  • Maintain backwards compatibility: velero plugin remove <image|container> remains valid.

Compatibility

  • API backward compatible: new PluginInfo fields are optional.
  • CLI backward compatible: existing usage of velero plugin remove <image|container> continues to work.
  • No changes required to existing Velero deployments.

Security considerations

  • Built-in protection prevents accidental removal of mandatory plugins that ship with the Velero server binary.
  • The ServerStatusRequest remains a read-only status resource; no elevated privileges are introduced by these read-only fields.
  • Removal still requires permissions to patch the Velero Deployment (existing requirement).

Tests

  • Unit tests: server-side population of PluginInfo fields; printer output; remove command heuristics and error cases.
  • Integration tests: velero plugin get shows BuiltIn flags; velero plugin remove <plugin-name> resolves correctly and patches Deployment; refusing removal for BuiltIn plugins.

Implementation references

  • Implementation PR: https://github.com/vmware-tanzu/velero/pull/9352
  • Related issue: https://github.com/vmware-tanzu/velero/issues/3210
  • Files touched (main-branch locations):
    • pkg/apis/velero/v1/server_status_request_types.go
    • internal/velero/serverstatusrequest.go
    • pkg/cmd/util/output/plugin_printer.go
    • pkg/cmd/cli/plugin/remove.go

abendrothj avatar Oct 27 '25 06:10 abendrothj

might want to rebase. design proposal shouldn't contain .go changes.

kaovilai avatar Oct 27 '25 19:10 kaovilai

We can keep code changes in for now and once design is agreed and if implementation still need enhancement after that we can move implementation out to a follow up pr.

kaovilai avatar Oct 27 '25 19:10 kaovilai