167 lines
5.4 KiB
Go
167 lines
5.4 KiB
Go
package circonus
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/circonus-labs/circonus-gometrics/api/config"
|
|
"github.com/hashicorp/errwrap"
|
|
"github.com/hashicorp/terraform/helper/hashcode"
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
)
|
|
|
|
const (
|
|
// circonus_check.postgresql.* resource attribute names
|
|
checkPostgreSQLDSNAttr = "dsn"
|
|
// checkPostgreSQLHostAttr = "host"
|
|
// checkPostgreSQLNameAttr = "name"
|
|
// checkPostgreSQLPasswordAttr = "password"
|
|
// checkPostgreSQLPortAttr = "port"
|
|
checkPostgreSQLQueryAttr = "query"
|
|
// checkPostgreSQLSSLModeAttr = "sslmode"
|
|
// checkPostgreSQLUserAttr = "user"
|
|
)
|
|
|
|
var checkPostgreSQLDescriptions = attrDescrs{
|
|
checkPostgreSQLDSNAttr: "The connect DSN for the PostgreSQL instance",
|
|
// checkPostgreSQLHostAttr: "The Hostname to connect to",
|
|
// checkPostgreSQLNameAttr: "The database name to connect to",
|
|
// checkPostgreSQLPasswordAttr: "The password to use",
|
|
// checkPostgreSQLPortAttr: "The TCP port number to use to connect on",
|
|
checkPostgreSQLQueryAttr: "The SQL to use as the query",
|
|
// checkPostgreSQLSSLModeAttr: "The SSL Mode to connect as",
|
|
// checkPostgreSQLUserAttr: "The username to connect as",
|
|
}
|
|
|
|
var schemaCheckPostgreSQL = &schema.Schema{
|
|
Type: schema.TypeSet,
|
|
Optional: true,
|
|
MaxItems: 1,
|
|
MinItems: 1,
|
|
Set: hashCheckPostgreSQL,
|
|
Elem: &schema.Resource{
|
|
Schema: convertToHelperSchema(checkPostgreSQLDescriptions, map[schemaAttr]*schema.Schema{
|
|
checkPostgreSQLDSNAttr: &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ValidateFunc: validateRegexp(checkPostgreSQLDSNAttr, `^.+$`),
|
|
},
|
|
// TODO(sean@): Parse out the DSN into individual PostgreSQL connect
|
|
// options.
|
|
//
|
|
// checkPostgreSQLHostAttr: &schema.Schema{
|
|
// Type: schema.TypeString,
|
|
// Optional: true,
|
|
// Default: "/tmp",
|
|
// ValidateFunc: validateRegexp(checkPostgreSQLHostAttr, `^(/.+|[\S]+)$`),
|
|
// },
|
|
// checkPostgreSQLNameAttr: &schema.Schema{
|
|
// Type: schema.TypeString,
|
|
// Required: true,
|
|
// ValidateFunc: validateRegexp(checkPostgreSQLNameAttr, `^[\S]+$`),
|
|
// },
|
|
// checkPostgreSQLPasswordAttr: &schema.Schema{
|
|
// Type: schema.TypeString,
|
|
// Optional: true,
|
|
// Sensitive: true,
|
|
// },
|
|
// checkPostgreSQLPortAttr: &schema.Schema{
|
|
// Type: schema.TypeInt,
|
|
// Optional: true,
|
|
// Default: 5432,
|
|
// ValidateFunc: validateFuncs(
|
|
// validateIntMin(checkPostgreSQLPortAttr, 1),
|
|
// validateIntMax(checkPostgreSQLPortAttr, 65535),
|
|
// ),
|
|
// },
|
|
checkPostgreSQLQueryAttr: &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
StateFunc: suppressWhitespace,
|
|
ValidateFunc: validateRegexp(checkPostgreSQLQueryAttr, `.+`),
|
|
},
|
|
// checkPostgreSQLSSLModeAttr: &schema.Schema{
|
|
// Type: schema.TypeString,
|
|
// Optional: true,
|
|
// Default: "require",
|
|
// ValidateFunc: validateRegexp(checkPostgreSQLSSLModeAttr, `^(disable|require|verify-ca|verify-full)$`),
|
|
// },
|
|
// checkPostgreSQLUserAttr: &schema.Schema{
|
|
// Type: schema.TypeString,
|
|
// Required: true,
|
|
// ValidateFunc: validateRegexp(checkPostgreSQLUserAttr, `.+`),
|
|
// },
|
|
}),
|
|
},
|
|
}
|
|
|
|
// checkAPIToStatePostgreSQL reads the Config data out of circonusCheck.CheckBundle into the
|
|
// statefile.
|
|
func checkAPIToStatePostgreSQL(c *circonusCheck, d *schema.ResourceData) error {
|
|
postgresqlConfig := make(map[string]interface{}, len(c.Config))
|
|
|
|
// TODO(sean@): Parse out the DSN into individual PostgreSQL connect options
|
|
postgresqlConfig[string(checkPostgreSQLDSNAttr)] = c.Config[config.DSN]
|
|
postgresqlConfig[string(checkPostgreSQLQueryAttr)] = c.Config[config.SQL]
|
|
|
|
if err := d.Set(checkPostgreSQLAttr, schema.NewSet(hashCheckPostgreSQL, []interface{}{postgresqlConfig})); err != nil {
|
|
return errwrap.Wrapf(fmt.Sprintf("Unable to store check %q attribute: {{err}}", checkPostgreSQLAttr), err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// hashCheckPostgreSQL creates a stable hash of the normalized values
|
|
func hashCheckPostgreSQL(v interface{}) int {
|
|
m := v.(map[string]interface{})
|
|
b := &bytes.Buffer{}
|
|
b.Grow(defaultHashBufSize)
|
|
|
|
// writeInt := func(attrName schemaAttr) {
|
|
// if v, ok := m[string(attrName)]; ok {
|
|
// fmt.Fprintf(b, "%x", v.(int))
|
|
// }
|
|
// }
|
|
|
|
writeString := func(attrName schemaAttr) {
|
|
if v, ok := m[string(attrName)]; ok && v.(string) != "" {
|
|
fmt.Fprint(b, strings.TrimSpace(v.(string)))
|
|
}
|
|
}
|
|
|
|
// Order writes to the buffer using lexically sorted list for easy visual
|
|
// reconciliation with other lists.
|
|
writeString(checkPostgreSQLDSNAttr)
|
|
// writeString(checkPostgreSQLHostAttr)
|
|
// writeString(checkPostgreSQLNameAttr)
|
|
// writeString(checkPostgreSQLPasswordAttr)
|
|
// writeInt(checkPostgreSQLPortAttr)
|
|
// writeString(checkPostgreSQLSSLModeAttr)
|
|
writeString(checkPostgreSQLQueryAttr)
|
|
// writeString(checkPostgreSQLUserAttr)
|
|
|
|
s := b.String()
|
|
return hashcode.String(s)
|
|
}
|
|
|
|
func checkConfigToAPIPostgreSQL(c *circonusCheck, l interfaceList) error {
|
|
c.Type = string(apiCheckTypePostgreSQL)
|
|
|
|
// Iterate over all `postgres` attributes, even though we have a max of 1 in
|
|
// the schema.
|
|
for _, mapRaw := range l {
|
|
postgresConfig := newInterfaceMap(mapRaw)
|
|
|
|
if v, found := postgresConfig[checkPostgreSQLDSNAttr]; found {
|
|
c.Config[config.DSN] = v.(string)
|
|
}
|
|
|
|
if v, found := postgresConfig[checkPostgreSQLQueryAttr]; found {
|
|
c.Config[config.SQL] = v.(string)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|