@@ -6,32 +6,20 @@ package logical
6
6
7
7
import (
8
8
"context"
9
- "encoding/json"
10
9
"fmt"
11
10
12
11
"github.com/aws/aws-sdk-go/aws"
13
- "github.com/aws/aws-sdk-go/aws/arn"
14
- "github.com/aws/aws-sdk-go/aws/awserr"
15
12
"github.com/aws/aws-sdk-go/aws/session"
16
13
"github.com/aws/aws-sdk-go/service/iam"
17
14
"github.com/aws/aws-sdk-go/service/rds"
18
15
"github.com/aws/aws-sdk-go/service/rds/rdsutils"
19
- "github.com/docker/docker/api/types/mount"
20
16
"github.com/pkg/errors"
21
17
22
18
"gitlab.com/postgres-ai/database-lab/pkg/log"
23
19
)
24
20
25
21
const (
26
22
sslRootCert = "/cert/ssl-combined-ca-bundle.pem"
27
-
28
- // AWS service names.
29
- serviceIAM = "iam"
30
- serviceRDSDB = "rds-db"
31
-
32
- // RDS policy option values.
33
- rdsDocPolicyVersion = "2012-10-17"
34
- rdsDBConnectAction = "rds-db:connect"
35
23
)
36
24
37
25
type rdsDumper struct {
@@ -42,22 +30,9 @@ type rdsDumper struct {
42
30
43
31
// RDSConfig describes configuration of an RDS instance.
44
32
type RDSConfig struct {
45
- IamPolicyName string `yaml:"iamPolicyName"`
46
- AWSRegion string `yaml:"awsRegion"`
47
- DBInstance string `yaml:"dbInstanceIdentifier"`
48
- Username string `yaml:"username"`
49
- SSLRootCert string `yaml:"sslRootCert"`
50
- }
51
-
52
- type policyDocument struct {
53
- Version string `json:"Version"`
54
- Statement []policyStatement `json:"Statement"`
55
- }
56
-
57
- type policyStatement struct {
58
- Effect string `json:"Effect"`
59
- Action []string `json:"Action"`
60
- Resource []string `json:"Resource"`
33
+ AWSRegion string `yaml:"awsRegion"`
34
+ DBInstance string `yaml:"dbInstanceIdentifier"`
35
+ SSLRootCert string `yaml:"sslRootCert"`
61
36
}
62
37
63
38
func newRDSDumper (rdsCfg * RDSConfig ) (* rdsDumper , error ) {
@@ -85,30 +60,20 @@ Set up valid environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY`)
85
60
86
61
// GetEnvVariables returns dumper environment variables.
87
62
func (r * rdsDumper ) GetCmdEnvVariables () []string {
63
+ cert := sslRootCert
64
+
65
+ if r .rdsCfg .SSLRootCert != "" {
66
+ cert = r .rdsCfg .SSLRootCert
67
+ }
68
+
88
69
execEnvs := []string {
89
- "PGSSLROOTCERT=" + sslRootCert ,
70
+ "PGSSLROOTCERT=" + cert ,
90
71
"PGSSLMODE=verify-ca" ,
91
72
}
92
73
93
74
return execEnvs
94
75
}
95
76
96
- // GetMounts returns dumper volume configurations for mounting.
97
- func (r * rdsDumper ) GetMounts () []mount.Mount {
98
- mounts := []mount.Mount {}
99
-
100
- if r .rdsCfg != nil && r .rdsCfg .SSLRootCert != "" {
101
- // TODO (akartasov): Remove mounting after the image contains a built-in certificate.
102
- mounts = append (mounts , mount.Mount {
103
- Type : mount .TypeBind ,
104
- Source : r .rdsCfg .SSLRootCert ,
105
- Target : sslRootCert ,
106
- })
107
- }
108
-
109
- return mounts
110
- }
111
-
112
77
// SetConnectionOptions sets connection options for dumping.
113
78
func (r * rdsDumper ) SetConnectionOptions (ctx context.Context , c * Connection ) error {
114
79
dbInstancesOutput , err := r .rdsSvc .DescribeDBInstancesWithContext (ctx , & rds.DescribeDBInstancesInput {
@@ -126,28 +91,6 @@ func (r *rdsDumper) SetConnectionOptions(ctx context.Context, c *Connection) err
126
91
127
92
dbInstance := dbInstancesOutput .DBInstances [0 ]
128
93
129
- dbARN := dbInstancesOutput .DBInstances [0 ].DBInstanceArn
130
- parsedDBArn , err := arn .Parse (aws .StringValue (dbARN ))
131
-
132
- if err != nil {
133
- return errors .Wrap (err , "failed to parse a database ARN" )
134
- }
135
-
136
- policy , err := r .getPolicy (r .getPolicyARN (parsedDBArn ).String (), parsedDBArn , dbInstance )
137
- if err != nil {
138
- return errors .Wrap (err , "failed to get a policy" )
139
- }
140
-
141
- _ , err = r .iamSvc .AttachUserPolicy (& iam.AttachUserPolicyInput {
142
- PolicyArn : policy .Arn ,
143
- UserName : aws .String (r .rdsCfg .Username ),
144
- })
145
- if err != nil {
146
- return errors .Wrap (err , "failed to attach policy to a user" )
147
- }
148
-
149
- log .Msg (fmt .Sprintf ("Policy %q has been attached to %s" , aws .StringValue (policy .Arn ), r .rdsCfg .Username ))
150
-
151
94
dbAuthToken , err := rdsutils .BuildAuthToken (
152
95
fmt .Sprintf ("%s:%d" , aws .StringValue (dbInstance .Endpoint .Address ), int (aws .Int64Value (dbInstance .Endpoint .Port ))),
153
96
r .rdsCfg .AWSRegion ,
@@ -164,67 +107,3 @@ func (r *rdsDumper) SetConnectionOptions(ctx context.Context, c *Connection) err
164
107
165
108
return nil
166
109
}
167
-
168
- func (r * rdsDumper ) getPolicyARN (parsedDBArn arn.ARN ) arn.ARN {
169
- policyARN := arn.ARN {
170
- Partition : parsedDBArn .Partition ,
171
- Service : serviceIAM ,
172
- AccountID : parsedDBArn .AccountID ,
173
- Resource : "policy/" + r .rdsCfg .IamPolicyName ,
174
- }
175
-
176
- return policyARN
177
- }
178
-
179
- func (r * rdsDumper ) getPolicy (policyARN string , parsedDBArn arn.ARN , dbInstance * rds.DBInstance ) (* iam.Policy , error ) {
180
- policyOutput , err := r .iamSvc .GetPolicy (& iam.GetPolicyInput {
181
- PolicyArn : aws .String (policyARN ),
182
- })
183
- if err == nil {
184
- return policyOutput .Policy , nil
185
- }
186
-
187
- if awsErr , ok := err .(awserr.Error ); ok && awsErr .Code () != iam .ErrCodeNoSuchEntityException {
188
- return nil , errors .Wrap (err , "failed to get policy" )
189
- }
190
-
191
- policyDocumentData , err := json .Marshal (r .buildPolicyDocument (parsedDBArn , dbInstance ))
192
- if err != nil {
193
- return nil , errors .Wrap (err , "failed to marshal a policy document" )
194
- }
195
-
196
- createPolicyOutput , err := r .iamSvc .CreatePolicy (& iam.CreatePolicyInput {
197
- PolicyDocument : aws .String (string (policyDocumentData )),
198
- PolicyName : aws .String (r .rdsCfg .IamPolicyName ),
199
- })
200
- if err != nil {
201
- return nil , errors .Wrap (err , "failed to create a policy" )
202
- }
203
-
204
- log .Msg (fmt .Sprintf ("Policy has been created: %v" , aws .StringValue (createPolicyOutput .Policy .Arn )))
205
-
206
- return createPolicyOutput .Policy , nil
207
- }
208
-
209
- func (r * rdsDumper ) buildPolicyDocument (parsedDBArn arn.ARN , dbInstance * rds.DBInstance ) policyDocument {
210
- dbPolicyARN := arn.ARN {
211
- Partition : parsedDBArn .Partition ,
212
- Service : serviceRDSDB ,
213
- Region : parsedDBArn .Region ,
214
- AccountID : parsedDBArn .AccountID ,
215
- Resource : fmt .Sprintf ("dbuser:%s/*" , aws .StringValue (dbInstance .DbiResourceId )),
216
- }
217
-
218
- policyDocument := policyDocument {
219
- Version : rdsDocPolicyVersion ,
220
- Statement : []policyStatement {
221
- {
222
- Effect : "Allow" ,
223
- Action : []string {rdsDBConnectAction },
224
- Resource : []string {dbPolicyARN .String ()},
225
- },
226
- },
227
- }
228
-
229
- return policyDocument
230
- }
0 commit comments