pomerium/internal/zero/bootstrap/writers/writers.go
Joe Kralicky de603f87de
Add new configurable bootstrap writers (#2405) (#5114)
* Add new configurable bootstrap writers (#2405)

This PR adds the ability to configure different backends to use for
storing modifications to the zero bootstrap config. The two currently
implemented backends allow writing changes to a file or to a Kubernetes
secret. Backend selection is determined by the scheme in a URI passed to
the flag '--config-writeback-uri'.

In a Kubernetes environment, where the bootstrap config is mounted into
the pod from a secret, this option allows Pomerium to write changes back
to the secret, as writes to the mounted secret file on disk are not
persisted.

* Use env vars for bootstrap config filepath/writeback uri

* linter pass and code cleanup

* Add new config writer options mechanism

This moves the encryption cipher parameter out of the WriteConfig()
method in the ConfigWriter interface and into a new ConfigWriterOptions
struct. Options (e.g. cipher) can be applied to an existing ConfigWriter
to allow customizing implementation-specific behavior.

* Code cleanup/lint fixes

* Move vendored k8s code into separate package, and add license header and package comment
2024-05-31 12:26:17 -04:00

50 lines
1.1 KiB
Go

package writers
import (
"context"
"crypto/cipher"
"fmt"
"net/url"
"sync"
cluster_api "github.com/pomerium/pomerium/pkg/zero/cluster"
)
type ConfigWriter interface {
WriteConfig(ctx context.Context, src *cluster_api.BootstrapConfig) error
WithOptions(opts ConfigWriterOptions) ConfigWriter
}
type ConfigWriterOptions struct {
// A cipher used to encrypt the configuration before writing it.
// If nil, the configuration will be written in plaintext.
Cipher cipher.AEAD
}
// A WriterBuilder creates and initializes a new ConfigWriter previously
// obtained from LoadWriter.
type WriterBuilder func(uri *url.URL) (ConfigWriter, error)
var writers sync.Map
func RegisterBuilder(scheme string, wb WriterBuilder) {
writers.Store(scheme, wb)
}
func LoadBuilder(scheme string) WriterBuilder {
if writer, ok := writers.Load(scheme); ok {
return writer.(WriterBuilder)
}
return nil
}
func NewForURI(uri string) (ConfigWriter, error) {
u, err := url.Parse(uri)
if err != nil {
return nil, fmt.Errorf("malformed uri: %w", err)
}
if wb := LoadBuilder(u.Scheme); wb != nil {
return wb(u)
}
return nil, fmt.Errorf("unknown scheme: %q", u.Scheme)
}