Skip to content

Commit d2479e2

Browse files
committed
Add llm proxy deployment support for gateway
1 parent 2e4b08e commit d2479e2

3 files changed

Lines changed: 248 additions & 0 deletions

File tree

gateway/gateway-controller/pkg/controlplane/client.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,10 @@ func (c *Client) handleMessage(messageType int, message []byte) {
564564
c.handleLLMProviderDeployedEvent(event)
565565
case "llmprovider.undeployed":
566566
c.handleLLMProviderUndeployedEvent(event)
567+
case "llmproxy.deployed":
568+
c.handleLLMProxyDeployedEvent(event)
569+
case "llmproxy.undeployed":
570+
c.handleLLMProxyUndeployedEvent(event)
567571
case "apikey.created":
568572
c.handleAPIKeyCreatedEvent(event)
569573
case "apikey.updated":
@@ -971,6 +975,143 @@ func (c *Client) handleLLMProviderUndeployedEvent(event map[string]interface{})
971975
)
972976
}
973977

978+
// handleLLMProxyDeployedEvent handles LLM proxy deployment events
979+
func (c *Client) handleLLMProxyDeployedEvent(event map[string]interface{}) {
980+
c.logger.Info("LLM Proxy Deployment Event",
981+
slog.Any("payload", event["payload"]),
982+
slog.Any("timestamp", event["timestamp"]),
983+
slog.Any("correlationId", event["correlationId"]),
984+
)
985+
986+
// Parse the event into structured format
987+
eventBytes, err := json.Marshal(event)
988+
if err != nil {
989+
c.logger.Error("Failed to marshal LLM proxy deployment event for parsing",
990+
slog.Any("error", err),
991+
)
992+
return
993+
}
994+
995+
var deployedEvent LLMProxyDeployedEvent
996+
if err := json.Unmarshal(eventBytes, &deployedEvent); err != nil {
997+
c.logger.Error("Failed to parse LLM proxy deployment event",
998+
slog.Any("error", err),
999+
)
1000+
return
1001+
}
1002+
1003+
proxyID := deployedEvent.Payload.ProxyID
1004+
if proxyID == "" {
1005+
c.logger.Error("Proxy ID is empty in LLM proxy deployment event")
1006+
return
1007+
}
1008+
1009+
c.logger.Info("Processing LLM proxy deployment",
1010+
slog.String("proxy_id", proxyID),
1011+
slog.String("environment", deployedEvent.Payload.Environment),
1012+
slog.String("deployment_id", deployedEvent.Payload.DeploymentID),
1013+
slog.String("vhost", deployedEvent.Payload.VHost),
1014+
slog.String("correlation_id", deployedEvent.CorrelationID),
1015+
)
1016+
1017+
// Fetch LLM proxy definition from control plane
1018+
zipData, err := c.apiUtilsService.FetchLLMProxyDefinition(proxyID)
1019+
if err != nil {
1020+
c.logger.Error("Failed to fetch LLM proxy definition",
1021+
slog.String("proxy_id", proxyID),
1022+
slog.Any("error", err),
1023+
)
1024+
return
1025+
}
1026+
1027+
// Extract YAML from ZIP
1028+
yamlData, err := c.apiUtilsService.ExtractYAMLFromZip(zipData)
1029+
if err != nil {
1030+
c.logger.Error("Failed to extract YAML from LLM proxy ZIP",
1031+
slog.String("proxy_id", proxyID),
1032+
slog.Any("error", err),
1033+
)
1034+
return
1035+
}
1036+
1037+
if c.llmDeploymentService == nil {
1038+
c.logger.Error("LLM deployment service not available",
1039+
slog.String("proxy_id", proxyID),
1040+
slog.String("correlation_id", deployedEvent.CorrelationID),
1041+
)
1042+
return
1043+
}
1044+
1045+
// Create LLM proxy configuration from YAML using the deployment service
1046+
_, err = c.apiUtilsService.CreateLLMProxyFromYAML(yamlData, proxyID, deployedEvent.CorrelationID, c.llmDeploymentService)
1047+
if err != nil {
1048+
c.logger.Error("Failed to create LLM proxy from YAML",
1049+
slog.String("proxy_id", proxyID),
1050+
slog.Any("error", err),
1051+
)
1052+
return
1053+
}
1054+
1055+
c.logger.Info("Successfully processed LLM proxy deployment event",
1056+
slog.String("proxy_id", proxyID),
1057+
slog.String("correlation_id", deployedEvent.CorrelationID),
1058+
)
1059+
}
1060+
1061+
// handleLLMProxyUndeployedEvent handles LLM proxy undeployment events
1062+
func (c *Client) handleLLMProxyUndeployedEvent(event map[string]interface{}) {
1063+
c.logger.Info("LLM Proxy Undeployment Event",
1064+
slog.Any("payload", event["payload"]),
1065+
slog.Any("timestamp", event["timestamp"]),
1066+
slog.Any("correlationId", event["correlationId"]),
1067+
)
1068+
1069+
// Parse the event into structured format
1070+
eventBytes, err := json.Marshal(event)
1071+
if err != nil {
1072+
c.logger.Error("Failed to marshal LLM proxy undeployment event for parsing",
1073+
slog.Any("error", err),
1074+
)
1075+
return
1076+
}
1077+
1078+
var undeployedEvent LLMProxyUndeployedEvent
1079+
if err := json.Unmarshal(eventBytes, &undeployedEvent); err != nil {
1080+
c.logger.Error("Failed to parse LLM proxy undeployment event",
1081+
slog.Any("error", err),
1082+
)
1083+
return
1084+
}
1085+
1086+
proxyID := undeployedEvent.Payload.ProxyID
1087+
if proxyID == "" {
1088+
c.logger.Error("Proxy ID is empty in LLM proxy undeployment event")
1089+
return
1090+
}
1091+
1092+
if c.llmDeploymentService == nil {
1093+
c.logger.Error("LLM deployment service not available",
1094+
slog.String("proxy_id", proxyID),
1095+
slog.String("correlation_id", undeployedEvent.CorrelationID),
1096+
)
1097+
return
1098+
}
1099+
1100+
_, err = c.llmDeploymentService.DeleteLLMProxy(proxyID, undeployedEvent.CorrelationID, c.logger)
1101+
if err != nil {
1102+
c.logger.Error("Failed to delete LLM proxy configuration",
1103+
slog.String("proxy_id", proxyID),
1104+
slog.Any("error", err),
1105+
)
1106+
return
1107+
}
1108+
1109+
c.logger.Info("Successfully processed LLM proxy undeployment event",
1110+
slog.String("proxy_id", proxyID),
1111+
slog.String("correlation_id", undeployedEvent.CorrelationID),
1112+
)
1113+
}
1114+
9741115
// handleAPIKeyCreatedEvent handles API key created events from platform-api
9751116
func (c *Client) handleAPIKeyCreatedEvent(event map[string]interface{}) {
9761117
baseLogger := c.logger

gateway/gateway-controller/pkg/controlplane/events.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,37 @@ type LLMProviderUndeployedEvent struct {
7474
CorrelationID string `json:"correlationId"`
7575
}
7676

77+
// LLMProxyDeployedEventPayload represents the payload of an LLM proxy deployment event
78+
type LLMProxyDeployedEventPayload struct {
79+
ProxyID string `json:"proxyId"`
80+
Environment string `json:"environment"`
81+
DeploymentID string `json:"deploymentId"`
82+
VHost string `json:"vhost"`
83+
}
84+
85+
// LLMProxyDeployedEvent represents the complete LLM proxy deployment event
86+
type LLMProxyDeployedEvent struct {
87+
Type string `json:"type"`
88+
Payload LLMProxyDeployedEventPayload `json:"payload"`
89+
Timestamp string `json:"timestamp"`
90+
CorrelationID string `json:"correlationId"`
91+
}
92+
93+
// LLMProxyUndeployedEventPayload represents the payload of an LLM proxy undeployment event
94+
type LLMProxyUndeployedEventPayload struct {
95+
ProxyID string `json:"proxyId"`
96+
Environment string `json:"environment"`
97+
VHost string `json:"vhost"`
98+
}
99+
100+
// LLMProxyUndeployedEvent represents the complete LLM proxy undeployment event
101+
type LLMProxyUndeployedEvent struct {
102+
Type string `json:"type"`
103+
Payload LLMProxyUndeployedEventPayload `json:"payload"`
104+
Timestamp string `json:"timestamp"`
105+
CorrelationID string `json:"correlationId"`
106+
}
107+
77108
// APIUndeployedEventPayload represents the payload of an API undeployment event
78109
type APIUndeployedEventPayload struct {
79110
APIID string `json:"apiId"`

gateway/gateway-controller/pkg/utils/api_utils.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,63 @@ func (s *APIUtilsService) FetchLLMProviderDefinition(providerID string) ([]byte,
176176
return bodyBytes, nil
177177
}
178178

179+
// FetchLLMProxyDefinition downloads the LLM proxy definition as a zip file from the control plane
180+
func (s *APIUtilsService) FetchLLMProxyDefinition(proxyID string) ([]byte, error) {
181+
// Construct the LLM proxy URL by appending the resource path
182+
proxyURL := s.config.BaseURL + "/llm-proxies/" + proxyID
183+
184+
s.logger.Info("Fetching LLM proxy definition",
185+
slog.String("proxy_id", proxyID),
186+
slog.String("url", proxyURL),
187+
)
188+
189+
// Create HTTP client with TLS configuration
190+
client := &http.Client{
191+
Timeout: s.config.Timeout,
192+
Transport: &http.Transport{
193+
TLSClientConfig: &tls.Config{
194+
InsecureSkipVerify: s.config.InsecureSkipVerify,
195+
},
196+
},
197+
}
198+
199+
// Create request
200+
req, err := http.NewRequest("GET", proxyURL, nil)
201+
if err != nil {
202+
return nil, fmt.Errorf("failed to create request: %w", err)
203+
}
204+
205+
// Add authentication header
206+
req.Header.Add("api-key", s.config.Token)
207+
req.Header.Add("Accept", "application/zip")
208+
209+
// Make request
210+
resp, err := client.Do(req)
211+
if err != nil {
212+
return nil, fmt.Errorf("failed to fetch LLM proxy definition: %w", err)
213+
}
214+
defer resp.Body.Close()
215+
216+
// Check response status
217+
if resp.StatusCode != http.StatusOK {
218+
bodyBytes, _ := io.ReadAll(resp.Body)
219+
return nil, fmt.Errorf("LLM proxy request failed with status %d: %s", resp.StatusCode, string(bodyBytes))
220+
}
221+
222+
// Read response body
223+
bodyBytes, err := io.ReadAll(resp.Body)
224+
if err != nil {
225+
return nil, fmt.Errorf("failed to read response body: %w", err)
226+
}
227+
228+
s.logger.Info("Successfully fetched LLM proxy definition",
229+
slog.String("proxy_id", proxyID),
230+
slog.Int("size_bytes", len(bodyBytes)),
231+
)
232+
233+
return bodyBytes, nil
234+
}
235+
179236
// ExtractYAMLFromZip extracts the API definition YAML from the zip file
180237
func (s *APIUtilsService) ExtractYAMLFromZip(zipData []byte) ([]byte, error) {
181238
// Create a reader from the zip data
@@ -250,6 +307,25 @@ func (s *APIUtilsService) CreateLLMProviderFromYAML(yamlData []byte, providerID
250307
return result, nil
251308
}
252309

310+
// CreateLLMProxyFromYAML creates an LLM proxy configuration from YAML data using the LLM deployment service
311+
func (s *APIUtilsService) CreateLLMProxyFromYAML(yamlData []byte, proxyID string, correlationID string,
312+
llmDeploymentService *LLMDeploymentService) (*APIDeploymentResult, error) {
313+
// Use the LLM deployment service to handle the proxy configuration deployment
314+
result, err := llmDeploymentService.DeployLLMProxyConfiguration(LLMDeploymentParams{
315+
Data: yamlData,
316+
ContentType: "application/yaml",
317+
ID: proxyID,
318+
CorrelationID: correlationID,
319+
Logger: s.logger,
320+
})
321+
322+
if err != nil {
323+
return nil, fmt.Errorf("failed to deploy LLM proxy configuration from YAML: %w", err)
324+
}
325+
326+
return result, nil
327+
}
328+
253329
// SaveAPIDefinition saves the API definition zip file to disk
254330
func (s *APIUtilsService) SaveAPIDefinition(apiID string, zipData []byte) error {
255331
// Create data directory if it doesn't exist

0 commit comments

Comments
 (0)