grafana / grafana/xk6-sql

Proposal: Introduce `Adapter` interface for driver-specific DSN parsing

Open
#177 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
190
Forks
65
Avg merge
2d 11h
Merged PRs (30d)
10

Description

## Context
With the release of k6 v1.5.0, extensions now have access to `GetAddrResolver()`. This allows extensions to resolve addresses while respecting k6's internal network policies, such as `blockHostnames`, `hosts` file configurations, and DNS rules.

To support centralized network validation in `xk6-sql` and ensure all SQL connections adhere to these security policies, the core module requires knowledge of the target hostname(s) before a connection is established.

## Problem
Currently, `xk6-sql` passes the DSN (Data Source Name) string directly to the underlying driver. The core module lacks visibility into connection details (host, port, etc.) because every database driver uses a unique DSN format. Implementing parsing logic for every supported driver inside the core `xk6-sql` module would be brittle and violate the separation of concerns.

## Proposal
This proposal introduces an `Adapter` interface and a new registration function, `RegisterAdapter`. This mechanism allows driver extensions to optionally provide a DSN parser.

**Crucially, for drivers registered via `RegisterAdapter`, the core `xk6-sql` module will automatically validate the addresses returned by the adapter using `GetAddrResolver().ResolveAddr()`.** This ensures that connections are checked against k6's network security policies (e.g., allowlists, blocklists) before the SQL driver attempts to open a socket. Drivers registered via the legacy method will bypass this validation to maintain backward compatibility.

## Proposed API Changes

The proposal adds a struct to hold extracted configuration and an interface for the adapter:

```go
package sql

// DataSourceInfo holds properties extracted from a Data Source Name (DSN).
type DataSourceInfo struct {
// Addrs is a list of "host" or "host:port" strings found in the DSN.
Addrs []string
}

// Adapter defines the interface that driver extensions can optionally implement
// to provide parsing logic.
type Adapter interface {
ParseDSN(dsn string) (DataSourceInfo, error)
}
```

A new registration function will be added alongside the existing `RegisterDriver`:

```go
// RegisterAdapter registers a driver with a custom adapter for DSN parsing.
// This allows the driver to opt-in to core validation logic.
//
// Note: This function registers the driver name internally.
// Extensions using RegisterAdapter do NOT need to call RegisterDriver separately.
func RegisterAdapter(driverName string, adapter Adapter) *sobek.Symbol
```

## Benefits
1. **Centralized Validation:** `xk6-sql` can enforce k6 network policies for all drivers that implement the adapter.
2. **Backward Compatibility:** Existing drivers using `RegisterDriver` (without an adapter) will continue to function as they do today.
3. **Decoupling:** The parsing logic remains within the driver extension (which is aware of its own DSN format), while the policy enforcement logic resides centrally in the core.

Contributor guide

Open the contributing guide

Research direction

Start by reading the existing RegisterDriver entry point and the proposed Adapter, DataSourceInfo, and RegisterAdapter APIs. Trace how GetAddrResolver() would validate adapter-provided addresses while preserving legacy behavior. Done means adapter-backed drivers can parse DSNs, receive centralized validation, and existing RegisterDriver users remain compatible.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.