diff --git a/step-templates/mysql-execute-command.json b/step-templates/mysql-execute-command.json index 06f9247ac..8232d3bca 100644 --- a/step-templates/mysql-execute-command.json +++ b/step-templates/mysql-execute-command.json @@ -3,14 +3,14 @@ "Name": "MySQL - Execute Command", "Description": "Enables ad-hoc command execution on a MySQL server", "ActionType": "Octopus.Script", - "Version": 3, + "Version": 4, "Author": "coryreid", "CommunityActionTemplateId": null, "Packages": [], "Properties": { "Octopus.Action.Script.ScriptSource": "Inline", "Octopus.Action.Script.Syntax": "PowerShell", - "Octopus.Action.Script.ScriptBody": "# Define functions\nfunction Get-ModuleInstalled {\n # Define parameters\n param(\n $PowerShellModuleName\n )\n\n # Check to see if the module is installed\n if ($null -ne (Get-Module -ListAvailable -Name $PowerShellModuleName)) {\n # It is installed\n return $true\n }\n else {\n # Module not installed\n return $false\n }\n}\n\nfunction Install-PowerShellModule {\n # Define parameters\n param(\n $PowerShellModuleName,\n $LocalModulesPath\n )\n\n # Check to see if the package provider has been installed\n if ((Get-NugetPackageProviderNotInstalled) -ne $false) {\n # Display that we need the nuget package provider\n Write-Host \"Nuget package provider not found, installing ...\"\n \n # Install Nuget package provider\n Install-PackageProvider -Name Nuget -Force\n }\n\n # Save the module in the temporary location\n Save-Module -Name $PowerShellModuleName -Path $LocalModulesPath -Force\n}\n\nfunction Get-NugetPackageProviderNotInstalled {\n # See if the nuget package provider has been installed\n return ($null -eq (Get-PackageProvider -ListAvailable -Name Nuget -ErrorAction SilentlyContinue))\n}\n\n# Define PowerShell Modules path\n$LocalModules = (New-Item \"$PSScriptRoot\\Modules\" -ItemType Directory -Force).FullName\n$env:PSModulePath = \"$LocalModules$([System.IO.Path]::PathSeparator)$env:PSModulePath\"\n$PowerShellModuleName = \"SimplySql\"\n\n# Set secure protocols\n[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [System.Net.SecurityProtocolType]::Tls12\n\n# Check to see if SimplySql module is installed\nif ((Get-ModuleInstalled -PowerShellModuleName $PowerShellModuleName) -ne $true) {\n # Tell user what we're doing\n Write-Output \"PowerShell module $PowerShellModuleName is not installed, downloading temporary copy ...\"\n\n # Install temporary copy\n Install-PowerShellModule -PowerShellModuleName $PowerShellModuleName -LocalModulesPath $LocalModules\n}\n\n# Display\nWrite-Output \"Importing module $PowerShellModuleName ...\"\n\n# Check to see if it was downloaded\nif ((Test-Path -Path \"$LocalModules\\$PowerShellModuleName\") -eq $true) {\n # Use specific version\n $PowerShellModuleName = \"$LocalModules\\$PowerShellModuleName\"\n}\n\n# Import the module\nImport-Module -Name $PowerShellModuleName\n\n# Get whether trust certificate is necessary\n$mySqlTrustSSL = [System.Convert]::ToBoolean(\"$mySqlTrustSSL\")\n\ntry {\n # Declare initial connection string\n $connectionString = \"Server=$mySqlServerName;Port=$mySqlServerPort;Database=$mySqlDatabaseName;\"\n \n # Check to see if we need to trust the ssl cert\n if ($mySqlTrustSSL -eq $true) {\n # Append SSL connection string components\n $connectionString += \"SslMode=Required;\"\n }\n\n # Update the connection string based on authentication method\n switch ($mySqlAuthenticationMethod) {\n \"azuremanagedidentity\" {\n # Get login token\n Write-Host \"Generating Azure Managed Identity token ...\"\n $token = Invoke-RestMethod -Method GET -Uri \"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://ossrdbms-aad.database.windows.net\" -Headers @{\"MetaData\" = \"true\" }\n \n # Append remaining portion of connection string\n $connectionString += \";Uid=$mySqlUsername;Pwd=`\"$($token.access_token)`\";\"\n \n break\n }\n \"awsiam\" {\n # Region is part of the RDS endpoint, extract\n $region = ($mySqlServerName.Split(\".\"))[2]\n\n Write-Host \"Generating AWS IAM token ...\"\n $mySqlPassword = (aws rds generate-db-auth-token --hostname $mySqlServerName --region $region --port $mySqlServerPort --username $mySqlUsername)\n\n # Append remaining portion of connection string\n $connectionString += \";Uid=$mySqlUsername;Pwd=`\"$mySqlPassword`\";\"\n\n break\n }\n \"gcpserviceaccount\" {\n # Define header\n $header = @{ \"Metadata-Flavor\" = \"Google\" }\n\n # Retrieve service accounts\n $serviceAccounts = Invoke-RestMethod -Method Get -Uri \"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/\" -Headers $header\n\n # Results returned in plain text format, get into array and remove empty entries\n $serviceAccounts = $serviceAccounts.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries)\n\n # Retreive the specific service account assigned to the VM\n $serviceAccount = $serviceAccounts | Where-Object { $_.Contains(\"iam.gserviceaccount.com\") }\n\n Write-Host \"Generating GCP IAM token ...\"\n # Retrieve token for account\n $token = Invoke-RestMethod -Method Get -Uri \"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$serviceAccount/token\" -Headers $header\n \n # Check to see if there was a username provided\n if ([string]::IsNullOrWhitespace($mySqlUsername)) {\n # Use the service account name, but strip off the .gserviceaccount.com part\n $mySqlUsername = $serviceAccount.SubString(0, $serviceAccount.IndexOf(\".gserviceaccount.com\"))\n }\n\n # Append remaining portion of connection string\n $connectionString += \";Uid=$mySqlUsername;Pwd=`\"$($token.access_token)`\";\"\n\n break\n }\n \"usernamepassword\" {\n # Append remaining portion of connection string\n $connectionString += \";Uid=$mySqlUsername;Pwd=`\"$mySqlPassword`\";\"\n\n break \n }\n\n \"windowsauthentication\" {\n # Append remaining portion of connection string\n $connectionString += \";Integrated Security=True;\"\n }\n }\n\n # Open connection\n Open-MySqlConnection -ConnectionString $connectionString\n\n # Execute the statement\n $executionResult = Invoke-SqlUpdate -Query \"$mySqlCommand\" -CommandTimeout $mySqlCommandTimeout\n \n # Display the result\n Get-SqlMessage\n}\nfinally {\n Close-SqlConnection\n}\n\n\n" + "Octopus.Action.Script.ScriptBody": "# Define global variables\n$connectionName = \"OctopusDeploy\"\n\n# Define functions\nfunction Get-ModuleInstalled {\n # Define parameters\n param(\n $PowerShellModuleName\n )\n\n # Check to see if the module is installed\n if ($null -ne (Get-Module -ListAvailable -Name $PowerShellModuleName)) {\n # It is installed\n return $true\n }\n else {\n # Module not installed\n return $false\n }\n}\n\nfunction Install-PowerShellModule {\n # Define parameters\n param(\n $PowerShellModuleName,\n $LocalModulesPath\n )\n\n # Check to see if the package provider has been installed\n if ((Get-NugetPackageProviderNotInstalled) -ne $false) {\n # Display that we need the nuget package provider\n Write-Host \"Nuget package provider not found, installing ...\"\n \n # Install Nuget package provider\n Install-PackageProvider -Name Nuget -Force\n }\n\n # Save the module in the temporary location\n Save-Module -Name $PowerShellModuleName -Path $LocalModulesPath -Force\n}\n\nfunction Get-NugetPackageProviderNotInstalled {\n # See if the nuget package provider has been installed\n return ($null -eq (Get-PackageProvider -ListAvailable -Name Nuget -ErrorAction SilentlyContinue))\n}\n\n# Define PowerShell Modules path\n$LocalModules = (New-Item \"$PSScriptRoot\\Modules\" -ItemType Directory -Force).FullName\n$env:PSModulePath = \"$LocalModules$([System.IO.Path]::PathSeparator)$env:PSModulePath\"\n$PowerShellModuleName = \"SimplySql\"\n\n# Set secure protocols\n[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [System.Net.SecurityProtocolType]::Tls12\n\n# Check to see if SimplySql module is installed\nif ((Get-ModuleInstalled -PowerShellModuleName $PowerShellModuleName) -ne $true) {\n # Tell user what we're doing\n Write-Output \"PowerShell module $PowerShellModuleName is not installed, downloading temporary copy ...\"\n\n # Install temporary copy\n Install-PowerShellModule -PowerShellModuleName $PowerShellModuleName -LocalModulesPath $LocalModules\n}\n\n# Display\nWrite-Output \"Importing module $PowerShellModuleName ...\"\n\n# Check to see if it was downloaded\nif ((Test-Path -Path \"$LocalModules\\$PowerShellModuleName\") -eq $true) {\n # Use specific version\n $PowerShellModuleName = \"$LocalModules\\$PowerShellModuleName\"\n}\n\n# Import the module\nImport-Module -Name $PowerShellModuleName\n\n# Get whether trust certificate is necessary\n$mySqlTrustSSL = [System.Convert]::ToBoolean(\"$mySqlTrustSSL\")\n\nif (![string]::IsNullOrWhitespace($mysqlAdditionalParameters))\n{\n foreach ($parameter in $mysqlAdditionalParameters.Split(\",\"))\n {\n # Check for delimiter\n if (!$connectionString.EndsWith(\";\") -and !$parameter.StartsWith(\";\"))\n {\n # Append delimeter\n $connectionString +=\";\"\n }\n $connectionString += $parameter.Trim()\n }\n}\n\ntry {\n # Declare initial connection string\n $connectionString = \"Server=$mySqlServerName;Port=$mySqlServerPort;Database=$mySqlDatabaseName;\"\n \n # Check to see if we need to trust the ssl cert\n if ($mySqlTrustSSL -eq $true) {\n # Append SSL connection string components\n $connectionString += \"SslMode=Required;\"\n }\n\n # Update the connection string based on authentication method\n switch ($mySqlAuthenticationMethod) {\n \"azuremanagedidentity\" {\n # Get login token\n Write-Host \"Generating Azure Managed Identity token ...\"\n $token = Invoke-RestMethod -Method GET -Uri \"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://ossrdbms-aad.database.windows.net\" -Headers @{\"MetaData\" = \"true\" }\n \n # Append remaining portion of connection string\n $connectionString += \";Uid=$mySqlUsername;Pwd=`\"$($token.access_token)`\";\"\n \n break\n }\n \"awsiam\" {\n # Region is part of the RDS endpoint, extract\n $region = ($mySqlServerName.Split(\".\"))[2]\n\n Write-Host \"Generating AWS IAM token ...\"\n $mySqlPassword = (aws rds generate-db-auth-token --hostname $mySqlServerName --region $region --port $mySqlServerPort --username $mySqlUsername)\n\n # Append remaining portion of connection string\n $connectionString += \";Uid=$mySqlUsername;Pwd=`\"$mySqlPassword`\";\"\n\n break\n }\n \"gcpserviceaccount\" {\n # Define header\n $header = @{ \"Metadata-Flavor\" = \"Google\" }\n\n # Retrieve service accounts\n $serviceAccounts = Invoke-RestMethod -Method Get -Uri \"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/\" -Headers $header\n\n # Results returned in plain text format, get into array and remove empty entries\n $serviceAccounts = $serviceAccounts.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries)\n\n # Retreive the specific service account assigned to the VM\n $serviceAccount = $serviceAccounts | Where-Object { $_.Contains(\"iam.gserviceaccount.com\") }\n\n Write-Host \"Generating GCP IAM token ...\"\n # Retrieve token for account\n $token = Invoke-RestMethod -Method Get -Uri \"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$serviceAccount/token\" -Headers $header\n \n # Check to see if there was a username provided\n if ([string]::IsNullOrWhitespace($mySqlUsername)) {\n # Use the service account name, but strip off the .gserviceaccount.com part\n $mySqlUsername = $serviceAccount.SubString(0, $serviceAccount.IndexOf(\".gserviceaccount.com\"))\n }\n\n # Append remaining portion of connection string\n $connectionString += \";Uid=$mySqlUsername;Pwd=`\"$($token.access_token)`\";\"\n\n break\n }\n \"usernamepassword\" {\n # Append remaining portion of connection string\n $connectionString += \";Uid=$mySqlUsername;Pwd=`\"$mySqlPassword`\";\"\n\n break \n }\n\n \"windowsauthentication\" {\n # Append remaining portion of connection string\n $connectionString += \";Integrated Security=True;\"\n }\n }\n\n # Open connection\n Open-MySqlConnection -ConnectionString $connectionString -ConnectionName $connectionName\n\n # Execute the statement\n $executionResult = Invoke-SqlUpdate -Query \"$mySqlCommand\" -CommandTimeout $mySqlCommandTimeout -ConnectionName $connectionName\n \n # Display the result\n Get-SqlMessage -ConnectionName $connectionName\n}\nfinally\n{\n\t# Close connection if open\n if ((Test-SqlConnection -ConnectionName $connectionName) -eq $true)\n {\n \tClose-SqlConnection -ConnectionName $connectionName\n }\n}\n\n\n" }, "Parameters": [ { @@ -84,12 +84,22 @@ "Octopus.ControlType": "Checkbox" } }, + { + "Id": "baefc692-47c2-4387-8498-ace7cd4c8ea6", + "Name": "mysqlAdditionalParameters", + "Label": "Additional connection string parameters", + "HelpText": "A comma-delimited list of additional parameters to add to the connection string. ex `AllowPublicKeyRetrieval=True`", + "DefaultValue": "", + "DisplaySettings": { + "Octopus.ControlType": "SingleLineText" + } + }, { "Id": "786d615c-e7cd-4f1d-adb0-7787bd26c476", "Name": "mySqlCommandTimeout", "Label": "Command Timeout", "HelpText": "Timeout value (in seconds) for SQL commands.", - "DefaultValue": "", + "DefaultValue": "30", "DisplaySettings": { "Octopus.ControlType": "SingleLineText" } @@ -107,10 +117,10 @@ ], "StepPackageId": "Octopus.Script", "$Meta": { - "ExportedAt": "2022-06-22T18:37:20.847Z", - "OctopusVersion": "2022.3.1455", + "ExportedAt": "2026-08-13T17:32:44.114Z", + "OctopusVersion": "2026.2.13319", "Type": "ActionTemplate" }, - "LastModifiedBy": "coryreid", + "LastModifiedBy": "twerthi", "Category": "mysql" }