...

Source file src/github.com/letsencrypt/boulder/observer/probers/http/http_conf.go

Documentation: github.com/letsencrypt/boulder/observer/probers/http

     1  package probers
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  
     7  	"github.com/letsencrypt/boulder/observer/probers"
     8  	"github.com/letsencrypt/boulder/strictyaml"
     9  	"github.com/prometheus/client_golang/prometheus"
    10  )
    11  
    12  // HTTPConf is exported to receive YAML configuration.
    13  type HTTPConf struct {
    14  	URL       string `yaml:"url"`
    15  	RCodes    []int  `yaml:"rcodes"`
    16  	UserAgent string `yaml:"useragent"`
    17  	Insecure  bool   `yaml:"insecure"`
    18  }
    19  
    20  // Kind returns a name that uniquely identifies the `Kind` of `Configurer`.
    21  func (c HTTPConf) Kind() string {
    22  	return "HTTP"
    23  }
    24  
    25  // UnmarshalSettings takes YAML as bytes and unmarshals it to the to an
    26  // HTTPConf object.
    27  func (c HTTPConf) UnmarshalSettings(settings []byte) (probers.Configurer, error) {
    28  	var conf HTTPConf
    29  	err := strictyaml.Unmarshal(settings, &conf)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	return conf, nil
    34  }
    35  
    36  func (c HTTPConf) validateURL() error {
    37  	url, err := url.Parse(c.URL)
    38  	if err != nil {
    39  		return fmt.Errorf(
    40  			"invalid 'url', got: %q, expected a valid url", c.URL)
    41  	}
    42  	if url.Scheme == "" {
    43  		return fmt.Errorf(
    44  			"invalid 'url', got: %q, missing scheme", c.URL)
    45  	}
    46  	return nil
    47  }
    48  
    49  func (c HTTPConf) validateRCodes() error {
    50  	if len(c.RCodes) == 0 {
    51  		return fmt.Errorf(
    52  			"invalid 'rcodes', got: %q, please specify at least one", c.RCodes)
    53  	}
    54  	for _, c := range c.RCodes {
    55  		// ensure rcode entry is in range 100-599
    56  		if c < 100 || c > 599 {
    57  			return fmt.Errorf(
    58  				"'rcodes' contains an invalid HTTP response code, '%d'", c)
    59  		}
    60  	}
    61  	return nil
    62  }
    63  
    64  // MakeProber constructs a `HTTPProbe` object from the contents of the
    65  // bound `HTTPConf` object. If the `HTTPConf` cannot be validated, an
    66  // error appropriate for end-user consumption is returned instead.
    67  func (c HTTPConf) MakeProber(_ map[string]prometheus.Collector) (probers.Prober, error) {
    68  	// validate `url`
    69  	err := c.validateURL()
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	// validate `rcodes`
    75  	err = c.validateRCodes()
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	// Set default User-Agent if none set.
    81  	if c.UserAgent == "" {
    82  		c.UserAgent = "letsencrypt/boulder-observer-http-client"
    83  	}
    84  	return HTTPProbe{c.URL, c.RCodes, c.UserAgent, c.Insecure}, nil
    85  }
    86  
    87  // Instrument is a no-op to implement the `Configurer` interface.
    88  func (c HTTPConf) Instrument() map[string]prometheus.Collector {
    89  	return nil
    90  }
    91  
    92  // init is called at runtime and registers `HTTPConf`, a `Prober`
    93  // `Configurer` type, as "HTTP".
    94  func init() {
    95  	probers.Register(HTTPConf{})
    96  }
    97  

View as plain text