func NewRegistry(configuration Config, asbNamespace string) (Registry, error) {
	return NewCustomRegistry(configuration, nil, asbNamespace)
}
NewRegistry - Create a new registry from the registry config.
package registries
import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"net/url"
	"regexp"
	"strings"
	"sync"
	"github.com/automationbroker/bundle-lib/bundle"
	"github.com/automationbroker/bundle-lib/clients"
	"github.com/automationbroker/bundle-lib/registries/adapters"
	log "github.com/sirupsen/logrus"
	yaml "gopkg.in/yaml.v1"
)
var regex = regexp.MustCompile(`[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*`)
type Config struct {
	URL string
	AuthType   string `yaml:"auth_type"`
	AuthName   string `yaml:"auth_name"`
	User       string
	Pass       string
	Token      string
	Org        string
	Tag        string
	Type       string
	Name       string
	Runner     string
	Images     []string
	Namespaces []string
	Fail          bool     `yaml:"fail_on_error"`
	WhiteList     []string `yaml:"white_list"`
	BlackList     []string `yaml:"black_list"`
	SkipVerifyTLS bool     `yaml:"skip_verify_tls"`
}
func (c Config) Validate() bool {
	if c.Name == "" {
		return false
	}
	switch c.AuthType {
	case "file":
		if c.AuthName == "" {
			return false
		}
	case "secret":
		if c.AuthName == "" {
			return false
		}
	case "config":
		if c.Type == "quay" && c.Token == "" {
			return false
		} else if c.User == "" || c.Pass == "" {
			return false
		}
	case "":
		if c.AuthName != "" {
			return false
		}
	default:
		return false
	}
	m := regex.FindString(c.Name)
	return m == c.Name
}
type Registry struct {
	adapter adapters.Adapter
	filter  Filter
	config  Config
}
func (r Registry) LoadSpecs() ([]*bundle.Spec, int, error) {
	imageNames, err := r.adapter.GetImageNames()
	if err != nil {
		log.Errorf("unable to retrieve image names for registry %v - %v",
			r.config.Name, err)
		return []*bundle.Spec{}, 0, err
	}
	validNames, filteredNames := r.filter.Run(imageNames)
	log.Debugf("Filter applied against registry: %s", r.config.Name)
	if len(validNames) != 0 {
		log.Debugf("Bundles passing white/blacklist filter:")
		for _, name := range validNames {
			log.Debugf("-> %s", name)
		}
	}
	if len(filteredNames) != 0 {
		var buffer bytes.Buffer
		buffer.WriteString("Bundles filtered by white/blacklist filter:")
		for _, name := range filteredNames {
			buffer.WriteString(fmt.Sprintf("-> %s", name))
		}
		log.Infof(buffer.String())
	}
	specs, err := r.adapter.FetchSpecs(validNames)
	if err != nil {
		log.Errorf("unable to fetch specs for registry %v - %v",
			r.config.Name, err)
		return []*bundle.Spec{}, 0, err
	}
	log.Infof("Validating specs...")
	validatedSpecs := validateSpecs(specs)
	failedSpecsCount := len(specs) - len(validatedSpecs)
	if failedSpecsCount != 0 {
		log.Warningf(
			"%d specs of %d discovered specs failed validation from registry: %s",
			failedSpecsCount, len(specs), r.adapter.RegistryName())
	} else {
		log.Infof("All specs passed validation!")
	}
	return validatedSpecs, len(imageNames), nil
}
func (r Registry) Fail(err error) bool {
	if r.config.Fail {
		return true
	}
	return false
}
func (r Registry) RegistryName() string {
	return r.config.Name
}
func NewCustomRegistry(configuration Config, adapter adapters.Adapter, asbNamespace string) (Registry, error) {
	if !configuration.Validate() {
		return Registry{}, errors.New("unable to validate registry name")
	}
	configuration, err := retrieveRegistryAuth(configuration, asbNamespace)
	if err != nil {
		log.Errorf("Unable to retrieve registry auth: %v", err)
		return Registry{}, err
	}
	log.Info("== REGISTRY CX == ")
	log.Info(fmt.Sprintf("Name: %s", configuration.Name))
	log.Info(fmt.Sprintf("Type: %s", configuration.Type))
	log.Info(fmt.Sprintf("Url: %s", configuration.URL))
	u, err := url.Parse(configuration.URL)
	if err != nil {
		log.Errorf("url is not valid: %v", configuration.URL)
		u = &url.URL{}
	}
	if u.Scheme == "" {
		u.Scheme = "http"
	}
	if adapter == nil {
		c := adapters.Configuration{
			URL:           u,
			User:          configuration.User,
			Pass:          configuration.Pass,
			Token:         configuration.Token,
			Org:           configuration.Org,
			Runner:        configuration.Runner,
			Images:        configuration.Images,
			Namespaces:    configuration.Namespaces,
			Tag:           configuration.Tag,
			SkipVerifyTLS: configuration.SkipVerifyTLS,
			AdapterName:   configuration.Name,
		}
		switch strings.ToLower(configuration.Type) {
		case "rhcc":
			adapter = adapters.NewRHCCAdapter(c)
		case "dockerhub":
			adapter = &adapters.DockerHubAdapter{Config: c}
		case "mock":
			adapter = &adapters.MockAdapter{Config: c}
		case "local_openshift":
			adapter = &adapters.LocalOpenShiftAdapter{Config: c}
		case "helm":
			adapter = &adapters.HelmAdapter{Config: c}
		case "openshift":
			adapter, err = adapters.NewOpenShiftAdapter(c)
		case "partner_rhcc":
			adapter, err = adapters.NewPartnerRhccAdapter(c)
		case "apiv2":
			adapter, err = adapters.NewAPIV2Adapter(c)
		case "quay":
			adapter, err = adapters.NewQuayAdapter(c)
		case "galaxy":
			adapter = &adapters.GalaxyAdapter{Config: c}
		default:
			log.Errorf("Unknown registry type - %s", configuration.Type)
			return Registry{}, errors.New("Unknown registry type")
		}
		if err != nil {
			return Registry{}, err
		}
	} else {
		log.Infof("Using custom adapter, %v", adapter.RegistryName())
	}
	return Registry{
		adapter: adapter,
		filter:  createFilter(configuration),
		config:  configuration,
	}, nil
}