Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2 - Use tedious mssql module instead of sqlcmd #96

Merged
merged 11 commits into from
Jun 7, 2022
Merged

Conversation

zijchen
Copy link
Contributor

@zijchen zijchen commented May 20, 2022

Use tedious node-mssql module for connection instead of using sqlcmd. This change adds the module and changes the IP address detection to use it. Script action still calls sqlcmd directly.

SqlConnectionStringBuilder has been replaced by SqlConnectionConfig which is a wrapper on mssql.config. Removed our own implementation for different parts of the connection string, instead leverage the parsing function from mssql to get a config object from a connection string, with some extra validation. AAD auth will be added in this class in subsequent PRs.

TODO in future PRs:

  • AAD/other authentication type support
  • Replace Script action with node-mssql execute directly
  • Input parameter breaking changes

@zijchen zijchen marked this pull request as draft May 20, 2022 18:57
@zijchen zijchen temporarily deployed to Automation test May 23, 2022 20:13 Inactive
@zijchen zijchen temporarily deployed to Automation test May 23, 2022 20:13 Inactive
@zijchen zijchen temporarily deployed to Automation test May 24, 2022 20:35 Inactive
@zijchen zijchen temporarily deployed to Automation test May 24, 2022 20:35 Inactive
@zijchen zijchen changed the title [WIP] Use tedious mssql library instead of sqlcmd Use tedious mssql library instead of sqlcmd May 24, 2022
@zijchen zijchen marked this pull request as ready for review May 24, 2022 20:41
@zijchen
Copy link
Contributor Author

zijchen commented May 24, 2022

@dzsquared @udeeshagautam thoughts on merging PR directly to main branch or have all changes on a feature branch until we're ready for v2 release?

@zijchen zijchen requested review from kisantia and llali May 24, 2022 20:42
@dzsquared
Copy link
Collaborator

@dzsquared Drew Skwiers-Koballa FTE @udeeshagautam Udeesha Gautam FTE thoughts on merging PR directly to main branch or have all changes on a feature branch until we're ready for v2 release?

please merge to a v2 branch, folks may have @master referenced in workflows using the action.

src/SqlUtils.ts Outdated Show resolved Hide resolved
@zijchen zijchen changed the base branch from master to v2 May 24, 2022 21:48
@zijchen zijchen changed the title Use tedious mssql library instead of sqlcmd v2 - Use tedious mssql library instead of sqlcmd May 25, 2022
@zijchen zijchen temporarily deployed to Automation test May 31, 2022 23:33 Inactive
@zijchen zijchen temporarily deployed to Automation test May 31, 2022 23:33 Inactive
@zijchen
Copy link
Contributor Author

zijchen commented Jun 1, 2022

I made 1 more large edit to this PR: SqlConnectionStringBuilder class has been replaced by SqlConnectionStringConfig which is a wrapper on mssql.config. Connection is made directly with the config object which sets us up nicely for AAD auth in the next PR.

@zijchen zijchen changed the title v2 - Use tedious mssql library instead of sqlcmd v2 - Use tedious mssql module instead of sqlcmd Jun 1, 2022
@zijchen zijchen requested review from ssreerama and Benjin June 1, 2022 03:10
@zijchen zijchen temporarily deployed to Automation test June 1, 2022 19:59 Inactive
@zijchen zijchen temporarily deployed to Automation test June 1, 2022 19:59 Inactive
@@ -1,5 +1,7 @@
export default class Constants {
static readonly ipv4MatchPattern = /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/;
static readonly connectionStringTester = /^[;\s]*([\w\s]+=(?:('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*)))(;[;\s]*([\w\s]+=(?:('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*))))*[;\s]*$/;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof, that's a beefy regex. Regex is a powerful tool, but should be wielded carefully because it's difficult to review/debug. Did you get this regex from somewhere official, or write it yourself?

I think I'd rather have a function that manually parses a connection string; probs would be more performant, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's from the file I replaced (SqlConnectionConfig replaced SqlConnectionStringBuilder)

