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
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (r *VirtualMCPCompositeToolDefinition) validateParameters() error {
// Unmarshal to validate structure
var params map[string]interface{}
if err := json.Unmarshal(r.Spec.Parameters.Raw, &params); err != nil {
return fmt.Errorf("spec.parameters: invalid JSON: %v", err)
return fmt.Errorf("spec.parameters: invalid JSON: %w", err)
}

// Validate that it has "type" field
Expand All @@ -131,7 +131,7 @@ func (r *VirtualMCPCompositeToolDefinition) validateParameters() error {

// Validate using JSON Schema validator
if err := validateJSONSchema(r.Spec.Parameters.Raw); err != nil {
return fmt.Errorf("spec.parameters: invalid JSON Schema: %v", err)
return fmt.Errorf("spec.parameters: invalid JSON Schema: %w", err)
}

return nil
Expand Down Expand Up @@ -194,7 +194,7 @@ func (r *VirtualMCPCompositeToolDefinition) validateStep(index int, step Workflo

if step.Timeout != "" {
if err := validateDuration(step.Timeout); err != nil {
return fmt.Errorf("spec.steps[%d].timeout: %v", index, err)
return fmt.Errorf("spec.steps[%d].timeout: %w", index, err)
}
}

Expand Down Expand Up @@ -245,34 +245,34 @@ func validateWorkflowStepTemplates(pathPrefix string, index int, step WorkflowSt
if step.Arguments != nil && len(step.Arguments.Raw) > 0 {
var args map[string]any
if err := json.Unmarshal(step.Arguments.Raw, &args); err != nil {
return fmt.Errorf("%s[%d].arguments: invalid JSON: %v", pathPrefix, index, err)
return fmt.Errorf("%s[%d].arguments: invalid JSON: %w", pathPrefix, index, err)
}
for argName, argValue := range args {
// Only validate template syntax for string values
if strValue, ok := argValue.(string); ok {
if err := validateTemplate(strValue); err != nil {
return fmt.Errorf("%s[%d].arguments[%s]: invalid template: %v", pathPrefix, index, argName, err)
return fmt.Errorf("%s[%d].arguments[%s]: invalid template: %w", pathPrefix, index, argName, err)
}
}
}
}

if step.Condition != "" {
if err := validateTemplate(step.Condition); err != nil {
return fmt.Errorf("%s[%d].condition: invalid template: %v", pathPrefix, index, err)
return fmt.Errorf("%s[%d].condition: invalid template: %w", pathPrefix, index, err)
}
}

if step.Message != "" {
if err := validateTemplate(step.Message); err != nil {
return fmt.Errorf("%s[%d].message: invalid template: %v", pathPrefix, index, err)
return fmt.Errorf("%s[%d].message: invalid template: %w", pathPrefix, index, err)
}
}

// Validate JSON Schema for elicitation steps
if step.Schema != nil {
if err := validateJSONSchema(step.Schema.Raw); err != nil {
return fmt.Errorf("%s[%d].schema: invalid JSON Schema: %v", pathPrefix, index, err)
return fmt.Errorf("%s[%d].schema: invalid JSON Schema: %w", pathPrefix, index, err)
}
}

Expand Down Expand Up @@ -360,7 +360,7 @@ func validateTemplate(tmpl string) error {
// Try to parse as Go template
_, err := template.New("validation").Parse(tmpl)
if err != nil {
return fmt.Errorf("invalid template syntax: %v", err)
return fmt.Errorf("invalid template syntax: %w", err)
}
return nil
}
Expand All @@ -374,7 +374,7 @@ func validateJSONSchema(schemaBytes []byte) error {
// Parse the schema JSON to verify it's valid JSON
var schemaDoc interface{}
if err := json.Unmarshal(schemaBytes, &schemaDoc); err != nil {
return fmt.Errorf("failed to parse JSON: %v", err)
return fmt.Errorf("failed to parse JSON: %w", err)
}

// Use gojsonschema to validate the schema by attempting to use it as a schema
Expand All @@ -388,7 +388,7 @@ func validateJSONSchema(schemaBytes []byte) error {
_, err := gojsonschema.Validate(schemaLoader, documentLoader)
if err != nil {
// Check if error is about the schema itself (not validation failure)
return fmt.Errorf("invalid JSON Schema: %v", err)
return fmt.Errorf("invalid JSON Schema: %w", err)
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion cmd/thv-operator/pkg/controllerutil/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func AddAuthzConfigOptions(
if err := yaml.Unmarshal([]byte(raw), &cfg); err != nil {
// Fallback to JSON explicitly for clearer error paths
if err2 := json.Unmarshal([]byte(raw), &cfg); err2 != nil {
return fmt.Errorf("failed to parse authz config from ConfigMap %s/%s key %q: %v; json fallback error: %v",
return fmt.Errorf("failed to parse authz config from ConfigMap %s/%s key %q: %w; json fallback error: %w",
namespace, authzRef.ConfigMap.Name, key, err, err2)
}
}
Expand Down
8 changes: 4 additions & 4 deletions cmd/thv-proxyrunner/app/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func runCmdFunc(cmd *cobra.Command, args []string) error {
// Create container runtime
rt, err := container.NewFactory().Create(ctx)
if err != nil {
return fmt.Errorf("failed to create container runtime: %v", err)
return fmt.Errorf("failed to create container runtime: %w", err)
}

// Select an env var validation strategy depending on how the CLI is run:
Expand Down Expand Up @@ -178,7 +178,7 @@ func runWithFileBasedConfig(
if envVarValidator != nil {
validatedEnvVars, err := envVarValidator.Validate(ctx, imageMetadata, config, config.EnvVars)
if err != nil {
return fmt.Errorf("failed to validate environment variables: %v", err)
return fmt.Errorf("failed to validate environment variables: %w", err)
}
config.EnvVars = validatedEnvVars
}
Expand All @@ -187,7 +187,7 @@ func runWithFileBasedConfig(
if config.EnvFileDir != "" {
updatedConfig, err := config.WithEnvFilesFromDirectory(config.EnvFileDir)
if err != nil {
return fmt.Errorf("failed to process environment files from directory %s: %v", config.EnvFileDir, err)
return fmt.Errorf("failed to process environment files from directory %s: %w", config.EnvFileDir, err)
}
config = updatedConfig
}
Expand All @@ -199,7 +199,7 @@ func runWithFileBasedConfig(

workloadManager, err := workloads.NewManagerFromRuntime(rt)
if err != nil {
return fmt.Errorf("failed to create workload manager: %v", err)
return fmt.Errorf("failed to create workload manager: %w", err)
}
return workloadManager.RunWorkload(ctx, config)
}
6 changes: 3 additions & 3 deletions cmd/thv/app/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ func buildCmdFunc(cmd *cobra.Command, args []string) error {
dockerfileContent, err := runner.BuildFromProtocolSchemeWithName(
ctx, imageManager, protocolScheme, "", buildFlags.Tag, buildArgs, true)
if err != nil {
return fmt.Errorf("failed to generate Dockerfile for %s: %v", protocolScheme, err)
return fmt.Errorf("failed to generate Dockerfile for %s: %w", protocolScheme, err)
}

// Write to output file if specified
if buildFlags.Output != "" {
if err := os.WriteFile(buildFlags.Output, []byte(dockerfileContent), 0600); err != nil {
return fmt.Errorf("failed to write Dockerfile to %s: %v", buildFlags.Output, err)
return fmt.Errorf("failed to write Dockerfile to %s: %w", buildFlags.Output, err)
}
logger.Infof("Dockerfile written to: %s", buildFlags.Output)
fmt.Printf("Dockerfile written to: %s\n", buildFlags.Output)
Expand All @@ -116,7 +116,7 @@ func buildCmdFunc(cmd *cobra.Command, args []string) error {
// Build the image using the new protocol handler with custom name
imageName, err := runner.BuildFromProtocolSchemeWithName(ctx, imageManager, protocolScheme, "", buildFlags.Tag, buildArgs, false)
if err != nil {
return fmt.Errorf("failed to build container for %s: %v", protocolScheme, err)
return fmt.Errorf("failed to build container for %s: %w", protocolScheme, err)
}

logger.Infof("Successfully built container image: %s", imageName)
Expand Down
14 changes: 7 additions & 7 deletions cmd/thv/app/inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,20 @@ func inspectorCmdFunc(cmd *cobra.Command, args []string) error {
tokenBytes := make([]byte, 32)
_, err := rand.Read(tokenBytes)
if err != nil {
return fmt.Errorf("failed to generate auth token: %v", err)
return fmt.Errorf("failed to generate auth token: %w", err)
}
authToken := hex.EncodeToString(tokenBytes)

// find the port of the server if it is running / exists
serverPort, transportType, err := getServerPortAndTransport(ctx, serverName)
if err != nil {
return fmt.Errorf("failed to find server: %v", err)
return fmt.Errorf("failed to find server: %w", err)
}

imageManager := images.NewImageManager(ctx)
err = imageManager.PullImage(ctx, inspector.Image)
if err != nil {
return fmt.Errorf("failed to pull inspector image: %v", err)
return fmt.Errorf("failed to pull inspector image: %w", err)
}
processedImage := inspector.Image

Expand All @@ -128,7 +128,7 @@ func inspectorCmdFunc(cmd *cobra.Command, args []string) error {
// Create workload runtime
rt, err := container.NewFactory().Create(ctx)
if err != nil {
return fmt.Errorf("failed to create workload runtime: %v", err)
return fmt.Errorf("failed to create workload runtime: %w", err)
}

labelsMap := map[string]string{}
Expand All @@ -150,7 +150,7 @@ func inspectorCmdFunc(cmd *cobra.Command, args []string) error {
false, // Do not isolate network
)
if err != nil {
return fmt.Errorf("failed to create inspector workload: %v", err)
return fmt.Errorf("failed to create inspector workload: %w", err)
}

// Monitor inspector readiness by checking HTTP response
Expand Down Expand Up @@ -185,12 +185,12 @@ func getServerPortAndTransport(ctx context.Context, serverName string) (int, typ
// Instantiate the status manager and list all workloads.
manager, err := workloads.NewManager(ctx)
if err != nil {
return 0, types.TransportTypeSSE, fmt.Errorf("failed to create status manager: %v", err)
return 0, types.TransportTypeSSE, fmt.Errorf("failed to create status manager: %w", err)
}

workloadList, err := manager.ListWorkloads(ctx, true)
if err != nil {
return 0, types.TransportTypeSSE, fmt.Errorf("failed to list workloads: %v", err)
return 0, types.TransportTypeSSE, fmt.Errorf("failed to list workloads: %w", err)
}

for _, c := range workloadList {
Expand Down
10 changes: 5 additions & 5 deletions cmd/thv/app/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@ func listCmdFunc(cmd *cobra.Command, _ []string) error {
// Instantiate the status manager.
manager, err := workloads.NewManager(ctx)
if err != nil {
return fmt.Errorf("failed to create status manager: %v", err)
return fmt.Errorf("failed to create status manager: %w", err)
}

workloadList, err := manager.ListWorkloads(ctx, listAll, listLabelFilter...)
if err != nil {
return fmt.Errorf("failed to list workloads: %v", err)
return fmt.Errorf("failed to list workloads: %w", err)
}

// Apply group filtering if specified
if listGroupFilter != "" {
workloadList, err = workloads.FilterByGroup(workloadList, listGroupFilter)
if err != nil {
return fmt.Errorf("failed to filter workloads by group: %v", err)
return fmt.Errorf("failed to filter workloads by group: %w", err)
}
}

Expand Down Expand Up @@ -94,7 +94,7 @@ func printJSONOutput(workloadList []core.Workload) error {
// Marshal to JSON
jsonData, err := json.MarshalIndent(workloadList, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal JSON: %v", err)
return fmt.Errorf("failed to marshal JSON: %w", err)
}

// Print JSON directly to stdout
Expand All @@ -121,7 +121,7 @@ func printMCPServersOutput(workloadList []core.Workload) error {
"mcpServers": mcpServers,
}, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal JSON: %v", err)
return fmt.Errorf("failed to marshal JSON: %w", err)
}

// Print JSON directly to stdout
Expand Down
20 changes: 10 additions & 10 deletions cmd/thv/app/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func logsCmdFunc(cmd *cobra.Command, args []string) error {

manager, err := workloads.NewManager(ctx)
if err != nil {
return fmt.Errorf("failed to create workload manager: %v", err)
return fmt.Errorf("failed to create workload manager: %w", err)
}

if proxy {
Expand All @@ -103,7 +103,7 @@ func logsCmdFunc(cmd *cobra.Command, args []string) error {
logger.Infof("Workload %s not found", workloadName)
return nil
}
return fmt.Errorf("failed to get logs for workload %s: %v", workloadName, err)
return fmt.Errorf("failed to get logs for workload %s: %w", workloadName, err)
}

fmt.Print(logs)
Expand Down Expand Up @@ -142,7 +142,7 @@ func logsPruneCmdFunc(cmd *cobra.Command) error {
func getLogsDirectory() (string, error) {
logsDir, err := xdg.DataFile("toolhive/logs")
if err != nil {
return "", fmt.Errorf("failed to get logs directory path: %v", err)
return "", fmt.Errorf("failed to get logs directory path: %w", err)
}

if _, err := os.Stat(logsDir); os.IsNotExist(err) {
Expand All @@ -156,12 +156,12 @@ func getLogsDirectory() (string, error) {
func getManagedContainerNames(ctx context.Context) (map[string]bool, error) {
manager, err := workloads.NewManager(ctx)
if err != nil {
return nil, fmt.Errorf("failed to create status manager: %v", err)
return nil, fmt.Errorf("failed to create status manager: %w", err)
}

managedContainers, err := manager.ListWorkloads(ctx, true)
if err != nil {
return nil, fmt.Errorf("failed to list workloads: %v", err)
return nil, fmt.Errorf("failed to list workloads: %w", err)
}

managedNames := make(map[string]bool)
Expand All @@ -182,7 +182,7 @@ func getLogFiles(logsDir string) ([]string, error) {

logFiles, err := filepath.Glob(filepath.Join(logsDir, "*.log"))
if err != nil {
return nil, fmt.Errorf("failed to list log files: %v", err)
return nil, fmt.Errorf("failed to list log files: %w", err)
}

return logFiles, nil
Expand Down Expand Up @@ -232,7 +232,7 @@ func getProxyLogs(workloadName string) error {
// Get the proxy log file path
logFilePath, err := xdg.DataFile(fmt.Sprintf("toolhive/logs/%s.log", workloadName))
if err != nil {
return fmt.Errorf("failed to get proxy log file path: %v", err)
return fmt.Errorf("failed to get proxy log file path: %w", err)
}

// Clean the file path to prevent path traversal
Expand All @@ -255,7 +255,7 @@ func followProxyLogFile(logFilePath string) error {
// Open the file
file, err := os.Open(cleanLogFilePath)
if err != nil {
return fmt.Errorf("failed to open proxy log %s: %v", cleanLogFilePath, err)
return fmt.Errorf("failed to open proxy log %s: %w", cleanLogFilePath, err)
}
defer file.Close()

Expand All @@ -268,7 +268,7 @@ func followProxyLogFile(logFilePath string) error {
// Seek to the end of the file for following
_, err = file.Seek(0, 2)
if err != nil {
return fmt.Errorf("failed to seek to end of proxy log: %v", err)
return fmt.Errorf("failed to seek to end of proxy log: %w", err)
}

// Follow the file for new content
Expand All @@ -277,7 +277,7 @@ func followProxyLogFile(logFilePath string) error {
buffer := make([]byte, 1024)
n, err := file.Read(buffer)
if err != nil && err.Error() != "EOF" {
return fmt.Errorf("error reading proxy log: %v", err)
return fmt.Errorf("error reading proxy log: %w", err)
}

if n > 0 {
Expand Down
8 changes: 4 additions & 4 deletions cmd/thv/app/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func proxyCmdFunc(cmd *cobra.Command, args []string) error {
// Get authentication middleware for incoming requests
authMiddleware, authInfoHandler, err := auth.GetAuthenticationMiddleware(ctx, oidcConfig)
if err != nil {
return fmt.Errorf("failed to create authentication middleware: %v", err)
return fmt.Errorf("failed to create authentication middleware: %w", err)
}
middlewares = append(middlewares, types.NamedMiddleware{
Name: "auth",
Expand Down Expand Up @@ -264,7 +264,7 @@ func proxyCmdFunc(cmd *cobra.Command, args []string) error {
nil, // onHealthCheckFailed - not needed for local proxies
middlewares...)
if err := proxy.Start(ctx); err != nil {
return fmt.Errorf("failed to start proxy: %v", err)
return fmt.Errorf("failed to start proxy: %w", err)
}

logger.Infof("Transparent proxy started for server %s on port %d -> %s",
Expand Down Expand Up @@ -397,13 +397,13 @@ func addExternalTokenMiddleware(middlewares *[]types.NamedMiddleware, tokenSourc
// Create middleware using TokenSource - middleware handles token selection
tokenExchangeMiddleware, err = tokenexchange.CreateMiddlewareFromTokenSource(*tokenExchangeConfig, tokenSource)
if err != nil {
return fmt.Errorf("failed to create token exchange middleware: %v", err)
return fmt.Errorf("failed to create token exchange middleware: %w", err)
}
} else {
// Create middleware that extracts token from Authorization header
tokenExchangeMiddleware, err = tokenexchange.CreateMiddlewareFromHeader(*tokenExchangeConfig)
if err != nil {
return fmt.Errorf("failed to create token exchange middleware: %v", err)
return fmt.Errorf("failed to create token exchange middleware: %w", err)
}
}
*middlewares = append(*middlewares, types.NamedMiddleware{
Expand Down
Loading
Loading