build: generate worker control plane grpc contract

This commit is contained in:
youfak 2026-07-31 10:44:32 +08:00
parent 081e172970
commit 7d8d32af90
9 changed files with 3046 additions and 11 deletions

View File

@ -8,6 +8,17 @@ permissions:
contents: read
jobs:
proto:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- shell: pwsh
run: ./scripts/verify-proto.ps1
test:
strategy:
matrix:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,429 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.6.2
// - protoc v7.35.0
// source: controlplane/v1/controlplane.proto
package controlplanev1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
WorkerControlPlane_RegisterWorker_FullMethodName = "/proxy_pool.controlplane.v1.WorkerControlPlane/RegisterWorker"
WorkerControlPlane_WatchSnapshots_FullMethodName = "/proxy_pool.controlplane.v1.WorkerControlPlane/WatchSnapshots"
WorkerControlPlane_AcknowledgeSnapshot_FullMethodName = "/proxy_pool.controlplane.v1.WorkerControlPlane/AcknowledgeSnapshot"
WorkerControlPlane_ReportOutcomes_FullMethodName = "/proxy_pool.controlplane.v1.WorkerControlPlane/ReportOutcomes"
WorkerControlPlane_ReportRuntime_FullMethodName = "/proxy_pool.controlplane.v1.WorkerControlPlane/ReportRuntime"
)
// WorkerControlPlaneClient is the client API for WorkerControlPlane 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.
//
// WorkerControlPlane distributes immutable, worker-specific snapshots. The
// gateway hot path does not call this service for individual requests.
type WorkerControlPlaneClient interface {
RegisterWorker(ctx context.Context, in *RegisterWorkerRequest, opts ...grpc.CallOption) (*RegisterWorkerResponse, error)
WatchSnapshots(ctx context.Context, in *WatchSnapshotsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SnapshotEnvelope], error)
AcknowledgeSnapshot(ctx context.Context, in *AcknowledgeSnapshotRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
ReportOutcomes(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[OutcomeBatch, ReportOutcomesResponse], error)
ReportRuntime(ctx context.Context, in *ReportRuntimeRequest, opts ...grpc.CallOption) (*ReportRuntimeResponse, error)
}
type workerControlPlaneClient struct {
cc grpc.ClientConnInterface
}
func NewWorkerControlPlaneClient(cc grpc.ClientConnInterface) WorkerControlPlaneClient {
return &workerControlPlaneClient{cc}
}
func (c *workerControlPlaneClient) RegisterWorker(ctx context.Context, in *RegisterWorkerRequest, opts ...grpc.CallOption) (*RegisterWorkerResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RegisterWorkerResponse)
err := c.cc.Invoke(ctx, WorkerControlPlane_RegisterWorker_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *workerControlPlaneClient) WatchSnapshots(ctx context.Context, in *WatchSnapshotsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SnapshotEnvelope], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &WorkerControlPlane_ServiceDesc.Streams[0], WorkerControlPlane_WatchSnapshots_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[WatchSnapshotsRequest, SnapshotEnvelope]{ClientStream: stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type WorkerControlPlane_WatchSnapshotsClient = grpc.ServerStreamingClient[SnapshotEnvelope]
func (c *workerControlPlaneClient) AcknowledgeSnapshot(ctx context.Context, in *AcknowledgeSnapshotRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, WorkerControlPlane_AcknowledgeSnapshot_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *workerControlPlaneClient) ReportOutcomes(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[OutcomeBatch, ReportOutcomesResponse], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &WorkerControlPlane_ServiceDesc.Streams[1], WorkerControlPlane_ReportOutcomes_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[OutcomeBatch, ReportOutcomesResponse]{ClientStream: stream}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type WorkerControlPlane_ReportOutcomesClient = grpc.ClientStreamingClient[OutcomeBatch, ReportOutcomesResponse]
func (c *workerControlPlaneClient) ReportRuntime(ctx context.Context, in *ReportRuntimeRequest, opts ...grpc.CallOption) (*ReportRuntimeResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ReportRuntimeResponse)
err := c.cc.Invoke(ctx, WorkerControlPlane_ReportRuntime_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// WorkerControlPlaneServer is the server API for WorkerControlPlane service.
// All implementations must embed UnimplementedWorkerControlPlaneServer
// for forward compatibility.
//
// WorkerControlPlane distributes immutable, worker-specific snapshots. The
// gateway hot path does not call this service for individual requests.
type WorkerControlPlaneServer interface {
RegisterWorker(context.Context, *RegisterWorkerRequest) (*RegisterWorkerResponse, error)
WatchSnapshots(*WatchSnapshotsRequest, grpc.ServerStreamingServer[SnapshotEnvelope]) error
AcknowledgeSnapshot(context.Context, *AcknowledgeSnapshotRequest) (*emptypb.Empty, error)
ReportOutcomes(grpc.ClientStreamingServer[OutcomeBatch, ReportOutcomesResponse]) error
ReportRuntime(context.Context, *ReportRuntimeRequest) (*ReportRuntimeResponse, error)
mustEmbedUnimplementedWorkerControlPlaneServer()
}
// UnimplementedWorkerControlPlaneServer must 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.
type UnimplementedWorkerControlPlaneServer struct{}
func (UnimplementedWorkerControlPlaneServer) RegisterWorker(context.Context, *RegisterWorkerRequest) (*RegisterWorkerResponse, error) {
return nil, status.Error(codes.Unimplemented, "method RegisterWorker not implemented")
}
func (UnimplementedWorkerControlPlaneServer) WatchSnapshots(*WatchSnapshotsRequest, grpc.ServerStreamingServer[SnapshotEnvelope]) error {
return status.Error(codes.Unimplemented, "method WatchSnapshots not implemented")
}
func (UnimplementedWorkerControlPlaneServer) AcknowledgeSnapshot(context.Context, *AcknowledgeSnapshotRequest) (*emptypb.Empty, error) {
return nil, status.Error(codes.Unimplemented, "method AcknowledgeSnapshot not implemented")
}
func (UnimplementedWorkerControlPlaneServer) ReportOutcomes(grpc.ClientStreamingServer[OutcomeBatch, ReportOutcomesResponse]) error {
return status.Error(codes.Unimplemented, "method ReportOutcomes not implemented")
}
func (UnimplementedWorkerControlPlaneServer) ReportRuntime(context.Context, *ReportRuntimeRequest) (*ReportRuntimeResponse, error) {
return nil, status.Error(codes.Unimplemented, "method ReportRuntime not implemented")
}
func (UnimplementedWorkerControlPlaneServer) mustEmbedUnimplementedWorkerControlPlaneServer() {}
func (UnimplementedWorkerControlPlaneServer) testEmbeddedByValue() {}
// UnsafeWorkerControlPlaneServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to WorkerControlPlaneServer will
// result in compilation errors.
type UnsafeWorkerControlPlaneServer interface {
mustEmbedUnimplementedWorkerControlPlaneServer()
}
func RegisterWorkerControlPlaneServer(s grpc.ServiceRegistrar, srv WorkerControlPlaneServer) {
// If the following call panics, it indicates UnimplementedWorkerControlPlaneServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&WorkerControlPlane_ServiceDesc, srv)
}
func _WorkerControlPlane_RegisterWorker_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RegisterWorkerRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WorkerControlPlaneServer).RegisterWorker(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: WorkerControlPlane_RegisterWorker_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WorkerControlPlaneServer).RegisterWorker(ctx, req.(*RegisterWorkerRequest))
}
return interceptor(ctx, in, info, handler)
}
func _WorkerControlPlane_WatchSnapshots_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(WatchSnapshotsRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(WorkerControlPlaneServer).WatchSnapshots(m, &grpc.GenericServerStream[WatchSnapshotsRequest, SnapshotEnvelope]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type WorkerControlPlane_WatchSnapshotsServer = grpc.ServerStreamingServer[SnapshotEnvelope]
func _WorkerControlPlane_AcknowledgeSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AcknowledgeSnapshotRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WorkerControlPlaneServer).AcknowledgeSnapshot(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: WorkerControlPlane_AcknowledgeSnapshot_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WorkerControlPlaneServer).AcknowledgeSnapshot(ctx, req.(*AcknowledgeSnapshotRequest))
}
return interceptor(ctx, in, info, handler)
}
func _WorkerControlPlane_ReportOutcomes_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(WorkerControlPlaneServer).ReportOutcomes(&grpc.GenericServerStream[OutcomeBatch, ReportOutcomesResponse]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type WorkerControlPlane_ReportOutcomesServer = grpc.ClientStreamingServer[OutcomeBatch, ReportOutcomesResponse]
func _WorkerControlPlane_ReportRuntime_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ReportRuntimeRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WorkerControlPlaneServer).ReportRuntime(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: WorkerControlPlane_ReportRuntime_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WorkerControlPlaneServer).ReportRuntime(ctx, req.(*ReportRuntimeRequest))
}
return interceptor(ctx, in, info, handler)
}
// WorkerControlPlane_ServiceDesc is the grpc.ServiceDesc for WorkerControlPlane service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var WorkerControlPlane_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proxy_pool.controlplane.v1.WorkerControlPlane",
HandlerType: (*WorkerControlPlaneServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "RegisterWorker",
Handler: _WorkerControlPlane_RegisterWorker_Handler,
},
{
MethodName: "AcknowledgeSnapshot",
Handler: _WorkerControlPlane_AcknowledgeSnapshot_Handler,
},
{
MethodName: "ReportRuntime",
Handler: _WorkerControlPlane_ReportRuntime_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "WatchSnapshots",
Handler: _WorkerControlPlane_WatchSnapshots_Handler,
ServerStreams: true,
},
{
StreamName: "ReportOutcomes",
Handler: _WorkerControlPlane_ReportOutcomes_Handler,
ClientStreams: true,
},
},
Metadata: "controlplane/v1/controlplane.proto",
}
const (
CheckerControlPlane_StreamCheckTasks_FullMethodName = "/proxy_pool.controlplane.v1.CheckerControlPlane/StreamCheckTasks"
CheckerControlPlane_ReportObservations_FullMethodName = "/proxy_pool.controlplane.v1.CheckerControlPlane/ReportObservations"
)
// CheckerControlPlaneClient is the client API for CheckerControlPlane 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.
//
// CheckerControlPlane hands bounded check work to independently scalable
// checker processes. Observations are facts; only the Controller reducer may
// change authoritative proxy state.
type CheckerControlPlaneClient interface {
StreamCheckTasks(ctx context.Context, in *StreamCheckTasksRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[CheckTask], error)
ReportObservations(ctx context.Context, in *ObservationBatch, opts ...grpc.CallOption) (*ReportObservationsResponse, error)
}
type checkerControlPlaneClient struct {
cc grpc.ClientConnInterface
}
func NewCheckerControlPlaneClient(cc grpc.ClientConnInterface) CheckerControlPlaneClient {
return &checkerControlPlaneClient{cc}
}
func (c *checkerControlPlaneClient) StreamCheckTasks(ctx context.Context, in *StreamCheckTasksRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[CheckTask], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &CheckerControlPlane_ServiceDesc.Streams[0], CheckerControlPlane_StreamCheckTasks_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[StreamCheckTasksRequest, CheckTask]{ClientStream: stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type CheckerControlPlane_StreamCheckTasksClient = grpc.ServerStreamingClient[CheckTask]
func (c *checkerControlPlaneClient) ReportObservations(ctx context.Context, in *ObservationBatch, opts ...grpc.CallOption) (*ReportObservationsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ReportObservationsResponse)
err := c.cc.Invoke(ctx, CheckerControlPlane_ReportObservations_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// CheckerControlPlaneServer is the server API for CheckerControlPlane service.
// All implementations must embed UnimplementedCheckerControlPlaneServer
// for forward compatibility.
//
// CheckerControlPlane hands bounded check work to independently scalable
// checker processes. Observations are facts; only the Controller reducer may
// change authoritative proxy state.
type CheckerControlPlaneServer interface {
StreamCheckTasks(*StreamCheckTasksRequest, grpc.ServerStreamingServer[CheckTask]) error
ReportObservations(context.Context, *ObservationBatch) (*ReportObservationsResponse, error)
mustEmbedUnimplementedCheckerControlPlaneServer()
}
// UnimplementedCheckerControlPlaneServer must 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.
type UnimplementedCheckerControlPlaneServer struct{}
func (UnimplementedCheckerControlPlaneServer) StreamCheckTasks(*StreamCheckTasksRequest, grpc.ServerStreamingServer[CheckTask]) error {
return status.Error(codes.Unimplemented, "method StreamCheckTasks not implemented")
}
func (UnimplementedCheckerControlPlaneServer) ReportObservations(context.Context, *ObservationBatch) (*ReportObservationsResponse, error) {
return nil, status.Error(codes.Unimplemented, "method ReportObservations not implemented")
}
func (UnimplementedCheckerControlPlaneServer) mustEmbedUnimplementedCheckerControlPlaneServer() {}
func (UnimplementedCheckerControlPlaneServer) testEmbeddedByValue() {}
// UnsafeCheckerControlPlaneServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to CheckerControlPlaneServer will
// result in compilation errors.
type UnsafeCheckerControlPlaneServer interface {
mustEmbedUnimplementedCheckerControlPlaneServer()
}
func RegisterCheckerControlPlaneServer(s grpc.ServiceRegistrar, srv CheckerControlPlaneServer) {
// If the following call panics, it indicates UnimplementedCheckerControlPlaneServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&CheckerControlPlane_ServiceDesc, srv)
}
func _CheckerControlPlane_StreamCheckTasks_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(StreamCheckTasksRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(CheckerControlPlaneServer).StreamCheckTasks(m, &grpc.GenericServerStream[StreamCheckTasksRequest, CheckTask]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type CheckerControlPlane_StreamCheckTasksServer = grpc.ServerStreamingServer[CheckTask]
func _CheckerControlPlane_ReportObservations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ObservationBatch)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CheckerControlPlaneServer).ReportObservations(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: CheckerControlPlane_ReportObservations_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CheckerControlPlaneServer).ReportObservations(ctx, req.(*ObservationBatch))
}
return interceptor(ctx, in, info, handler)
}
// CheckerControlPlane_ServiceDesc is the grpc.ServiceDesc for CheckerControlPlane service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var CheckerControlPlane_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proxy_pool.controlplane.v1.CheckerControlPlane",
HandlerType: (*CheckerControlPlaneServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "ReportObservations",
Handler: _CheckerControlPlane_ReportObservations_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "StreamCheckTasks",
Handler: _CheckerControlPlane_StreamCheckTasks_Handler,
ServerStreams: true,
},
},
Metadata: "controlplane/v1/controlplane.proto",
}

