Documentation ¶
Index ¶
- Variables
- type ModifyHTTPRequestFunc
- type NewResourceFunc
- type NewSeederOpts
- type Options
- type OptionsBuilder
- func (b *OptionsBuilder) Build() (*Options, error)
- func (b *OptionsBuilder) WithIgnoredErrors(errs ...error) *OptionsBuilder
- func (b *OptionsBuilder) WithIncrementalTags(count int) *OptionsBuilder
- func (b *OptionsBuilder) WithModifyHTTPRequestFuncs(modifyRequestFuncs ...ModifyHTTPRequestFunc) *OptionsBuilder
- func (b *OptionsBuilder) WithNewResourceFunc(typ model.Type, inheritDefault bool, f NewResourceFunc) *OptionsBuilder
- func (b *OptionsBuilder) WithRandomTagCount(count int, allowEmpty bool) *OptionsBuilder
- func (b *OptionsBuilder) WithResourceCount(count int) *OptionsBuilder
- func (b *OptionsBuilder) WithStaticTags(tags []string) *OptionsBuilder
- type ResourceInfo
- type Result
- type Results
- type Seeder
Constants ¶
This section is empty.
Variables ¶
var DefaultNewResourceFuncs = map[model.Type]NewResourceFunc{ resource.TypeCACertificate: func(_ Seeder, m proto.Message, _ int) error { r := m.(*v1.CACertificate) var err error r.Cert, _, err = util.GenerateCertificate(defaultCertificateBits) return err }, resource.TypeCertificate: func(_ Seeder, m proto.Message, _ int) error { r := m.(*v1.Certificate) var err error r.Cert, r.Key, err = util.GenerateCertificate(defaultCertificateBits) return err }, resource.TypeConsumer: func(_ Seeder, m proto.Message, i int) error { r := m.(*v1.Consumer) r.Username = fmt.Sprintf("username-%d", i+1) return nil }, resource.TypePlugin: func(s Seeder, m proto.Message, i int) error { r := m.(*v1.Plugin) r.Name = "key-auth" services := s.Results().ByType(resource.TypeService).All() if l := len(services); l == 0 { return errors.New("must create services before seeding plugins, in order to ensure unique resources") } else if l < i+1 { return errors.New("must create an equal number of services & plugins") } r.Service = &v1.Service{Id: services[i].ID} return nil }, resource.TypePluginSchema: func(s Seeder, m proto.Message, i int) error { r := m.(*v1.PluginSchema) r.LuaSchema = fmt.Sprintf(`return { name = "%s", fields = { { config = { type = "record", fields = { { field = { type = "string" } } } } } } }`, fmt.Sprintf("plugin-schema-%d", i+1)) return nil }, resource.TypeRoute: func(_ Seeder, m proto.Message, i int) error { r := m.(*v1.Route) r.Name, r.Hosts = fmt.Sprintf("route-%d", i+1), []string{"example.com"} return nil }, resource.TypeService: func(_ Seeder, m proto.Message, i int) error { r := m.(*v1.Service) r.Name, r.Host = fmt.Sprintf("service-%d", i+1), "example.com" return nil }, resource.TypeSNI: func(s Seeder, m proto.Message, i int) error { r := m.(*v1.SNI) r.Name = fmt.Sprintf("example-%d.com", i) certificates := s.Results().ByType(resource.TypeCertificate).All() if len(certificates) == 0 { return errors.New("must create at least one certificate before seeding SNIs") } r.Certificate = &v1.Certificate{Id: certificates[0].ID} return nil }, resource.TypeTarget: func(s Seeder, m proto.Message, i int) error { r := m.(*v1.Target) r.Target = "127.0.0.1:8080" upstreams := s.Results().ByType(resource.TypeUpstream).All() if l := len(upstreams); l == 0 { return errors.New("must create upstreams before seeding targets, in order to ensure unique resources") } else if l < i+1 { return errors.New("must create an equal number of upstreams & targets") } r.Upstream = &v1.Upstream{Id: upstreams[i].ID} return nil }, resource.TypeUpstream: func(_ Seeder, m proto.Message, i int) error { r := m.(*v1.Upstream) r.Name = fmt.Sprintf("upstream-%d", i+1) return nil }, }
DefaultNewResourceFuncs contains the NewResourceFunc functions for resources that require other fields to be set. Read the documentation on the NewResourceFunc for more info.
This map must not be updated after application initialization (as it is not safe to update while a seeder is running). It is exported to allow callers the ability to define new functions that piggyback off the default behavior.
We know the resources are of the proper type, so we're disabling the type assertion linter.
var DefaultRandSourceFunc = func(typ model.Type) (rand.Source, error) { h := fnv.New32a() if _, err := h.Write([]byte(typ)); err != nil { return nil, err } return rand.NewSource(int64(h.Sum32())), nil }
DefaultRandSourceFunc defines the default function used for determining the random source based on a given type.
var ErrRequiredFieldMissing = errors.New("field does not exist for type")
ErrRequiredFieldMissing is returned during a seed call when a type does not have a required field to properly seed the resource. For example, this can happen when tags should be created, however, the resource is missing the `tags` field.
Functions ¶
This section is empty.
Types ¶
type ModifyHTTPRequestFunc ¶
ModifyHTTPRequestFunc defines a function that can manipulate the passed in HTTP request for the given type. The function must be safe for concurrent use.
type NewResourceFunc ¶
NewResourceFunc allows the seeder to properly set the desired fields on a resource that require more fields than just an ID to be created.
The passed in seeder can be used to get IDs of dependent resources.
The passed in integer is the current resource's index in the underling storage. This is helpful when the resource requires a dependency, and uniqueness needs to be ensured.
The function must be safe for concurrent use.
type NewSeederOpts ¶
type NewSeederOpts struct { // The URL to the control plane RESTful API, with the scheme. e.g.: http://127.0.0.1:8080 URL string // Optional max amount of resources to be seeded at one time. When zero, // defaults to runtime.NumCPU(). Otherwise, must be a positive number. ConcurrencyLimit int // Optional HTTP client to use. When nil, will default to http.DefaultClient. HTTPClient *http.Client // Optional function that handles setting the random source used for deterministically generating random // data, like tags, based on the given type name. When nil, defaults to DefaultRandSourceFunc. RandSourceFunc func(typ model.Type) (rand.Source, error) // Optional map allowing to set custom NewResourceFunc functions, that will be called for the associated // type when creating the resource. When empty, will default to DefaultNewResourceFuncs. NewResourceFuncs map[model.Type]NewResourceFunc // Optional Protobuf registry, used for HTTP rule binding verification. // When nil, defaults to protoregistry.GlobalFiles. ProtoRegistry *protoregistry.Files }
NewSeederOpts defines the configuration used to instantiate a new seeder. The config should not be updated after it is set on a seeder.
type Options ¶
type Options struct {
// contains filtered or unexported fields
}
Options defines the non-exported options that the Seeder seed methods can take in. Must be formed using NewOptionsBuilder().
type OptionsBuilder ¶
type OptionsBuilder struct {
// contains filtered or unexported fields
}
OptionsBuilder allows seeder options to be built, used for each seed call.
func NewOptionsBuilder ¶
func NewOptionsBuilder() *OptionsBuilder
NewOptionsBuilder instantiates a new instance of an OptionsBuilder.
func (*OptionsBuilder) Build ¶
func (b *OptionsBuilder) Build() (*Options, error)
Build validates the passed in options & returns the generated options, that can be passed to the seed methods.
func (*OptionsBuilder) WithIgnoredErrors ¶
func (b *OptionsBuilder) WithIgnoredErrors(errs ...error) *OptionsBuilder
WithIgnoredErrors can be used to skip specific errors when seeding all types with the Seeder.SeedAllTypes() call. For example,the ErrRequiredFieldMissing error can be set to continue seeding when a type is missing a field that is expected.
func (*OptionsBuilder) WithIncrementalTags ¶
func (b *OptionsBuilder) WithIncrementalTags(count int) *OptionsBuilder
WithIncrementalTags sets the specified number of unique tags on each resource, starting from "tag-1".
The count argument must be a non-zero, positive number, and it represents the max number of tags that can be created on a resource. If it's set to one, each resource will only have one tag. If it's set to any higher number, resources can have more than one tag, but each tag is only used once.
E.g.: If ten resources are being seeded, with the count set to one, "tag-1"-"tag-10" will be used. In the event the seeder is run multiple times, it will still ensure unique tags (as long as this option is specified).
func (*OptionsBuilder) WithModifyHTTPRequestFuncs ¶
func (b *OptionsBuilder) WithModifyHTTPRequestFuncs(modifyRequestFuncs ...ModifyHTTPRequestFunc) *OptionsBuilder
WithModifyHTTPRequestFuncs can be used to modify the HTTP request to create a resource. The functions are executed in the order they are provided.
func (*OptionsBuilder) WithNewResourceFunc ¶
func (b *OptionsBuilder) WithNewResourceFunc(typ model.Type, inheritDefault bool, f NewResourceFunc) *OptionsBuilder
WithNewResourceFunc overrides a default NewResourceFunc for a single seed call.
When inheritDefault is true, the new resource function on the seeder will be executed before, and if said function is not defined, it will then default to those defined in DefaultNewResourceFuncs.
func (*OptionsBuilder) WithRandomTagCount ¶
func (b *OptionsBuilder) WithRandomTagCount(count int, allowEmpty bool) *OptionsBuilder
WithRandomTagCount sets the max number of tags to be created, starting from "tag-1".
When zero (or option is redacted), no tags will be set on the resources. When the field is non-zero, random tags will be created for each object (using NewSeederOpts.RandSourceFunc), up to the given amount.
The allowEmpty flag controls whether resources can be created with no tags.
E.g.: If `2` is set & allowEmpty is true, a resource can have any of the given combinations of tags: (no tags), `tag-1`, `tag-2`, `tag-1, tag-2`.
func (*OptionsBuilder) WithResourceCount ¶
func (b *OptionsBuilder) WithResourceCount(count int) *OptionsBuilder
WithResourceCount sets the number of resources to create for each type being seeded. Must be a non-zero, positive number.
func (*OptionsBuilder) WithStaticTags ¶
func (b *OptionsBuilder) WithStaticTags(tags []string) *OptionsBuilder
WithStaticTags sets optional tags to set on each resource. When used, this overrides all default tag generation behavior (as in, no other tags will be set but these).
type ResourceInfo ¶
type ResourceInfo struct { // The resource being described. Name model.Type // Our custom JSON schema extension defining internal config for a resource. JSONSchemaConfig *extension.Config // The relevant JSON schema for this resource. Schema *jsonschema.Schema // contains filtered or unexported fields }
ResourceInfo stores various information related to a specific resource.
func (*ResourceInfo) HasField ¶
func (ri *ResourceInfo) HasField(fieldName string) bool
HasField is a helper function to determine if a field exists on the JSON schema.
type Result ¶
Result defines a single resource, with some common fields shared across resources & its underling Protobuf message.
type Results ¶
type Results struct {
// contains filtered or unexported fields
}
Results is a list of Result objects.
func (*Results) Add ¶
Add is used to insert new results for a specific type. This is safe for concurrent use.
func (*Results) All ¶
All returns all results, regardless of resource type. This is safe for concurrent use.
func (*Results) AllByType ¶
AllByType returns all results keyed by its resource type. This is safe for concurrent use.
func (*Results) ByType ¶
ByType returns the given results for a particular resource type. In the event no results were created for the type, nil is returned. This is safe for concurrent use.
type Seeder ¶
type Seeder interface { // Results returns all resources that were created by result of running the seeder (in the event // the seeder was run multiple times, all resources created across each run will be returned). Results() *Results // AllResourceInfo returns extended information about all registered resources that are capable of being seeded. // // Resources that cannot be seeded include: // - Resources missing `$["x-koko-config"].resourceAPIPath` on the JSON schema. // - Resources missing a `POST /v1/(resource)` HTTP binding defined on the gRPC service. AllResourceInfo() []*ResourceInfo // ResourceInfoByType returns extended information for the provided resource. ResourceInfoByType(typ model.Type) *ResourceInfo // SeedAllTypes creates resources, based on the provided options, for all registered // resources. For more information, read the documentation for Seeder.Seed(). SeedAllTypes(context.Context, *Options) (*Results, error) // Seed creates the given number of resources for the provided resource. The newly created results will be // returned & added to the underlining seeder object. // // In the event this method is called multiple times, any newly created resources will be appended to the // seeder instance. This will affect the results when calling seeder.Results(). // // The ErrNoResourcePath & ErrRequiredFieldMissing errors may be returned as a wrapped error, and can be // checked using errors.Is(). See documentation for the mentioned errors in this file for more detail. Seed(context.Context, *Options, ...model.Type) (*Results, error) }
Seeder handles creating test resources, usually used to ease integration testing. All methods defined on the interface are safe for concurrent use.
func New ¶
func New(opts NewSeederOpts) (Seeder, error)
New instantiates a seeder with the given config.
In the event new resources are registered, you must instantiate a new seeder for those resources to be picked up.