Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions go/deploy/builderd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ curl -X POST http://localhost:8082/builder.v1.BuilderService/CreateBuild \
-d '{
"config": {
"tenant": {
"tenant_id": "test-tenant",
"tenant_id": "example-tenant",
"tier": "TENANT_TIER_FREE"
},
"source": {
Expand Down Expand Up @@ -220,8 +220,8 @@ import (
req := &builderv1.CreateBuildRequest{
Config: &builderv1.BuildConfig{
Tenant: &builderv1.TenantContext{
TenantId: "tenant-123",
CustomerId: "customer-456",
TenantId: "example-tenant",
CustomerId: "example-customer",
Tier: builderv1.TenantTier_TENANT_TIER_PRO,
},
Source: &builderv1.BuildSource{
Expand Down
92 changes: 9 additions & 83 deletions go/deploy/builderd/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package client
import (
"context"
"fmt"
"net/http"
"time"

"connectrpc.com/connect"
Expand All @@ -20,12 +19,10 @@ type Config struct {
// ServerAddress is the builderd server endpoint (e.g., "https://builderd:8082")
ServerAddress string

// UserID is the user identifier for authentication
// I do not understand what this userID is.
// Is it an unkey user? or is it a linux user on the metal host?
UserID string

// TenantID is the tenant identifier for data scoping
TenantID string

// TLS configuration
TLSMode string // "disabled", "file", or "spiffe"
SPIFFESocketPath string // Path to SPIFFE agent socket
Expand All @@ -39,12 +36,9 @@ type Config struct {
Timeout time.Duration
}

// Client provides a high-level interface to builderd services
type Client struct {
builderService builderdv1connect.BuilderServiceClient
tlsProvider tls.Provider
userID string
tenantID string
serverAddr string
}

Expand Down Expand Up @@ -84,13 +78,6 @@ func New(ctx context.Context, config Config) (*Client, error) {
httpClient := tlsProvider.HTTPClient()
httpClient.Timeout = config.Timeout

// Add authentication and tenant isolation transport
httpClient.Transport = &tenantTransport{
Base: httpClient.Transport,
UserID: config.UserID,
TenantID: config.TenantID,
}

// Create ConnectRPC client
builderService := builderdv1connect.NewBuilderServiceClient(
httpClient,
Expand All @@ -100,8 +87,6 @@ func New(ctx context.Context, config Config) (*Client, error) {
return &Client{
builderService: builderService,
tlsProvider: tlsProvider,
userID: config.UserID,
tenantID: config.TenantID,
serverAddr: config.ServerAddress,
}, nil
}
Expand Down Expand Up @@ -136,8 +121,7 @@ func (c *Client) CreateBuild(ctx context.Context, req *CreateBuildRequest) (*Cre
// GetBuild retrieves build status and progress
func (c *Client) GetBuild(ctx context.Context, req *GetBuildRequest) (*GetBuildResponse, error) {
pbReq := &builderv1.GetBuildRequest{
BuildId: req.BuildID,
TenantId: req.TenantID,
BuildId: req.BuildID,
}

resp, err := c.builderService.GetBuild(ctx, connect.NewRequest(pbReq))
Expand All @@ -150,10 +134,9 @@ func (c *Client) GetBuild(ctx context.Context, req *GetBuildRequest) (*GetBuildR
}, nil
}

// ListBuilds lists builds with filtering (tenant-scoped)
// ListBuilds lists builds with filtering
func (c *Client) ListBuilds(ctx context.Context, req *ListBuildsRequest) (*ListBuildsResponse, error) {
pbReq := &builderv1.ListBuildsRequest{
TenantId: req.TenantID,
StateFilter: req.State,
PageSize: req.PageSize,
PageToken: req.PageToken,
Expand All @@ -174,8 +157,7 @@ func (c *Client) ListBuilds(ctx context.Context, req *ListBuildsRequest) (*ListB
// CancelBuild cancels a running build
func (c *Client) CancelBuild(ctx context.Context, req *CancelBuildRequest) (*CancelBuildResponse, error) {
pbReq := &builderv1.CancelBuildRequest{
BuildId: req.BuildID,
TenantId: req.TenantID,
BuildId: req.BuildID,
}

resp, err := c.builderService.CancelBuild(ctx, connect.NewRequest(pbReq))
Expand All @@ -192,9 +174,8 @@ func (c *Client) CancelBuild(ctx context.Context, req *CancelBuildRequest) (*Can
// DeleteBuild deletes a build and its artifacts
func (c *Client) DeleteBuild(ctx context.Context, req *DeleteBuildRequest) (*DeleteBuildResponse, error) {
pbReq := &builderv1.DeleteBuildRequest{
BuildId: req.BuildID,
TenantId: req.TenantID,
Force: req.Force,
BuildId: req.BuildID,
Force: req.Force,
}

resp, err := c.builderService.DeleteBuild(ctx, connect.NewRequest(pbReq))
Expand All @@ -210,9 +191,8 @@ func (c *Client) DeleteBuild(ctx context.Context, req *DeleteBuildRequest) (*Del
// StreamBuildLogs streams build logs in real-time
func (c *Client) StreamBuildLogs(ctx context.Context, req *StreamBuildLogsRequest) (*connect.ServerStreamForClient[builderv1.StreamBuildLogsResponse], error) {
pbReq := &builderv1.StreamBuildLogsRequest{
BuildId: req.BuildID,
TenantId: req.TenantID,
Follow: req.Follow,
BuildId: req.BuildID,
Follow: req.Follow,
}

stream, err := c.builderService.StreamBuildLogs(ctx, connect.NewRequest(pbReq))
Expand All @@ -223,28 +203,9 @@ func (c *Client) StreamBuildLogs(ctx context.Context, req *StreamBuildLogsReques
return stream, nil
}

// GetTenantQuotas retrieves tenant quotas and usage
func (c *Client) GetTenantQuotas(ctx context.Context, req *GetTenantQuotasRequest) (*GetTenantQuotasResponse, error) {
pbReq := &builderv1.GetTenantQuotasRequest{
TenantId: req.TenantID,
}

resp, err := c.builderService.GetTenantQuotas(ctx, connect.NewRequest(pbReq))
if err != nil {
return nil, fmt.Errorf("failed to get tenant quotas: %w", err)
}

return &GetTenantQuotasResponse{
Quotas: resp.Msg.CurrentLimits,
Usage: resp.Msg.CurrentUsage,
Violations: resp.Msg.Violations,
}, nil
}

// GetBuildStats retrieves build statistics
func (c *Client) GetBuildStats(ctx context.Context, req *GetBuildStatsRequest) (*GetBuildStatsResponse, error) {
pbReq := &builderv1.GetBuildStatsRequest{
TenantId: req.TenantID,
StartTime: req.StartTime,
EndTime: req.EndTime,
}
Expand All @@ -259,42 +220,7 @@ func (c *Client) GetBuildStats(ctx context.Context, req *GetBuildStatsRequest) (
}, nil
}

// GetTenantID returns the tenant ID associated with this client
func (c *Client) GetTenantID() string {
return c.tenantID
}

// GetServerAddress returns the server address this client is connected to
func (c *Client) GetServerAddress() string {
return c.serverAddr
}

// tenantTransport adds authentication and tenant isolation headers to all requests
type tenantTransport struct {
Base http.RoundTripper
UserID string
TenantID string
}

func (t *tenantTransport) RoundTrip(req *http.Request) (*http.Response, error) {
// Clone the request to avoid modifying the original
req2 := req.Clone(req.Context())
if req2.Header == nil {
req2.Header = make(http.Header)
}

// Set Authorization header with development token format
// AIDEV-BUSINESS_RULE: In development, use "dev_user_<id>" format
// TODO: Update to proper JWT tokens in production
req2.Header.Set("Authorization", fmt.Sprintf("Bearer dev_user_%s", t.UserID))

// Also set X-Tenant-ID header for tenant identification
req2.Header.Set("X-Tenant-ID", t.TenantID)

// Use the base transport, or default if nil
base := t.Base
if base == nil {
base = http.DefaultTransport
}
return base.RoundTrip(req2)
}
30 changes: 6 additions & 24 deletions go/deploy/builderd/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ type CreateBuildResponse struct {

// GetBuildRequest wraps builderv1.GetBuildRequest
type GetBuildRequest struct {
BuildID string
TenantID string
BuildID string
}

// GetBuildResponse wraps builderv1.GetBuildResponse
Expand All @@ -34,7 +33,6 @@ type GetBuildResponse struct {

// ListBuildsRequest wraps builderv1.ListBuildsRequest
type ListBuildsRequest struct {
TenantID string
State []builderv1.BuildState
PageSize int32
PageToken string
Expand All @@ -49,8 +47,7 @@ type ListBuildsResponse struct {

// CancelBuildRequest wraps builderv1.CancelBuildRequest
type CancelBuildRequest struct {
BuildID string
TenantID string
BuildID string
}

// CancelBuildResponse wraps builderv1.CancelBuildResponse
Expand All @@ -61,9 +58,8 @@ type CancelBuildResponse struct {

// DeleteBuildRequest wraps builderv1.DeleteBuildRequest
type DeleteBuildRequest struct {
BuildID string
TenantID string
Force bool
BuildID string
Force bool
}

// DeleteBuildResponse wraps builderv1.DeleteBuildResponse
Expand All @@ -73,26 +69,12 @@ type DeleteBuildResponse struct {

// StreamBuildLogsRequest wraps builderv1.StreamBuildLogsRequest
type StreamBuildLogsRequest struct {
BuildID string
TenantID string
Follow bool
}

// GetTenantQuotasRequest wraps builderv1.GetTenantQuotasRequest
type GetTenantQuotasRequest struct {
TenantID string
}

// GetTenantQuotasResponse wraps builderv1.GetTenantQuotasResponse
type GetTenantQuotasResponse struct {
Quotas *builderv1.TenantResourceLimits
Usage *builderv1.TenantUsageStats
Violations []*builderv1.QuotaViolation
BuildID string
Follow bool
}

// GetBuildStatsRequest wraps builderv1.GetBuildStatsRequest
type GetBuildStatsRequest struct {
TenantID string
StartTime *timestamppb.Timestamp
EndTime *timestamppb.Timestamp
}
Expand Down
Loading