13
go.mod
View File

@ -7,6 +7,8 @@ require (
github.com/prometheus/client_golang v1.24.1
github.com/redis/go-redis/v9 v9.19.0
go.yaml.in/yaml/v4 v4.0.0-rc.3
google.golang.org/grpc v1.83.0
google.golang.org/protobuf v1.36.11
)
require (
@ -20,9 +22,16 @@ require (
github.com/prometheus/common v0.70.1 // indirect
github.com/prometheus/procfs v0.21.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/crypto v0.54.0 // indirect
golang.org/x/net v0.57.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.40.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 // indirect
)
tool (
google.golang.org/grpc/cmd/protoc-gen-go-grpc
google.golang.org/protobuf/cmd/protoc-gen-go
)

34
go.sum
View File

@ -9,8 +9,16 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
@ -46,6 +54,18 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@ -54,14 +74,24 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go=
go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ=
google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 h1:rgSNvqscFZ1JgV/4wH5GOsZFSFkR2Eua9As3KIr2LlM=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2/go.mod h1:iMEtFwDlAhjDU9L5mY6U1XLwlIId/G3h+QcBHDIvrJ8=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -0,0 +1,62 @@
param(
[string]$Protoc = "",
[string]$IncludePath = $env:PROTOC_INCLUDE,
[string]$OutputRoot = ""
)
$ErrorActionPreference = "Stop"
$repositoryRoot = Split-Path -Parent $PSScriptRoot
$protoRoot = Join-Path $repositoryRoot "api/proto"
$source = Join-Path $protoRoot "controlplane/v1/controlplane.proto"
$toolRoot = Join-Path $repositoryRoot ".tmp-proto/tools"
New-Item -ItemType Directory -Force -Path $toolRoot | Out-Null
if ([string]::IsNullOrWhiteSpace($Protoc)) {
$Protoc = & (Join-Path $PSScriptRoot "install-protoc.ps1")
}
$runningWindows = [System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform(
[System.Runtime.InteropServices.OSPlatform]::Windows
)
$suffix = if ($runningWindows) { ".exe" } else { "" }
$protocGenGo = Join-Path $toolRoot ("protoc-gen-go" + $suffix)
$protocGenGoGRPC = Join-Path $toolRoot ("protoc-gen-go-grpc" + $suffix)
go build -o $protocGenGo google.golang.org/protobuf/cmd/protoc-gen-go
if ($LASTEXITCODE -ne 0) { throw "build protoc-gen-go failed" }
go build -o $protocGenGoGRPC google.golang.org/grpc/cmd/protoc-gen-go-grpc
if ($LASTEXITCODE -ne 0) { throw "build protoc-gen-go-grpc failed" }
$protocCommand = Get-Command $Protoc -ErrorAction Stop
$protocVersion = (& $protocCommand.Source --version).Trim()
if ($protocVersion -ne "libprotoc 35.0") { throw "protoc 35.0 is required" }
if ([string]::IsNullOrWhiteSpace($IncludePath)) {
$installationRoot = Split-Path (Split-Path $protocCommand.Source -Parent) -Parent
$IncludePath = @(
(Join-Path $installationRoot "include"),
"/usr/include",
"/usr/local/include"
) |
Where-Object { Test-Path (Join-Path $_ "google/protobuf/timestamp.proto") } |
Select-Object -First 1
}
if ([string]::IsNullOrWhiteSpace($OutputRoot)) { $OutputRoot = $repositoryRoot }
if ([string]::IsNullOrWhiteSpace($IncludePath) -or
-not (Test-Path (Join-Path $IncludePath "google/protobuf/timestamp.proto"))) {
throw "protoc well-known type include directory was not found"
}
New-Item -ItemType Directory -Force -Path $OutputRoot | Out-Null
& $protocCommand.Source `
"--proto_path=$protoRoot" `
"--proto_path=$IncludePath" `
"--plugin=protoc-gen-go=$protocGenGo" `
"--plugin=protoc-gen-go-grpc=$protocGenGoGRPC" `
"--go_out=$OutputRoot" `
"--go_opt=module=proxy-pool" `
"--go-grpc_out=$OutputRoot" `
"--go-grpc_opt=module=proxy-pool" `
$source
if ($LASTEXITCODE -ne 0) { throw "protobuf Go generation failed" }

View File

@ -0,0 +1,61 @@
param()
$ErrorActionPreference = "Stop"
$repositoryRoot = Split-Path -Parent $PSScriptRoot
$runtime = [System.Runtime.InteropServices.RuntimeInformation]
$runningWindows = $runtime::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Windows)
$runningLinux = $runtime::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Linux)
if ($runtime::OSArchitecture -ne [System.Runtime.InteropServices.Architecture]::X64) {
throw "protoc bootstrap supports x64 only"
}
if ($runningWindows) {
$asset = "protoc-35.0-win64.zip"
$expectedHash = "d1cede9e308cc3eb072392af1c02ccae4bdd3d2f374ec2970dbd8cdfdaa91363"
$executableName = "protoc.exe"
}
elseif ($runningLinux) {
$asset = "protoc-35.0-linux-x86_64.zip"
$expectedHash = "a45cda0989c17dd950db55f6fbe1e5814c50fda08e87aa422980ac1f89dddbbc"
$executableName = "protoc"
}
else {
throw "protoc bootstrap supports Windows x64 and Linux x64 only"
}
$cacheDirectory = Join-Path $repositoryRoot ".tmp-proto/downloads"
$installationDirectory = Join-Path $repositoryRoot ".tmp-proto/protoc-35.0"
$archivePath = Join-Path $cacheDirectory $asset
$downloadURL = "https://github.com/protocolbuffers/protobuf/releases/download/v35.0/$asset"
New-Item -ItemType Directory -Force -Path $cacheDirectory | Out-Null
$needsDownload = -not (Test-Path -LiteralPath $archivePath)
if (-not $needsDownload) {
$actualHash = (Get-FileHash -LiteralPath $archivePath -Algorithm SHA256).Hash.ToLowerInvariant()
$needsDownload = $actualHash -ne $expectedHash
}
if ($needsDownload) {
Invoke-WebRequest -Uri $downloadURL -OutFile $archivePath
}
$actualHash = (Get-FileHash -LiteralPath $archivePath -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actualHash -ne $expectedHash) {
throw "protoc archive SHA-256 mismatch"
}
New-Item -ItemType Directory -Force -Path $installationDirectory | Out-Null
Expand-Archive -LiteralPath $archivePath -DestinationPath $installationDirectory -Force
$protocPath = Join-Path $installationDirectory "bin/$executableName"
if (-not (Test-Path -LiteralPath $protocPath)) {
throw "protoc executable was not extracted"
}
$version = (& $protocPath --version).Trim()
if ($version -ne "libprotoc 35.0") {
throw "protoc version mismatch: $version"
}
(Resolve-Path -LiteralPath $protocPath).Path

View File

@ -1,5 +1,5 @@
param(
[string]$Protoc = "protoc",
[string]$Protoc = "",
[string]$IncludePath = $env:PROTOC_INCLUDE,
[string]$OutputPath = ""
)
@ -10,7 +10,14 @@ $repositoryRoot = Split-Path -Parent $PSScriptRoot
$protoRoot = Join-Path $repositoryRoot "api/proto"
$source = Join-Path $protoRoot "controlplane/v1/controlplane.proto"
if ([string]::IsNullOrWhiteSpace($Protoc)) {
$Protoc = & (Join-Path $PSScriptRoot "install-protoc.ps1")
}
$protocCommand = Get-Command $Protoc -ErrorAction Stop
$protocVersion = (& $protocCommand.Source --version).Trim()
if ($protocVersion -ne "libprotoc 35.0") {
throw "protoc 35.0 is required"
}
if ([string]::IsNullOrWhiteSpace($IncludePath)) {
$installationRoot = Split-Path (Split-Path $protocCommand.Source -Parent) -Parent
$candidates = @(
@ -49,3 +56,25 @@ if ($descriptor.Length -le 0) {
throw "protoc produced an empty descriptor set"
}
Write-Host "descriptor: $($descriptor.FullName) ($($descriptor.Length) bytes)"
$outputRoot = Join-Path $repositoryRoot ".tmp-proto/generated"
& (Join-Path $PSScriptRoot "generate-proto.ps1") `
-Protoc $protocCommand.Source `
-IncludePath $IncludePath `
-OutputRoot $outputRoot
$generated = @(
"gen/controlplane/v1/controlplane.pb.go",
"gen/controlplane/v1/controlplane_grpc.pb.go"
)
foreach ($relative in $generated) {
$committed = Join-Path $repositoryRoot $relative
$candidate = Join-Path $outputRoot $relative
if (-not (Test-Path -LiteralPath $committed) -or
-not (Test-Path -LiteralPath $candidate) -or
-not [System.Linq.Enumerable]::SequenceEqual(
[System.IO.File]::ReadAllBytes($committed),
[System.IO.File]::ReadAllBytes($candidate))) {
throw "generated protobuf drift: $relative"
}
}

View File

@ -22,12 +22,7 @@ if ($unformatted) {
Invoke-Step "go vet" { go vet ./... }
Invoke-Step "unit tests" { go test -timeout 60s ./... }
if (Get-Command protoc -ErrorAction SilentlyContinue) {
Invoke-Step "protobuf descriptor" { & (Join-Path $PSScriptRoot "verify-proto.ps1") }
}
else {
Write-Host "==> protobuf descriptor skipped: protoc is not installed"
}
Invoke-Step "protobuf contracts" { & (Join-Path $PSScriptRoot "verify-proto.ps1") }
if ((go env CGO_ENABLED) -eq "1") {
Invoke-Step "race tests" { go test -race -timeout 60s ./internal/... }