Documentation
¶
Index ¶
- Constants
- Variables
- func RegisterGeneratorAPIServer(s grpc.ServiceRegistrar, srv GeneratorAPIServer)
- func RegisterGeneratorAPITools(server *mcp.Server, impl GeneratorAPIToolHandler, ...) error
- type CreatePluginRequest
- func (*CreatePluginRequest) Descriptor() ([]byte, []int)deprecated
- func (x *CreatePluginRequest) GetConfig() *structpb.Struct
- func (x *CreatePluginRequest) GetGroup() string
- func (x *CreatePluginRequest) GetName() string
- func (x *CreatePluginRequest) GetTags() []string
- func (x *CreatePluginRequest) GetVersion() string
- func (*CreatePluginRequest) ProtoMessage()
- func (x *CreatePluginRequest) ProtoReflect() protoreflect.Message
- func (x *CreatePluginRequest) Reset()
- func (x *CreatePluginRequest) String() string
- type CreatePluginResponse
- func (*CreatePluginResponse) Descriptor() ([]byte, []int)deprecated
- func (x *CreatePluginResponse) GetPlugin() *PluginInfo
- func (*CreatePluginResponse) ProtoMessage()
- func (x *CreatePluginResponse) ProtoReflect() protoreflect.Message
- func (x *CreatePluginResponse) Reset()
- func (x *CreatePluginResponse) String() string
- type DeletePluginRequest
- func (*DeletePluginRequest) Descriptor() ([]byte, []int)deprecated
- func (x *DeletePluginRequest) GetGroup() string
- func (x *DeletePluginRequest) GetName() string
- func (x *DeletePluginRequest) GetVersion() string
- func (*DeletePluginRequest) ProtoMessage()
- func (x *DeletePluginRequest) ProtoReflect() protoreflect.Message
- func (x *DeletePluginRequest) Reset()
- func (x *DeletePluginRequest) String() string
- type DeletePluginResponse
- type GenerateCodeRequest
- func (*GenerateCodeRequest) Descriptor() ([]byte, []int)deprecated
- func (x *GenerateCodeRequest) GetCodeGeneratorRequest() *pluginpb.CodeGeneratorRequest
- func (x *GenerateCodeRequest) GetPluginName() string
- func (*GenerateCodeRequest) ProtoMessage()
- func (x *GenerateCodeRequest) ProtoReflect() protoreflect.Message
- func (x *GenerateCodeRequest) Reset()
- func (x *GenerateCodeRequest) String() string
- type GenerateCodeResponse
- func (*GenerateCodeResponse) Descriptor() ([]byte, []int)deprecated
- func (x *GenerateCodeResponse) GetCodeGeneratorResponse() *pluginpb.CodeGeneratorResponse
- func (*GenerateCodeResponse) ProtoMessage()
- func (x *GenerateCodeResponse) ProtoReflect() protoreflect.Message
- func (x *GenerateCodeResponse) Reset()
- func (x *GenerateCodeResponse) String() string
- type GeneratorAPIClient
- type GeneratorAPIServer
- type GeneratorAPIToolHandler
- type PluginInfo
- func (*PluginInfo) Descriptor() ([]byte, []int)deprecated
- func (x *PluginInfo) GetCreatedAt() *timestamppb.Timestamp
- func (x *PluginInfo) GetGroup() string
- func (x *PluginInfo) GetId() string
- func (x *PluginInfo) GetName() string
- func (x *PluginInfo) GetTags() []string
- func (x *PluginInfo) GetVersion() string
- func (*PluginInfo) ProtoMessage()
- func (x *PluginInfo) ProtoReflect() protoreflect.Message
- func (x *PluginInfo) Reset()
- func (x *PluginInfo) String() string
- type PluginsRequest
- func (*PluginsRequest) Descriptor() ([]byte, []int)deprecated
- func (x *PluginsRequest) GetGroup() string
- func (x *PluginsRequest) GetName() string
- func (x *PluginsRequest) GetPageSize() uint32
- func (x *PluginsRequest) GetPageToken() string
- func (x *PluginsRequest) GetTags() []string
- func (x *PluginsRequest) GetVersion() string
- func (*PluginsRequest) ProtoMessage()
- func (x *PluginsRequest) ProtoReflect() protoreflect.Message
- func (x *PluginsRequest) Reset()
- func (x *PluginsRequest) String() string
- type PluginsResponse
- func (*PluginsResponse) Descriptor() ([]byte, []int)deprecated
- func (x *PluginsResponse) GetNextPageToken() string
- func (x *PluginsResponse) GetPlugins() []*PluginInfo
- func (*PluginsResponse) ProtoMessage()
- func (x *PluginsResponse) ProtoReflect() protoreflect.Message
- func (x *PluginsResponse) Reset()
- func (x *PluginsResponse) String() string
- type UnimplementedGeneratorAPIServer
- func (UnimplementedGeneratorAPIServer) CreatePlugin(context.Context, *CreatePluginRequest) (*CreatePluginResponse, error)
- func (UnimplementedGeneratorAPIServer) DeletePlugin(context.Context, *DeletePluginRequest) (*DeletePluginResponse, error)
- func (UnimplementedGeneratorAPIServer) GenerateCode(context.Context, *GenerateCodeRequest) (*GenerateCodeResponse, error)
- func (UnimplementedGeneratorAPIServer) Plugins(context.Context, *PluginsRequest) (*PluginsResponse, error)
- func (UnimplementedGeneratorAPIServer) UpdatePlugin(context.Context, *UpdatePluginRequest) (*UpdatePluginResponse, error)
- type UnsafeGeneratorAPIServer
- type UpdatePluginRequest
- func (*UpdatePluginRequest) Descriptor() ([]byte, []int)deprecated
- func (x *UpdatePluginRequest) GetConfig() *structpb.Struct
- func (x *UpdatePluginRequest) GetGroup() string
- func (x *UpdatePluginRequest) GetName() string
- func (x *UpdatePluginRequest) GetTags() []string
- func (x *UpdatePluginRequest) GetUpdateMask() *fieldmaskpb.FieldMask
- func (x *UpdatePluginRequest) GetVersion() string
- func (*UpdatePluginRequest) ProtoMessage()
- func (x *UpdatePluginRequest) ProtoReflect() protoreflect.Message
- func (x *UpdatePluginRequest) Reset()
- func (x *UpdatePluginRequest) String() string
- type UpdatePluginResponse
- func (*UpdatePluginResponse) Descriptor() ([]byte, []int)deprecated
- func (x *UpdatePluginResponse) GetPlugin() *PluginInfo
- func (*UpdatePluginResponse) ProtoMessage()
- func (x *UpdatePluginResponse) ProtoReflect() protoreflect.Message
- func (x *UpdatePluginResponse) Reset()
- func (x *UpdatePluginResponse) String() string
Constants ¶
const ( GeneratorAPI_GenerateCode_FullMethodName = "/easyp.generator.v1.GeneratorAPI/GenerateCode" GeneratorAPI_Plugins_FullMethodName = "/easyp.generator.v1.GeneratorAPI/Plugins" GeneratorAPI_CreatePlugin_FullMethodName = "/easyp.generator.v1.GeneratorAPI/CreatePlugin" GeneratorAPI_UpdatePlugin_FullMethodName = "/easyp.generator.v1.GeneratorAPI/UpdatePlugin" GeneratorAPI_DeletePlugin_FullMethodName = "/easyp.generator.v1.GeneratorAPI/DeletePlugin" )
const GeneratorAPI_Plugins_ToolSpecInputSchemaJSON = "" /* 695-byte string literal not displayed */
const GeneratorAPI_Plugins_ToolSpecOutputSchemaJSON = "" /* 1372-byte string literal not displayed */
Variables ¶
var File_easyp_generator_v1_generator_proto protoreflect.FileDescriptor
var GeneratorAPI_ServiceDesc = grpc.ServiceDesc{ ServiceName: "easyp.generator.v1.GeneratorAPI", HandlerType: (*GeneratorAPIServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GenerateCode", Handler: _GeneratorAPI_GenerateCode_Handler, }, { MethodName: "Plugins", Handler: _GeneratorAPI_Plugins_Handler, }, { MethodName: "CreatePlugin", Handler: _GeneratorAPI_CreatePlugin_Handler, }, { MethodName: "UpdatePlugin", Handler: _GeneratorAPI_UpdatePlugin_Handler, }, { MethodName: "DeletePlugin", Handler: _GeneratorAPI_DeletePlugin_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "easyp/generator/v1/generator.proto", }
GeneratorAPI_ServiceDesc is the grpc.ServiceDesc for GeneratorAPI service. It's only intended for direct use with grpc.RegisterService, and not to be introspected or modified (even as a copy)
Functions ¶
func RegisterGeneratorAPIServer ¶
func RegisterGeneratorAPIServer(s grpc.ServiceRegistrar, srv GeneratorAPIServer)
func RegisterGeneratorAPITools ¶
func RegisterGeneratorAPITools(server *mcp.Server, impl GeneratorAPIToolHandler, opts ...mcpruntime.RegisterOption) error
RegisterGeneratorAPITools registers generated MCP tools for GeneratorAPI.
Types ¶
type CreatePluginRequest ¶
type CreatePluginRequest struct {
// Group to which the plugin belongs.
Group string `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"`
// Name of the plugin.
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
// Version of the plugin.
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
// Optional plugin configuration.
Config *structpb.Struct `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"`
// Tags for the plugin.
Tags []string `protobuf:"bytes,5,rep,name=tags,proto3" json:"tags,omitempty"`
// contains filtered or unexported fields
}
Request message for creating a plugin.
func (*CreatePluginRequest) Descriptor
deprecated
func (*CreatePluginRequest) Descriptor() ([]byte, []int)
Deprecated: Use CreatePluginRequest.ProtoReflect.Descriptor instead.
func (*CreatePluginRequest) GetConfig ¶
func (x *CreatePluginRequest) GetConfig() *structpb.Struct
func (*CreatePluginRequest) GetGroup ¶
func (x *CreatePluginRequest) GetGroup() string
func (*CreatePluginRequest) GetName ¶
func (x *CreatePluginRequest) GetName() string
func (*CreatePluginRequest) GetTags ¶
func (x *CreatePluginRequest) GetTags() []string
func (*CreatePluginRequest) GetVersion ¶
func (x *CreatePluginRequest) GetVersion() string
func (*CreatePluginRequest) ProtoMessage ¶
func (*CreatePluginRequest) ProtoMessage()
func (*CreatePluginRequest) ProtoReflect ¶
func (x *CreatePluginRequest) ProtoReflect() protoreflect.Message
func (*CreatePluginRequest) Reset ¶
func (x *CreatePluginRequest) Reset()
func (*CreatePluginRequest) String ¶
func (x *CreatePluginRequest) String() string
type CreatePluginResponse ¶
type CreatePluginResponse struct {
// The created plugin information.
Plugin *PluginInfo `protobuf:"bytes,1,opt,name=plugin,proto3" json:"plugin,omitempty"`
// contains filtered or unexported fields
}
Response message for creating a plugin.
func (*CreatePluginResponse) Descriptor
deprecated
func (*CreatePluginResponse) Descriptor() ([]byte, []int)
Deprecated: Use CreatePluginResponse.ProtoReflect.Descriptor instead.
func (*CreatePluginResponse) GetPlugin ¶
func (x *CreatePluginResponse) GetPlugin() *PluginInfo
func (*CreatePluginResponse) ProtoMessage ¶
func (*CreatePluginResponse) ProtoMessage()
func (*CreatePluginResponse) ProtoReflect ¶
func (x *CreatePluginResponse) ProtoReflect() protoreflect.Message
func (*CreatePluginResponse) Reset ¶
func (x *CreatePluginResponse) Reset()
func (*CreatePluginResponse) String ¶
func (x *CreatePluginResponse) String() string
type DeletePluginRequest ¶
type DeletePluginRequest struct {
// Group to which the plugin belongs.
Group string `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"`
// Name of the plugin.
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
// Version of the plugin.
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
// contains filtered or unexported fields
}
Request message for deleting a plugin.
func (*DeletePluginRequest) Descriptor
deprecated
func (*DeletePluginRequest) Descriptor() ([]byte, []int)
Deprecated: Use DeletePluginRequest.ProtoReflect.Descriptor instead.
func (*DeletePluginRequest) GetGroup ¶
func (x *DeletePluginRequest) GetGroup() string
func (*DeletePluginRequest) GetName ¶
func (x *DeletePluginRequest) GetName() string
func (*DeletePluginRequest) GetVersion ¶
func (x *DeletePluginRequest) GetVersion() string
func (*DeletePluginRequest) ProtoMessage ¶
func (*DeletePluginRequest) ProtoMessage()
func (*DeletePluginRequest) ProtoReflect ¶
func (x *DeletePluginRequest) ProtoReflect() protoreflect.Message
func (*DeletePluginRequest) Reset ¶
func (x *DeletePluginRequest) Reset()
func (*DeletePluginRequest) String ¶
func (x *DeletePluginRequest) String() string
type DeletePluginResponse ¶
type DeletePluginResponse struct {
// contains filtered or unexported fields
}
Response message for deleting a plugin.
func (*DeletePluginResponse) Descriptor
deprecated
func (*DeletePluginResponse) Descriptor() ([]byte, []int)
Deprecated: Use DeletePluginResponse.ProtoReflect.Descriptor instead.
func (*DeletePluginResponse) ProtoMessage ¶
func (*DeletePluginResponse) ProtoMessage()
func (*DeletePluginResponse) ProtoReflect ¶
func (x *DeletePluginResponse) ProtoReflect() protoreflect.Message
func (*DeletePluginResponse) Reset ¶
func (x *DeletePluginResponse) Reset()
func (*DeletePluginResponse) String ¶
func (x *DeletePluginResponse) String() string
type GenerateCodeRequest ¶
type GenerateCodeRequest struct {
// Standard protobuf code generator request.
//
// This should contain the proto files to process and any plugin-specific parameters.
// The request is passed directly to the plugin's stdin.
CodeGeneratorRequest *pluginpb.CodeGeneratorRequest `protobuf:"bytes,1,opt,name=code_generator_request,json=codeGeneratorRequest,proto3" json:"code_generator_request,omitempty"`
// Name of the plugin to use for generation.
//
// Format: `<group>/<name>:<version>`
//
// Examples:
// - `protocolbuffers/go:v1.36.10`
// - `grpc/go:v1.5.1`
// - `grpc-ecosystem/gateway:latest`
PluginName string `protobuf:"bytes,2,opt,name=plugin_name,json=pluginName,proto3" json:"plugin_name,omitempty"`
// contains filtered or unexported fields
}
Request message for code generation.
func (*GenerateCodeRequest) Descriptor
deprecated
func (*GenerateCodeRequest) Descriptor() ([]byte, []int)
Deprecated: Use GenerateCodeRequest.ProtoReflect.Descriptor instead.
func (*GenerateCodeRequest) GetCodeGeneratorRequest ¶
func (x *GenerateCodeRequest) GetCodeGeneratorRequest() *pluginpb.CodeGeneratorRequest
func (*GenerateCodeRequest) GetPluginName ¶
func (x *GenerateCodeRequest) GetPluginName() string
func (*GenerateCodeRequest) ProtoMessage ¶
func (*GenerateCodeRequest) ProtoMessage()
func (*GenerateCodeRequest) ProtoReflect ¶
func (x *GenerateCodeRequest) ProtoReflect() protoreflect.Message
func (*GenerateCodeRequest) Reset ¶
func (x *GenerateCodeRequest) Reset()
func (*GenerateCodeRequest) String ¶
func (x *GenerateCodeRequest) String() string
type GenerateCodeResponse ¶
type GenerateCodeResponse struct {
// Standard protobuf code generator response.
//
// Contains the generated files and any error messages from the plugin.
// Check the `error` field in the response for plugin-level errors.
CodeGeneratorResponse *pluginpb.CodeGeneratorResponse `` /* 126-byte string literal not displayed */
// contains filtered or unexported fields
}
Response message for code generation.
func (*GenerateCodeResponse) Descriptor
deprecated
func (*GenerateCodeResponse) Descriptor() ([]byte, []int)
Deprecated: Use GenerateCodeResponse.ProtoReflect.Descriptor instead.
func (*GenerateCodeResponse) GetCodeGeneratorResponse ¶
func (x *GenerateCodeResponse) GetCodeGeneratorResponse() *pluginpb.CodeGeneratorResponse
func (*GenerateCodeResponse) ProtoMessage ¶
func (*GenerateCodeResponse) ProtoMessage()
func (*GenerateCodeResponse) ProtoReflect ¶
func (x *GenerateCodeResponse) ProtoReflect() protoreflect.Message
func (*GenerateCodeResponse) Reset ¶
func (x *GenerateCodeResponse) Reset()
func (*GenerateCodeResponse) String ¶
func (x *GenerateCodeResponse) String() string
type GeneratorAPIClient ¶
type GeneratorAPIClient interface {
// Generate code using a specified plugin.
//
// This method executes a protobuf code generation plugin and returns the generated files.
// The plugin runs as a local child process under the limits described on the
// service above — notably a time bound and an output-size bound, and notably
// *not* a memory, CPU or network bound.
//
// This method is anonymous: it requires no credentials. Only the mutating
// methods take a write token.
//
// ## Error Codes
//
// | Code | Description |
// |------|-------------|
// | `NOT_FOUND` | Plugin not found in registry |
// | `INVALID_ARGUMENT` | Invalid plugin name format |
// | `RESOURCE_EXHAUSTED` | The service is at its concurrency limit; retry later |
// | `UNAVAILABLE` | Object storage is unreachable, or the service is shutting down |
// | `FAILED_PRECONDITION` | The plugin is registered but its archive is not in storage |
// | `INTERNAL` | Plugin execution failed |
// | `DEADLINE_EXCEEDED` | Plugin execution timeout |
GenerateCode(ctx context.Context, in *GenerateCodeRequest, opts ...grpc.CallOption) (*GenerateCodeResponse, error)
// List available plugins.
//
// Returns a list of all plugins registered in the service.
// Use this to discover available plugins and their versions.
Plugins(ctx context.Context, in *PluginsRequest, opts ...grpc.CallOption) (*PluginsResponse, error)
// Create a new plugin registration.
//
// Registers a plugin with the given group, name, version, optional config, and tags.
// Requires an Enterprise license.
//
// ## Error Codes
//
// | Code | Description |
// |------|-------------|
// | `ALREADY_EXISTS` | Plugin with same group/name/version exists |
// | `INVALID_ARGUMENT` | Invalid plugin name format |
// | `RESOURCE_EXHAUSTED` | Max plugins limit reached |
// | `PERMISSION_DENIED` | Enterprise license required |
CreatePlugin(ctx context.Context, in *CreatePluginRequest, opts ...grpc.CallOption) (*CreatePluginResponse, error)
// Update an existing plugin.
//
// Replaces the config and tags of an existing plugin identified by group/name/version.
// Requires an Enterprise license.
//
// ## Error Codes
//
// | Code | Description |
// |------|-------------|
// | `NOT_FOUND` | Plugin not found |
// | `INVALID_ARGUMENT` | Invalid plugin name format |
// | `PERMISSION_DENIED` | Enterprise license required |
UpdatePlugin(ctx context.Context, in *UpdatePluginRequest, opts ...grpc.CallOption) (*UpdatePluginResponse, error)
// Delete a plugin.
//
// Removes a plugin from the registry by group/name/version.
// Requires an Enterprise license.
//
// ## Error Codes
//
// | Code | Description |
// |------|-------------|
// | `NOT_FOUND` | Plugin not found |
// | `PERMISSION_DENIED` | Enterprise license required |
DeletePlugin(ctx context.Context, in *DeletePluginRequest, opts ...grpc.CallOption) (*DeletePluginResponse, error)
}
GeneratorAPIClient is the client API for GeneratorAPI service.
For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
EasyP Code Generation Service ¶
This service provides a centralized API for executing protobuf/gRPC code generation plugins. Plugins are executed by the service, so every caller uses the same plugin version.
## Benefits
- **Version Control**: All developers use the same plugin versions - **Zero Setup**: No local plugin installation required - **Auditability**: Centralized logging of all generation requests
## How plugins are executed
A plugin is a binary the service runs as a local child process. It is not a container. Stated plainly because this file said the opposite until v0.14.0, and a customer's security review is the wrong place to discover it.
What the service does constrain:
- **Environment**: the child gets only the variables in the plugin's own config — the service's environment, including its database and object storage credentials, is not inherited
- **Process group**: each plugin runs in its own group, so a timeout kills the whole tree rather than leaving orphans
- **Time**: bounded by `worker_pool.generation_timeout` (120s by default)
- **Concurrency**: bounded by `worker_pool.max_concurrent_generations`
- **Output size**: bounded by `registry.max_output_size`
- **Executable**: must live inside the configured plugins directory
What it does **not** constrain: memory, CPU, filesystem access beyond the service account's own, and **network access** — a plugin can reach anything the service's pod can reach. Registering a plugin is therefore as privileged as running code on the host, and the write token that authorises it should be treated accordingly.
## Quick Start
1. Call `Plugins` to list available plugins 2. Build a `CodeGeneratorRequest` with your proto files 3. Call `GenerateCode` with the plugin name and request 4. Process the `CodeGeneratorResponse` with generated files
## Plugin Naming Convention
Plugins are identified using the format: `<group>/<name>:<version>`
Examples: - `protocolbuffers/go:v1.36.10` — Official Go protobuf plugin - `grpc/go:v1.5.1` — Official gRPC Go plugin - `grpc-ecosystem/gateway:v2.27.3` — gRPC-Gateway plugin
Use `latest` as version to get the most recent version: - `protocolbuffers/go:latest`
func NewGeneratorAPIClient ¶
func NewGeneratorAPIClient(cc grpc.ClientConnInterface) GeneratorAPIClient
type GeneratorAPIServer ¶
type GeneratorAPIServer interface {
// Generate code using a specified plugin.
//
// This method executes a protobuf code generation plugin and returns the generated files.
// The plugin runs as a local child process under the limits described on the
// service above — notably a time bound and an output-size bound, and notably
// *not* a memory, CPU or network bound.
//
// This method is anonymous: it requires no credentials. Only the mutating
// methods take a write token.
//
// ## Error Codes
//
// | Code | Description |
// |------|-------------|
// | `NOT_FOUND` | Plugin not found in registry |
// | `INVALID_ARGUMENT` | Invalid plugin name format |
// | `RESOURCE_EXHAUSTED` | The service is at its concurrency limit; retry later |
// | `UNAVAILABLE` | Object storage is unreachable, or the service is shutting down |
// | `FAILED_PRECONDITION` | The plugin is registered but its archive is not in storage |
// | `INTERNAL` | Plugin execution failed |
// | `DEADLINE_EXCEEDED` | Plugin execution timeout |
GenerateCode(context.Context, *GenerateCodeRequest) (*GenerateCodeResponse, error)
// List available plugins.
//
// Returns a list of all plugins registered in the service.
// Use this to discover available plugins and their versions.
Plugins(context.Context, *PluginsRequest) (*PluginsResponse, error)
// Create a new plugin registration.
//
// Registers a plugin with the given group, name, version, optional config, and tags.
// Requires an Enterprise license.
//
// ## Error Codes
//
// | Code | Description |
// |------|-------------|
// | `ALREADY_EXISTS` | Plugin with same group/name/version exists |
// | `INVALID_ARGUMENT` | Invalid plugin name format |
// | `RESOURCE_EXHAUSTED` | Max plugins limit reached |
// | `PERMISSION_DENIED` | Enterprise license required |
CreatePlugin(context.Context, *CreatePluginRequest) (*CreatePluginResponse, error)
// Update an existing plugin.
//
// Replaces the config and tags of an existing plugin identified by group/name/version.
// Requires an Enterprise license.
//
// ## Error Codes
//
// | Code | Description |
// |------|-------------|
// | `NOT_FOUND` | Plugin not found |
// | `INVALID_ARGUMENT` | Invalid plugin name format |
// | `PERMISSION_DENIED` | Enterprise license required |
UpdatePlugin(context.Context, *UpdatePluginRequest) (*UpdatePluginResponse, error)
// Delete a plugin.
//
// Removes a plugin from the registry by group/name/version.
// Requires an Enterprise license.
//
// ## Error Codes
//
// | Code | Description |
// |------|-------------|
// | `NOT_FOUND` | Plugin not found |
// | `PERMISSION_DENIED` | Enterprise license required |
DeletePlugin(context.Context, *DeletePluginRequest) (*DeletePluginResponse, error)
}
GeneratorAPIServer is the server API for GeneratorAPI service. All implementations should embed UnimplementedGeneratorAPIServer for forward compatibility.
EasyP Code Generation Service ¶
This service provides a centralized API for executing protobuf/gRPC code generation plugins. Plugins are executed by the service, so every caller uses the same plugin version.
## Benefits
- **Version Control**: All developers use the same plugin versions - **Zero Setup**: No local plugin installation required - **Auditability**: Centralized logging of all generation requests
## How plugins are executed
A plugin is a binary the service runs as a local child process. It is not a container. Stated plainly because this file said the opposite until v0.14.0, and a customer's security review is the wrong place to discover it.
What the service does constrain:
- **Environment**: the child gets only the variables in the plugin's own config — the service's environment, including its database and object storage credentials, is not inherited
- **Process group**: each plugin runs in its own group, so a timeout kills the whole tree rather than leaving orphans
- **Time**: bounded by `worker_pool.generation_timeout` (120s by default)
- **Concurrency**: bounded by `worker_pool.max_concurrent_generations`
- **Output size**: bounded by `registry.max_output_size`
- **Executable**: must live inside the configured plugins directory
What it does **not** constrain: memory, CPU, filesystem access beyond the service account's own, and **network access** — a plugin can reach anything the service's pod can reach. Registering a plugin is therefore as privileged as running code on the host, and the write token that authorises it should be treated accordingly.
## Quick Start
1. Call `Plugins` to list available plugins 2. Build a `CodeGeneratorRequest` with your proto files 3. Call `GenerateCode` with the plugin name and request 4. Process the `CodeGeneratorResponse` with generated files
## Plugin Naming Convention
Plugins are identified using the format: `<group>/<name>:<version>`
Examples: - `protocolbuffers/go:v1.36.10` — Official Go protobuf plugin - `grpc/go:v1.5.1` — Official gRPC Go plugin - `grpc-ecosystem/gateway:v2.27.3` — gRPC-Gateway plugin
Use `latest` as version to get the most recent version: - `protocolbuffers/go:latest`
type GeneratorAPIToolHandler ¶
type GeneratorAPIToolHandler interface {
Plugins(ctx context.Context, req *PluginsRequest) (*PluginsResponse, error)
}
GeneratorAPIToolHandler defines the business logic required by generated MCP tools.
type PluginInfo ¶
type PluginInfo struct {
// Unique identifier for the plugin.
//
// This is an internal UUID assigned when the plugin is registered.
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// Group to which the plugin belongs.
//
// Groups organize plugins by maintainer or ecosystem.
//
// Common groups:
// - `protocolbuffers` — Official Google protobuf plugins
// - `grpc` — Official gRPC plugins
// - `grpc-ecosystem` — gRPC ecosystem plugins (gateway, openapi)
// - `community` — Community-maintained plugins
Group string `protobuf:"bytes,2,opt,name=group,proto3" json:"group,omitempty"`
// Name of the plugin.
//
// This is the plugin's identifier within its group.
//
// Examples: `go`, `python`, `gateway`, `openapiv2`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
// Version of the plugin.
//
// Follows semantic versioning (semver) format.
Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
// Timestamp when the plugin was registered.
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,proto3" json:"created_at,omitempty"`
// Tags associated with the plugin for categorization.
//
// Tags help organize and filter plugins by category.
// Examples: `go`, `grpc`, `official`, `community`
Tags []string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty"`
// contains filtered or unexported fields
}
Information about a registered plugin.
func (*PluginInfo) Descriptor
deprecated
func (*PluginInfo) Descriptor() ([]byte, []int)
Deprecated: Use PluginInfo.ProtoReflect.Descriptor instead.
func (*PluginInfo) GetCreatedAt ¶
func (x *PluginInfo) GetCreatedAt() *timestamppb.Timestamp
func (*PluginInfo) GetGroup ¶
func (x *PluginInfo) GetGroup() string
func (*PluginInfo) GetId ¶
func (x *PluginInfo) GetId() string
func (*PluginInfo) GetName ¶
func (x *PluginInfo) GetName() string
func (*PluginInfo) GetTags ¶
func (x *PluginInfo) GetTags() []string
func (*PluginInfo) GetVersion ¶
func (x *PluginInfo) GetVersion() string
func (*PluginInfo) ProtoMessage ¶
func (*PluginInfo) ProtoMessage()
func (*PluginInfo) ProtoReflect ¶
func (x *PluginInfo) ProtoReflect() protoreflect.Message
func (*PluginInfo) Reset ¶
func (x *PluginInfo) Reset()
func (*PluginInfo) String ¶
func (x *PluginInfo) String() string
type PluginsRequest ¶
type PluginsRequest struct {
// Filter by exact plugin group.
//
// Omit to return plugins from all groups.
Group *string `protobuf:"bytes,1,opt,name=group,proto3,oneof" json:"group,omitempty"`
// Filter by exact plugin name.
//
// Omit to return plugins with any name.
Name *string `protobuf:"bytes,2,opt,name=name,proto3,oneof" json:"name,omitempty"`
// Filter by exact plugin version.
//
// Omit to return all versions.
Version *string `protobuf:"bytes,3,opt,name=version,proto3,oneof" json:"version,omitempty"`
// Filter by tags.
//
// A plugin must contain all specified tags to match.
Tags []string `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"`
// Maximum number of plugins to return in one response.
//
// Omitting it (or zero) selects the server's default page size (100).
// Values above the server's ceiling (1000) are cut down to it rather than
// rejected.
PageSize *uint32 `protobuf:"varint,5,opt,name=page_size,json=pageSize,proto3,oneof" json:"page_size,omitempty"`
// Continuation token from a previous response's next_page_token.
//
// Omit to read the first page. The token is opaque: it is only meaningful
// to the server that issued it, and only together with the same filters —
// changing the filters between pages makes the result undefined.
PageToken *string `protobuf:"bytes,6,opt,name=page_token,json=pageToken,proto3,oneof" json:"page_token,omitempty"`
// contains filtered or unexported fields
}
Request message for listing plugins.
func (*PluginsRequest) Descriptor
deprecated
func (*PluginsRequest) Descriptor() ([]byte, []int)
Deprecated: Use PluginsRequest.ProtoReflect.Descriptor instead.
func (*PluginsRequest) GetGroup ¶
func (x *PluginsRequest) GetGroup() string
func (*PluginsRequest) GetName ¶
func (x *PluginsRequest) GetName() string
func (*PluginsRequest) GetPageSize ¶
func (x *PluginsRequest) GetPageSize() uint32
func (*PluginsRequest) GetPageToken ¶
func (x *PluginsRequest) GetPageToken() string
func (*PluginsRequest) GetTags ¶
func (x *PluginsRequest) GetTags() []string
func (*PluginsRequest) GetVersion ¶
func (x *PluginsRequest) GetVersion() string
func (*PluginsRequest) ProtoMessage ¶
func (*PluginsRequest) ProtoMessage()
func (*PluginsRequest) ProtoReflect ¶
func (x *PluginsRequest) ProtoReflect() protoreflect.Message
func (*PluginsRequest) Reset ¶
func (x *PluginsRequest) Reset()
func (*PluginsRequest) String ¶
func (x *PluginsRequest) String() string
type PluginsResponse ¶
type PluginsResponse struct {
// List of available plugins matching the supplied filters.
//
// Plugins are sorted by group, name, and version.
Plugins []*PluginInfo `protobuf:"bytes,1,rep,name=plugins,proto3" json:"plugins,omitempty"`
// Token for the next page, empty when this response is the last page.
//
// Pass it back in PluginsRequest.page_token, with the same filters, to
// continue the listing.
NextPageToken string `protobuf:"bytes,3,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"`
// contains filtered or unexported fields
}
Response message for listing plugins.
func (*PluginsResponse) Descriptor
deprecated
func (*PluginsResponse) Descriptor() ([]byte, []int)
Deprecated: Use PluginsResponse.ProtoReflect.Descriptor instead.
func (*PluginsResponse) GetNextPageToken ¶
func (x *PluginsResponse) GetNextPageToken() string
func (*PluginsResponse) GetPlugins ¶
func (x *PluginsResponse) GetPlugins() []*PluginInfo
func (*PluginsResponse) ProtoMessage ¶
func (*PluginsResponse) ProtoMessage()
func (*PluginsResponse) ProtoReflect ¶
func (x *PluginsResponse) ProtoReflect() protoreflect.Message
func (*PluginsResponse) Reset ¶
func (x *PluginsResponse) Reset()
func (*PluginsResponse) String ¶
func (x *PluginsResponse) String() string
type UnimplementedGeneratorAPIServer ¶
type UnimplementedGeneratorAPIServer struct{}
UnimplementedGeneratorAPIServer should be embedded to have forward compatible implementations.
NOTE: this should be embedded by value instead of pointer to avoid a nil pointer dereference when methods are called.
func (UnimplementedGeneratorAPIServer) CreatePlugin ¶
func (UnimplementedGeneratorAPIServer) CreatePlugin(context.Context, *CreatePluginRequest) (*CreatePluginResponse, error)
func (UnimplementedGeneratorAPIServer) DeletePlugin ¶
func (UnimplementedGeneratorAPIServer) DeletePlugin(context.Context, *DeletePluginRequest) (*DeletePluginResponse, error)
func (UnimplementedGeneratorAPIServer) GenerateCode ¶
func (UnimplementedGeneratorAPIServer) GenerateCode(context.Context, *GenerateCodeRequest) (*GenerateCodeResponse, error)
func (UnimplementedGeneratorAPIServer) Plugins ¶
func (UnimplementedGeneratorAPIServer) Plugins(context.Context, *PluginsRequest) (*PluginsResponse, error)
func (UnimplementedGeneratorAPIServer) UpdatePlugin ¶
func (UnimplementedGeneratorAPIServer) UpdatePlugin(context.Context, *UpdatePluginRequest) (*UpdatePluginResponse, error)
type UnsafeGeneratorAPIServer ¶
type UnsafeGeneratorAPIServer interface {
// contains filtered or unexported methods
}
UnsafeGeneratorAPIServer may be embedded to opt out of forward compatibility for this service. Use of this interface is not recommended, as added methods to GeneratorAPIServer will result in compilation errors.
type UpdatePluginRequest ¶
type UpdatePluginRequest struct {
// Group to which the plugin belongs.
Group string `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"`
// Name of the plugin.
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
// Version of the plugin.
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
// New plugin configuration.
//
// Replaces the existing config when `update_mask` selects it. Note that a
// config is validated on the way in: `command[0]` must name the plugin
// executable inside the service's plugins directory.
Config *structpb.Struct `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"`
// New tags. Replaces the existing tags when `update_mask` selects them.
Tags []string `protobuf:"bytes,5,rep,name=tags,proto3" json:"tags,omitempty"`
// Fields to replace: any of "config", "tags".
//
// Omitting the mask replaces both, which is what this RPC has always done.
//
// The mask exists because "both, always" made a tag edit impossible: `config`
// is validated before anything else, an absent one was an empty one, and the
// call was rejected. Renaming a tag therefore meant resending the plugin's
// whole command line, and getting that wrong is how a registry entry starts
// pointing at the wrong binary.
UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,6,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
// contains filtered or unexported fields
}
Request message for updating a plugin.
func (*UpdatePluginRequest) Descriptor
deprecated
func (*UpdatePluginRequest) Descriptor() ([]byte, []int)
Deprecated: Use UpdatePluginRequest.ProtoReflect.Descriptor instead.
func (*UpdatePluginRequest) GetConfig ¶
func (x *UpdatePluginRequest) GetConfig() *structpb.Struct
func (*UpdatePluginRequest) GetGroup ¶
func (x *UpdatePluginRequest) GetGroup() string
func (*UpdatePluginRequest) GetName ¶
func (x *UpdatePluginRequest) GetName() string
func (*UpdatePluginRequest) GetTags ¶
func (x *UpdatePluginRequest) GetTags() []string
func (*UpdatePluginRequest) GetUpdateMask ¶
func (x *UpdatePluginRequest) GetUpdateMask() *fieldmaskpb.FieldMask
func (*UpdatePluginRequest) GetVersion ¶
func (x *UpdatePluginRequest) GetVersion() string
func (*UpdatePluginRequest) ProtoMessage ¶
func (*UpdatePluginRequest) ProtoMessage()
func (*UpdatePluginRequest) ProtoReflect ¶
func (x *UpdatePluginRequest) ProtoReflect() protoreflect.Message
func (*UpdatePluginRequest) Reset ¶
func (x *UpdatePluginRequest) Reset()
func (*UpdatePluginRequest) String ¶
func (x *UpdatePluginRequest) String() string
type UpdatePluginResponse ¶
type UpdatePluginResponse struct {
// The updated plugin information.
Plugin *PluginInfo `protobuf:"bytes,1,opt,name=plugin,proto3" json:"plugin,omitempty"`
// contains filtered or unexported fields
}
Response message for updating a plugin.
func (*UpdatePluginResponse) Descriptor
deprecated
func (*UpdatePluginResponse) Descriptor() ([]byte, []int)
Deprecated: Use UpdatePluginResponse.ProtoReflect.Descriptor instead.
func (*UpdatePluginResponse) GetPlugin ¶
func (x *UpdatePluginResponse) GetPlugin() *PluginInfo
func (*UpdatePluginResponse) ProtoMessage ¶
func (*UpdatePluginResponse) ProtoMessage()
func (*UpdatePluginResponse) ProtoReflect ¶
func (x *UpdatePluginResponse) ProtoReflect() protoreflect.Message
func (*UpdatePluginResponse) Reset ¶
func (x *UpdatePluginResponse) Reset()
func (*UpdatePluginResponse) String ¶
func (x *UpdatePluginResponse) String() string