1
0
Fork 0

New logger for the Traefik logs

This commit is contained in:
Ludovic Fernandez 2022-11-21 18:36:05 +01:00 committed by GitHub
parent 27c02b5a56
commit 56f7515ecd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
297 changed files with 2337 additions and 1934 deletions

View file

@ -19,9 +19,10 @@ import (
"github.com/go-acme/lego/v4/lego"
"github.com/go-acme/lego/v4/providers/dns"
"github.com/go-acme/lego/v4/registration"
"github.com/rs/zerolog/log"
ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/log"
"github.com/traefik/traefik/v2/pkg/logs"
httpmuxer "github.com/traefik/traefik/v2/pkg/muxer/http"
tcpmuxer "github.com/traefik/traefik/v2/pkg/muxer/tcp"
"github.com/traefik/traefik/v2/pkg/safe"
@ -131,8 +132,7 @@ func (p *Provider) ListenConfiguration(config dynamic.Configuration) {
// Init for compatibility reason the BaseProvider implements an empty Init.
func (p *Provider) Init() error {
ctx := log.With(context.Background(), log.Str(log.ProviderName, p.ResolverName+".acme"))
logger := log.FromContext(ctx)
logger := log.With().Str(logs.ProviderName, p.ResolverName+".acme").Logger()
if len(p.Configuration.Storage) == 0 {
return errors.New("unable to initialize ACME provider with no storage location for the certificates")
@ -149,8 +149,8 @@ func (p *Provider) Init() error {
}
// Reset Account if caServer changed, thus registration URI can be updated
if p.account != nil && p.account.Registration != nil && !isAccountMatchingCaServer(ctx, p.account.Registration.URI, p.CAServer) {
logger.Info("Account URI does not match the current CAServer. The account will be reset.")
if p.account != nil && p.account.Registration != nil && !isAccountMatchingCaServer(logger.WithContext(context.Background()), p.account.Registration.URI, p.CAServer) {
logger.Info().Msg("Account URI does not match the current CAServer. The account will be reset.")
p.account = nil
}
@ -169,17 +169,17 @@ func (p *Provider) Init() error {
}
func isAccountMatchingCaServer(ctx context.Context, accountURI, serverURI string) bool {
logger := log.FromContext(ctx)
logger := log.Ctx(ctx)
aru, err := url.Parse(accountURI)
if err != nil {
logger.Infof("Unable to parse account.Registration URL: %v", err)
logger.Info().Err(err).Str("registrationURL", accountURI).Msg("Unable to parse account.Registration URL")
return false
}
cau, err := url.Parse(serverURI)
if err != nil {
logger.Infof("Unable to parse CAServer URL: %v", err)
logger.Info().Err(err).Str("caServerURL", serverURI).Msg("Unable to parse CAServer URL")
return false
}
@ -194,9 +194,9 @@ func (p *Provider) ThrottleDuration() time.Duration {
// Provide allows the file provider to provide configurations to traefik
// using the given Configuration channel.
func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
ctx := log.With(context.Background(),
log.Str(log.ProviderName, p.ResolverName+".acme"),
log.Str("ACME CA", p.Configuration.CAServer))
logger := log.With().Str(logs.ProviderName, p.ResolverName+".acme").Str("acmeCA", p.Configuration.CAServer).
Logger()
ctx := logger.WithContext(context.Background())
p.pool = pool
@ -211,7 +211,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
p.configurationChan <- msg
renewPeriod, renewInterval := getCertificateRenewDurations(p.CertificatesDuration)
log.FromContext(ctx).Debugf("Attempt to renew certificates %q before expiry and check every %q",
logger.Debug().Msgf("Attempt to renew certificates %q before expiry and check every %q",
renewPeriod, renewInterval)
p.renewCertificates(ctx, renewPeriod)
@ -236,8 +236,9 @@ func (p *Provider) getClient() (*lego.Client, error) {
p.clientMutex.Lock()
defer p.clientMutex.Unlock()
ctx := log.With(context.Background(), log.Str(log.ProviderName, p.ResolverName+".acme"))
logger := log.FromContext(ctx)
logger := log.With().Str(logs.ProviderName, p.ResolverName+".acme").Logger()
ctx := logger.WithContext(context.Background())
if p.client != nil {
return p.client, nil
@ -248,13 +249,13 @@ func (p *Provider) getClient() (*lego.Client, error) {
return nil, err
}
logger.Debug("Building ACME client...")
logger.Debug().Msg("Building ACME client...")
caServer := lego.LEDirectoryProduction
if len(p.CAServer) > 0 {
caServer = p.CAServer
}
logger.Debug(caServer)
logger.Debug().Msg(caServer)
config := lego.NewConfig(account)
config.CADirURL = caServer
@ -290,7 +291,7 @@ func (p *Provider) getClient() (*lego.Client, error) {
}
if p.DNSChallenge != nil && len(p.DNSChallenge.Provider) > 0 {
logger.Debugf("Using DNS Challenge provider: %s", p.DNSChallenge.Provider)
logger.Debug().Msgf("Using DNS Challenge provider: %s", p.DNSChallenge.Provider)
var provider challenge.Provider
provider, err = dns.NewDNSChallengeProviderByName(p.DNSChallenge.Provider)
@ -302,7 +303,7 @@ func (p *Provider) getClient() (*lego.Client, error) {
dns01.CondOption(len(p.DNSChallenge.Resolvers) > 0, dns01.AddRecursiveNameservers(p.DNSChallenge.Resolvers)),
dns01.WrapPreCheck(func(domain, fqdn, value string, check dns01.PreCheckFunc) (bool, error) {
if p.DNSChallenge.DelayBeforeCheck > 0 {
logger.Debugf("Delaying %d rather than validating DNS propagation now.", p.DNSChallenge.DelayBeforeCheck)
logger.Debug().Msgf("Delaying %d rather than validating DNS propagation now.", p.DNSChallenge.DelayBeforeCheck)
time.Sleep(time.Duration(p.DNSChallenge.DelayBeforeCheck))
}
@ -319,7 +320,7 @@ func (p *Provider) getClient() (*lego.Client, error) {
}
if p.HTTPChallenge != nil && len(p.HTTPChallenge.EntryPoint) > 0 {
logger.Debug("Using HTTP Challenge provider.")
logger.Debug().Msg("Using HTTP Challenge provider.")
err = client.Challenge.SetHTTP01Provider(p.HTTPChallengeProvider)
if err != nil {
@ -328,7 +329,7 @@ func (p *Provider) getClient() (*lego.Client, error) {
}
if p.TLSChallenge != nil {
logger.Debug("Using TLS Challenge provider.")
logger.Debug().Msg("Using TLS Challenge provider.")
err = client.Challenge.SetTLSALPN01Provider(p.TLSChallengeProvider)
if err != nil {
@ -358,30 +359,30 @@ func (p *Provider) initAccount(ctx context.Context) (*Account, error) {
}
func (p *Provider) register(ctx context.Context, client *lego.Client) (*registration.Resource, error) {
logger := log.FromContext(ctx)
logger := log.Ctx(ctx)
if p.EAB != nil {
logger.Info("Register with external account binding...")
logger.Info().Msg("Register with external account binding...")
eabOptions := registration.RegisterEABOptions{TermsOfServiceAgreed: true, Kid: p.EAB.Kid, HmacEncoded: p.EAB.HmacEncoded}
return client.Registration.RegisterWithExternalAccountBinding(eabOptions)
}
logger.Info("Register...")
logger.Info().Msg("Register...")
return client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
}
func (p *Provider) resolveDomains(ctx context.Context, domains []string, tlsStore string) {
logger := log.FromContext(ctx)
logger := log.Ctx(ctx)
if len(domains) == 0 {
logger.Debug("No domain parsed in provider ACME")
logger.Debug().Msg("No domain parsed in provider ACME")
return
}
logger.Debugf("Trying to challenge certificate for domain %v found in HostSNI rule", domains)
logger.Debug().Msgf("Trying to challenge certificate for domain %v found in HostSNI rule", domains)
var domain types.Domain
if len(domains) > 0 {
@ -393,20 +394,22 @@ func (p *Provider) resolveDomains(ctx context.Context, domains []string, tlsStor
safe.Go(func() {
dom, cert, err := p.resolveCertificate(ctx, domain, tlsStore)
if err != nil {
logger.Errorf("Unable to obtain ACME certificate for domains %q: %v", strings.Join(domains, ","), err)
logger.Error().Err(err).Strs("domains", domains).Msg("Unable to obtain ACME certificate for domains")
return
}
err = p.addCertificateForDomain(dom, cert, tlsStore)
if err != nil {
logger.WithError(err).Error("Error adding certificate for domain")
logger.Error().Err(err).Strs("domains", dom.ToStrArray()).Msg("Error adding certificate for domains")
}
})
}
}
func (p *Provider) watchNewDomains(ctx context.Context) {
ctx = log.With(ctx, log.Str(log.ProviderName, p.ResolverName+".acme"))
rootLogger := log.Ctx(ctx).With().Str(logs.ProviderName, p.ResolverName+".acme").Logger()
ctx = rootLogger.WithContext(ctx)
p.pool.GoCtx(func(ctxPool context.Context) {
for {
select {
@ -417,8 +420,8 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
continue
}
ctxRouter := log.With(ctx, log.Str(log.RouterName, routerName), log.Str(log.Rule, route.Rule))
logger := log.FromContext(ctxRouter)
logger := rootLogger.With().Str(logs.RouterName, routerName).Str(logs.Rule, route.Rule).Logger()
ctxRouter := logger.WithContext(ctx)
if len(route.TLS.Domains) > 0 {
domains := deleteUnnecessaryDomains(ctxRouter, route.TLS.Domains)
@ -427,20 +430,20 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
safe.Go(func() {
dom, cert, err := p.resolveCertificate(ctx, domain, traefiktls.DefaultTLSStoreName)
if err != nil {
logger.WithError(err).Errorf("Unable to obtain ACME certificate for domains %q", strings.Join(domain.ToStrArray(), ","))
logger.Error().Err(err).Strs("domains", domain.ToStrArray()).Msg("Unable to obtain ACME certificate for domains")
return
}
err = p.addCertificateForDomain(dom, cert, traefiktls.DefaultTLSStoreName)
if err != nil {
logger.WithError(err).Error("Error adding certificate for domain")
logger.Error().Err(err).Strs("domains", dom.ToStrArray()).Msg("Error adding certificate for domains")
}
})
}
} else {
domains, err := tcpmuxer.ParseHostSNI(route.Rule)
if err != nil {
logger.WithError(err).Errorf("Error parsing domains in provider ACME")
logger.Error().Err(err).Msg("Error parsing domains in provider ACME")
continue
}
p.resolveDomains(ctxRouter, domains, traefiktls.DefaultTLSStoreName)
@ -454,8 +457,8 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
continue
}
ctxRouter := log.With(ctx, log.Str(log.RouterName, routerName), log.Str(log.Rule, route.Rule))
logger := log.FromContext(ctxRouter)
logger := rootLogger.With().Str(logs.RouterName, routerName).Str(logs.Rule, route.Rule).Logger()
ctxRouter := logger.WithContext(ctx)
if len(route.TLS.Domains) > 0 {
domains := deleteUnnecessaryDomains(ctxRouter, route.TLS.Domains)
@ -464,20 +467,20 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
safe.Go(func() {
dom, cert, err := p.resolveCertificate(ctx, domain, traefiktls.DefaultTLSStoreName)
if err != nil {
logger.WithError(err).Errorf("Unable to obtain ACME certificate for domains %q", strings.Join(domain.ToStrArray(), ","))
logger.Error().Err(err).Strs("domains", domain.ToStrArray()).Msg("Unable to obtain ACME certificate for domains")
return
}
err = p.addCertificateForDomain(dom, cert, traefiktls.DefaultTLSStoreName)
if err != nil {
logger.WithError(err).Error("Error adding certificate for domain")
logger.Error().Err(err).Strs("domains", dom.ToStrArray()).Msg("Error adding certificate for domain")
}
})
}
} else {
domains, err := httpmuxer.ParseDomains(route.Rule)
if err != nil {
logger.WithError(err).Errorf("Error parsing domains in provider ACME")
logger.Error().Err(err).Msg("Error parsing domains in provider ACME")
continue
}
p.resolveDomains(ctxRouter, domains, traefiktls.DefaultTLSStoreName)
@ -490,11 +493,10 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
}
for tlsStoreName, tlsStore := range config.TLS.Stores {
ctxTLSStore := log.With(ctx, log.Str(log.TLSStoreName, tlsStoreName))
logger := log.FromContext(ctxTLSStore)
logger := rootLogger.With().Str(logs.TLSStoreName, tlsStoreName).Logger()
if tlsStore.DefaultCertificate != nil && tlsStore.DefaultGeneratedCert != nil {
logger.Warn("defaultCertificate and defaultGeneratedCert cannot be defined at the same time.")
logger.Warn().Msg("defaultCertificate and defaultGeneratedCert cannot be defined at the same time.")
}
// Gives precedence to the user defined default certificate.
@ -503,7 +505,7 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
}
if tlsStore.DefaultGeneratedCert.Domain == nil || tlsStore.DefaultGeneratedCert.Resolver == "" {
logger.Warn("default generated certificate domain or resolver is missing.")
logger.Warn().Msg("default generated certificate domain or resolver is missing.")
continue
}
@ -513,18 +515,18 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
validDomains, err := p.sanitizeDomains(ctx, *tlsStore.DefaultGeneratedCert.Domain)
if err != nil {
logger.WithError(err).Errorf("domains validation: %s", strings.Join(tlsStore.DefaultGeneratedCert.Domain.ToStrArray(), ","))
logger.Error().Err(err).Strs("domains", tlsStore.DefaultGeneratedCert.Domain.ToStrArray()).Msg("domains validation")
}
if p.certExists(validDomains) {
logger.Debug("Default ACME certificate generation is not required.")
logger.Debug().Msg("Default ACME certificate generation is not required.")
continue
}
safe.Go(func() {
cert, err := p.resolveDefaultCertificate(ctx, validDomains)
if err != nil {
logger.WithError(err).Errorf("Unable to obtain ACME certificate for domain %q", strings.Join(validDomains, ","))
logger.Error().Err(err).Strs("domains", validDomains).Msgf("Unable to obtain ACME certificate for domain")
return
}
@ -537,7 +539,7 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
err = p.addCertificateForDomain(domain, cert, traefiktls.DefaultTLSStoreName)
if err != nil {
logger.WithError(err).Error("Error adding certificate for domain")
logger.Error().Err(err).Msg("Error adding certificate for domain")
}
})
}
@ -549,7 +551,7 @@ func (p *Provider) watchNewDomains(ctx context.Context) {
}
func (p *Provider) resolveDefaultCertificate(ctx context.Context, domains []string) (*certificate.Resource, error) {
logger := log.FromContext(ctx)
logger := log.Ctx(ctx)
p.resolvingDomainsMutex.Lock()
@ -571,7 +573,7 @@ func (p *Provider) resolveDefaultCertificate(ctx context.Context, domains []stri
defer p.removeResolvingDomains(append(domains, domainKey))
logger.Debugf("Loading ACME certificates %+v...", domains)
logger.Debug().Msgf("Loading ACME certificates %+v...", domains)
client, err := p.getClient()
if err != nil {
@ -596,7 +598,7 @@ func (p *Provider) resolveDefaultCertificate(ctx context.Context, domains []stri
return nil, fmt.Errorf("certificate for domains %v is empty: %v", domains, cert)
}
logger.Debugf("Default certificate obtained for domains %+v", domains)
logger.Debug().Msgf("Default certificate obtained for domains %+v", domains)
return cert, nil
}
@ -615,8 +617,8 @@ func (p *Provider) resolveCertificate(ctx context.Context, domain types.Domain,
defer p.removeResolvingDomains(uncheckedDomains)
logger := log.FromContext(ctx)
logger.Debugf("Loading ACME certificates %+v...", uncheckedDomains)
logger := log.Ctx(ctx)
logger.Debug().Msgf("Loading ACME certificates %+v...", uncheckedDomains)
client, err := p.getClient()
if err != nil {
@ -641,7 +643,7 @@ func (p *Provider) resolveCertificate(ctx context.Context, domain types.Domain,
return types.Domain{}, nil, fmt.Errorf("certificate for domains %v is empty: %v", uncheckedDomains, cert)
}
logger.Debugf("Certificates obtained for domains %+v", uncheckedDomains)
logger.Debug().Msgf("Certificates obtained for domains %+v", uncheckedDomains)
domain = types.Domain{Main: uncheckedDomains[0]}
if len(uncheckedDomains) > 1 {
@ -712,7 +714,7 @@ func getCertificateRenewDurations(certificatesDuration int) (time.Duration, time
func deleteUnnecessaryDomains(ctx context.Context, domains []types.Domain) []types.Domain {
var newDomains []types.Domain
logger := log.FromContext(ctx)
logger := log.Ctx(ctx)
for idxDomainToCheck, domainToCheck := range domains {
keepDomain := true
@ -724,7 +726,7 @@ func deleteUnnecessaryDomains(ctx context.Context, domains []types.Domain) []typ
if reflect.DeepEqual(domain, domainToCheck) {
if idxDomainToCheck > idxDomain {
logger.Warnf("The domain %v is duplicated in the configuration but will be process by ACME provider only once.", domainToCheck)
logger.Warn().Msgf("The domain %v is duplicated in the configuration but will be process by ACME provider only once.", domainToCheck)
keepDomain = false
}
break
@ -736,11 +738,11 @@ func deleteUnnecessaryDomains(ctx context.Context, domains []types.Domain) []typ
for _, domainProcessed := range domainToCheck.ToStrArray() {
if idxDomain < idxDomainToCheck && isDomainAlreadyChecked(domainProcessed, domain.ToStrArray()) {
// The domain is duplicated in a CN
logger.Warnf("Domain %q is duplicated in the configuration or validated by the domain %v. It will be processed once.", domainProcessed, domain)
logger.Warn().Msgf("Domain %q is duplicated in the configuration or validated by the domain %v. It will be processed once.", domainProcessed, domain)
continue
} else if domain.Main != domainProcessed && strings.HasPrefix(domain.Main, "*") && isDomainAlreadyChecked(domainProcessed, []string{domain.Main}) {
// Check if a wildcard can validate the domain
logger.Warnf("Domain %q will not be processed by ACME provider because it is validated by the wildcard %q", domainProcessed, domain.Main)
logger.Warn().Msgf("Domain %q will not be processed by ACME provider because it is validated by the wildcard %q", domainProcessed, domain.Main)
continue
}
newDomainsToCheck = append(newDomainsToCheck, domainProcessed)
@ -791,9 +793,9 @@ func (p *Provider) buildMessage() dynamic.Message {
}
func (p *Provider) renewCertificates(ctx context.Context, renewPeriod time.Duration) {
logger := log.FromContext(ctx)
logger := log.Ctx(ctx)
logger.Info("Testing certificate renew...")
logger.Info().Msg("Testing certificate renew...")
p.certificatesMu.RLock()
@ -811,11 +813,11 @@ func (p *Provider) renewCertificates(ctx context.Context, renewPeriod time.Durat
for _, cert := range certificates {
client, err := p.getClient()
if err != nil {
logger.WithError(err).Infof("Error renewing certificate from LE : %+v", cert.Domain)
logger.Info().Err(err).Msgf("Error renewing certificate from LE : %+v", cert.Domain)
continue
}
logger.Infof("Renewing certificate from LE : %+v", cert.Domain)
logger.Info().Msgf("Renewing certificate from LE : %+v", cert.Domain)
renewedCert, err := client.Certificate.Renew(certificate.Resource{
Domain: cert.Domain.Main,
@ -823,18 +825,18 @@ func (p *Provider) renewCertificates(ctx context.Context, renewPeriod time.Durat
Certificate: cert.Certificate.Certificate,
}, true, ocspMustStaple, p.PreferredChain)
if err != nil {
logger.WithError(err).Errorf("Error renewing certificate from LE: %v", cert.Domain)
logger.Error().Err(err).Msgf("Error renewing certificate from LE: %v", cert.Domain)
continue
}
if len(renewedCert.Certificate) == 0 || len(renewedCert.PrivateKey) == 0 {
logger.Errorf("domains %v renew certificate with no value: %v", cert.Domain.ToStrArray(), cert)
logger.Error().Msgf("domains %v renew certificate with no value: %v", cert.Domain.ToStrArray(), cert)
continue
}
err = p.addCertificateForDomain(cert.Domain, renewedCert, cert.Store)
if err != nil {
logger.WithError(err).Error("Error adding certificate for domain")
logger.Error().Err(err).Msg("Error adding certificate for domain")
}
}
}
@ -842,7 +844,7 @@ func (p *Provider) renewCertificates(ctx context.Context, renewPeriod time.Durat
// Get provided certificate which check a domains list (Main and SANs)
// from static and dynamic provided certificates.
func (p *Provider) getUncheckedDomains(ctx context.Context, domainsToCheck []string, tlsStore string) []string {
log.FromContext(ctx).Debugf("Looking for provided certificate(s) to validate %q...", domainsToCheck)
log.Ctx(ctx).Debug().Msgf("Looking for provided certificate(s) to validate %q...", domainsToCheck)
var allDomains []string
store := p.tlsManager.GetStore(tlsStore)
@ -884,21 +886,24 @@ func searchUncheckedDomains(ctx context.Context, domainsToCheck, existentDomains
}
}
logger := log.FromContext(ctx)
logger := log.Ctx(ctx)
if len(uncheckedDomains) == 0 {
logger.Debugf("No ACME certificate generation required for domains %q.", domainsToCheck)
logger.Debug().Strs("domains", domainsToCheck).Msg("No ACME certificate generation required for domains")
} else {
logger.Debugf("Domains %q need ACME certificates generation for domains %q.", domainsToCheck, strings.Join(uncheckedDomains, ","))
logger.Debug().Strs("domains", domainsToCheck).Msgf("Domains need ACME certificates generation for domains %q.", strings.Join(uncheckedDomains, ","))
}
return uncheckedDomains
}
func getX509Certificate(ctx context.Context, cert *Certificate) (*x509.Certificate, error) {
logger := log.FromContext(ctx)
logger := log.Ctx(ctx)
tlsCert, err := tls.X509KeyPair(cert.Certificate, cert.Key)
if err != nil {
logger.WithError(err).Errorf("Failed to load TLS key pair from ACME certificate for domain %q (SAN : %q), certificate will be renewed", cert.Domain.Main, strings.Join(cert.Domain.SANs, ","))
logger.Error().Err(err).
Str("domain", cert.Domain.Main).
Strs("SANs", cert.Domain.SANs).
Msg("Failed to load TLS key pair from ACME certificate for domain, certificate will be renewed")
return nil, err
}
@ -906,7 +911,10 @@ func getX509Certificate(ctx context.Context, cert *Certificate) (*x509.Certifica
if crt == nil {
crt, err = x509.ParseCertificate(tlsCert.Certificate[0])
if err != nil {
logger.WithError(err).Errorf("Failed to parse TLS key pair from ACME certificate for domain %q (SAN : %q), certificate will be renewed", cert.Domain.Main, strings.Join(cert.Domain.SANs, ","))
logger.Error().Err(err).
Str("domain", cert.Domain.Main).
Strs("SANs", cert.Domain.SANs).
Msg("Failed to parse TLS key pair from ACME certificate for domain, certificate will be renewed")
}
}
@ -935,7 +943,7 @@ func (p *Provider) sanitizeDomains(ctx context.Context, domain types.Domain) ([]
canonicalDomain := types.CanonicalDomain(dom)
cleanDomain := dns01.UnFqdn(canonicalDomain)
if canonicalDomain != cleanDomain {
log.FromContext(ctx).Warnf("FQDN detected, please remove the trailing dot: %s", canonicalDomain)
log.Ctx(ctx).Warn().Msgf("FQDN detected, please remove the trailing dot: %s", canonicalDomain)
}
cleanDomains = append(cleanDomains, cleanDomain)