Skip to content

Commit

Permalink
Fix tcp in server name when adding firewall rule (#233)
Browse files Browse the repository at this point in the history
* Test TCP connection

* Add debug message

* Remove tcp from server name

* Explicitly exclude tcp

* Rebuild main.js
  • Loading branch information
zijchen authored Jul 1, 2024
1 parent 83d6b65 commit 048d916
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 25 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/adhoc-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,29 @@ jobs:
- name: Test DACPAC Action
uses: ./
with:
connection-string: '${{ secrets.ADHOC_CONNECTION_STRING_NO_DATABASE }}Initial Catalog=${{ env.TEST_DB }};'
connection-string: 'Server=tcp:${{ secrets.TEST_SERVER }};Initial Catalog=${{ env.TEST_DB }};Authentication=Active Directory Default;'
path: ./__testdata__/sql-action.dacpac
action: 'publish'

# Build and publish sqlproj that should create a new view
- name: Test Build and Publish
uses: ./
with:
connection-string: '${{ secrets.ADHOC_CONNECTION_STRING_NO_DATABASE }}Initial Catalog=${{ env.TEST_DB }};'
connection-string: 'Server=tcp:${{ secrets.TEST_SERVER }};Initial Catalog=${{ env.TEST_DB }};Authentication=Active Directory Default;'
path: ./__testdata__/TestProject/sql-action.sqlproj
action: 'publish'

# Execute testsql.sql via script action on server
- name: Test SQL Action
uses: ./
with:
connection-string: '${{ secrets.ADHOC_CONNECTION_STRING_NO_DATABASE }}Initial Catalog=${{ env.TEST_DB }};'
connection-string: 'Server=tcp:${{ secrets.TEST_SERVER }};Initial Catalog=${{ env.TEST_DB }};Authentication=Active Directory Default;'
path: ./__testdata__/testsql.sql

- name: Cleanup Test Database
if: always()
uses: ./
with:
connection-string: '${{ secrets.ADHOC_CONNECTION_STRING_NO_DATABASE }}Initial Catalog=master;'
connection-string: 'Server=${{ secrets.TEST_SERVER }};Initial Catalog=master;Authentication=Active Directory Default;'
path: ./__testdata__/cleanup.sql
arguments: '-v DbName="${{ env.TEST_DB }}"'
arguments: '-v DbName="${{ env.TEST_DB }}"'
4 changes: 2 additions & 2 deletions __tests__/AzureSqlResourceManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe.only('AzureSqlResourceManager tests', () => {
let resourceManager = await AzureSqlResourceManager.getResourceManager('testServer.database.windows.net', await AuthorizerFactory.getAuthorizer());
let server = resourceManager.getSqlServer();

expect(server!.name).toMatch('testServer');
expect(server!.name).toBe('testServer');
expect(getRequestUrlSpy).toHaveBeenCalledTimes(1);
expect(beginRequestSpy).toHaveBeenCalledTimes(1);
});
Expand Down Expand Up @@ -116,7 +116,7 @@ describe.only('AzureSqlResourceManager tests', () => {
let firewallRule = await resourceManager.addFirewallRule('1.2.3.4', '1.2.3.4');

expect(beginRequestSpy).toHaveBeenCalledTimes(1);
expect(firewallRule.name).toMatch('FirewallRuleName');
expect(firewallRule.name).toBe('FirewallRuleName');
beginRequestSpy.mockReset();
})

Expand Down
2 changes: 1 addition & 1 deletion __tests__/FirewallManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('FirewallManager tests', () => {
firewallManager.removeFirewallRule();

expect(removeFirewallRuleSpy).toHaveBeenCalledTimes(1);
expect(removeFirewallRuleSpy.mock.calls[0][0].name).toMatch('FirewallRuleName');
expect(removeFirewallRuleSpy.mock.calls[0][0].name).toBe('FirewallRuleName');
});
});

