...

Source file src/github.com/prometheus/alertmanager/cli/utils.go

Documentation: github.com/prometheus/alertmanager/cli

     1  // Copyright 2018 Prometheus Team
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package cli
    15  
    16  import (
    17  	"context"
    18  	"errors"
    19  	"fmt"
    20  	"net/url"
    21  	"os"
    22  	"path"
    23  
    24  	"github.com/prometheus/common/model"
    25  	kingpin "gopkg.in/alecthomas/kingpin.v2"
    26  
    27  	"github.com/prometheus/alertmanager/api/v2/client/general"
    28  	"github.com/prometheus/alertmanager/api/v2/models"
    29  	"github.com/prometheus/alertmanager/config"
    30  	"github.com/prometheus/alertmanager/pkg/labels"
    31  )
    32  
    33  // GetAlertmanagerURL appends the given path to the alertmanager base URL
    34  func GetAlertmanagerURL(p string) url.URL {
    35  	amURL := *alertmanagerURL
    36  	amURL.Path = path.Join(alertmanagerURL.Path, p)
    37  	return amURL
    38  }
    39  
    40  // parseMatchers parses a list of matchers (cli arguments).
    41  func parseMatchers(inputMatchers []string) ([]labels.Matcher, error) {
    42  	matchers := make([]labels.Matcher, 0, len(inputMatchers))
    43  
    44  	for _, v := range inputMatchers {
    45  		matcher, err := labels.ParseMatcher(v)
    46  		if err != nil {
    47  			return []labels.Matcher{}, err
    48  		}
    49  
    50  		matchers = append(matchers, *matcher)
    51  	}
    52  
    53  	return matchers, nil
    54  }
    55  
    56  // getRemoteAlertmanagerConfigStatus returns status responsecontaining configuration from remote Alertmanager
    57  func getRemoteAlertmanagerConfigStatus(ctx context.Context, alertmanagerURL *url.URL) (*models.AlertmanagerStatus, error) {
    58  	amclient := NewAlertmanagerClient(alertmanagerURL)
    59  	params := general.NewGetStatusParams().WithContext(ctx)
    60  	getOk, err := amclient.General.GetStatus(params)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	return getOk.Payload, nil
    66  }
    67  
    68  func checkRoutingConfigInputFlags(alertmanagerURL *url.URL, configFile string) {
    69  	if alertmanagerURL != nil && configFile != "" {
    70  		fmt.Fprintln(os.Stderr, "Warning: --config.file flag overrides the --alertmanager.url.")
    71  	}
    72  	if alertmanagerURL == nil && configFile == "" {
    73  		kingpin.Fatalf("You have to specify one of --config.file or --alertmanager.url flags.")
    74  	}
    75  }
    76  
    77  func loadAlertmanagerConfig(ctx context.Context, alertmanagerURL *url.URL, configFile string) (*config.Config, error) {
    78  	checkRoutingConfigInputFlags(alertmanagerURL, configFile)
    79  	if configFile != "" {
    80  		cfg, err := config.LoadFile(configFile)
    81  		if err != nil {
    82  			return nil, err
    83  		}
    84  		return cfg, nil
    85  	}
    86  	if alertmanagerURL == nil {
    87  		return nil, errors.New("failed to get Alertmanager configuration")
    88  	}
    89  	configStatus, err := getRemoteAlertmanagerConfigStatus(ctx, alertmanagerURL)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	return config.Load(*configStatus.Config.Original)
    94  }
    95  
    96  // convertClientToCommonLabelSet converts client.LabelSet to model.Labelset
    97  func convertClientToCommonLabelSet(cls models.LabelSet) model.LabelSet {
    98  	mls := make(model.LabelSet, len(cls))
    99  	for ln, lv := range cls {
   100  		mls[model.LabelName(ln)] = model.LabelValue(lv)
   101  	}
   102  	return mls
   103  }
   104  
   105  // parseLabels parses a list of labels (cli arguments).
   106  func parseLabels(inputLabels []string) (models.LabelSet, error) {
   107  	labelSet := make(models.LabelSet, len(inputLabels))
   108  
   109  	for _, l := range inputLabels {
   110  		matcher, err := labels.ParseMatcher(l)
   111  		if err != nil {
   112  			return models.LabelSet{}, err
   113  		}
   114  		if matcher.Type != labels.MatchEqual {
   115  			return models.LabelSet{}, errors.New("labels must be specified as key=value pairs")
   116  		}
   117  
   118  		labelSet[matcher.Name] = matcher.Value
   119  	}
   120  
   121  	return labelSet, nil
   122  }
   123  
   124  // TypeMatchers only valid for when you are going to add a silence
   125  func TypeMatchers(matchers []labels.Matcher) models.Matchers {
   126  	typeMatchers := make(models.Matchers, len(matchers))
   127  	for i, matcher := range matchers {
   128  		typeMatchers[i] = TypeMatcher(matcher)
   129  	}
   130  	return typeMatchers
   131  }
   132  
   133  // TypeMatcher only valid for when you are going to add a silence
   134  func TypeMatcher(matcher labels.Matcher) *models.Matcher {
   135  	name := matcher.Name
   136  	value := matcher.Value
   137  	typeMatcher := models.Matcher{
   138  		Name:  &name,
   139  		Value: &value,
   140  	}
   141  
   142  	isEqual := (matcher.Type == labels.MatchEqual) || (matcher.Type == labels.MatchRegexp)
   143  	isRegex := (matcher.Type == labels.MatchRegexp) || (matcher.Type == labels.MatchNotRegexp)
   144  	typeMatcher.IsEqual = &isEqual
   145  	typeMatcher.IsRegex = &isRegex
   146  	return &typeMatcher
   147  }
   148  
   149  // Helper function for adding the ctx with timeout into an action.
   150  func execWithTimeout(fn func(context.Context, *kingpin.ParseContext) error) func(*kingpin.ParseContext) error {
   151  	return func(x *kingpin.ParseContext) error {
   152  		ctx, cancel := context.WithTimeout(context.Background(), timeout)
   153  		defer cancel()
   154  		return fn(ctx, x)
   155  	}
   156  }
   157  

View as plain text