Documentation
¶
Overview ¶
Package dbfwd connects a program to a database that is reachable only through a forward, such as a database that runs on Kubernetes.
Resolve reads a URL that github.com/xo/dburl parsed, such as k+cnpg://pg.prod/app, finds the database and its credentials, starts the forward, and returns a Forward with an ordinary URL for a local port. The URL holds no password. The backend finds it.
A backend registers itself from init. A program imports the backends it uses:
import _ "github.com/xo/dbfwd/k8s"
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Backend ¶
type Backend interface {
// Lookup runs the lookup for u.
Lookup(ctx context.Context, u *dburl.URL, cfg Config) (*Match, error)
// Open starts a forward to the database that u names, and returns once it
// is ready.
Open(ctx context.Context, u *dburl.URL, cfg Config) (*Opened, error)
}
Backend finds a database and starts a forward to it. A backend registers itself from init with Register.
type Config ¶
type Config struct {
// Tools maps the name of a tool, such as kubectl, to its path.
Tools map[string]string
// Env holds the variables that WithEnv set, as KEY=value, in order.
Env []string
// Interactive runs a child process with the terminal, or is nil.
Interactive func(run func(tty *os.File) error) error
}
Config is the configuration of one call, built from its options. A caller never builds one. A backend reads it.
type Error ¶
type Error string
Error is an error.
const ( // ErrNoBackend is the error for a URL whose scheme has no backend. ErrNoBackend Error = "no backend for the scheme" // ErrNoTool is the error when a tool that the backend runs, such as // kubectl, is missing or cannot run. The error that wraps it names the // tool. ErrNoTool Error = "tool is missing or cannot run" // refused, because they expired or a login failed. The fix is to log in // again. ErrUnauthorized Error = "not logged in" // ErrForbidden is the error when a step was not allowed, by RBAC or by // IAM. The fix is to ask for access. ErrForbidden Error = "not allowed" // ErrNotFound is the error when no step of the lookup matched. ErrNotFound Error = "not found" // ErrAmbiguous is the error when a step matched more than one object, or // the signals for the type disagree. ErrAmbiguous Error = "more than one match" // ErrUnsupported is the error for a database that no database/sql driver // can reach, such as MongoDB, or for a target that a forward cannot reach, // such as an ExternalName Service. ErrUnsupported Error = "not supported" // ErrRoleConflict is the error when role disagrees with the target, such // as role=ro with the Service pg-rw. ErrRoleConflict Error = "role conflicts with the target" // ErrQueryKey is the error when a driver key has the name of a key of the // backend. ErrQueryKey Error = "query key clashes with a key of the backend" // ErrBadURL is the error when a URL cannot be read. It names no part of // the URL, because a local URL holds a password. ErrBadURL Error = "the URL is not valid" // ErrForwardLost is the error when a running forward stops on its own. ErrForwardLost Error = "forward lost" // ErrClosed is the error when a forward is used after Close. ErrClosed Error = "forward closed" )
Error values.
type Forward ¶
type Forward struct {
// User is the user the URL logs in as.
User string
// Database is the database the URL opens. It is empty when the database
// has none.
Database string
// Target is the object that the lookup matched.
Target Target
// contains filtered or unexported fields
}
Forward is a running forward to a database. Its methods are safe to call from more than one goroutine.
func Resolve ¶
Resolve finds the database that u names, starts a forward to it, and returns the Forward. It returns when the forward is ready.
The backend is chosen by u.SchemeName. Canceling ctx before Resolve returns stops it and releases everything it started. After Resolve returns, ctx no longer controls the forward, and Forward.Close does.
func (*Forward) Close ¶
Close stops the forward and releases the local port. It is safe to call more than once.
func (*Forward) Done ¶
func (f *Forward) Done() <-chan struct{}
Done returns a channel that is closed when the forward stops, by Close or because it was lost.
func (*Forward) Err ¶
Err returns nil while the forward runs and after Close. It returns why the forward was lost, as an error that wraps ErrForwardLost.
func (*Forward) String ¶
String returns the target, such as "Service pg-rw in context kind-prod, namespace prod, owned by CloudNativePG Cluster pg". It never holds the password.
func (*Forward) URL ¶
URL returns the URL of the local end, such as postgres://app:...@127.0.0.1:41234/app. It holds the password, so it must never be printed or logged. When the credential of the backend expires, URL makes a new one first. After the forward is lost, it returns an error that wraps ErrForwardLost.
Call URL for each new connection, and do not keep its result. It is cheap when nothing expired, and safe to call from many goroutines at once.
type LookupError ¶
type LookupError struct {
// Name is the name in the URL.
Name string
// Scope is where the lookup looked.
Scope []Field
// Steps is each step that was tried.
Steps []Step
// Err is the error value, such as ErrNotFound.
Err error
}
LookupError is the error of a lookup that failed. It names what was tried, and wraps one of the error values.
func (*LookupError) Error ¶
func (err *LookupError) Error() string
Error satisfies the error interface.
type Match ¶
type Match struct {
// Target is the object that matched.
Target Target
// Steps is each step that Lookup tried, in order.
Steps []Step
}
Match is what Lookup found.
type Opened ¶
type Opened struct {
// URL is the URL of the local end, as a string for dburl.Parse. It holds
// the password.
URL string
// Expires is when the credential in URL expires. It is zero when the
// credential does not expire.
Expires time.Time
// Renew makes a new URL when the credential expires, and returns when the
// new one expires. It is nil when the credential does not expire.
Renew func(ctx context.Context) (string, time.Time, error)
// User is the user the URL logs in as.
User string
// Database is the database the URL opens, or empty.
Database string
// Target is the object that the lookup matched.
Target Target
// Tunnel is the running forward.
Tunnel Tunnel
}
Opened is what a backend returns from Open.
type Option ¶
type Option func(*Config)
Option sets one value of the Config of a call of Resolve or Lookup.
func WithEnv ¶
WithEnv sets the environment variable key to value for every child process of the call, such as WithEnv("KUBECONFIG", path). With no such option, a child process gets the environment of the caller.
func WithInteractive ¶
WithInteractive runs each child process that can prompt inside fn, so that a credential plugin or a login can use the terminal. With no such option, no child process gets a terminal.
type Step ¶
type Step struct {
// Kind is the kind that the step looked for, such as "Helm release".
Kind string
// Result says what the step found, such as "no match", "not installed",
// "not allowed" or "match".
Result string
}
Step is one step of a lookup.
type Target ¶
type Target struct {
// Backend is the name of the backend, such as "k8s".
Backend string
// Scope is where the object lives, from the outside in, such as the
// context and the namespace for Kubernetes.
Scope []Field
// Kind is the kind of the object that matched, such as "Service".
Kind string
// Name is the name of the object that matched, such as "pg-rw".
Name string
// Owner is what manages the object, such as "CloudNativePG Cluster pg".
// It is empty when nothing manages it.
Owner string
// Type is the database type, such as "postgres".
Type string
}
Target is the object that a lookup matched.
type Tunnel ¶
type Tunnel interface {
// Done returns a channel that is closed when the tunnel stops.
Done() <-chan struct{}
// Err returns why the tunnel stopped, after Done is closed.
Err() error
// Close stops the tunnel. It is safe to call more than once.
Close() error
}
Tunnel is the running forward of a backend.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
dbfwd
command
Command dbfwd connects the native client of a database, or usql, to a database that is reachable only through a forward, such as a database that runs on Kubernetes.
|
Command dbfwd connects the native client of a database, or usql, to a database that is reachable only through a forward, such as a database that runs on Kubernetes. |
|
Package k8s is the Kubernetes backend of dbfwd.
|
Package k8s is the Kubernetes backend of dbfwd. |