Skip to content

Commit 53d848c

Browse files
mikeeesicoyleyaron2shivamkm07Shivam Kumar
authored
Chore/rebase from main (#3666)
Signed-off-by: Samantha Coyle <[email protected]> Signed-off-by: Shivam Kumar <[email protected]> Signed-off-by: joshvanl <[email protected]> Signed-off-by: MattCosturos <[email protected]> Signed-off-by: Matt Costuros <[email protected]> Signed-off-by: Elena Kolevska <[email protected]> Signed-off-by: Mike Nguyen <[email protected]> Co-authored-by: Sam <[email protected]> Co-authored-by: Yaron Schneider <[email protected]> Co-authored-by: Shivam Kumar <[email protected]> Co-authored-by: Shivam Kumar <[email protected]> Co-authored-by: Josh van Leeuwen <[email protected]> Co-authored-by: MattCosturos <[email protected]> Co-authored-by: Artur Souza <[email protected]> Co-authored-by: Elena Kolevska <[email protected]>
1 parent 20f0277 commit 53d848c

File tree

27 files changed

+766
-552
lines changed

27 files changed

+766
-552
lines changed

.build-tools/builtin-authentication-profiles.yaml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,37 @@ aws:
55
metadata:
66
- name: region
77
type: string
8-
required: true
8+
required: false
9+
description: |
10+
The AWS Region where the AWS resource is deployed to.
11+
This will be marked required in Dapr 1.17.
12+
example: '"us-east-1"'
13+
- name: awsRegion
14+
type: string
15+
required: false
916
description: |
17+
This maintains backwards compatibility with existing fields.
18+
It will be deprecated as of Dapr 1.17. Use 'region' instead.
1019
The AWS Region where the AWS resource is deployed to.
1120
example: '"us-east-1"'
1221
- name: accessKey
1322
description: AWS access key associated with an IAM account
14-
required: true
23+
required: false
1524
sensitive: true
1625
example: '"AKIAIOSFODNN7EXAMPLE"'
1726
- name: secretKey
1827
description: The secret key associated with the access key
19-
required: true
28+
required: false
2029
sensitive: true
2130
example: '"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"'
2231
- name: sessionToken
32+
type: string
2333
required: false
2434
sensitive: true
2535
description: |
2636
AWS session token to use. A session token is only required if you are using
2737
temporary security credentials.
38+
example: '"TOKEN"'
2839
- title: "AWS: Assume IAM Role"
2940
description: |
3041
Assume a specific IAM role. Note: This is only supported for Kafka and PostgreSQL.
@@ -41,6 +52,7 @@ aws:
4152
description: |
4253
IAM role that has access to AWS resource.
4354
This is another option to authenticate with MSK and RDS Aurora aside from the AWS Credentials.
55+
This will be marked required in Dapr 1.17.
4456
example: '"arn:aws:iam::123456789:role/mskRole"'
4557
- name: sessionName
4658
type: string
@@ -51,7 +63,7 @@ aws:
5163
- title: "AWS: Credentials from Environment Variables"
5264
description: Use AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from the environment
5365
- title: "AWS: IAM Roles Anywhere"
54-
description: Use X.509 certificates to establish trust between AWS and your AWS account and the Dapr cluster using AWS IAM Roles Anywhere.
66+
description: Use X.509 certificates to establish trust between your AWS account and the Dapr cluster using AWS IAM Roles Anywhere.
5567
metadata:
5668
- name: trustAnchorArn
5769
description: |

.build-tools/pkg/metadataschema/builtin-authentication-profiles.go

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,40 +32,32 @@ func ParseBuiltinAuthenticationProfile(bi BuiltinAuthenticationProfile, componen
3232
for i, profile := range profiles {
3333
res[i] = profile
3434

35-
// convert slice to a slice of pointers to update in place for required -> non-required fields
36-
metadataPtr := make([]*Metadata, len(profile.Metadata))
37-
for j := range profile.Metadata {
38-
metadataPtr[j] = &profile.Metadata[j]
35+
// deep copy the metadata slice to avoid side effects when manually updating some req -> non-req fields to deprecate some fields for kafka/postgres
36+
// TODO: rm all of this manipulation in Dapr 1.17!!
37+
originalMetadata := profile.Metadata
38+
metadataCopy := make([]Metadata, len(originalMetadata))
39+
copy(metadataCopy, originalMetadata)
40+
41+
if componentTitle == "Apache Kafka" || strings.ToLower(componentTitle) == "postgresql" {
42+
removeRequiredOnSomeAWSFields(&metadataCopy)
3943
}
4044

41-
if componentTitle == "Apache Kafka" {
42-
removeRequiredOnSomeAWSFields(&metadataPtr)
43-
}
44-
45-
// convert back to value slices for merging
46-
updatedMetadata := make([]Metadata, 0, len(metadataPtr))
47-
for _, ptr := range metadataPtr {
48-
if ptr != nil {
49-
updatedMetadata = append(updatedMetadata, *ptr)
50-
}
51-
}
52-
53-
merged := mergedMetadata(bi.Metadata, updatedMetadata...)
45+
merged := mergedMetadata(bi.Metadata, metadataCopy...)
5446

5547
// Note: We must apply the removal of deprecated fields after the merge!!
5648

5749
// Here, we remove some deprecated fields as we support the transition to a new auth profile
58-
if profile.Title == "AWS: Assume specific IAM Role" && componentTitle == "Apache Kafka" {
50+
if profile.Title == "AWS: Assume IAM Role" && componentTitle == "Apache Kafka" || profile.Title == "AWS: Assume IAM Role" && strings.ToLower(componentTitle) == "postgresql" {
5951
merged = removeSomeDeprecatedFieldsOnUnrelatedAuthProfiles(merged)
6052
}
6153

6254
// Here, there are no metadata fields that need deprecating
63-
if profile.Title == "AWS: Credentials from Environment Variables" && componentTitle == "Apache Kafka" {
55+
if profile.Title == "AWS: Credentials from Environment Variables" && componentTitle == "Apache Kafka" || profile.Title == "AWS: Credentials from Environment Variables" && strings.ToLower(componentTitle) == "postgresql" {
6456
merged = removeAllDeprecatedFieldsOnUnrelatedAuthProfiles(merged)
6557
}
6658

6759
// Here, this is a new auth profile, so rm all deprecating fields as unrelated.
68-
if profile.Title == "AWS: IAM Roles Anywhere" && componentTitle == "Apache Kafka" {
60+
if profile.Title == "AWS: IAM Roles Anywhere" && componentTitle == "Apache Kafka" || profile.Title == "AWS: IAM Roles Anywhere" && strings.ToLower(componentTitle) == "postgresql" {
6961
merged = removeAllDeprecatedFieldsOnUnrelatedAuthProfiles(merged)
7062
}
7163

@@ -92,12 +84,14 @@ func mergedMetadata(base []Metadata, add ...Metadata) []Metadata {
9284
// We normally have accessKey, secretKey, and region fields marked required as it is part of the builtin AWS auth profile fields.
9385
// However, as we rm the aws prefixed ones, we need to then mark the normally required ones as not required only for postgres and kafka.
9486
// This way we do not break existing users, and transition them to the standardized fields.
95-
func removeRequiredOnSomeAWSFields(metadata *[]*Metadata) {
87+
func removeRequiredOnSomeAWSFields(metadata *[]Metadata) {
9688
if metadata == nil {
9789
return
9890
}
9991

100-
for _, field := range *metadata {
92+
for i := range *metadata {
93+
field := &(*metadata)[i]
94+
10195
if field == nil {
10296
continue
10397
}
@@ -125,7 +119,11 @@ func removeSomeDeprecatedFieldsOnUnrelatedAuthProfiles(metadata []Metadata) []Me
125119
filteredMetadata := []Metadata{}
126120

127121
for _, field := range metadata {
128-
if field.Name == "awsAccessKey" || field.Name == "awsSecretKey" || field.Name == "awsSessionToken" {
122+
// region is required in Assume Role auth profile, so this is needed for now.
123+
if field.Name == "region" {
124+
field.Required = true
125+
}
126+
if field.Name == "awsAccessKey" || field.Name == "awsSecretKey" || field.Name == "awsSessionToken" || field.Name == "awsRegion" {
129127
continue
130128
} else {
131129
filteredMetadata = append(filteredMetadata, field)

bindings/kafka/metadata.yaml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,6 @@ builtinAuthenticationProfiles:
2929
example: '"awsiam"'
3030
allowedValues:
3131
- "awsiam"
32-
- name: awsRegion
33-
type: string
34-
required: false
35-
description: |
36-
This maintains backwards compatibility with existing fields.
37-
It will be deprecated as of Dapr 1.17. Use 'region' instead.
38-
The AWS Region where the AWS Relational Database Service is deployed to.
39-
example: '"us-east-1"'
4032
- name: awsAccessKey
4133
type: string
4234
required: false
@@ -82,7 +74,7 @@ builtinAuthenticationProfiles:
8274
If both fields are set, then 'sessionName' value will be used.
8375
Represents the session name for assuming a role.
8476
example: '"MyAppSession"'
85-
default: '"MSKSASLDefaultSession"'
77+
default: '"DaprDefaultSession"'
8678
authenticationProfiles:
8779
- title: "OIDC Authentication"
8880
description: |

bindings/postgres/metadata.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const (
2828

2929
type psqlMetadata struct {
3030
pgauth.PostgresAuthMetadata `mapstructure:",squash"`
31-
aws.AWSIAM `mapstructure:",squash"`
31+
aws.DeprecatedPostgresIAM `mapstructure:",squash"`
3232
Timeout time.Duration `mapstructure:"timeout" mapstructurealiases:"timeoutInSeconds"`
3333
}
3434

bindings/postgres/metadata.yaml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,21 @@ builtinAuthenticationProfiles:
5656
example: |
5757
"host=mydb.postgres.database.aws.com user=myapplication port=5432 dbname=dapr_test sslmode=require"
5858
type: string
59-
- name: awsRegion
60-
type: string
61-
required: true
62-
description: |
63-
The AWS Region where the AWS Relational Database Service is deployed to.
64-
example: '"us-east-1"'
6559
- name: awsAccessKey
6660
type: string
67-
required: true
61+
required: false
6862
description: |
63+
Deprecated as of Dapr 1.17. Use 'accessKey' instead if using AWS IAM.
64+
If both fields are set, then 'accessKey' value will be used.
6965
AWS access key associated with an IAM account.
7066
example: '"AKIAIOSFODNN7EXAMPLE"'
7167
- name: awsSecretKey
7268
type: string
73-
required: true
69+
required: false
7470
sensitive: true
7571
description: |
72+
Deprecated as of Dapr 1.17. Use 'secretKey' instead if using AWS IAM.
73+
If both fields are set, then 'secretKey' value will be used.
7674
The secret key associated with the access key.
7775
example: '"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"'
7876
authenticationProfiles:

bindings/postgres/postgres.go

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626
"github.com/jackc/pgx/v5/pgxpool"
2727

2828
"github.com/dapr/components-contrib/bindings"
29+
awsAuth "github.com/dapr/components-contrib/common/authentication/aws"
30+
pgauth "github.com/dapr/components-contrib/common/authentication/postgresql"
2931
"github.com/dapr/components-contrib/metadata"
3032
"github.com/dapr/kit/logger"
3133
)
@@ -45,6 +47,11 @@ type Postgres struct {
4547
logger logger.Logger
4648
db *pgxpool.Pool
4749
closed atomic.Bool
50+
51+
enableAzureAD bool
52+
enableAWSIAM bool
53+
54+
awsAuthProvider awsAuth.Provider
4855
}
4956

5057
// NewPostgres returns a new PostgreSQL output binding.
@@ -59,18 +66,36 @@ func (p *Postgres) Init(ctx context.Context, meta bindings.Metadata) error {
5966
if p.closed.Load() {
6067
return errors.New("cannot initialize a previously-closed component")
6168
}
62-
69+
opts := pgauth.InitWithMetadataOpts{
70+
AzureADEnabled: p.enableAzureAD,
71+
AWSIAMEnabled: p.enableAWSIAM,
72+
}
6373
m := psqlMetadata{}
64-
err := m.InitWithMetadata(meta.Properties)
65-
if err != nil {
74+
if err := m.InitWithMetadata(meta.Properties); err != nil {
6675
return err
6776
}
6877

78+
var err error
6979
poolConfig, err := m.GetPgxPoolConfig()
7080
if err != nil {
7181
return err
7282
}
7383

84+
if opts.AWSIAMEnabled && m.UseAWSIAM {
85+
opts, validateErr := m.BuildAwsIamOptions(p.logger, meta.Properties)
86+
if validateErr != nil {
87+
return fmt.Errorf("failed to validate AWS IAM authentication fields: %w", validateErr)
88+
}
89+
90+
var provider awsAuth.Provider
91+
provider, err = awsAuth.NewProvider(ctx, *opts, awsAuth.GetConfig(*opts))
92+
if err != nil {
93+
return err
94+
}
95+
p.awsAuthProvider = provider
96+
p.awsAuthProvider.UpdatePostgres(ctx, poolConfig)
97+
}
98+
7499
// This context doesn't control the lifetime of the connection pool, and is
75100
// only scoped to postgres creating resources at init.
76101
connCtx, connCancel := context.WithTimeout(ctx, m.Timeout)
@@ -186,7 +211,11 @@ func (p *Postgres) Close() error {
186211
}
187212
p.db = nil
188213

189-
return nil
214+
errs := make([]error, 1)
215+
if p.awsAuthProvider != nil {
216+
errs[0] = p.awsAuthProvider.Close()
217+
}
218+
return errors.Join(errs...)
190219
}
191220

192221
func (p *Postgres) query(ctx context.Context, sql string, args ...any) (result []byte, err error) {

0 commit comments

Comments
 (0)