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 }