Add client TLS configuration

Allows connecting to alertmanager instances behind a TLS endpoint that
requires mutual TLS. Conveniently also allows specifying a CA
certificate file for alertmanagers that use trusted roots not in the
system root trust store.

Fixes: https://github.com/prometheus/alertmanager/issues/2652
Signed-off-by: Joe Groocock <me@frebib.net>
This commit is contained in:
Joe Groocock 2021-11-10 09:15:33 +00:00 committed by Julien Pivotto
parent 4fbcae7d05
commit 4fcbeeca9e
1 changed files with 33 additions and 12 deletions

View File

@ -23,6 +23,7 @@ import (
"time" "time"
"github.com/go-openapi/strfmt" "github.com/go-openapi/strfmt"
promconfig "github.com/prometheus/common/config"
"github.com/prometheus/common/version" "github.com/prometheus/common/version"
"golang.org/x/mod/semver" "golang.org/x/mod/semver"
kingpin "gopkg.in/alecthomas/kingpin.v2" kingpin "gopkg.in/alecthomas/kingpin.v2"
@ -35,12 +36,12 @@ import (
) )
var ( var (
verbose bool verbose bool
alertmanagerURL *url.URL alertmanagerURL *url.URL
output string output string
timeout time.Duration timeout time.Duration
tlsInsecureSkipVerify bool tlsConfig *tls.Config
versionCheck bool versionCheck bool
configFiles = []string{os.ExpandEnv("$HOME/.config/amtool/config.yml"), "/etc/amtool/config.yml"} configFiles = []string{os.ExpandEnv("$HOME/.config/amtool/config.yml"), "/etc/amtool/config.yml"}
legacyFlags = map[string]string{"comment_required": "require-comment"} legacyFlags = map[string]string{"comment_required": "require-comment"}
@ -84,11 +85,8 @@ func NewAlertmanagerClient(amURL *url.URL) *client.Alertmanager {
cr := clientruntime.New(address, path.Join(amURL.Path, defaultAmApiv2path), schemes) cr := clientruntime.New(address, path.Join(amURL.Path, defaultAmApiv2path), schemes)
if tlsInsecureSkipVerify { cr.Transport = &http.Transport{
transport := http.Transport{ TLSClientConfig: tlsConfig,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
cr.Transport = &transport
} }
if amURL.User != nil { if amURL.User != nil {
@ -119,6 +117,7 @@ func NewAlertmanagerClient(amURL *url.URL) *client.Alertmanager {
func Execute() { func Execute() {
var ( var (
app = kingpin.New("amtool", helpRoot).UsageWriter(os.Stdout) app = kingpin.New("amtool", helpRoot).UsageWriter(os.Stdout)
tls = promconfig.TLSConfig{}
) )
format.InitFormatFlags(app) format.InitFormatFlags(app)
@ -127,12 +126,20 @@ func Execute() {
app.Flag("alertmanager.url", "Alertmanager to talk to").URLVar(&alertmanagerURL) app.Flag("alertmanager.url", "Alertmanager to talk to").URLVar(&alertmanagerURL)
app.Flag("output", "Output formatter (simple, extended, json)").Short('o').Default("simple").EnumVar(&output, "simple", "extended", "json") app.Flag("output", "Output formatter (simple, extended, json)").Short('o').Default("simple").EnumVar(&output, "simple", "extended", "json")
app.Flag("timeout", "Timeout for the executed command").Default("30s").DurationVar(&timeout) app.Flag("timeout", "Timeout for the executed command").Default("30s").DurationVar(&timeout)
app.Flag("tls.insecure.skip.verify", "Skip TLS certificate verification").BoolVar(&tlsInsecureSkipVerify) app.Flag("tls.certfile", "TLS client certificate file").PlaceHolder("<filename>").ExistingFileVar(&tls.CertFile)
app.Flag("tls.keyfile", "TLS client private key file").PlaceHolder("<filename>").ExistingFileVar(&tls.KeyFile)
app.Flag("tls.cafile", "TLS trusted certificate authorities file").PlaceHolder("<filename>").ExistingFileVar(&tls.CAFile)
app.Flag("tls.servername", "ServerName to verify hostname of alertmanager").PlaceHolder("<string>").StringVar(&tls.ServerName)
app.Flag("tls.insecure.skip.verify", "Skip TLS certificate verification").Default("false").BoolVar(&tls.InsecureSkipVerify)
app.Flag("version-check", "Check alertmanager version. Use --no-version-check to disable.").Default("true").BoolVar(&versionCheck) app.Flag("version-check", "Check alertmanager version. Use --no-version-check to disable.").Default("true").BoolVar(&versionCheck)
app.Version(version.Print("amtool")) app.Version(version.Print("amtool"))
app.GetFlag("help").Short('h') app.GetFlag("help").Short('h')
app.UsageTemplate(kingpin.CompactUsageTemplate) app.UsageTemplate(kingpin.CompactUsageTemplate)
app.PreAction(func(pc *kingpin.ParseContext) (err error) {
tlsConfig, err = promconfig.NewTLSConfig(&tls)
return err
})
resolver, err := config.NewResolver(configFiles, legacyFlags) resolver, err := config.NewResolver(configFiles, legacyFlags)
if err != nil { if err != nil {
@ -184,6 +191,20 @@ static configuration:
date.format date.format
Sets the output format for dates. Defaults to "2006-01-02 15:04:05 MST" Sets the output format for dates. Defaults to "2006-01-02 15:04:05 MST"
tls.certfile
TLS client certificate file for mutual-TLS authentication.
Requires tls.keyfile to be useful.
tls.keyfile
TLS client private key file for mutual-TLS authentication.
Requires tls.certfile to be useful.
tls.cafile
TLS trusted certificate authorities file.
tls.servername
ServerName to verify hostname of alertmanager.
tls.insecure.skip.verify tls.insecure.skip.verify
Skips TLS certificate verification for all HTTPS requests. Skips TLS certificate verification for all HTTPS requests.
Defaults to false. Defaults to false.