Skip to content

Commit fc42f46

Browse files
authored
Merge pull request #24907 from DrFaust92/redshift-auth-profile
r/redshift_authentication_profile - new resource
2 parents 077be83 + db3e2ac commit fc42f46

File tree

7 files changed

+385
-0
lines changed

7 files changed

+385
-0
lines changed

.changelog/24907.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:new-resource
2+
aws_redshift_authentication_profile
3+
```

internal/provider/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,7 @@ func Provider() *schema.Provider {
17611761
"aws_rds_cluster_role_association": rds.ResourceClusterRoleAssociation(),
17621762
"aws_rds_global_cluster": rds.ResourceGlobalCluster(),
17631763

1764+
"aws_redshift_authentication_profile": redshift.ResourceAuthenticationProfile(),
17641765
"aws_redshift_cluster": redshift.ResourceCluster(),
17651766
"aws_redshift_event_subscription": redshift.ResourceEventSubscription(),
17661767
"aws_redshift_hsm_client_certificate": redshift.ResourceHsmClientCertificate(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package redshift
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/aws/aws-sdk-go/aws"
8+
"github.com/aws/aws-sdk-go/service/redshift"
9+
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
13+
"github.com/hashicorp/terraform-provider-aws/internal/conns"
14+
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
15+
"github.com/hashicorp/terraform-provider-aws/internal/verify"
16+
)
17+
18+
func ResourceAuthenticationProfile() *schema.Resource {
19+
return &schema.Resource{
20+
Create: resourceAuthenticationProfileCreate,
21+
Read: resourceAuthenticationProfileRead,
22+
Update: resourceAuthenticationProfileUpdate,
23+
Delete: resourceAuthenticationProfileDelete,
24+
25+
Importer: &schema.ResourceImporter{
26+
State: schema.ImportStatePassthrough,
27+
},
28+
29+
Schema: map[string]*schema.Schema{
30+
"authentication_profile_name": {
31+
Type: schema.TypeString,
32+
Required: true,
33+
ForceNew: true,
34+
},
35+
"authentication_profile_content": {
36+
Type: schema.TypeString,
37+
Required: true,
38+
ValidateFunc: validation.StringIsJSON,
39+
DiffSuppressFunc: verify.SuppressEquivalentJSONDiffs,
40+
StateFunc: func(v interface{}) string {
41+
json, _ := structure.NormalizeJsonString(v)
42+
return json
43+
},
44+
},
45+
},
46+
}
47+
}
48+
49+
func resourceAuthenticationProfileCreate(d *schema.ResourceData, meta interface{}) error {
50+
conn := meta.(*conns.AWSClient).RedshiftConn
51+
52+
authProfileName := d.Get("authentication_profile_name").(string)
53+
54+
input := redshift.CreateAuthenticationProfileInput{
55+
AuthenticationProfileName: aws.String(authProfileName),
56+
AuthenticationProfileContent: aws.String(d.Get("authentication_profile_content").(string)),
57+
}
58+
59+
out, err := conn.CreateAuthenticationProfile(&input)
60+
61+
if err != nil {
62+
return fmt.Errorf("error creating Redshift Authentication Profile (%s): %s", authProfileName, err)
63+
}
64+
65+
d.SetId(aws.StringValue(out.AuthenticationProfileName))
66+
67+
return resourceAuthenticationProfileRead(d, meta)
68+
}
69+
70+
func resourceAuthenticationProfileRead(d *schema.ResourceData, meta interface{}) error {
71+
conn := meta.(*conns.AWSClient).RedshiftConn
72+
73+
out, err := FindAuthenticationProfileByID(conn, d.Id())
74+
if !d.IsNewResource() && tfresource.NotFound(err) {
75+
log.Printf("[WARN] Redshift Authentication Profile (%s) not found, removing from state", d.Id())
76+
d.SetId("")
77+
return nil
78+
}
79+
80+
if err != nil {
81+
return fmt.Errorf("error reading Redshift Authentication Profile (%s): %w", d.Id(), err)
82+
}
83+
84+
d.Set("authentication_profile_content", out.AuthenticationProfileContent)
85+
d.Set("authentication_profile_name", out.AuthenticationProfileName)
86+
87+
return nil
88+
}
89+
90+
func resourceAuthenticationProfileUpdate(d *schema.ResourceData, meta interface{}) error {
91+
conn := meta.(*conns.AWSClient).RedshiftConn
92+
93+
input := &redshift.ModifyAuthenticationProfileInput{
94+
AuthenticationProfileName: aws.String(d.Id()),
95+
AuthenticationProfileContent: aws.String(d.Get("authentication_profile_content").(string)),
96+
}
97+
98+
_, err := conn.ModifyAuthenticationProfile(input)
99+
100+
if err != nil {
101+
return fmt.Errorf("error modifying Redshift Authentication Profile (%s): %w", d.Id(), err)
102+
}
103+
104+
return resourceAuthenticationProfileRead(d, meta)
105+
}
106+
107+
func resourceAuthenticationProfileDelete(d *schema.ResourceData, meta interface{}) error {
108+
conn := meta.(*conns.AWSClient).RedshiftConn
109+
110+
deleteInput := redshift.DeleteAuthenticationProfileInput{
111+
AuthenticationProfileName: aws.String(d.Id()),
112+
}
113+
114+
log.Printf("[DEBUG] Deleting Redshift Authentication Profile: %s", d.Id())
115+
_, err := conn.DeleteAuthenticationProfile(&deleteInput)
116+
117+
if err != nil {
118+
if tfawserr.ErrCodeEquals(err, redshift.ErrCodeAuthenticationProfileNotFoundFault) {
119+
return nil
120+
}
121+
return err
122+
}
123+
124+
return err
125+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package redshift_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/aws/aws-sdk-go/service/redshift"
8+
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
11+
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
12+
"github.com/hashicorp/terraform-provider-aws/internal/conns"
13+
tfredshift "github.com/hashicorp/terraform-provider-aws/internal/service/redshift"
14+
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
15+
)
16+
17+
func TestAccRedshiftAuthenticationProfile_basic(t *testing.T) {
18+
resourceName := "aws_redshift_authentication_profile.test"
19+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
20+
rNameUpdated := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
21+
22+
resource.ParallelTest(t, resource.TestCase{
23+
PreCheck: func() { acctest.PreCheck(t) },
24+
ErrorCheck: acctest.ErrorCheck(t, redshift.EndpointsID),
25+
ProviderFactories: acctest.ProviderFactories,
26+
CheckDestroy: testAccCheckAuthenticationProfileDestroy,
27+
Steps: []resource.TestStep{
28+
{
29+
Config: testAccAuthenticationProfileBasic(rName, rName),
30+
Check: resource.ComposeTestCheckFunc(
31+
testAccCheckAuthenticationProfileExists(resourceName),
32+
resource.TestCheckResourceAttr(resourceName, "authentication_profile_name", rName),
33+
),
34+
},
35+
{
36+
ResourceName: resourceName,
37+
ImportState: true,
38+
ImportStateVerify: true,
39+
},
40+
{
41+
Config: testAccAuthenticationProfileBasic(rName, rNameUpdated),
42+
Check: resource.ComposeTestCheckFunc(
43+
testAccCheckAuthenticationProfileExists(resourceName),
44+
resource.TestCheckResourceAttr(resourceName, "authentication_profile_name", rName),
45+
),
46+
},
47+
},
48+
})
49+
}
50+
51+
func TestAccRedshiftAuthenticationProfile_disappears(t *testing.T) {
52+
resourceName := "aws_redshift_authentication_profile.test"
53+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
54+
55+
resource.ParallelTest(t, resource.TestCase{
56+
PreCheck: func() { acctest.PreCheck(t) },
57+
ErrorCheck: acctest.ErrorCheck(t, redshift.EndpointsID),
58+
ProviderFactories: acctest.ProviderFactories,
59+
CheckDestroy: testAccCheckAuthenticationProfileDestroy,
60+
Steps: []resource.TestStep{
61+
{
62+
Config: testAccAuthenticationProfileBasic(rName, rName),
63+
Check: resource.ComposeTestCheckFunc(
64+
testAccCheckAuthenticationProfileExists(resourceName),
65+
acctest.CheckResourceDisappears(acctest.Provider, tfredshift.ResourceAuthenticationProfile(), resourceName),
66+
),
67+
ExpectNonEmptyPlan: true,
68+
},
69+
},
70+
})
71+
}
72+
73+
func testAccCheckAuthenticationProfileDestroy(s *terraform.State) error {
74+
conn := acctest.Provider.Meta().(*conns.AWSClient).RedshiftConn
75+
76+
for _, rs := range s.RootModule().Resources {
77+
if rs.Type != "aws_redshift_authentication_profile" {
78+
continue
79+
}
80+
81+
_, err := tfredshift.FindAuthenticationProfileByID(conn, rs.Primary.ID)
82+
83+
if tfresource.NotFound(err) {
84+
continue
85+
}
86+
87+
if err != nil {
88+
return err
89+
}
90+
91+
return fmt.Errorf("Redshift Authentication Profile %s still exists", rs.Primary.ID)
92+
}
93+
94+
return nil
95+
}
96+
97+
func testAccCheckAuthenticationProfileExists(name string) resource.TestCheckFunc {
98+
return func(s *terraform.State) error {
99+
rs, ok := s.RootModule().Resources[name]
100+
if !ok {
101+
return fmt.Errorf("not found: %s", name)
102+
}
103+
104+
if rs.Primary.ID == "" {
105+
return fmt.Errorf("Authentication Profile ID is not set")
106+
}
107+
108+
conn := acctest.Provider.Meta().(*conns.AWSClient).RedshiftConn
109+
110+
_, err := tfredshift.FindAuthenticationProfileByID(conn, rs.Primary.ID)
111+
112+
if err != nil {
113+
return err
114+
}
115+
116+
return nil
117+
}
118+
}
119+
120+
func testAccAuthenticationProfileBasic(rName, id string) string {
121+
return fmt.Sprintf(`
122+
resource "aws_redshift_authentication_profile" "test" {
123+
authentication_profile_name = %[1]q
124+
authentication_profile_content = jsonencode(
125+
{
126+
AllowDBUserOverride = "1"
127+
Client_ID = "ExampleClientID"
128+
App_ID = %[2]q
129+
}
130+
)
131+
}
132+
`, rName, id)
133+
}

internal/service/redshift/find.go

+28
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,31 @@ func FindUsageLimitByID(conn *redshift.Redshift, id string) (*redshift.UsageLimi
172172

173173
return output.UsageLimits[0], nil
174174
}
175+
176+
func FindAuthenticationProfileByID(conn *redshift.Redshift, id string) (*redshift.AuthenticationProfile, error) {
177+
input := redshift.DescribeAuthenticationProfilesInput{
178+
AuthenticationProfileName: aws.String(id),
179+
}
180+
181+
out, err := conn.DescribeAuthenticationProfiles(&input)
182+
if tfawserr.ErrCodeEquals(err, redshift.ErrCodeAuthenticationProfileNotFoundFault) {
183+
return nil, &resource.NotFoundError{
184+
LastError: err,
185+
LastRequest: input,
186+
}
187+
}
188+
189+
if err != nil {
190+
return nil, err
191+
}
192+
193+
if out == nil || len(out.AuthenticationProfiles) == 0 {
194+
return nil, tfresource.NewEmptyResultError(input)
195+
}
196+
197+
if count := len(out.AuthenticationProfiles); count > 1 {
198+
return nil, tfresource.NewTooManyResultsError(count, input)
199+
}
200+
201+
return out.AuthenticationProfiles[0], nil
202+
}

internal/service/redshift/sweep.go

+48
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ func init() {
3535
F: sweepHsmClientCertificates,
3636
})
3737

38+
resource.AddTestSweepers("aws_redshift_authentication_profile", &resource.Sweeper{
39+
Name: "aws_redshift_authentication_profile",
40+
F: sweepAuthenticationProfiles,
41+
})
42+
3843
resource.AddTestSweepers("aws_redshift_event_subscription", &resource.Sweeper{
3944
Name: "aws_redshift_event_subscription",
4045
F: sweepEventSubscriptions,
@@ -385,3 +390,46 @@ func sweepHsmClientCertificates(region string) error {
385390

386391
return errs.ErrorOrNil()
387392
}
393+
394+
func sweepAuthenticationProfiles(region string) error {
395+
client, err := sweep.SharedRegionalSweepClient(region)
396+
397+
if err != nil {
398+
return fmt.Errorf("error getting client: %s", err)
399+
}
400+
401+
conn := client.(*conns.AWSClient).RedshiftConn
402+
sweepResources := make([]*sweep.SweepResource, 0)
403+
var errs *multierror.Error
404+
405+
input := &redshift.DescribeAuthenticationProfilesInput{}
406+
output, err := conn.DescribeAuthenticationProfiles(input)
407+
408+
if len(output.AuthenticationProfiles) == 0 {
409+
log.Print("[DEBUG] No Redshift Authentication Profiles to sweep")
410+
}
411+
412+
if err != nil {
413+
errs = multierror.Append(errs, fmt.Errorf("error describing Redshift Authentication Profiles: %w", err))
414+
// in case work can be done, don't jump out yet
415+
}
416+
417+
for _, c := range output.AuthenticationProfiles {
418+
r := ResourceAuthenticationProfile()
419+
d := r.Data(nil)
420+
d.SetId(aws.StringValue(c.AuthenticationProfileName))
421+
422+
sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client))
423+
}
424+
425+
if err = sweep.SweepOrchestrator(sweepResources); err != nil {
426+
errs = multierror.Append(errs, fmt.Errorf("error sweeping Redshift Authentication Profiles for %s: %w", region, err))
427+
}
428+
429+
if sweep.SkipSweepError(errs.ErrorOrNil()) {
430+
log.Printf("[WARN] Skipping Redshift Authentication Profile sweep for %s: %s", region, err)
431+
return nil
432+
}
433+
434+
return errs.ErrorOrNil()
435+
}

0 commit comments

Comments
 (0)