github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/circonus/resource_circonus_check_postgresql.go (about)

     1  package circonus
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/circonus-labs/circonus-gometrics/api/config"
     9  	"github.com/hashicorp/errwrap"
    10  	"github.com/hashicorp/terraform/helper/hashcode"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  )
    13  
    14  const (
    15  	// circonus_check.postgresql.* resource attribute names
    16  	checkPostgreSQLDSNAttr = "dsn"
    17  	// checkPostgreSQLHostAttr      = "host"
    18  	// checkPostgreSQLNameAttr      = "name"
    19  	// checkPostgreSQLPasswordAttr  = "password"
    20  	// checkPostgreSQLPortAttr      = "port"
    21  	checkPostgreSQLQueryAttr = "query"
    22  	// checkPostgreSQLSSLModeAttr   = "sslmode"
    23  	// checkPostgreSQLUserAttr      = "user"
    24  )
    25  
    26  var checkPostgreSQLDescriptions = attrDescrs{
    27  	checkPostgreSQLDSNAttr: "The connect DSN for the PostgreSQL instance",
    28  	// checkPostgreSQLHostAttr:     "The Hostname to connect to",
    29  	// checkPostgreSQLNameAttr:     "The database name to connect to",
    30  	// checkPostgreSQLPasswordAttr: "The password to use",
    31  	// checkPostgreSQLPortAttr:     "The TCP port number to use to connect on",
    32  	checkPostgreSQLQueryAttr: "The SQL to use as the query",
    33  	// checkPostgreSQLSSLModeAttr:  "The SSL Mode to connect as",
    34  	// checkPostgreSQLUserAttr:     "The username to connect as",
    35  }
    36  
    37  var schemaCheckPostgreSQL = &schema.Schema{
    38  	Type:     schema.TypeSet,
    39  	Optional: true,
    40  	MaxItems: 1,
    41  	MinItems: 1,
    42  	Set:      hashCheckPostgreSQL,
    43  	Elem: &schema.Resource{
    44  		Schema: convertToHelperSchema(checkPostgreSQLDescriptions, map[schemaAttr]*schema.Schema{
    45  			checkPostgreSQLDSNAttr: &schema.Schema{
    46  				Type:         schema.TypeString,
    47  				Required:     true,
    48  				ValidateFunc: validateRegexp(checkPostgreSQLDSNAttr, `^.+$`),
    49  			},
    50  			// TODO(sean@): Parse out the DSN into individual PostgreSQL connect
    51  			// options.
    52  			//
    53  			// checkPostgreSQLHostAttr: &schema.Schema{
    54  			// 	Type:         schema.TypeString,
    55  			// 	Optional:     true,
    56  			// 	Default:      "/tmp",
    57  			// 	ValidateFunc: validateRegexp(checkPostgreSQLHostAttr, `^(/.+|[\S]+)$`),
    58  			// },
    59  			// checkPostgreSQLNameAttr: &schema.Schema{
    60  			// 	Type:         schema.TypeString,
    61  			// 	Required:     true,
    62  			// 	ValidateFunc: validateRegexp(checkPostgreSQLNameAttr, `^[\S]+$`),
    63  			// },
    64  			// checkPostgreSQLPasswordAttr: &schema.Schema{
    65  			// 	Type:      schema.TypeString,
    66  			// 	Optional:  true,
    67  			// 	Sensitive: true,
    68  			// },
    69  			// checkPostgreSQLPortAttr: &schema.Schema{
    70  			// 	Type:     schema.TypeInt,
    71  			// 	Optional: true,
    72  			// 	Default:  5432,
    73  			// 	ValidateFunc: validateFuncs(
    74  			// 		validateIntMin(checkPostgreSQLPortAttr, 1),
    75  			// 		validateIntMax(checkPostgreSQLPortAttr, 65535),
    76  			// 	),
    77  			// },
    78  			checkPostgreSQLQueryAttr: &schema.Schema{
    79  				Type:         schema.TypeString,
    80  				Required:     true,
    81  				StateFunc:    suppressWhitespace,
    82  				ValidateFunc: validateRegexp(checkPostgreSQLQueryAttr, `.+`),
    83  			},
    84  			// checkPostgreSQLSSLModeAttr: &schema.Schema{
    85  			// 	Type:         schema.TypeString,
    86  			// 	Optional:     true,
    87  			// 	Default:      "require",
    88  			// 	ValidateFunc: validateRegexp(checkPostgreSQLSSLModeAttr, `^(disable|require|verify-ca|verify-full)$`),
    89  			// },
    90  			// checkPostgreSQLUserAttr: &schema.Schema{
    91  			// 	Type:         schema.TypeString,
    92  			// 	Required:     true,
    93  			// 	ValidateFunc: validateRegexp(checkPostgreSQLUserAttr, `.+`),
    94  			// },
    95  		}),
    96  	},
    97  }
    98  
    99  // checkAPIToStatePostgreSQL reads the Config data out of circonusCheck.CheckBundle into the
   100  // statefile.
   101  func checkAPIToStatePostgreSQL(c *circonusCheck, d *schema.ResourceData) error {
   102  	postgresqlConfig := make(map[string]interface{}, len(c.Config))
   103  
   104  	// TODO(sean@): Parse out the DSN into individual PostgreSQL connect options
   105  	postgresqlConfig[string(checkPostgreSQLDSNAttr)] = c.Config[config.DSN]
   106  	postgresqlConfig[string(checkPostgreSQLQueryAttr)] = c.Config[config.SQL]
   107  
   108  	if err := d.Set(checkPostgreSQLAttr, schema.NewSet(hashCheckPostgreSQL, []interface{}{postgresqlConfig})); err != nil {
   109  		return errwrap.Wrapf(fmt.Sprintf("Unable to store check %q attribute: {{err}}", checkPostgreSQLAttr), err)
   110  	}
   111  
   112  	return nil
   113  }
   114  
   115  // hashCheckPostgreSQL creates a stable hash of the normalized values
   116  func hashCheckPostgreSQL(v interface{}) int {
   117  	m := v.(map[string]interface{})
   118  	b := &bytes.Buffer{}
   119  	b.Grow(defaultHashBufSize)
   120  
   121  	// writeInt := func(attrName schemaAttr) {
   122  	// 	if v, ok := m[string(attrName)]; ok {
   123  	// 		fmt.Fprintf(b, "%x", v.(int))
   124  	// 	}
   125  	// }
   126  
   127  	writeString := func(attrName schemaAttr) {
   128  		if v, ok := m[string(attrName)]; ok && v.(string) != "" {
   129  			fmt.Fprint(b, strings.TrimSpace(v.(string)))
   130  		}
   131  	}
   132  
   133  	// Order writes to the buffer using lexically sorted list for easy visual
   134  	// reconciliation with other lists.
   135  	writeString(checkPostgreSQLDSNAttr)
   136  	// writeString(checkPostgreSQLHostAttr)
   137  	// writeString(checkPostgreSQLNameAttr)
   138  	// writeString(checkPostgreSQLPasswordAttr)
   139  	// writeInt(checkPostgreSQLPortAttr)
   140  	// writeString(checkPostgreSQLSSLModeAttr)
   141  	writeString(checkPostgreSQLQueryAttr)
   142  	// writeString(checkPostgreSQLUserAttr)
   143  
   144  	s := b.String()
   145  	return hashcode.String(s)
   146  }
   147  
   148  func checkConfigToAPIPostgreSQL(c *circonusCheck, l interfaceList) error {
   149  	c.Type = string(apiCheckTypePostgreSQL)
   150  
   151  	// Iterate over all `postgres` attributes, even though we have a max of 1 in
   152  	// the schema.
   153  	for _, mapRaw := range l {
   154  		postgresConfig := newInterfaceMap(mapRaw)
   155  
   156  		if v, found := postgresConfig[checkPostgreSQLDSNAttr]; found {
   157  			c.Config[config.DSN] = v.(string)
   158  		}
   159  
   160  		if v, found := postgresConfig[checkPostgreSQLQueryAttr]; found {
   161  			c.Config[config.SQL] = v.(string)
   162  		}
   163  	}
   164  
   165  	return nil
   166  }