Skip to content

Commit 20e0318

Browse files
authored
test: secrets manager integration (#426)
1 parent a1893ab commit 20e0318

1 file changed

Lines changed: 215 additions & 0 deletions

File tree

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/*
2+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License").
5+
You may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import { TestEnvironment } from "./utils/test_environment";
18+
import { DriverHelper } from "./utils/driver_helper";
19+
import { AwsWrapperError } from "../../../../common/lib/utils/errors";
20+
import { AwsPGClient } from "../../../../pg/lib";
21+
import { AwsMySQLClient } from "../../../../mysql/lib";
22+
import { logger } from "../../../../common/logutils";
23+
import { TestEnvironmentFeatures } from "./utils/test_environment_features";
24+
import { features, instanceCount } from "./config";
25+
import { PluginManager } from "../../../../common/lib";
26+
import { CreateSecretCommand, CreateSecretCommandOutput, DeleteSecretCommand, SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
27+
import { RDSClient } from "@aws-sdk/client-rds";
28+
import { AuroraTestUtility } from "./utils/aurora_test_utility";
29+
import { ProxyHelper } from "./utils/proxy_helper";
30+
31+
const itIf =
32+
!features.includes(TestEnvironmentFeatures.PERFORMANCE) &&
33+
!features.includes(TestEnvironmentFeatures.RUN_AUTOSCALING_TESTS_ONLY) &&
34+
features.includes(TestEnvironmentFeatures.IAM) &&
35+
instanceCount == 2
36+
? it
37+
: it.skip;
38+
39+
let env: TestEnvironment;
40+
let driver;
41+
let initClientFunc: (props: any) => any;
42+
let secretId: string;
43+
let secretARN: string;
44+
let secretsManagerClient: RDSClient;
45+
let auroraTestUtility: AuroraTestUtility;
46+
47+
async function initConfig(host: string, secretId: string): Promise<any> {
48+
env = await TestEnvironment.getCurrent();
49+
let props = {
50+
host: host,
51+
database: env.databaseInfo.defaultDbName,
52+
port: env.databaseInfo.instanceEndpointPort,
53+
secretRegion: env.region,
54+
secretId: secretId,
55+
plugins: "secretsManager"
56+
};
57+
props = DriverHelper.addDriverSpecificConfiguration(props, env.engine);
58+
59+
return props;
60+
}
61+
62+
async function validateConnection(client: AwsPGClient | AwsMySQLClient) {
63+
try {
64+
await client.connect();
65+
const res = await DriverHelper.executeQuery(env.engine, client, "select 1");
66+
expect(res).not.toBeNull();
67+
} finally {
68+
try {
69+
await client.end();
70+
} catch (error) {
71+
// pass
72+
}
73+
}
74+
}
75+
76+
async function createCommand(secretName: string) {
77+
const secretObj = {
78+
engine: `${env.engine}`,
79+
username: `${env.databaseInfo.username}`,
80+
password: `${env.databaseInfo.password}`,
81+
host: `${env.databaseInfo.writerInstanceEndpoint}`,
82+
dbname: `${env.databaseInfo.defaultDbName}`,
83+
port: `${env.databaseInfo.instanceEndpointPort}`
84+
};
85+
const input = {
86+
Name: secretName,
87+
ForceOverwriteReplicaSecret: true,
88+
SecretString: JSON.stringify(secretObj)
89+
};
90+
91+
const command = new CreateSecretCommand(input);
92+
const result: CreateSecretCommandOutput = await secretsManagerClient.send(command);
93+
secretId = result.Name;
94+
secretARN = result.ARN;
95+
}
96+
97+
async function deleteCommand() {
98+
const deleteInput = { SecretId: secretId, ForceDeleteWithoutRecovery: true };
99+
const command = new DeleteSecretCommand(deleteInput);
100+
await secretsManagerClient.send(command);
101+
}
102+
103+
describe("aurora secrets manager", () => {
104+
beforeAll(async () => {
105+
env = await TestEnvironment.getCurrent();
106+
secretsManagerClient = new SecretsManagerClient({ region: env.region });
107+
auroraTestUtility = new AuroraTestUtility(env.region);
108+
driver = DriverHelper.getDriverForDatabaseEngine(env.engine);
109+
initClientFunc = DriverHelper.getClient(driver);
110+
await ProxyHelper.enableAllConnectivity();
111+
112+
await TestEnvironment.verifyClusterStatus();
113+
}, 1000000);
114+
115+
afterAll(async () => {
116+
secretsManagerClient.destroy();
117+
});
118+
119+
beforeEach(async () => {
120+
logger.info(`Test started: ${expect.getState().currentTestName}`);
121+
env = await TestEnvironment.getCurrent();
122+
auroraTestUtility = new AuroraTestUtility(env.region);
123+
driver = DriverHelper.getDriverForDatabaseEngine(env.engine);
124+
initClientFunc = DriverHelper.getClient(driver);
125+
await ProxyHelper.enableAllConnectivity();
126+
await TestEnvironment.verifyClusterStatus();
127+
}, 1320000);
128+
129+
afterEach(async () => {
130+
if (secretId != null) {
131+
await deleteCommand();
132+
}
133+
secretId = null;
134+
secretARN = null;
135+
await PluginManager.releaseResources();
136+
logger.info(`Test finished: ${expect.getState().currentTestName}`);
137+
}, 1320000);
138+
139+
itIf(
140+
"secrets manager wrong secretId",
141+
async () => {
142+
await createCommand("wrongSecretId");
143+
144+
const config = await initConfig(env.databaseInfo.writerInstanceEndpoint, `WRONG_${env.info.databaseInfo.username}_USER`);
145+
const client: AwsPGClient | AwsMySQLClient = initClientFunc(config);
146+
147+
await expect(client.connect()).rejects.toThrow();
148+
},
149+
100000
150+
);
151+
152+
itIf(
153+
"secrets manager no secretId",
154+
async () => {
155+
const config = await initConfig(env.databaseInfo.writerInstanceEndpoint, undefined);
156+
const client: AwsPGClient | AwsMySQLClient = initClientFunc(config);
157+
158+
await expect(client.connect()).rejects.toBeInstanceOf(AwsWrapperError);
159+
},
160+
100000
161+
);
162+
163+
itIf(
164+
"secrets manager invalid region",
165+
async () => {
166+
await createCommand("invalidRegion");
167+
168+
const config = await initConfig(env.databaseInfo.writerInstanceEndpoint, secretId);
169+
config["secretRegion"] = "<>";
170+
const client: AwsPGClient | AwsMySQLClient = initClientFunc(config);
171+
172+
await expect(client.connect()).rejects.toBeInstanceOf(AwsWrapperError);
173+
},
174+
100000
175+
);
176+
177+
itIf(
178+
"secrets manager valid connection properties",
179+
async () => {
180+
await createCommand("validConnectionProperties");
181+
182+
const config = await initConfig(env.databaseInfo.writerInstanceEndpoint, secretId);
183+
const client: AwsPGClient | AwsMySQLClient = initClientFunc(config);
184+
await validateConnection(client);
185+
},
186+
100000
187+
);
188+
189+
itIf(
190+
"secrets manager valid secret ARN",
191+
async () => {
192+
await createCommand("validSecretARN");
193+
194+
const config = await initConfig(env.databaseInfo.writerInstanceEndpoint, secretARN);
195+
// Region not required if secret is ARN.
196+
config["region"] = undefined;
197+
const client: AwsPGClient | AwsMySQLClient = initClientFunc(config);
198+
await validateConnection(client);
199+
},
200+
100000
201+
);
202+
203+
itIf(
204+
"secrets manager valid secret ARN with password",
205+
async () => {
206+
await createCommand("validSecretARNWithPassword");
207+
const config = await initConfig(env.databaseInfo.writerInstanceEndpoint, secretARN);
208+
// Password is not needed.
209+
config["password"] = "anything";
210+
const client: AwsPGClient | AwsMySQLClient = initClientFunc(config);
211+
await validateConnection(client);
212+
},
213+
100000
214+
);
215+
});

0 commit comments

Comments
 (0)