Skip to content

Commit ca97be0

Browse files
jbuntingstanleyz
authored andcommitted
fix quote ident for objectname and provider
1 parent abe2693 commit ca97be0

File tree

6 files changed

+454
-0
lines changed

6 files changed

+454
-0
lines changed

postgresql/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const (
4545
featureFunction
4646
featureServer
4747
featureCreateRoleSelfGrant
48+
featureSecurityLabel
4849
)
4950

5051
var (
@@ -120,6 +121,7 @@ var (
120121
// New privileges rules in version 16
121122
// https://www.postgresql.org/docs/16/release-16.html#RELEASE-16-PRIVILEGES
122123
featureCreateRoleSelfGrant: semver.MustParseRange(">=16.0.0"),
124+
featureSecurityLabel: semver.MustParseRange(">=11.0.0"),
123125
}
124126
)
125127

postgresql/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ func Provider() *schema.Provider {
207207
"postgresql_function": resourcePostgreSQLFunction(),
208208
"postgresql_server": resourcePostgreSQLServer(),
209209
"postgresql_user_mapping": resourcePostgreSQLUserMapping(),
210+
"postgresql_security_label": resourcePostgreSQLSecurityLabel(),
210211
},
211212

212213
DataSourcesMap: map[string]*schema.Resource{
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
package postgresql
2+
3+
import (
4+
"bytes"
5+
"database/sql"
6+
"fmt"
7+
"log"
8+
"regexp"
9+
"strings"
10+
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
"github.com/lib/pq"
13+
)
14+
15+
const (
16+
securityLabelObjectNameAttr = "object_name"
17+
securityLabelObjectTypeAttr = "object_type"
18+
securityLabelProviderAttr = "label_provider"
19+
securityLabelLabelAttr = "label"
20+
)
21+
22+
func resourcePostgreSQLSecurityLabel() *schema.Resource {
23+
return &schema.Resource{
24+
Create: PGResourceFunc(resourcePostgreSQLSecurityLabelCreate),
25+
Read: PGResourceFunc(resourcePostgreSQLSecurityLabelRead),
26+
Update: PGResourceFunc(resourcePostgreSQLSecurityLabelUpdate),
27+
Delete: PGResourceFunc(resourcePostgreSQLSecurityLabelDelete),
28+
Importer: &schema.ResourceImporter{
29+
StateContext: schema.ImportStatePassthroughContext,
30+
},
31+
32+
Schema: map[string]*schema.Schema{
33+
securityLabelObjectNameAttr: {
34+
Type: schema.TypeString,
35+
Required: true,
36+
ForceNew: true,
37+
Description: "The name of the existing object to apply the security label to",
38+
},
39+
securityLabelObjectTypeAttr: {
40+
Type: schema.TypeString,
41+
Required: true,
42+
ForceNew: true,
43+
Description: "The type of the existing object to apply the security label to",
44+
},
45+
securityLabelProviderAttr: {
46+
Type: schema.TypeString,
47+
Required: true,
48+
ForceNew: true,
49+
Description: "The provider to apply the security label for",
50+
},
51+
securityLabelLabelAttr: {
52+
Type: schema.TypeString,
53+
Required: true,
54+
ForceNew: false,
55+
Description: "The label to be applied",
56+
},
57+
},
58+
}
59+
}
60+
61+
func resourcePostgreSQLSecurityLabelCreate(db *DBConnection, d *schema.ResourceData) error {
62+
if !db.featureSupported(featureSecurityLabel) {
63+
return fmt.Errorf(
64+
"security Label is not supported for this Postgres version (%s)",
65+
db.version,
66+
)
67+
}
68+
log.Printf("[WARN] PostgreSQL security label Create")
69+
label := d.Get(securityLabelLabelAttr).(string)
70+
if err := resourcePostgreSQLSecurityLabelUpdateImpl(db, d, pq.QuoteLiteral(label)); err != nil {
71+
return err
72+
}
73+
74+
d.SetId(generateSecurityLabelID(d))
75+
76+
return resourcePostgreSQLSecurityLabelReadImpl(db, d)
77+
}
78+
79+
func resourcePostgreSQLSecurityLabelUpdateImpl(db *DBConnection, d *schema.ResourceData, label string) error {
80+
b := bytes.NewBufferString("SECURITY LABEL ")
81+
82+
objectType := d.Get(securityLabelObjectTypeAttr).(string)
83+
objectName := d.Get(securityLabelObjectNameAttr).(string)
84+
provider := d.Get(securityLabelProviderAttr).(string)
85+
fmt.Fprint(b, " FOR ", pq.QuoteIdentifier(provider))
86+
fmt.Fprint(b, " ON ", objectType, pq.QuoteIdentifier(objectName))
87+
fmt.Fprint(b, " IS ", label)
88+
89+
if _, err := db.Exec(b.String()); err != nil {
90+
log.Printf("[WARN] PostgreSQL security label Create failed %s", err)
91+
return err
92+
}
93+
return nil
94+
}
95+
96+
func resourcePostgreSQLSecurityLabelRead(db *DBConnection, d *schema.ResourceData) error {
97+
if !db.featureSupported(featureSecurityLabel) {
98+
return fmt.Errorf(
99+
"Security Label is not supported for this Postgres version (%s)",
100+
db.version,
101+
)
102+
}
103+
log.Printf("[WARN] PostgreSQL security label Read")
104+
105+
return resourcePostgreSQLSecurityLabelReadImpl(db, d)
106+
}
107+
108+
func resourcePostgreSQLSecurityLabelReadImpl(db *DBConnection, d *schema.ResourceData) error {
109+
objectType := d.Get(securityLabelObjectTypeAttr).(string)
110+
objectName := d.Get(securityLabelObjectNameAttr).(string)
111+
provider := d.Get(securityLabelProviderAttr).(string)
112+
113+
txn, err := startTransaction(db.client, "")
114+
if err != nil {
115+
return err
116+
}
117+
defer deferredRollback(txn)
118+
119+
query := "SELECT objtype, provider, label FROM pg_seclabels WHERE objtype = $1 and objname = $2 and provider = $3"
120+
row := db.QueryRow(query, objectType, quoteIdentifier(objectName), quoteIdentifier(provider))
121+
122+
var label string
123+
err = row.Scan(&objectType, &provider, &label)
124+
switch {
125+
case err == sql.ErrNoRows:
126+
log.Printf("[WARN] PostgreSQL security label for (%s '%s') with provider %s not found", objectType, objectName, provider)
127+
d.SetId("")
128+
return nil
129+
case err != nil:
130+
return fmt.Errorf("Error reading security label: %w", err)
131+
}
132+
133+
d.Set(securityLabelObjectTypeAttr, objectType)
134+
d.Set(securityLabelObjectNameAttr, objectName)
135+
d.Set(securityLabelProviderAttr, provider)
136+
d.Set(securityLabelLabelAttr, label)
137+
d.SetId(generateSecurityLabelID(d))
138+
139+
return nil
140+
}
141+
142+
func resourcePostgreSQLSecurityLabelDelete(db *DBConnection, d *schema.ResourceData) error {
143+
if !db.featureSupported(featureSecurityLabel) {
144+
return fmt.Errorf(
145+
"Security Label is not supported for this Postgres version (%s)",
146+
db.version,
147+
)
148+
}
149+
log.Printf("[WARN] PostgreSQL security label Delete")
150+
151+
if err := resourcePostgreSQLSecurityLabelUpdateImpl(db, d, "NULL"); err != nil {
152+
return err
153+
}
154+
155+
d.SetId("")
156+
157+
return nil
158+
}
159+
160+
func resourcePostgreSQLSecurityLabelUpdate(db *DBConnection, d *schema.ResourceData) error {
161+
if !db.featureSupported(featureServer) {
162+
return fmt.Errorf(
163+
"Security Label is not supported for this Postgres version (%s)",
164+
db.version,
165+
)
166+
}
167+
log.Printf("[WARN] PostgreSQL security label Update")
168+
169+
label := d.Get(securityLabelLabelAttr).(string)
170+
if err := resourcePostgreSQLSecurityLabelUpdateImpl(db, d, pq.QuoteLiteral(label)); err != nil {
171+
return err
172+
}
173+
174+
return resourcePostgreSQLSecurityLabelReadImpl(db, d)
175+
}
176+
177+
func generateSecurityLabelID(d *schema.ResourceData) string {
178+
return strings.Join([]string{
179+
d.Get(securityLabelProviderAttr).(string),
180+
d.Get(securityLabelObjectTypeAttr).(string),
181+
d.Get(securityLabelObjectNameAttr).(string),
182+
}, ".")
183+
}
184+
185+
func quoteIdentifier(s string) string {
186+
var result = s
187+
re := regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`)
188+
if !re.MatchString(s) || s != strings.ToLower(s) {
189+
result = pq.QuoteIdentifier(s)
190+
}
191+
return result
192+
}

0 commit comments

Comments
 (0)