Add `consul` check type to `circonus_check` resource (#13030)
* Add the `consul` check type to the `circonus_check` resource. * Fix a tab-complete fail. `Parse` != `Path`, but lexically close. * Dept of 2nd thoughts: `s/service_name/service/g`
This commit is contained in:
parent
c5935ab1ad
commit
32db4d184f
|
@ -25,6 +25,7 @@ const (
|
|||
|
||||
const (
|
||||
apiCheckTypeCAQL circonusCheckType = "caql"
|
||||
apiCheckTypeConsul circonusCheckType = "consul"
|
||||
apiCheckTypeICMPPing circonusCheckType = "ping_icmp"
|
||||
apiCheckTypeHTTP circonusCheckType = "http"
|
||||
apiCheckTypeJSON circonusCheckType = "json"
|
||||
|
@ -108,15 +109,24 @@ func (c *circonusCheck) Fixup() error {
|
|||
}
|
||||
|
||||
func (c *circonusCheck) Validate() error {
|
||||
if len(c.Metrics) == 0 {
|
||||
return fmt.Errorf("At least one %s must be specified", checkMetricAttr)
|
||||
}
|
||||
|
||||
if c.Timeout > float32(c.Period) {
|
||||
return fmt.Errorf("Timeout (%f) can not exceed period (%d)", c.Timeout, c.Period)
|
||||
}
|
||||
|
||||
// Check-type specific validation
|
||||
switch apiCheckType(c.Type) {
|
||||
case apiCheckTypeCloudWatchAttr:
|
||||
if !(c.Period == 60 || c.Period == 300) {
|
||||
return fmt.Errorf("Period must be either 1m or 5m for a %s check", apiCheckTypeCloudWatchAttr)
|
||||
}
|
||||
case apiCheckTypeConsulAttr:
|
||||
if v, found := c.Config[config.URL]; !found || v == "" {
|
||||
return fmt.Errorf("%s must have at least one check mode set: %s, %s, or %s must be set", checkConsulAttr, checkConsulServiceAttr, checkConsulNodeAttr, checkConsulStateAttr)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -17,6 +17,19 @@ const (
|
|||
providerAutoTagAttr = "auto_tag"
|
||||
providerKeyAttr = "key"
|
||||
|
||||
apiConsulCheckBlacklist = "check_name_blacklist"
|
||||
apiConsulDatacenterAttr = "dc"
|
||||
apiConsulNodeBlacklist = "node_blacklist"
|
||||
apiConsulServiceBlacklist = "service_blacklist"
|
||||
apiConsulStaleAttr = "stale"
|
||||
checkConsulTokenHeader = `X-Consul-Token`
|
||||
checkConsulV1NodePrefix = "node"
|
||||
checkConsulV1Prefix = "/v1/health"
|
||||
checkConsulV1ServicePrefix = "service"
|
||||
checkConsulV1StatePrefix = "state"
|
||||
defaultCheckConsulHTTPAddr = "http://consul.service.consul"
|
||||
defaultCheckConsulPort = "8500"
|
||||
|
||||
defaultCheckJSONMethod = "GET"
|
||||
defaultCheckJSONPort = "443"
|
||||
defaultCheckJSONVersion = "1.1"
|
||||
|
|
|
@ -33,21 +33,22 @@ const (
|
|||
checkCAQLAttr = "caql"
|
||||
checkCloudWatchAttr = "cloudwatch"
|
||||
checkCollectorAttr = "collector"
|
||||
checkConsulAttr = "consul"
|
||||
checkHTTPAttr = "http"
|
||||
checkHTTPTrapAttr = "httptrap"
|
||||
checkICMPPingAttr = "icmp_ping"
|
||||
checkJSONAttr = "json"
|
||||
checkMetricAttr = "metric"
|
||||
checkMetricLimitAttr = "metric_limit"
|
||||
checkMySQLAttr = "mysql"
|
||||
checkNameAttr = "name"
|
||||
checkNotesAttr = "notes"
|
||||
checkPeriodAttr = "period"
|
||||
checkPostgreSQLAttr = "postgresql"
|
||||
checkMetricAttr = "metric"
|
||||
checkStatsdAttr = "statsd"
|
||||
checkTCPAttr = "tcp"
|
||||
checkTagsAttr = "tags"
|
||||
checkTargetAttr = "target"
|
||||
checkTCPAttr = "tcp"
|
||||
checkTimeoutAttr = "timeout"
|
||||
checkTypeAttr = "type"
|
||||
|
||||
|
@ -75,6 +76,7 @@ const (
|
|||
// Circonus API constants from their API endpoints
|
||||
apiCheckTypeCAQLAttr apiCheckType = "caql"
|
||||
apiCheckTypeCloudWatchAttr apiCheckType = "cloudwatch"
|
||||
apiCheckTypeConsulAttr apiCheckType = "consul"
|
||||
apiCheckTypeHTTPAttr apiCheckType = "http"
|
||||
apiCheckTypeHTTPTrapAttr apiCheckType = "httptrap"
|
||||
apiCheckTypeICMPPingAttr apiCheckType = "ping_icmp"
|
||||
|
@ -90,6 +92,7 @@ var checkDescriptions = attrDescrs{
|
|||
checkCAQLAttr: "CAQL check configuration",
|
||||
checkCloudWatchAttr: "CloudWatch check configuration",
|
||||
checkCollectorAttr: "The collector(s) that are responsible for gathering the metrics",
|
||||
checkConsulAttr: "Consul check configuration",
|
||||
checkHTTPAttr: "HTTP check configuration",
|
||||
checkHTTPTrapAttr: "HTTP Trap check configuration",
|
||||
checkICMPPingAttr: "ICMP ping check configuration",
|
||||
|
@ -157,6 +160,7 @@ func resourceCheck() *schema.Resource {
|
|||
}),
|
||||
},
|
||||
},
|
||||
checkConsulAttr: schemaCheckConsul,
|
||||
checkHTTPAttr: schemaCheckHTTP,
|
||||
checkHTTPTrapAttr: schemaCheckHTTPTrap,
|
||||
checkJSONAttr: schemaCheckJSON,
|
||||
|
@ -577,6 +581,7 @@ func checkConfigToAPI(c *circonusCheck, d *schema.ResourceData) error {
|
|||
checkTypeParseMap := map[string]func(*circonusCheck, interfaceList) error{
|
||||
checkCAQLAttr: checkConfigToAPICAQL,
|
||||
checkCloudWatchAttr: checkConfigToAPICloudWatch,
|
||||
checkConsulAttr: checkConfigToAPIConsul,
|
||||
checkHTTPAttr: checkConfigToAPIHTTP,
|
||||
checkHTTPTrapAttr: checkConfigToAPIHTTPTrap,
|
||||
checkICMPPingAttr: checkConfigToAPIICMPPing,
|
||||
|
@ -589,9 +594,18 @@ func checkConfigToAPI(c *circonusCheck, d *schema.ResourceData) error {
|
|||
|
||||
for checkType, fn := range checkTypeParseMap {
|
||||
if listRaw, found := d.GetOk(checkType); found {
|
||||
if err := fn(c, listRaw.(*schema.Set).List()); err != nil {
|
||||
switch u := listRaw.(type) {
|
||||
case []interface{}:
|
||||
if err := fn(c, u); err != nil {
|
||||
return errwrap.Wrapf(fmt.Sprintf("Unable to parse type %q: {{err}}", string(checkType)), err)
|
||||
}
|
||||
case *schema.Set:
|
||||
if err := fn(c, u.List()); err != nil {
|
||||
return errwrap.Wrapf(fmt.Sprintf("Unable to parse type %q: {{err}}", string(checkType)), err)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("PROVIDER BUG: unsupported check type interface: %q", checkType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,6 +618,7 @@ func parseCheckTypeConfig(c *circonusCheck, d *schema.ResourceData) error {
|
|||
checkTypeConfigHandlers := map[apiCheckType]func(*circonusCheck, *schema.ResourceData) error{
|
||||
apiCheckTypeCAQLAttr: checkAPIToStateCAQL,
|
||||
apiCheckTypeCloudWatchAttr: checkAPIToStateCloudWatch,
|
||||
apiCheckTypeConsulAttr: checkAPIToStateConsul,
|
||||
apiCheckTypeHTTPAttr: checkAPIToStateHTTP,
|
||||
apiCheckTypeHTTPTrapAttr: checkAPIToStateHTTPTrap,
|
||||
apiCheckTypeICMPPingAttr: checkAPIToStateICMPPing,
|
||||
|
|
|
@ -0,0 +1,412 @@
|
|||
package circonus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/circonus-labs/circonus-gometrics/api/config"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
// circonus_check.consul.* resource attribute names
|
||||
checkConsulACLTokenAttr = "acl_token"
|
||||
checkConsulAllowStaleAttr = "allow_stale"
|
||||
checkConsulCAChainAttr = "ca_chain"
|
||||
checkConsulCertFileAttr = "certificate_file"
|
||||
checkConsulCheckNameBlacklistAttr = "check_blacklist"
|
||||
checkConsulCiphersAttr = "ciphers"
|
||||
checkConsulDatacenterAttr = "dc"
|
||||
checkConsulHTTPAddrAttr = "http_addr"
|
||||
checkConsulHeadersAttr = "headers"
|
||||
checkConsulKeyFileAttr = "key_file"
|
||||
checkConsulNodeAttr = "node"
|
||||
checkConsulNodeBlacklistAttr = "node_blacklist"
|
||||
checkConsulServiceAttr = "service"
|
||||
checkConsulServiceNameBlacklistAttr = "service_blacklist"
|
||||
checkConsulStateAttr = "state"
|
||||
)
|
||||
|
||||
var checkConsulDescriptions = attrDescrs{
|
||||
checkConsulACLTokenAttr: "A Consul ACL token",
|
||||
checkConsulAllowStaleAttr: "Allow Consul to read from a non-leader system",
|
||||
checkConsulCAChainAttr: "A path to a file containing all the certificate authorities that should be loaded to validate the remote certificate (for TLS checks)",
|
||||
checkConsulCertFileAttr: "A path to a file containing the client certificate that will be presented to the remote server (for TLS-enabled checks)",
|
||||
checkConsulCheckNameBlacklistAttr: "A blacklist of check names to exclude from metric results",
|
||||
checkConsulCiphersAttr: "A list of ciphers to be used in the TLS protocol (for HTTPS checks)",
|
||||
checkConsulDatacenterAttr: "The Consul datacenter to extract health information from",
|
||||
checkConsulHeadersAttr: "Map of HTTP Headers to send along with HTTP Requests",
|
||||
checkConsulHTTPAddrAttr: "The HTTP Address of a Consul agent to query",
|
||||
checkConsulKeyFileAttr: "A path to a file containing key to be used in conjunction with the cilent certificate (for TLS checks)",
|
||||
checkConsulNodeAttr: "Node Name or NodeID of a Consul agent",
|
||||
checkConsulNodeBlacklistAttr: "A blacklist of node names or IDs to exclude from metric results",
|
||||
checkConsulServiceAttr: "Name of the Consul service to check",
|
||||
checkConsulServiceNameBlacklistAttr: "A blacklist of service names to exclude from metric results",
|
||||
checkConsulStateAttr: "Check for Consul services in this particular state",
|
||||
}
|
||||
|
||||
var consulHealthCheckRE = regexp.MustCompile(fmt.Sprintf(`^%s/(%s|%s|%s)/(.+)`, checkConsulV1Prefix, checkConsulV1NodePrefix, checkConsulV1ServicePrefix, checkConsulV1StatePrefix))
|
||||
|
||||
var schemaCheckConsul = &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: convertToHelperSchema(checkConsulDescriptions, map[schemaAttr]*schema.Schema{
|
||||
checkConsulACLTokenAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulACLTokenAttr, `^[a-zA-Z0-9\-]+$`),
|
||||
},
|
||||
checkConsulAllowStaleAttr: &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
},
|
||||
checkConsulCAChainAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulCAChainAttr, `.+`),
|
||||
},
|
||||
checkConsulCertFileAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulCertFileAttr, `.+`),
|
||||
},
|
||||
checkConsulCheckNameBlacklistAttr: &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
ValidateFunc: validateRegexp(checkConsulCheckNameBlacklistAttr, `^[A-Za-z0-9_-]+$`),
|
||||
},
|
||||
},
|
||||
checkConsulCiphersAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulCiphersAttr, `.+`),
|
||||
},
|
||||
checkConsulDatacenterAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulCertFileAttr, `^[a-zA-Z0-9]+$`),
|
||||
},
|
||||
checkConsulHTTPAddrAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: defaultCheckConsulHTTPAddr,
|
||||
ValidateFunc: validateHTTPURL(checkConsulHTTPAddrAttr, urlIsAbs|urlWithoutPath),
|
||||
},
|
||||
checkConsulHeadersAttr: &schema.Schema{
|
||||
Type: schema.TypeMap,
|
||||
Elem: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateHTTPHeaders,
|
||||
},
|
||||
checkConsulKeyFileAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulKeyFileAttr, `.+`),
|
||||
},
|
||||
checkConsulNodeAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulNodeAttr, `^[a-zA-Z0-9_\-]+$`),
|
||||
ConflictsWith: []string{
|
||||
checkConsulAttr + "." + checkConsulServiceAttr,
|
||||
checkConsulAttr + "." + checkConsulStateAttr,
|
||||
},
|
||||
},
|
||||
checkConsulNodeBlacklistAttr: &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
ValidateFunc: validateRegexp(checkConsulNodeBlacklistAttr, `^[A-Za-z0-9_-]+$`),
|
||||
},
|
||||
},
|
||||
checkConsulServiceAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulServiceAttr, `^[a-zA-Z0-9_\-]+$`),
|
||||
ConflictsWith: []string{
|
||||
checkConsulAttr + "." + checkConsulNodeAttr,
|
||||
checkConsulAttr + "." + checkConsulStateAttr,
|
||||
},
|
||||
},
|
||||
checkConsulServiceNameBlacklistAttr: &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
ValidateFunc: validateRegexp(checkConsulServiceNameBlacklistAttr, `^[A-Za-z0-9_-]+$`),
|
||||
},
|
||||
},
|
||||
checkConsulStateAttr: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateRegexp(checkConsulStateAttr, `^(any|passing|warning|critical)$`),
|
||||
ConflictsWith: []string{
|
||||
checkConsulAttr + "." + checkConsulNodeAttr,
|
||||
checkConsulAttr + "." + checkConsulServiceAttr,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
// checkAPIToStateConsul reads the Config data out of circonusCheck.CheckBundle into
|
||||
// the statefile.
|
||||
func checkAPIToStateConsul(c *circonusCheck, d *schema.ResourceData) error {
|
||||
consulConfig := make(map[string]interface{}, len(c.Config))
|
||||
|
||||
// swamp is a sanity check: it must be empty by the time this method returns
|
||||
swamp := make(map[config.Key]string, len(c.Config))
|
||||
for k, s := range c.Config {
|
||||
swamp[k] = s
|
||||
}
|
||||
|
||||
saveStringConfigToState := func(apiKey config.Key, attrName schemaAttr) {
|
||||
if s, ok := c.Config[apiKey]; ok && s != "" {
|
||||
consulConfig[string(attrName)] = s
|
||||
}
|
||||
|
||||
delete(swamp, apiKey)
|
||||
}
|
||||
|
||||
saveStringConfigToState(config.CAChain, checkConsulCAChainAttr)
|
||||
saveStringConfigToState(config.CertFile, checkConsulCertFileAttr)
|
||||
saveStringConfigToState(config.Ciphers, checkConsulCiphersAttr)
|
||||
|
||||
// httpAddrURL is used to compose the http_addr value using multiple c.Config
|
||||
// values.
|
||||
var httpAddrURL url.URL
|
||||
|
||||
headers := make(map[string]interface{}, len(c.Config)+1) // +1 is for the ACLToken
|
||||
headerPrefixLen := len(config.HeaderPrefix)
|
||||
|
||||
// Explicitly handle several config parameters in sequence: URL, then port,
|
||||
// then everything else.
|
||||
if v, found := c.Config[config.URL]; found {
|
||||
u, err := url.Parse(v)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf(fmt.Sprintf("unable to parse %q from config: {{err}}", config.URL), err)
|
||||
}
|
||||
|
||||
queryArgs := u.Query()
|
||||
if vals, found := queryArgs[apiConsulStaleAttr]; found && len(vals) > 0 {
|
||||
consulConfig[string(checkConsulAllowStaleAttr)] = true
|
||||
}
|
||||
|
||||
if dc := queryArgs.Get(apiConsulDatacenterAttr); dc != "" {
|
||||
consulConfig[string(checkConsulDatacenterAttr)] = dc
|
||||
}
|
||||
|
||||
httpAddrURL.Host = u.Host
|
||||
httpAddrURL.Scheme = u.Scheme
|
||||
|
||||
md := consulHealthCheckRE.FindStringSubmatch(u.EscapedPath())
|
||||
if md == nil {
|
||||
return fmt.Errorf("config %q failed to match the health regexp", config.URL)
|
||||
}
|
||||
|
||||
checkMode := md[1]
|
||||
checkArg := md[2]
|
||||
switch checkMode {
|
||||
case checkConsulV1NodePrefix:
|
||||
consulConfig[string(checkConsulNodeAttr)] = checkArg
|
||||
case checkConsulV1ServicePrefix:
|
||||
consulConfig[string(checkConsulServiceAttr)] = checkArg
|
||||
case checkConsulV1StatePrefix:
|
||||
consulConfig[string(checkConsulStateAttr)] = checkArg
|
||||
default:
|
||||
return fmt.Errorf("PROVIDER BUG: unsupported check mode %q from %q", checkMode, u.EscapedPath())
|
||||
}
|
||||
|
||||
delete(swamp, config.URL)
|
||||
}
|
||||
|
||||
if v, found := c.Config[config.Port]; found {
|
||||
hostInfo := strings.SplitN(httpAddrURL.Host, ":", 2)
|
||||
switch {
|
||||
case len(hostInfo) == 1 && v != defaultCheckConsulPort, len(hostInfo) > 1:
|
||||
httpAddrURL.Host = net.JoinHostPort(hostInfo[0], v)
|
||||
}
|
||||
|
||||
delete(swamp, config.Port)
|
||||
}
|
||||
|
||||
if v, found := c.Config[apiConsulCheckBlacklist]; found {
|
||||
consulConfig[checkConsulCheckNameBlacklistAttr] = strings.Split(v, ",")
|
||||
}
|
||||
|
||||
if v, found := c.Config[apiConsulNodeBlacklist]; found {
|
||||
consulConfig[checkConsulNodeBlacklistAttr] = strings.Split(v, ",")
|
||||
}
|
||||
|
||||
if v, found := c.Config[apiConsulServiceBlacklist]; found {
|
||||
consulConfig[checkConsulServiceNameBlacklistAttr] = strings.Split(v, ",")
|
||||
}
|
||||
|
||||
// NOTE(sean@): headers attribute processed last. See below.
|
||||
|
||||
consulConfig[string(checkConsulHTTPAddrAttr)] = httpAddrURL.String()
|
||||
|
||||
saveStringConfigToState(config.KeyFile, checkConsulKeyFileAttr)
|
||||
|
||||
// Process the headers last in order to provide an escape hatch capible of
|
||||
// overriding any other derived value above.
|
||||
for k, v := range c.Config {
|
||||
if len(k) <= headerPrefixLen {
|
||||
continue
|
||||
}
|
||||
|
||||
// Handle all of the prefix variable headers, like `header_`
|
||||
if strings.Compare(string(k[:headerPrefixLen]), string(config.HeaderPrefix)) == 0 {
|
||||
key := k[headerPrefixLen:]
|
||||
switch key {
|
||||
case checkConsulTokenHeader:
|
||||
consulConfig[checkConsulACLTokenAttr] = v
|
||||
default:
|
||||
headers[string(key)] = v
|
||||
}
|
||||
}
|
||||
|
||||
delete(swamp, k)
|
||||
}
|
||||
consulConfig[string(checkConsulHeadersAttr)] = headers
|
||||
|
||||
whitelistedConfigKeys := map[config.Key]struct{}{
|
||||
config.Port: struct{}{},
|
||||
config.ReverseSecretKey: struct{}{},
|
||||
config.SubmissionURL: struct{}{},
|
||||
config.URL: struct{}{},
|
||||
}
|
||||
|
||||
for k := range swamp {
|
||||
if _, ok := whitelistedConfigKeys[k]; ok {
|
||||
delete(c.Config, k)
|
||||
}
|
||||
|
||||
if _, ok := whitelistedConfigKeys[k]; !ok {
|
||||
return fmt.Errorf("PROVIDER BUG: API Config not empty: %#v", swamp)
|
||||
}
|
||||
}
|
||||
|
||||
if err := d.Set(checkConsulAttr, []interface{}{consulConfig}); err != nil {
|
||||
return errwrap.Wrapf(fmt.Sprintf("Unable to store check %q attribute: {{err}}", checkConsulAttr), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkConfigToAPIConsul(c *circonusCheck, l interfaceList) error {
|
||||
c.Type = string(apiCheckTypeConsul)
|
||||
|
||||
// Iterate over all `consul` attributes, even though we have a max of 1 in the
|
||||
// schema.
|
||||
for _, mapRaw := range l {
|
||||
consulConfig := newInterfaceMap(mapRaw)
|
||||
if v, found := consulConfig[checkConsulCAChainAttr]; found {
|
||||
c.Config[config.CAChain] = v.(string)
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulCertFileAttr]; found {
|
||||
c.Config[config.CertFile] = v.(string)
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulCheckNameBlacklistAttr]; found {
|
||||
listRaw := v.([]interface{})
|
||||
checks := make([]string, 0, len(listRaw))
|
||||
for _, v := range listRaw {
|
||||
checks = append(checks, v.(string))
|
||||
}
|
||||
c.Config[apiConsulCheckBlacklist] = strings.Join(checks, ",")
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulCiphersAttr]; found {
|
||||
c.Config[config.Ciphers] = v.(string)
|
||||
}
|
||||
|
||||
if headers := consulConfig.CollectMap(checkConsulHeadersAttr); headers != nil {
|
||||
for k, v := range headers {
|
||||
h := config.HeaderPrefix + config.Key(k)
|
||||
c.Config[h] = v
|
||||
}
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulKeyFileAttr]; found {
|
||||
c.Config[config.KeyFile] = v.(string)
|
||||
}
|
||||
|
||||
{
|
||||
// Extract all of the input attributes necessary to construct the
|
||||
// Consul agent's URL.
|
||||
|
||||
httpAddr := consulConfig[checkConsulHTTPAddrAttr].(string)
|
||||
checkURL, err := url.Parse(httpAddr)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf(fmt.Sprintf("Unable to parse %s's attribute %q: {{err}}", checkConsulAttr, httpAddr), err)
|
||||
}
|
||||
|
||||
hostInfo := strings.SplitN(checkURL.Host, ":", 2)
|
||||
if len(c.Target) == 0 {
|
||||
c.Target = hostInfo[0]
|
||||
}
|
||||
|
||||
if len(hostInfo) > 1 {
|
||||
c.Config[config.Port] = hostInfo[1]
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulNodeAttr]; found && v.(string) != "" {
|
||||
checkURL.Path = strings.Join([]string{checkConsulV1Prefix, checkConsulV1NodePrefix, v.(string)}, "/")
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulServiceAttr]; found && v.(string) != "" {
|
||||
checkURL.Path = strings.Join([]string{checkConsulV1Prefix, checkConsulV1ServicePrefix, v.(string)}, "/")
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulStateAttr]; found && v.(string) != "" {
|
||||
checkURL.Path = strings.Join([]string{checkConsulV1Prefix, checkConsulV1StatePrefix, v.(string)}, "/")
|
||||
}
|
||||
|
||||
q := checkURL.Query()
|
||||
|
||||
if v, found := consulConfig[checkConsulAllowStaleAttr]; found && v.(bool) {
|
||||
q.Set(apiConsulStaleAttr, "")
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulDatacenterAttr]; found && v.(string) != "" {
|
||||
q.Set(apiConsulDatacenterAttr, v.(string))
|
||||
}
|
||||
|
||||
checkURL.RawQuery = q.Encode()
|
||||
|
||||
c.Config[config.URL] = checkURL.String()
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulNodeBlacklistAttr]; found {
|
||||
listRaw := v.([]interface{})
|
||||
checks := make([]string, 0, len(listRaw))
|
||||
for _, v := range listRaw {
|
||||
checks = append(checks, v.(string))
|
||||
}
|
||||
c.Config[apiConsulNodeBlacklist] = strings.Join(checks, ",")
|
||||
}
|
||||
|
||||
if v, found := consulConfig[checkConsulServiceNameBlacklistAttr]; found {
|
||||
listRaw := v.([]interface{})
|
||||
checks := make([]string, 0, len(listRaw))
|
||||
for _, v := range listRaw {
|
||||
checks = append(checks, v.(string))
|
||||
}
|
||||
c.Config[apiConsulServiceBlacklist] = strings.Join(checks, ",")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,282 @@
|
|||
package circonus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/circonus-labs/circonus-gometrics/api/config"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccCirconusCheckConsul_node(t *testing.T) {
|
||||
checkName := fmt.Sprintf("Terraform test: consul.service.consul mode=state check - %s", acctest.RandString(5))
|
||||
|
||||
checkNode := fmt.Sprintf("my-node-name-or-node-id-%s", acctest.RandString(5))
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckDestroyCirconusCheckBundle,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fmt.Sprintf(testAccCirconusCheckConsulConfigV1HealthNodeFmt, checkName, checkNode),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "active", "true"),
|
||||
resource.TestMatchResourceAttr("circonus_check.consul_server", "check_id", regexp.MustCompile(config.CheckCIDRegex)),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "collector.#", "1"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "collector.2084916526.id", "/broker/2110"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.#", "1"),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.ca_chain", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.certificate_file", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.ciphers", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.key_file", ""),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.dc", "dc2"),
|
||||
resource.TestCheckNoResourceAttr("circonus_check.consul_server", "consul.0.headers"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.http_addr", "http://consul.service.consul:8501"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.node", checkNode),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.node_blacklist.#", "3"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.node_blacklist.0", "a"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.node_blacklist.1", "bad"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.node_blacklist.2", "node"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "notes", ""),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "period", "60s"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.active", "true"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.name", "KnownLeader"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.type", "text"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.active", "true"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.name", "LastContact"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.type", "numeric"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.unit", "seconds"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "target", "consul.service.consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "type", "consul"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccCirconusCheckConsul_service(t *testing.T) {
|
||||
checkName := fmt.Sprintf("Terraform test: consul.service.consul mode=service check - %s", acctest.RandString(5))
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckDestroyCirconusCheckBundle,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fmt.Sprintf(testAccCirconusCheckConsulConfigV1HealthServiceFmt, checkName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "active", "true"),
|
||||
resource.TestMatchResourceAttr("circonus_check.consul_server", "check_id", regexp.MustCompile(config.CheckCIDRegex)),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "collector.#", "1"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "collector.2084916526.id", "/broker/2110"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.#", "1"),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.ca_chain", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.certificate_file", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.ciphers", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.key_file", ""),
|
||||
resource.TestCheckNoResourceAttr("circonus_check.consul_server", "consul.0.headers"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.http_addr", "http://consul.service.consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.service", "consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.service_blacklist.#", "3"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.service_blacklist.0", "bad"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.service_blacklist.1", "hombre"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.service_blacklist.2", "service"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "name", checkName),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "notes", ""),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "period", "60s"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.active", "true"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.name", "KnownLeader"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.type", "text"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.active", "true"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.name", "LastContact"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.type", "numeric"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.unit", "seconds"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "target", "consul.service.consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "type", "consul"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccCirconusCheckConsul_state(t *testing.T) {
|
||||
checkName := fmt.Sprintf("Terraform test: consul.service.consul mode=state check - %s", acctest.RandString(5))
|
||||
|
||||
checkState := "critical"
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckDestroyCirconusCheckBundle,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fmt.Sprintf(testAccCirconusCheckConsulConfigV1HealthStateFmt, checkName, checkState),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "active", "true"),
|
||||
resource.TestMatchResourceAttr("circonus_check.consul_server", "check_id", regexp.MustCompile(config.CheckCIDRegex)),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "collector.#", "1"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "collector.2084916526.id", "/broker/2110"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.#", "1"),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.ca_chain", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.certificate_file", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.ciphers", ""),
|
||||
// resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.key_file", ""),
|
||||
resource.TestCheckNoResourceAttr("circonus_check.consul_server", "consul.0.headers"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.http_addr", "http://consul.service.consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.state", checkState),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.check_blacklist.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.check_blacklist.0", "worthless"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "consul.0.check_blacklist.1", "check"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "name", checkName),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "notes", ""),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "period", "60s"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.active", "true"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.name", "KnownLeader"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3333874791.type", "text"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.active", "true"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.name", "LastContact"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.type", "numeric"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "metric.3148913305.unit", "seconds"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.#", "2"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.1401442048", "lifecycle:unittest"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "tags.2058715988", "source:consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "target", "consul.service.consul"),
|
||||
resource.TestCheckResourceAttr("circonus_check.consul_server", "type", "consul"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const testAccCirconusCheckConsulConfigV1HealthNodeFmt = `
|
||||
resource "circonus_check" "consul_server" {
|
||||
active = true
|
||||
name = "%s"
|
||||
period = "60s"
|
||||
|
||||
collector {
|
||||
id = "/broker/2110"
|
||||
}
|
||||
|
||||
consul {
|
||||
dc = "dc2"
|
||||
http_addr = "http://consul.service.consul:8501"
|
||||
node = "%s"
|
||||
node_blacklist = ["a","bad","node"]
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "LastContact"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "numeric"
|
||||
unit = "seconds"
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "KnownLeader"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "text"
|
||||
}
|
||||
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
|
||||
target = "consul.service.consul"
|
||||
}
|
||||
`
|
||||
|
||||
const testAccCirconusCheckConsulConfigV1HealthServiceFmt = `
|
||||
resource "circonus_check" "consul_server" {
|
||||
active = true
|
||||
name = "%s"
|
||||
period = "60s"
|
||||
|
||||
collector {
|
||||
id = "/broker/2110"
|
||||
}
|
||||
|
||||
consul {
|
||||
service = "consul"
|
||||
service_blacklist = ["bad","hombre","service"]
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "LastContact"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "numeric"
|
||||
unit = "seconds"
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "KnownLeader"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "text"
|
||||
}
|
||||
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
|
||||
target = "consul.service.consul"
|
||||
}
|
||||
`
|
||||
|
||||
const testAccCirconusCheckConsulConfigV1HealthStateFmt = `
|
||||
resource "circonus_check" "consul_server" {
|
||||
active = true
|
||||
name = "%s"
|
||||
period = "60s"
|
||||
|
||||
collector {
|
||||
id = "/broker/2110"
|
||||
}
|
||||
|
||||
consul {
|
||||
state = "%s"
|
||||
check_blacklist = ["worthless","check"]
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "LastContact"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "numeric"
|
||||
unit = "seconds"
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "KnownLeader"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "text"
|
||||
}
|
||||
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
|
||||
target = "consul.service.consul"
|
||||
}
|
||||
`
|
|
@ -372,6 +372,10 @@ func checkConfigToAPIHTTP(c *circonusCheck, l interfaceList) error {
|
|||
if len(c.Target) == 0 {
|
||||
c.Target = hostInfo[0]
|
||||
}
|
||||
|
||||
if len(hostInfo) > 1 && c.Config[config.Port] == "" {
|
||||
c.Config[config.Port] = hostInfo[1]
|
||||
}
|
||||
}
|
||||
|
||||
if v, found := httpConfig[checkHTTPVersionAttr]; found {
|
||||
|
|
|
@ -355,6 +355,10 @@ func checkConfigToAPIJSON(c *circonusCheck, l interfaceList) error {
|
|||
if len(c.Target) == 0 {
|
||||
c.Target = hostInfo[0]
|
||||
}
|
||||
|
||||
if len(hostInfo) > 1 && c.Config[config.Port] == "" {
|
||||
c.Config[config.Port] = hostInfo[1]
|
||||
}
|
||||
}
|
||||
|
||||
if v, found := jsonConfig[checkJSONVersionAttr]; found {
|
||||
|
|
|
@ -314,6 +314,7 @@ type urlParseFlags int
|
|||
const (
|
||||
urlIsAbs urlParseFlags = 1 << iota
|
||||
urlOptional
|
||||
urlWithoutPath
|
||||
urlWithoutPort
|
||||
urlWithoutSchema
|
||||
)
|
||||
|
@ -345,6 +346,10 @@ func validateHTTPURL(attrName schemaAttr, checkFlags urlParseFlags) func(v inter
|
|||
errors = append(errors, fmt.Errorf("Schema is present on URL %q (HINT: drop the https://%s)", v.(string), v.(string)))
|
||||
}
|
||||
|
||||
if checkFlags&urlWithoutPath != 0 && u.Path != "" {
|
||||
errors = append(errors, fmt.Errorf("Path is present on URL %q (HINT: drop the %s)", v.(string), u.Path))
|
||||
}
|
||||
|
||||
if checkFlags&urlWithoutPort != 0 {
|
||||
hostParts := strings.SplitN(u.Host, ":", 2)
|
||||
if len(hostParts) != 1 {
|
||||
|
|
|
@ -88,6 +88,9 @@ resource "circonus_metric" "used" {
|
|||
enterprise collector running in your datacenter. One collection of metrics
|
||||
will be automatically created for each `collector` specified.
|
||||
|
||||
* `consul` - (Optional) A native Consul check. See below for details on how to
|
||||
configure a `consul` check.
|
||||
|
||||
* `http` - (Optional) A poll-based HTTP check. See below for details on how to configure
|
||||
the `http` check.
|
||||
|
||||
|
@ -249,6 +252,140 @@ resource "circonus_check" "rds_metrics" {
|
|||
}
|
||||
```
|
||||
|
||||
### `consul` Check Type Attributes
|
||||
|
||||
* `acl_token` - (Optional) An ACL Token authenticate the API request. When an
|
||||
ACL Token is set, this value is transmitted as an HTTP Header in order to not
|
||||
show up in any logs. The default value is an empty string.
|
||||
|
||||
* `allow_stale` - (Optional) A boolean value that indicates whether or not this
|
||||
check should require the health information come from the Consul leader node.
|
||||
For scalability reasons, this value defaults to `false`. See below for
|
||||
details on detecting the staleness of health information.
|
||||
|
||||
* `ca_chain` - (Optional) A path to a file containing all the certificate
|
||||
authorities that should be loaded to validate the remote certificate (required
|
||||
when `http_addr` is a TLS-enabled endpoint).
|
||||
|
||||
* `certificate_file` - (Optional) A path to a file containing the client
|
||||
certificate that will be presented to the remote server (required when
|
||||
`http_addr` is a TLS-enabled endpoint).
|
||||
|
||||
* `check_blacklist` - (Optional) A list of check names to exclude from the
|
||||
result of checks (i.e. no metrics will be generated by whose check name is in
|
||||
the `check_blacklist`). This blacklist is applied to the `node`,
|
||||
`service`, and `state` check modes.
|
||||
|
||||
* `ciphers` - (Optional) A list of ciphers to be used in the TLS protocol
|
||||
(only used when `http_addr` is a TLS-enabled endpoint).
|
||||
|
||||
* `dc` - (Optional) Explicitly name the Consul datacenter to use. The default
|
||||
value is an empty string. When an empty value is specified, the Consul
|
||||
datacenter of the agent at the `http_addr` is implicitly used.
|
||||
|
||||
* `headers` - (Optional) A map of the HTTP headers to be sent when executing the
|
||||
check. NOTE: the `headers` attribute is processed last and will takes
|
||||
precidence over any other derived value that is transmitted as an HTTP header
|
||||
to Consul (i.e. it is possible to override the `acl_token` by setting a
|
||||
headers value).
|
||||
|
||||
* `http_addr` - (Optional) The Consul HTTP endpoint to to query for health
|
||||
information. The default value is `http://consul.service.consul:8500`. The
|
||||
scheme must change from `http` to `https` when the endpoint has been
|
||||
TLS-enabled.
|
||||
|
||||
* `key_file` - (Optional) A path to a file containing key to be used in
|
||||
conjunction with the cilent certificate (required when `http_addr` is a
|
||||
TLS-enabled endpoint).
|
||||
|
||||
* `node` - (Optional) Check the health of this node. The value can be either a
|
||||
Consul Node ID (Consul Version >= 0.7.4) or Node Name. See also the
|
||||
`service_blacklist`, `node_blacklist`, and `check_blacklist` attributes. This
|
||||
attribute conflicts with the `service` and `state` attributes.
|
||||
|
||||
* `node_blacklist` - (Optional) A list of node IDs or node names to exclude from
|
||||
the results of checks (i.e. no metrics will be generated from nodes in the
|
||||
`node_blacklist`). This blacklist is applied to the `node`, `service`, and
|
||||
`state` check modes.
|
||||
|
||||
* `service` - (Optional) Check the cluster-wide health of this named service.
|
||||
See also the `service_blacklist`, `node_blacklist`, and `check_blacklist`
|
||||
attributes. This attribute conflicts with the `node` and `state` attributes.
|
||||
|
||||
* `service_blacklist` - (Optional) A list of service names to exclude from the
|
||||
result of checks (i.e. no metrics will be generated by services whose service
|
||||
name is in the `service_blacklist`). This blacklist is applied to the `node`,
|
||||
`service`, and `state` check modes.
|
||||
|
||||
* `state` - (Optional) A Circonus check to monitor Consul checks across the
|
||||
entire Consul cluster. This value may be either `passing`, `warning`, or
|
||||
`critical`. This `consul` check mode is intended to act as the cluster check
|
||||
of last resort. This check type is useful when first starting and is intended
|
||||
to act as a check of last resort before transitioning to explicitly defined
|
||||
checks for individual services or nodes. The metrics returned from check will
|
||||
be sorted based on the `CreateIndex` of the entry in order to have a stable
|
||||
set of metrics in the array of returned values. See also the
|
||||
`service_blacklist`, `node_blacklist`, and `check_blacklist` attributes. This
|
||||
attribute conflicts with the `node` and `state` attributes.
|
||||
|
||||
Available metrics depend on the consul check being performed (`node`, `service`,
|
||||
or `state`). In addition to the data avilable from the endpoints, the `consul`
|
||||
check also returns a set of metrics that are a variant of:
|
||||
`{Num,Pct}{,Passing,Warning,Critical}{Checks,Nodes,Services}` (see the
|
||||
`GLOB_BRACE` section of your local `glob(3)` documentation).
|
||||
|
||||
Example Consul check (partial metrics collection):
|
||||
|
||||
```
|
||||
resource "circonus_check" "consul_server" {
|
||||
active = true
|
||||
name = "%s"
|
||||
period = "60s"
|
||||
|
||||
collector {
|
||||
# Collector ID must be an Enterprise broker able to reach the Consul agent
|
||||
# listed in `http_addr`.
|
||||
id = "/broker/2110"
|
||||
}
|
||||
|
||||
consul {
|
||||
service = "consul"
|
||||
|
||||
# Other consul check modes:
|
||||
# node = "consul1"
|
||||
# state = "critical"
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "NumNodes"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "numeric"
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "LastContact"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "numeric"
|
||||
unit = "seconds"
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "Index"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "numeric"
|
||||
unit = "transactions"
|
||||
}
|
||||
|
||||
metric {
|
||||
name = "KnownLeader"
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
type = "text"
|
||||
}
|
||||
|
||||
tags = [ "source:consul", "lifecycle:unittest" ]
|
||||
}
|
||||
```
|
||||
|
||||
### `http` Check Type Attributes
|
||||
|
||||
* `auth_method` - (Optional) HTTP Authentication method to use. When set must
|
||||
|
|
Loading…
Reference in New Issue