iperf3exporter/vendor/gocloud.dev/secrets/secrets.go

232 lines
7.3 KiB
Go
Raw Normal View History

2021-10-20 10:08:56 +02:00
// Copyright 2019 The Go Cloud Development Kit Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package secrets provides an easy and portable way to encrypt and decrypt
// messages. Subpackages contain driver implementations of
// secrets for supported services.
//
// See https://gocloud.dev/howto/secrets/ for a detailed how-to guide.
//
//
// OpenCensus Integration
//
// OpenCensus supports tracing and metric collection for multiple languages and
// backend providers. See https://opencensus.io.
//
// This API collects OpenCensus traces and metrics for the following methods:
// - Encrypt
// - Decrypt
// All trace and metric names begin with the package import path.
// The traces add the method name.
// For example, "gocloud.dev/secrets/Encrypt".
// The metrics are "completed_calls", a count of completed method calls by driver,
// method and status (error code); and "latency", a distribution of method latency
// by driver and method.
// For example, "gocloud.dev/secrets/latency".
//
// To enable trace collection in your application, see "Configure Exporter" at
// https://opencensus.io/quickstart/go/tracing.
// To enable metric collection in your application, see "Exporting stats" at
// https://opencensus.io/quickstart/go/metrics.
package secrets // import "gocloud.dev/secrets"
import (
"context"
"net/url"
"sync"
"gocloud.dev/internal/gcerr"
"gocloud.dev/internal/oc"
"gocloud.dev/internal/openurl"
"gocloud.dev/secrets/driver"
)
// Keeper does encryption and decryption. To create a Keeper, use constructors
// found in driver subpackages.
type Keeper struct {
k driver.Keeper
tracer *oc.Tracer
// mu protects the closed variable.
// Read locks are kept to allow holding a read lock for long-running calls,
// and thereby prevent closing until a call finishes.
mu sync.RWMutex
closed bool
}
// NewKeeper is intended for use by drivers only. Do not use in application code.
var NewKeeper = newKeeper
// newKeeper creates a Keeper.
func newKeeper(k driver.Keeper) *Keeper {
return &Keeper{
k: k,
tracer: &oc.Tracer{
Package: pkgName,
Provider: oc.ProviderName(k),
LatencyMeasure: latencyMeasure,
},
}
}
const pkgName = "gocloud.dev/secrets"
var (
latencyMeasure = oc.LatencyMeasure(pkgName)
// OpenCensusViews are predefined views for OpenCensus metrics.
// The views include counts and latency distributions for API method calls.
// See the example at https://godoc.org/go.opencensus.io/stats/view for usage.
OpenCensusViews = oc.Views(pkgName, latencyMeasure)
)
// Encrypt encrypts the plaintext and returns the cipher message.
func (k *Keeper) Encrypt(ctx context.Context, plaintext []byte) (ciphertext []byte, err error) {
ctx = k.tracer.Start(ctx, "Encrypt")
defer func() { k.tracer.End(ctx, err) }()
k.mu.RLock()
defer k.mu.RUnlock()
if k.closed {
return nil, errClosed
}
b, err := k.k.Encrypt(ctx, plaintext)
if err != nil {
return nil, wrapError(k, err)
}
return b, nil
}
// Decrypt decrypts the ciphertext and returns the plaintext.
func (k *Keeper) Decrypt(ctx context.Context, ciphertext []byte) (plaintext []byte, err error) {
ctx = k.tracer.Start(ctx, "Decrypt")
defer func() { k.tracer.End(ctx, err) }()
k.mu.RLock()
defer k.mu.RUnlock()
if k.closed {
return nil, errClosed
}
b, err := k.k.Decrypt(ctx, ciphertext)
if err != nil {
return nil, wrapError(k, err)
}
return b, nil
}
var errClosed = gcerr.Newf(gcerr.FailedPrecondition, nil, "secrets: Keeper has been closed")
// Close releases any resources used for the Keeper.
func (k *Keeper) Close() error {
k.mu.Lock()
prev := k.closed
k.closed = true
k.mu.Unlock()
if prev {
return errClosed
}
return wrapError(k, k.k.Close())
}
// ErrorAs converts i to driver-specific types. See
// https://gocloud.dev/concepts/as/ for background information and the
// driver package documentation for the specific types supported for
// that driver.
//
// ErrorAs panics if i is nil or not a pointer.
// ErrorAs returns false if err == nil.
func (k *Keeper) ErrorAs(err error, i interface{}) bool {
return gcerr.ErrorAs(err, i, k.k.ErrorAs)
}
func wrapError(k *Keeper, err error) error {
if err == nil {
return nil
}
if gcerr.DoNotWrap(err) {
return err
}
return gcerr.New(k.k.ErrorCode(err), err, 2, "secrets")
}
// KeeperURLOpener represents types that can open Keepers based on a URL.
// The opener must not modify the URL argument. OpenKeeperURL must be safe to
// call from multiple goroutines.
//
// This interface is generally implemented by types in driver packages.
type KeeperURLOpener interface {
OpenKeeperURL(ctx context.Context, u *url.URL) (*Keeper, error)
}
// URLMux is a URL opener multiplexer. It matches the scheme of the URLs
// against a set of registered schemes and calls the opener that matches the
// URL's scheme.
// See https://gocloud.dev/concepts/urls/ for more information.
//
// The zero value is a multiplexer with no registered schemes.
type URLMux struct {
schemes openurl.SchemeMap
}
// KeeperSchemes returns a sorted slice of the registered Keeper schemes.
func (mux *URLMux) KeeperSchemes() []string { return mux.schemes.Schemes() }
// ValidKeeperScheme returns true iff scheme has been registered for Keepers.
func (mux *URLMux) ValidKeeperScheme(scheme string) bool { return mux.schemes.ValidScheme(scheme) }
// RegisterKeeper registers the opener with the given scheme. If an opener
// already exists for the scheme, RegisterKeeper panics.
func (mux *URLMux) RegisterKeeper(scheme string, opener KeeperURLOpener) {
mux.schemes.Register("secrets", "Keeper", scheme, opener)
}
// OpenKeeper calls OpenKeeperURL with the URL parsed from urlstr.
// OpenKeeper is safe to call from multiple goroutines.
func (mux *URLMux) OpenKeeper(ctx context.Context, urlstr string) (*Keeper, error) {
opener, u, err := mux.schemes.FromString("Keeper", urlstr)
if err != nil {
return nil, err
}
return opener.(KeeperURLOpener).OpenKeeperURL(ctx, u)
}
// OpenKeeperURL dispatches the URL to the opener that is registered with the
// URL's scheme. OpenKeeperURL is safe to call from multiple goroutines.
func (mux *URLMux) OpenKeeperURL(ctx context.Context, u *url.URL) (*Keeper, error) {
opener, err := mux.schemes.FromURL("Keeper", u)
if err != nil {
return nil, err
}
return opener.(KeeperURLOpener).OpenKeeperURL(ctx, u)
}
var defaultURLMux = new(URLMux)
// DefaultURLMux returns the URLMux used by OpenKeeper.
//
// Driver packages can use this to register their KeeperURLOpener on the mux.
func DefaultURLMux() *URLMux {
return defaultURLMux
}
// OpenKeeper opens the Keeper identified by the URL given.
// See the URLOpener documentation in driver subpackages for
// details on supported URL formats, and https://gocloud.dev/concepts/urls
// for more information.
func OpenKeeper(ctx context.Context, urlstr string) (*Keeper, error) {
return defaultURLMux.OpenKeeper(ctx, urlstr)
}