Skip to content

Commit 718efa7

Browse files
committed
Added ssl.keyfile option for serving metrics over TLS
1 parent 600e533 commit 718efa7

File tree

28 files changed

+3219
-10
lines changed

28 files changed

+3219
-10
lines changed

main.go

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
123
package main
224

325
import (
@@ -19,13 +41,11 @@ var (
1941
maskAny = errors.WithStack
2042

2143
cmdMain = &cobra.Command{
22-
Use: "arangodb_exporter",
44+
Use: "arangodb-exporter",
2345
Run: cmdMainRun,
2446
}
2547

26-
serverOptions struct {
27-
listenAddress string
28-
}
48+
serverOptions ServerConfig
2949
arangodbOptions struct {
3050
endpoint string
3151
jwtSecret string
@@ -36,7 +56,8 @@ var (
3656
func init() {
3757
f := cmdMain.Flags()
3858

39-
f.StringVar(&serverOptions.listenAddress, "server.address", ":9101", "Address the exporter will listen on (IP:port)")
59+
f.StringVar(&serverOptions.Address, "server.address", ":9101", "Address the exporter will listen on (IP:port)")
60+
f.StringVar(&serverOptions.TLSKeyfile, "ssl.keyfile", "", "File containing TLS certificate used for the metrics server. Format equal to ArangoDB keyfiles")
4061

4162
f.StringVar(&arangodbOptions.endpoint, "arangodb.endpoint", "http://127.0.0.1:8529", "Endpoint used to reach the ArangoDB server")
4263
f.StringVar(&arangodbOptions.jwtSecret, "arangodb.jwtsecret", "", "JWT Secret used for authentication with ArangoDB server")
@@ -48,18 +69,22 @@ func main() {
4869
}
4970

5071
func cmdMainRun(cmd *cobra.Command, args []string) {
51-
log.Infoln(fmt.Sprintf("Starting arangodb_exporter %s, build %s", projectVersion, projectBuild))
72+
log.Infoln(fmt.Sprintf("Starting arangodb-exporter %s, build %s", projectVersion, projectBuild))
5273

5374
exporter, err := NewExporter(arangodbOptions.endpoint, arangodbOptions.jwtSecret, false, arangodbOptions.timeout)
5475
if err != nil {
5576
log.Fatal(err)
5677
}
5778
prometheus.MustRegister(exporter)
79+
version.Version = projectVersion
80+
version.Revision = projectBuild
5881
prometheus.MustRegister(version.NewCollector("arangodb_exporter"))
5982

60-
log.Infoln("Listening on", serverOptions.listenAddress)
61-
http.Handle("/metrics", prometheus.Handler())
62-
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
83+
log.Infoln("Listening on", serverOptions.Address)
84+
85+
mux := http.NewServeMux()
86+
mux.Handle("/metrics", prometheus.Handler())
87+
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
6388
w.Write([]byte(`<html>
6489
<head><title>ArangoDB Exporter</title></head>
6590
<body>
@@ -68,5 +93,10 @@ func cmdMainRun(cmd *cobra.Command, args []string) {
6893
</body>
6994
</html>`))
7095
})
71-
log.Fatal(http.ListenAndServe(serverOptions.listenAddress, nil))
96+
97+
server, err := NewServer(mux, serverOptions)
98+
if err != nil {
99+
log.Fatal(err)
100+
}
101+
log.Fatal(server.Run())
72102
}

server.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
package main
24+
25+
import (
26+
"crypto/tls"
27+
"net/http"
28+
_ "net/http/pprof"
29+
"time"
30+
31+
certificates "github.com/arangodb-helper/go-certificates"
32+
)
33+
34+
// ServerConfig settings for the Server
35+
type ServerConfig struct {
36+
Address string // Address to listen on
37+
TLSKeyfile string // Keyfile containing TLS certificate
38+
}
39+
40+
// Server is the HTTPS server for the operator.
41+
type Server struct {
42+
httpServer *http.Server
43+
}
44+
45+
// NewServer creates a new server, fetching/preparing a TLS certificate.
46+
func NewServer(handler http.Handler, cfg ServerConfig) (*Server, error) {
47+
httpServer := &http.Server{
48+
Addr: cfg.Address,
49+
Handler: handler,
50+
ReadTimeout: time.Second * 30,
51+
ReadHeaderTimeout: time.Second * 15,
52+
WriteTimeout: time.Second * 30,
53+
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
54+
}
55+
56+
if cfg.TLSKeyfile != "" {
57+
tlsConfig, err := createTLSConfig(cfg.TLSKeyfile)
58+
if err != nil {
59+
return nil, maskAny(err)
60+
}
61+
tlsConfig.BuildNameToCertificate()
62+
httpServer.TLSConfig = tlsConfig
63+
}
64+
65+
return &Server{
66+
httpServer: httpServer,
67+
}, nil
68+
}
69+
70+
// Run the server until the program stops.
71+
func (s *Server) Run() error {
72+
if s.httpServer.TLSConfig != nil {
73+
if err := s.httpServer.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
74+
return maskAny(err)
75+
}
76+
} else {
77+
if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
78+
return maskAny(err)
79+
}
80+
}
81+
return nil
82+
}
83+
84+
// createTLSConfig creates a TLS config from the given keyfile.
85+
func createTLSConfig(keyfile string) (*tls.Config, error) {
86+
cert, err := certificates.LoadKeyFile(keyfile)
87+
if err != nil {
88+
return nil, maskAny(err)
89+
}
90+
return &tls.Config{
91+
Certificates: []tls.Certificate{cert},
92+
}, nil
93+
}

vendor/github.com/arangodb-helper/go-certificates/LICENSE

Lines changed: 202 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/arangodb-helper/go-certificates/README.md

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)