mirror of
https://github.com/prometheus/alertmanager
synced 2025-02-07 22:21:52 +00:00
amtool to support http_config to access alertmanager (#2764)
* Support http_config for amtool Co-authored-by: Julien Pivotto <roidelapluie@gmail.com> Co-authored-by: Simon Pasquier <spasquie@redhat.com> Signed-off-by: clyang82 <chuyang@redhat.com>
This commit is contained in:
parent
c91717bc89
commit
ef25f81f1b
39
cli/config/http_config.go
Normal file
39
cli/config/http_config.go
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2021 Prometheus Team
|
||||
// Licensed 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 config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
promconfig "github.com/prometheus/common/config"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// LoadHTTPConfigFile returns HTTPClientConfig for the given http_config file
|
||||
func LoadHTTPConfigFile(filename string) (*promconfig.HTTPClientConfig, error) {
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
httpConfig := &promconfig.HTTPClientConfig{}
|
||||
err = yaml.UnmarshalStrict(b, httpConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
httpConfig.SetDirectory(filepath.Dir(filepath.Dir(filename)))
|
||||
|
||||
return httpConfig, nil
|
||||
}
|
55
cli/config/http_config_test.go
Normal file
55
cli/config/http_config_test.go
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright 2021 Prometheus Team
|
||||
// Licensed 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 config
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInvalidHTTPConfig(t *testing.T) {
|
||||
_, err := LoadHTTPConfigFile("testdata/http_config.bad.yml")
|
||||
errMsg := `authorization type cannot be set to "basic", use "basic_auth" instead`
|
||||
if !strings.Contains(err.Error(), errMsg) {
|
||||
t.Errorf("Expected error for invalid HTTP client configuration to contain %q but got: %s", errMsg, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidHTTPConfig(t *testing.T) {
|
||||
cfg, err := LoadHTTPConfigFile("testdata/http_config.good.yml")
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading HTTP client config: %v", err)
|
||||
}
|
||||
|
||||
proxyURL := "http://remote.host"
|
||||
if cfg.ProxyURL.String() != proxyURL {
|
||||
t.Fatalf("Expected proxy_url is %q but got: %s", proxyURL, cfg.ProxyURL.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidBasicAuthHTTPConfig(t *testing.T) {
|
||||
cfg, err := LoadHTTPConfigFile("testdata/http_config.basic_auth.good.yml")
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading HTTP client config: %v", err)
|
||||
}
|
||||
|
||||
if cfg.BasicAuth.Username != "user" {
|
||||
t.Fatalf("Expected username is %q but got: %s", "user", cfg.BasicAuth.Username)
|
||||
}
|
||||
|
||||
password := string(cfg.BasicAuth.Password)
|
||||
if password != "password" {
|
||||
t.Fatalf("Expected password is %q but got: %s", "password", password)
|
||||
}
|
||||
}
|
2
cli/config/testdata/http_config.bad.yml
vendored
Normal file
2
cli/config/testdata/http_config.bad.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
authorization:
|
||||
type: Basic
|
3
cli/config/testdata/http_config.basic_auth.good.yml
vendored
Normal file
3
cli/config/testdata/http_config.basic_auth.good.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
basic_auth:
|
||||
username: user
|
||||
password: password
|
4
cli/config/testdata/http_config.good.yml
vendored
Normal file
4
cli/config/testdata/http_config.good.yml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
authorization:
|
||||
type: Bearer
|
||||
credentials: theanswertothegreatquestionoflifetheuniverseandeverythingisfortytwo
|
||||
proxy_url: "http://remote.host"
|
53
cli/root.go
53
cli/root.go
@ -14,9 +14,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
@ -40,7 +38,7 @@ var (
|
||||
alertmanagerURL *url.URL
|
||||
output string
|
||||
timeout time.Duration
|
||||
tlsConfig *tls.Config
|
||||
httpConfigFile string
|
||||
versionCheck bool
|
||||
|
||||
configFiles = []string{os.ExpandEnv("$HOME/.config/amtool/config.yml"), "/etc/amtool/config.yml"}
|
||||
@ -85,8 +83,8 @@ func NewAlertmanagerClient(amURL *url.URL) *client.Alertmanager {
|
||||
|
||||
cr := clientruntime.New(address, path.Join(amURL.Path, defaultAmApiv2path), schemes)
|
||||
|
||||
cr.Transport = &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
if amURL.User != nil && httpConfigFile != "" {
|
||||
kingpin.Fatalf("basic authentication and http.config.file are mutually exclusive")
|
||||
}
|
||||
|
||||
if amURL.User != nil {
|
||||
@ -94,6 +92,20 @@ func NewAlertmanagerClient(amURL *url.URL) *client.Alertmanager {
|
||||
cr.DefaultAuthentication = clientruntime.BasicAuth(amURL.User.Username(), password)
|
||||
}
|
||||
|
||||
if httpConfigFile != "" {
|
||||
var err error
|
||||
httpConfig, err := config.LoadHTTPConfigFile(httpConfigFile)
|
||||
if err != nil {
|
||||
kingpin.Fatalf("failed to load HTTP config file: %v", err)
|
||||
}
|
||||
|
||||
httpclient, err := promconfig.NewClientFromConfig(*httpConfig, "amtool")
|
||||
if err != nil {
|
||||
kingpin.Fatalf("failed to create a new HTTP client: %v", err)
|
||||
}
|
||||
cr = clientruntime.NewWithClient(address, path.Join(amURL.Path, defaultAmApiv2path), schemes, httpclient)
|
||||
}
|
||||
|
||||
c := client.New(cr, strfmt.Default)
|
||||
|
||||
if !versionCheck {
|
||||
@ -117,7 +129,6 @@ func NewAlertmanagerClient(amURL *url.URL) *client.Alertmanager {
|
||||
func Execute() {
|
||||
var (
|
||||
app = kingpin.New("amtool", helpRoot).UsageWriter(os.Stdout)
|
||||
tls = promconfig.TLSConfig{}
|
||||
)
|
||||
|
||||
format.InitFormatFlags(app)
|
||||
@ -126,20 +137,12 @@ func Execute() {
|
||||
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("timeout", "Timeout for the executed command").Default("30s").DurationVar(&timeout)
|
||||
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("http.config.file", "HTTP client configuration file for amtool to connect to Alertmanager.").PlaceHolder("<filename>").ExistingFileVar(&httpConfigFile)
|
||||
app.Flag("version-check", "Check alertmanager version. Use --no-version-check to disable.").Default("true").BoolVar(&versionCheck)
|
||||
|
||||
app.Version(version.Print("amtool"))
|
||||
app.GetFlag("help").Short('h')
|
||||
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)
|
||||
if err != nil {
|
||||
@ -191,22 +194,8 @@ static configuration:
|
||||
date.format
|
||||
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
|
||||
Skips TLS certificate verification for all HTTPS requests.
|
||||
Defaults to false.
|
||||
http.config.file
|
||||
HTTP client configuration file for amtool to connect to Alertmanager.
|
||||
The format is https://prometheus.io/docs/alerting/latest/configuration/#http_config.
|
||||
`
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user