pkg/api/config.go (82 lines of code) (raw):

// 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 api import ( "errors" "io" "net/http" "net/url" "strings" "time" "github.com/elastic/cloud-sdk-go/pkg/auth" "github.com/elastic/cloud-sdk-go/pkg/multierror" ) var ( errEmptyAuthWriter = errors.New("auth writer must not be empty") errESSInvalidAuth = errors.New( "apikey is the only valid authentication mechanism when targeting the Elasticsearch Service", ) ) // Config contains the API config type Config struct { Client *http.Client AuthWriter auth.Writer Host string // SkipTLSVerify will not perform any TLS/SSL verification. SkipTLSVerify bool // SkipLogin skips validating the user / password with the instanced API // when AuthWriter equals *auth.UserLogin. SkipLogin bool // ErrorDevice is used to send errors to prevent cluttering the output. ErrorDevice io.Writer VerboseSettings // Timeout for all of the API calls performed through the API structure. Timeout time.Duration // UserAgent if specified, it sets the user agent on all outgoing requests. UserAgent string // Number of retries to perform on request timeout. Retries int // Cooldown time between retries. RetryBackoff time.Duration } // Validate returns an error if the config is invalid func (c *Config) Validate() error { var merr = multierror.NewPrefixed("invalid api config") if c.Client == nil { merr = merr.Append(errors.New("client cannot be empty")) } if c.AuthWriter == nil { merr = merr.Append(errEmptyAuthWriter) } merr = merr.Append(checkHost(c.Host)) merr = merr.Append(c.VerboseSettings.Validate()) _, apikeyPtr := c.AuthWriter.(*auth.APIKey) _, apikey := c.AuthWriter.(auth.APIKey) if c.Host == ESSEndpoint && !(apikey || apikeyPtr) { merr = merr.Append(errESSInvalidAuth) } return merr.ErrorOrNil() } func (c *Config) fillDefaults() { if c.Timeout.Nanoseconds() <= 0 { c.Timeout = DefaultTimeout } if c.UserAgent == "" { c.UserAgent = DefaultUserAgent } if c.Host == "" { c.Host = ESSEndpoint } } // VerboseSettings define the behaviour of verbosity. type VerboseSettings struct { Device io.Writer Verbose bool // RedactAuth replaces the contents of the Authorization header with: // "[REDACTED]". RedactAuth bool } // Validate ensures the settings are usable. func (settings VerboseSettings) Validate() error { var merr = multierror.NewPrefixed("invalid verbose settings") if settings.Verbose && settings.Device == nil { merr = merr.Append(errors.New( "output device cannot be empty when verbose is enabled", )) } return merr.ErrorOrNil() } func checkHost(host string) error { if host == "" { return errors.New("host cannot be empty") } if !strings.HasSuffix(host, "/") { host += "/" } _, err := url.ParseRequestURI(host) return err }