Expand Down
24 changes: 12 additions & 12 deletions __tests__/SqlConnectionConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ describe('SqlConnectionConfig tests', () => {
it.each(validConnectionStrings)('Input `%s` %s', (connectionStringInput, testDescription, passwordOutput) => {
const connectionString = new SqlConnectionConfig(connectionStringInput);

expect(connectionString.Password).toMatch(passwordOutput);
expect(connectionString.UserId).toMatch(`user`);
expect(connectionString.Database).toMatch('testdb');
expect(connectionString.Server).toMatch('test1.database.windows.net');
expect(connectionString.Password).toBe(passwordOutput);
expect(connectionString.UserId).toBe(`user`);
expect(connectionString.Database).toBe('testdb');
expect(connectionString.Server).toBe('test1.database.windows.net');
});
})

Expand Down Expand Up @@ -80,17 +80,17 @@ describe('SqlConnectionConfig tests', () => {
it.each(connectionStrings)('should parse different authentication types successfully', (connectionStringInput, expectedAuthType) => {
const config = new SqlConnectionConfig(connectionStringInput);

expect(config.Server).toMatch('test1.database.windows.net');
expect(config.Database).toMatch('testdb');
expect(config.Server).toBe('test1.database.windows.net');
expect(config.Database).toBe('testdb');
expect(config.EscapedConnectionString.replace(/""/g, '"')).toMatch(connectionStringInput);
expect(config.FormattedAuthentication ?? '').toMatch(expectedAuthType);
expect(config.FormattedAuthentication ?? '').toBe(expectedAuthType);
switch (expectedAuthType) {
case '':
case 'sqlpassword':
case 'activedirectorypassword':
case 'activedirectoryserviceprincipal': {
expect(config.UserId).toMatch('user');
expect(config.Password).toMatch('placeholder');
expect(config.UserId).toBe('user');
expect(config.Password).toBe('placeholder');
break;
}
case 'activedirectorydefault': {
Expand All @@ -114,9 +114,9 @@ describe('SqlConnectionConfig tests', () => {
it.each(connectionStrings)('should parse server name successfully', (connectionStringInput, expectedServerName, expectedPortNumber) => {
const config = new SqlConnectionConfig(connectionStringInput);

expect(config.Server).toMatch(expectedServerName);
expect(config.Port?.toString() || '').toMatch(expectedPortNumber);
expect(config.Database).toMatch('testdb');
expect(config.Server).toBe(expectedServerName);
expect(config.Port?.toString() || '').toBe(expectedPortNumber);
expect(config.Database).toBe('testdb');
expect(config.EscapedConnectionString).toMatch(connectionStringInput);
});
});
Expand Down
2 changes: 1 addition & 1 deletion lib/main.js

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions src/SqlConnectionConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ export default class SqlConnectionConfig {
}

public get Server(): string {
const server = this._parsedConnectionString['data source'] as string;
let server = this._parsedConnectionString['data source'] as string;
// Remove port number
if (server?.includes(',')) {
return server.split(',')[0].trim();
server = server.split(',')[0].trim();
}
// Remove tcp protocol
if (server?.startsWith('tcp:')) {
server = server.slice(4).trim();
}
return server;
}
Expand Down
4 changes: 2 additions & 2 deletions src/SqlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ export default class SqlUtils {
};
}
catch (error) {
console.log(`${error.message}`);
console.log(`SqlCmd stderr: ${sqlCmdError}`);
core.debug(`${error.message}`);
core.debug(`SqlCmd stderr: ${sqlCmdError}`);
return {
success: false,
errorMessage: sqlCmdError,
Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default async function run() {
if (inputs.skipFirewallCheck !== true) {
const runnerIPAddress = await SqlUtils.detectIPAddress(inputs.connectionConfig);
if (runnerIPAddress) {
core.debug(`Temporarily adding '${runnerIPAddress}' to the firewall of ${inputs.connectionConfig.Server}.`);
let azureResourceAuthorizer = await AuthorizerFactory.getAuthorizer();
let azureSqlResourceManager = await AzureSqlResourceManager.getResourceManager(inputs.connectionConfig.Server, azureResourceAuthorizer);
firewallManager = new FirewallManager(azureSqlResourceManager);
Expand Down

0 comments on commit 048d916

Please sign in to comment.