cvtplugin

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 21, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package cvtplugin is the Go SDK for authoring CVT plugins.

A CVT plugin is a separate binary that implements one or more of the CVT plugin services (RegistryProvider, EventHandler) and communicates with `cvt` via hashicorp/go-plugin over a unix socket.

Minimal registry plugin:

package main

import (
	"context"
	"github.com/sahina/cvt/pkg/cvtplugin"
	registrypb "github.com/sahina/cvt/pkg/cvtplugin/pb/registry/v1"
)

type myRegistry struct{}

func (*myRegistry) FetchSchema(ctx context.Context, req *registrypb.FetchSchemaRequest) (*registrypb.FetchSchemaResponse, error) {
	// ... fetch from your registry ...
	return &registrypb.FetchSchemaResponse{Spec: specBytes}, nil
}

func (*myRegistry) RegisterConsumerUsage(ctx context.Context, req *registrypb.RegisterConsumerUsageRequest) (*registrypb.RegisterConsumerUsageResponse, error) {
	// ... idempotent upsert ...
	return &registrypb.RegisterConsumerUsageResponse{Acknowledged: true}, nil
}

func main() {
	cvtplugin.Serve(cvtplugin.PluginInfo{
		Name: "my-registry", Version: "0.1.0",
	}, cvtplugin.WithRegistryProvider(&myRegistry{}))
}

See docs/plugins/authoring-go.md for the full guide.

Index

Constants

View Source
const (
	ServiceRegistryV1 = "registry.v1"
	ServiceEventsV1   = "events.v1"
)

Service identifiers declared in PluginHandshake.Info.services.

View Source
const (
	PluginKeyHandshake = "handshake"
	PluginKeyRegistry  = "registry"
	PluginKeyEvents    = "events"
)

Plugin set keys. Core dispenses clients by these keys via Client.Dispense. Exported so core-side consumers (internal/pluginmgr) can use the same identifiers without redefining them.

View Source
const ProtocolVersion uint32 = 1

ProtocolVersion is the CVT plugin protocol version. Bumped on breaking changes to the plugin ABI. Core and plugin must agree.

Variables

View Source
var Handshake = plugin.HandshakeConfig{
	ProtocolVersion:  uint(ProtocolVersion),
	MagicCookieKey:   "CVT_PLUGIN_MAGIC_COOKIE",
	MagicCookieValue: "cvt-plugin-v1",
}

Handshake is the hashicorp/go-plugin handshake shared between CVT core and every CVT plugin. The magic cookie is a handshake-only check (NOT authentication); a mismatched cookie means the plugin binary was invoked directly by a user rather than launched by CVT, and the plugin exits with a helpful message.

Functions

func NewHCLogFromZap

func NewHCLogFromZap(z *zap.Logger, pluginName string) hclog.Logger

NewHCLogFromZap returns an hclog.Logger that forwards to a Zap logger. CVT core uses this to wire plugin log output (which arrives as hclog calls via hashicorp/go-plugin's native forwarding) into the project's existing Zap-based logger.

The returned logger's With/Named methods create sub-loggers that carry additional fields through to Zap.

func Serve

func Serve(info PluginInfo, opts ...Option)

Serve is the plugin author's entry point. Call from main():

func main() {
	cvtplugin.Serve(cvtplugin.PluginInfo{Name: "my-registry", Version: "0.1.0"},
		cvtplugin.WithRegistryProvider(&myRegistry{}))
}

Serve blocks until CVT core disconnects. It never returns; any return from plugin.Serve causes the go-plugin framework to exit the process.

Types

type ConfigReceiver

type ConfigReceiver interface {
	SetConfig(ctx context.Context, key, value string) error
}

ConfigReceiver is an optional interface a provider can implement to receive config values (including secrets) from core via SetConfig. Providers that don't need config can skip this interface.

type EventHandler

type EventHandler interface {
	OnBreakingChangeDetected(ctx context.Context, req *eventspb.BreakingChangeDetectedRequest) (*eventspb.EventResponse, error)
	OnValidationFailed(ctx context.Context, req *eventspb.ValidationFailedRequest) (*eventspb.EventResponse, error)
}

EventHandler is the Go interface plugin authors implement to receive CVT events (breaking-change detection, validation failure). Methods must be safe for concurrent use and should dedup/rate-limit on the plugin side since core fires every event.

Plugins that don't care about a particular event can return status.Error(codes.Unimplemented, "not handled"); core treats that as a no-op, not an error. Alternatively, embed UnimplementedEventHandler to opt out of specific events at compile time.

type Option

type Option func(*serveConfig)

Option configures a plugin Serve invocation.

func WithConfigReceiver

func WithConfigReceiver(r ConfigReceiver) Option

WithConfigReceiver registers an optional handler for SetConfig RPC calls. The receiver gets called once per config key after Info succeeds and before any extension-point RPC runs. Secret keys declared in plugins.<name>.secrets arrive here, not via os.Getenv.

func WithEventHandler

func WithEventHandler(h EventHandler) Option

WithEventHandler registers an EventHandler implementation.

func WithLogger

func WithLogger(l hclog.Logger) Option

WithLogger overrides the default hclog logger. The SDK's default writes JSON-structured logs to stderr, which hashicorp/go-plugin forwards to the CVT host's structured logger.

func WithRegistryProvider

func WithRegistryProvider(p RegistryProvider) Option

WithRegistryProvider registers a RegistryProvider implementation.

type PluginInfo

type PluginInfo struct {
	// Name is the plugin's self-reported name. Used in logs/audit as
	// reported_name; core does not trust it for identity.
	Name string

	// Version is the plugin's self-reported version. Logged as
	// reported_version; core uses install-time sha256 as trusted identity.
	Version string
}

PluginInfo is the static identity plugin authors provide to Serve. Values flow into the Info RPC response.

type RegistryProvider

type RegistryProvider interface {
	FetchSchema(ctx context.Context, req *registrypb.FetchSchemaRequest) (*registrypb.FetchSchemaResponse, error)
	RegisterConsumerUsage(ctx context.Context, req *registrypb.RegisterConsumerUsageRequest) (*registrypb.RegisterConsumerUsageResponse, error)
}

RegistryProvider is the Go interface plugin authors implement to provide a schema registry backend. Methods must be safe for concurrent use.

type UnimplementedEventHandler

type UnimplementedEventHandler = eventspb.UnimplementedEventHandlerServer

UnimplementedEventHandler can be embedded in a partial EventHandler implementation to opt out of events the plugin doesn't handle. Embedded methods return Unimplemented, which core treats as a no-op.

Directories

Path Synopsis
pb
Package plugintest provides an in-process test harness for CVT plugin authors.
Package plugintest provides an in-process test harness for CVT plugin authors.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL