github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/builtin/providers/postgresql/resource_postgresql_database.go (about) 1 package postgresql 2 3 import ( 4 "database/sql" 5 "fmt" 6 "strings" 7 8 "github.com/hashicorp/errwrap" 9 "github.com/hashicorp/terraform/helper/schema" 10 "github.com/lib/pq" 11 ) 12 13 func resourcePostgreSQLDatabase() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourcePostgreSQLDatabaseCreate, 16 Read: resourcePostgreSQLDatabaseRead, 17 Update: resourcePostgreSQLDatabaseUpdate, 18 Delete: resourcePostgreSQLDatabaseDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "name": { 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 "owner": { 27 Type: schema.TypeString, 28 Optional: true, 29 Computed: true, 30 }, 31 }, 32 } 33 } 34 35 func resourcePostgreSQLDatabaseCreate(d *schema.ResourceData, meta interface{}) error { 36 client := meta.(*Client) 37 conn, err := client.Connect() 38 if err != nil { 39 return errwrap.Wrapf("Error connecting to PostgreSQL: {{err}}", err) 40 } 41 defer conn.Close() 42 43 dbName := d.Get("name").(string) 44 dbOwner := d.Get("owner").(string) 45 connUsername := client.username 46 47 var dbOwnerCfg string 48 if dbOwner != "" { 49 dbOwnerCfg = fmt.Sprintf("WITH OWNER=%s", pq.QuoteIdentifier(dbOwner)) 50 } else { 51 dbOwnerCfg = "" 52 } 53 54 //needed in order to set the owner of the db if the connection user is not a superuser 55 err = grantRoleMembership(conn, dbOwner, connUsername) 56 if err != nil { 57 return err 58 } 59 60 query := fmt.Sprintf("CREATE DATABASE %s %s", pq.QuoteIdentifier(dbName), dbOwnerCfg) 61 _, err = conn.Query(query) 62 if err != nil { 63 return errwrap.Wrapf(fmt.Sprintf("Error creating database %s: {{err}}", dbName), err) 64 } 65 66 d.SetId(dbName) 67 68 return resourcePostgreSQLDatabaseRead(d, meta) 69 } 70 71 func resourcePostgreSQLDatabaseDelete(d *schema.ResourceData, meta interface{}) error { 72 client := meta.(*Client) 73 conn, err := client.Connect() 74 if err != nil { 75 return errwrap.Wrapf("Error connecting to PostgreSQL: {{err}}", err) 76 } 77 defer conn.Close() 78 79 dbName := d.Get("name").(string) 80 connUsername := client.username 81 dbOwner := d.Get("owner").(string) 82 //needed in order to set the owner of the db if the connection user is not a superuser 83 err = grantRoleMembership(conn, dbOwner, connUsername) 84 if err != nil { 85 return err 86 } 87 88 query := fmt.Sprintf("DROP DATABASE %s", pq.QuoteIdentifier(dbName)) 89 _, err = conn.Query(query) 90 if err != nil { 91 return errwrap.Wrapf("Error dropping database: {{err}}", err) 92 } 93 94 d.SetId("") 95 96 return nil 97 } 98 99 func resourcePostgreSQLDatabaseRead(d *schema.ResourceData, meta interface{}) error { 100 client := meta.(*Client) 101 conn, err := client.Connect() 102 if err != nil { 103 return err 104 } 105 defer conn.Close() 106 107 dbName := d.Get("name").(string) 108 109 var owner string 110 err = conn.QueryRow("SELECT pg_catalog.pg_get_userbyid(d.datdba) from pg_database d WHERE datname=$1", dbName).Scan(&owner) 111 switch { 112 case err == sql.ErrNoRows: 113 d.SetId("") 114 return nil 115 case err != nil: 116 return errwrap.Wrapf("Error reading database: {{err}}", err) 117 default: 118 d.Set("owner", owner) 119 return nil 120 } 121 } 122 123 func resourcePostgreSQLDatabaseUpdate(d *schema.ResourceData, meta interface{}) error { 124 client := meta.(*Client) 125 conn, err := client.Connect() 126 if err != nil { 127 return err 128 } 129 defer conn.Close() 130 131 dbName := d.Get("name").(string) 132 133 if d.HasChange("owner") { 134 owner := d.Get("owner").(string) 135 if owner != "" { 136 query := fmt.Sprintf("ALTER DATABASE %s OWNER TO %s", pq.QuoteIdentifier(dbName), pq.QuoteIdentifier(owner)) 137 _, err := conn.Query(query) 138 if err != nil { 139 return errwrap.Wrapf("Error updating owner: {{err}}", err) 140 } 141 } 142 } 143 144 return resourcePostgreSQLDatabaseRead(d, meta) 145 } 146 147 func grantRoleMembership(conn *sql.DB, dbOwner string, connUsername string) error { 148 if dbOwner != "" && dbOwner != connUsername { 149 query := fmt.Sprintf("GRANT %s TO %s", pq.QuoteIdentifier(dbOwner), pq.QuoteIdentifier(connUsername)) 150 _, err := conn.Query(query) 151 if err != nil { 152 //is already member or role 153 if strings.Contains(err.Error(), "duplicate key value violates unique constraint") { 154 return nil 155 } 156 return errwrap.Wrapf("Error granting membership: {{err}}", err) 157 } 158 } 159 return nil 160 }