Skip to content

Instantly share code, notes, and snippets.

@azdagron
Last active July 16, 2024 20:35
Show Gist options
  • Save azdagron/b55f1e70e1855cfa1aa73cb8f0027699 to your computer and use it in GitHub Desktop.
Save azdagron/b55f1e70e1855cfa1aa73cb8f0027699 to your computer and use it in GitHub Desktop.
Plugin configuration/validation common code
package pluginconf
import (
"fmt"
configv1 "github.com/spiffe/spire-plugin-sdk/proto/spire/service/common/config/v1"
"github.com/spiffe/spire/pkg/common/catalog"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type Status struct {
notes []string
err error
}
func (r *Status) ReportInfof(format string, args ...any) {
r.appendNote(format, args...)
}
func (r *Status) ReportErrorf(format string, args ...any) {
note := r.appendNote(format, args...)
if r.err == nil {
r.err = status.Error(codes.InvalidArgument, note)
}
}
func (r *Status) appendNote(format string, args ...any) string {
note := fmt.Sprintf(format, args...)
r.notes = append(r.notes, note)
return note
}
// Request represents either a ConfigureRequest or a ValidateRequest
type Request interface {
GetCoreConfiguration() *configv1.CoreConfiguration
GetHclConfiguration() string
}
func Build[C any](req Request, build func(coreConfig catalog.CoreConfig, hclTest string, status *Status, configOut *C) (*C, []string, error) {
var coreConfig catalog.CoreConfig
// TODO: validate core config and convert into a catalog.CoreConfig (more strongly typed)
var status Status
var config C
build(coreConfig, req.GetHclConfiguration(), &status, &config)
if status.err != nil {
return nil, status.notes, status.err
}
return &config, status.notes, nil
}
// Use it like so:
//
//
//import (
// "github.com/spiffe/spire/pkg/common/pluginconf"
//)
//
//func (p *Plugin) Configure(_ context.Context, req *configv1.ConfigureRequest) (*configv1.ConfigureResponse, error) {
// config, _, err := pluginconf.Build(req, buildConfig)
// if err != nil {
// return nil, err
// }
//
// // TODO: stash config
// return nil
// }
//
//func (p *Plugin) Validate(_ context.Context, req *configv1.ValidateRequest) (*configv1.ValidateResponse, error) {
// _, notes, err := pluginconf.Build(req, buildConfig)
// return &configv1.ValidateResponse{
// Valid: err == nil,
// Notes: notes,
// }, nil
// }
//
//type MyPluginsConfig struct {
// Foo string
//}
//
//func buildConfig(coreConfig catalog.CoreConfig, hclTest string, status *Status, out *MyPluginsConfig) {
// // Do whatever is needed to parse the config
// //
// // When you hit an error
// status.ReportErrorf("oh no: dooooooom %v", err)
//
// // When you have an informational note
// status.ReportInfof("hmm")
//
// // Otherwise, just populate "out"
// out.Foo = "whatever"
//}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment