youtubebeat/vendor/github.com/elastic/beats/libbeat/autodiscover/builder.go

130 lines
3.5 KiB
Go

// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you 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
//
// http://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 autodiscover
import (
"errors"
"fmt"
"strings"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/common/bus"
"github.com/elastic/beats/libbeat/logp"
)
// Builder provides an interface by which configs can be built from provider metadata
type Builder interface {
// CreateConfig creates a config from hints passed from providers
CreateConfig(event bus.Event) []*common.Config
}
// Builders is a list of Builder objects
type Builders []Builder
// BuilderConstructor is a func used to generate a Builder object
type BuilderConstructor func(*common.Config) (Builder, error)
// AddBuilder registers a new BuilderConstructor
func (r *registry) AddBuilder(name string, builder BuilderConstructor) error {
r.lock.Lock()
defer r.lock.Unlock()
if name == "" {
return fmt.Errorf("builder name is required")
}
_, exists := r.builders[name]
if exists {
return fmt.Errorf("builder '%s' is already registered", name)
}
if builder == nil {
return fmt.Errorf("builder '%s' cannot be registered with a nil factory", name)
}
r.builders[name] = builder
logp.Debug(debugK, "Builder registered: %s", name)
return nil
}
// GetBuilder returns the provider with the giving name, nil if it doesn't exist
func (r *registry) GetBuilder(name string) BuilderConstructor {
r.lock.RLock()
defer r.lock.RUnlock()
name = strings.ToLower(name)
return r.builders[name]
}
// BuildBuilder reads provider configuration and instantiate one
func (r *registry) BuildBuilder(c *common.Config) (Builder, error) {
var config BuilderConfig
err := c.Unpack(&config)
if err != nil {
return nil, err
}
builder := r.GetBuilder(config.Type)
if builder == nil {
return nil, fmt.Errorf("unknown autodiscover builder %s", config.Type)
}
return builder(c)
}
// GetConfig creates configs for all builders initialized.
func (b Builders) GetConfig(event bus.Event) []*common.Config {
var configs []*common.Config
for _, builder := range b {
if config := builder.CreateConfig(event); config != nil {
configs = append(configs, config...)
}
}
return configs
}
// NewBuilders instances the given list of builders. If hintsEnabled is true it will
// just enable the hints builder
func NewBuilders(bConfigs []*common.Config, hintsEnabled bool) (Builders, error) {
var builders Builders
if hintsEnabled {
if len(bConfigs) > 0 {
return nil, errors.New("hints.enabled is incompatible with manually defining builders")
}
hints, err := common.NewConfigFrom(map[string]string{"type": "hints"})
if err != nil {
return nil, err
}
bConfigs = append(bConfigs, hints)
}
for _, bcfg := range bConfigs {
builder, err := Registry.BuildBuilder(bcfg)
if err != nil {
return nil, err
}
builders = append(builders, builder)
}
return builders, nil
}