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 const (
13 nextUpdateName = "obs_crl_next_update"
14 thisUpdateName = "obs_crl_this_update"
15 certCountName = "obs_crl_revoked_cert_count"
16 )
17
18
19 type CRLConf struct {
20 URL string `yaml:"url"`
21 }
22
23
24 func (c CRLConf) Kind() string {
25 return "CRL"
26 }
27
28
29 func (c CRLConf) UnmarshalSettings(settings []byte) (probers.Configurer, error) {
30 var conf CRLConf
31 err := strictyaml.Unmarshal(settings, &conf)
32
33 if err != nil {
34 return nil, err
35 }
36 return conf, nil
37 }
38
39 func (c CRLConf) validateURL() error {
40 url, err := url.Parse(c.URL)
41 if err != nil {
42 return fmt.Errorf(
43 "invalid 'url', got: %q, expected a valid url", c.URL)
44 }
45 if url.Scheme == "" {
46 return fmt.Errorf(
47 "invalid 'url', got: %q, missing scheme", c.URL)
48 }
49 return nil
50 }
51
52
53
54
55 func (c CRLConf) MakeProber(collectors map[string]prometheus.Collector) (probers.Prober, error) {
56
57 err := c.validateURL()
58 if err != nil {
59 return nil, err
60 }
61
62
63 coll, ok := collectors[nextUpdateName]
64 if !ok {
65 return nil, fmt.Errorf("crl prober did not receive collector %q", nextUpdateName)
66 }
67 nextUpdateColl, ok := coll.(*prometheus.GaugeVec)
68 if !ok {
69 return nil, fmt.Errorf("crl prober received collector %q of wrong type, got: %T, expected *prometheus.GaugeVec", nextUpdateName, coll)
70 }
71
72 coll, ok = collectors[thisUpdateName]
73 if !ok {
74 return nil, fmt.Errorf("crl prober did not receive collector %q", thisUpdateName)
75 }
76 thisUpdateColl, ok := coll.(*prometheus.GaugeVec)
77 if !ok {
78 return nil, fmt.Errorf("crl prober received collector %q of wrong type, got: %T, expected *prometheus.GaugeVec", thisUpdateName, coll)
79 }
80
81 coll, ok = collectors[certCountName]
82 if !ok {
83 return nil, fmt.Errorf("crl prober did not receive collector %q", certCountName)
84 }
85 certCountColl, ok := coll.(*prometheus.GaugeVec)
86 if !ok {
87 return nil, fmt.Errorf("crl prober received collector %q of wrong type, got: %T, expected *prometheus.GaugeVec", certCountName, coll)
88 }
89
90 return CRLProbe{c.URL, nextUpdateColl, thisUpdateColl, certCountColl}, nil
91 }
92
93
94
95
96
97 func (c CRLConf) Instrument() map[string]prometheus.Collector {
98 nextUpdate := prometheus.Collector(prometheus.NewGaugeVec(
99 prometheus.GaugeOpts{
100 Name: nextUpdateName,
101 Help: "CRL nextUpdate Unix timestamp in seconds",
102 }, []string{"url"},
103 ))
104 thisUpdate := prometheus.Collector(prometheus.NewGaugeVec(
105 prometheus.GaugeOpts{
106 Name: thisUpdateName,
107 Help: "CRL thisUpdate Unix timestamp in seconds",
108 }, []string{"url"},
109 ))
110 certCount := prometheus.Collector(prometheus.NewGaugeVec(
111 prometheus.GaugeOpts{
112 Name: certCountName,
113 Help: "number of certificates revoked in CRL",
114 }, []string{"url"},
115 ))
116 return map[string]prometheus.Collector{
117 nextUpdateName: nextUpdate,
118 thisUpdateName: thisUpdate,
119 certCountName: certCount,
120 }
121 }
122
123
124
125 func init() {
126 probers.Register(CRLConf{})
127 }
128
View as plain text