const connectionStringParserRegex = /(?<key>[\w\s]+)=(?<val>('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*))/g
const connectionStringTester = /^[;\s]*([\w\s]+=(?:('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*)))(;[;\s]*([\w\s]+=(?:('[^']*(''[^']*)*')|("[^"]*(""[^"]*)*")|((?!['"])[^;]*))))*[;\s]*$/

src/FirewallManager.ts Outdated Show resolved Hide resolved
@@ -11,7 +11,7 @@ export default class FirewallManager {
core.debug(`Client has access to Sql server. Skip adding firewall exception.`);
return;
}
console.log(`Client does not have access to Sql server. Adding firewall exception for client's IP address.`)
console.log(`Client does not have access to Sql server. Adding firewall exception for client's IP address.`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

core.debug vs. console.log? Dunno whether these should use the same printout method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

core.debug only logs when debug logging is enabled

console.log will display 100% of the time, so I think this makes sense

src/SqlConnectionConfig.ts Outdated Show resolved Hide resolved
@@ -47,20 +43,28 @@ export default async function run() {
}
}

function setUserAgentVariable(): void {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this UA construction defined/specced anywhere that you could add a link to?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, couldn't find any documentation. This logic was already there, I just moved it to its own private function. I'll keep an eye out in the docs if I come across anything like this.

@@ -123,7 +122,7 @@ export default class AzureSqlAction {

switch (inputs.sqlpackageAction) {
case SqlPackageAction.Publish: {
args += `/Action:Publish /TargetConnectionString:"${inputs.connectionString.connectionString}" /SourceFile:"${inputs.dacpacPackage}"`;
args += `/Action:Publish /TargetConnectionString:"${inputs.connectionConfig.ConnectionString}" /SourceFile:"${inputs.dacpacPackage}"`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might you need to escape any doublequotes inside the connection string here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll add a test case for that also

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I don't believe this needs to be escaped. This string is the same as the one user supplied on the command line, so it should be properly escaped already otherwise it will fail validation early on.

@zijchen zijchen temporarily deployed to Automation test June 3, 2022 00:50 Inactive
@zijchen zijchen temporarily deployed to Automation test June 3, 2022 00:50 Inactive
@zijchen zijchen temporarily deployed to Automation test June 4, 2022 03:07 Inactive
@zijchen zijchen temporarily deployed to Automation test June 4, 2022 03:07 Inactive
@zijchen zijchen requested review from Benjin and kisantia June 6, 2022 15:29
src/SqlUtils.ts Outdated
stderr: (data: Buffer) => sqlCmdError += data.toString()
}
});
core.debug(`Validating if client ' has access to SQL Server '${connectionConfig.Config.server}'.`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra ' here: Validating if client ' has access...?

@zijchen zijchen temporarily deployed to Automation test June 6, 2022 21:43 Inactive
@zijchen zijchen temporarily deployed to Automation test June 6, 2022 21:43 Inactive
@zijchen zijchen merged commit eb605f8 into v2 Jun 7, 2022
@zijchen zijchen deleted the zijchen/node-mssql branch June 21, 2022 19:37
zijchen added a commit that referenced this pull request Sep 28, 2022
* v2 - Use tedious mssql module instead of sqlcmd (#96)

* Use tedious mssql library instead of sqlcmd

* Fix mssql connection

* Fix SqlUtils tests

* Use config instead of connection string

* Replace conn string builder with mssql config

* Connect to master db

* Restore connection string validation regex

* PR comments, fix error handling

* Update main.js

* Use try catch for error handling

* Fix typo

* v2 - Change script action from sqlcmd to mssql query (#99)

* Change script action from sqlcmd to mssql query

* Update action.yml

* Fully qualify Table1 in sql script

* Add more debug logging

* Clone config before changing db to master

* Cleanup

* Set TEST_DB name before cleanup

* Use runner.temp

* Always cleanup

* PR comments

* Fix database cleanup step in pr-check (#101)

* Debug script contents

* Fix sed command

* Remove debug

* v2 - Add support for AAD password, AAD default, and AAD service principal auth (#100)

* Use tedious mssql library instead of sqlcmd

* Fix mssql connection

* Fix SqlUtils tests

* Use config instead of connection string

* Replace conn string builder with mssql config

* Connect to master db

* Restore connection string validation regex

* AAD auth

* Add support for client and tenant IDs

* Add more debug messaging

* Fix connection string find array

* Make client-id and tenant-id action inputs

* Fix error handling

* More fixes

* Use try catch instead

* Add tests to pr-check.yml

* Change script action from sqlcmd to mssql query

* Update action.yml

* Fully qualify Table1 in sql script

* Add more debug logging

* Clone config before changing db to master

* Cleanup

* Set TEST_DB name before cleanup

* Use runner.temp

* Always cleanup

* Add tests for different auth types

* Mask tenant and client IDs

* Add AAD password test to pr-check.yml

* Fix yaml

* Limit max-parallel to 2

* Add test for service principal

* PR comments

* Fix typo

* Cleanup sqlcmd references (#102)

* Retry connection with user DB if master connection fails (#104)

* Retry with DB connection if master fails

* Add tests

* Add ConnectionResult interface

* Add missing doc comment

* PR comments

* PR Comments

* Download and extract go-sqlcmd before main action (#108)

* Add setup script to download go-sqlcmd

* Add sqlcmd call to pr-check.yml

* Add bz2 specific extract tar

* Move setup code to main

* Move setup code to main

* Fix casing of Setup.ts

* Use go-sqlcmd for script action (#113)

* call go-sqlcmd for script action

* Fix auth options not flowing through

* Add test cases

* Restore sqlcmd variable in cleanup script

* Fix pr-check cleanup

* Undo changes to pr-check.yml

* Undo pr-check.yml changes

* PR comments

* Change inputs (#105)

* Update SQL API version to 2021-11-01 (#117)

* Add support for Script, DeployReport, and DriftReport (#106)

* Change inputs

* Add other publish like actions

* Add tests

* Fix test

* PR comments

* Add mockReturnValue for auth type test

* Remove MacOS from ci.yml

* links to documentation on each argument type (#123)

* v2 - Remove client-id and tenant-id as inputs (#124)

* Set tenantId and clientId only when passed in

* Default to empty string

* Default to empty string

* Replace mssql call with go-sqlcmd query

* Capture sqlcmd error message

* Add more debug

* Capture stdout too

* Fix config passing

* Completely remove client-id and tenant-id

* cleanup

* Update sqlcmd query

* adding connection string format to docs (#138)

adding connection string format to docs

Co-authored-by: Drew Skwiers-Koballa <dzsquared@users.noreply.github.com>
zijchen added a commit that referenced this pull request Oct 6, 2022
* Use tedious mssql library instead of sqlcmd

* Fix mssql connection

* Fix SqlUtils tests

* Use config instead of connection string

* Replace conn string builder with mssql config

* Connect to master db

* Restore connection string validation regex

* PR comments, fix error handling

* Update main.js

* Use try catch for error handling

* Fix typo
zijchen added a commit that referenced this pull request Oct 11, 2022
* v2 - Use tedious mssql module instead of sqlcmd (#96)

* Use tedious mssql library instead of sqlcmd

* Fix mssql connection

* Fix SqlUtils tests

* Use config instead of connection string

* Replace conn string builder with mssql config

* Connect to master db

* Restore connection string validation regex

* PR comments, fix error handling

* Update main.js

* Use try catch for error handling

* Fix typo

* Fix path to cleanup.sql
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants