Add state.sqlserver conformance test against Azure SQL (#1182)
* Add Azure SQL to setup-azure-conf-test.sh * Add state.sqlserver conformance test on Azure SQL Co-authored-by: Dapr Bot <56698301+dapr-bot@users.noreply.github.com>
This commit is contained in:
parent
e457b307b6
commit
9f77037de2
|
@ -0,0 +1,25 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation and Dapr Contributors.
|
||||
// Licensed under the MIT License.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
param sqlServerName string
|
||||
param rgLocation string = resourceGroup().location
|
||||
param confTestTags object = {}
|
||||
param sqlServerAdminPassword string
|
||||
|
||||
var sqlServerAdminName = '${sqlServerName}-admin'
|
||||
|
||||
resource sqlServer 'Microsoft.Sql/servers@2021-02-01-preview' = {
|
||||
name: sqlServerName
|
||||
location: rgLocation
|
||||
tags: confTestTags
|
||||
properties: {
|
||||
administratorLogin: sqlServerAdminName
|
||||
administratorLoginPassword: sqlServerAdminPassword
|
||||
minimalTlsVersion: '1.2'
|
||||
publicNetworkAccess: 'Enabled'
|
||||
}
|
||||
}
|
||||
|
||||
output sqlServerAdminName string = sqlServer.properties.administratorLogin
|
|
@ -33,6 +33,10 @@ param sdkAuthSpId string
|
|||
@description('Provide the objectId of the Service Principal using cert auth with get and list access to all assets in Azure Key Vault.')
|
||||
param certAuthSpId string
|
||||
|
||||
@minLength(16)
|
||||
@description('Provide the SQL server admin password of at least 16 characters.')
|
||||
param sqlServerAdminPassword string
|
||||
|
||||
var confTestRgName = '${toLower(namePrefix)}-conf-test-rg'
|
||||
var cosmosDbName = '${toLower(namePrefix)}-conf-test-db'
|
||||
var eventGridTopicName = '${toLower(namePrefix)}-conf-test-eventgrid-topic'
|
||||
|
@ -40,6 +44,7 @@ var eventHubsNamespaceName = '${toLower(namePrefix)}-conf-test-eventhubs'
|
|||
var iotHubName = '${toLower(namePrefix)}-conf-test-iothub'
|
||||
var keyVaultName = '${toLower(namePrefix)}-conf-test-kv'
|
||||
var serviceBusName = '${toLower(namePrefix)}-conf-test-servicebus'
|
||||
var sqlServerName = '${toLower(namePrefix)}-conf-test-sql'
|
||||
var storageName = '${toLower(namePrefix)}ctstorage'
|
||||
|
||||
resource confTestRg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
|
||||
|
@ -105,6 +110,16 @@ module serviceBus 'conf-test-azure-servicebus.bicep' = {
|
|||
}
|
||||
}
|
||||
|
||||
module sqlServer 'conf-test-azure-sqlserver.bicep' = {
|
||||
name: sqlServerName
|
||||
scope: resourceGroup(confTestRg.name)
|
||||
params: {
|
||||
confTestTags: confTestTags
|
||||
sqlServerName: sqlServerName
|
||||
sqlServerAdminPassword: sqlServerAdminPassword
|
||||
}
|
||||
}
|
||||
|
||||
module storage 'conf-test-azure-storage.bicep' = {
|
||||
name: storageName
|
||||
scope: resourceGroup(confTestRg.name)
|
||||
|
@ -131,4 +146,6 @@ output iotHubBindingsConsumerGroupName string = iotHub.outputs.iotHubBindingsCon
|
|||
output iotHubPubsubConsumerGroupName string = iotHub.outputs.iotHubPubsubConsumerGroupName
|
||||
output keyVaultName string = keyVault.name
|
||||
output serviceBusName string = serviceBus.name
|
||||
output sqlServerName string = sqlServer.name
|
||||
output sqlServerAdminName string = sqlServer.outputs.sqlServerAdminName
|
||||
output storageName string = storage.name
|
||||
|
|
|
@ -184,8 +184,13 @@ KEYVAULT_CLIENT_ID_VAR_NAME="AzureKeyVaultSecretStoreClientId"
|
|||
KEYVAULT_TENANT_ID_VAR_NAME="AzureKeyVaultSecretStoreTenantId"
|
||||
KEYVAULT_NAME_VAR_NAME="AzureKeyVaultName"
|
||||
|
||||
RESOURCE_GROUP_NAME_VAR_NAME="AzureResourceGroupName"
|
||||
|
||||
SERVICE_BUS_CONNECTION_STRING_VAR_NAME="AzureServiceBusConnectionString"
|
||||
|
||||
SQL_SERVER_NAME_VAR_NAME="AzureSqlServerName"
|
||||
SQL_SERVER_CONNECTION_STRING_VAR_NAME="AzureSqlServerConnectionString"
|
||||
|
||||
STORAGE_ACCESS_KEY_VAR_NAME="AzureBlobStorageAccessKey"
|
||||
STORAGE_ACCOUNT_VAR_NAME="AzureBlobStorageAccount"
|
||||
STORAGE_CONTAINER_VAR_NAME="AzureBlobStorageContainer"
|
||||
|
@ -231,6 +236,9 @@ else
|
|||
echo "${SDK_AUTH_SP_INFO}" > "${AZURE_CREDENTIALS_FILENAME}"
|
||||
fi
|
||||
|
||||
# Generate new password for SQL Server admin
|
||||
SQL_SERVER_ADMIN_PASSWORD=$(openssl rand -base64 32)
|
||||
|
||||
# Build the bicep template and deploy to Azure
|
||||
az bicep install
|
||||
ARM_TEMPLATE_FILE="${OUTPUT_PATH}/${PREFIX}-azure-conf-test.json"
|
||||
|
@ -238,7 +246,7 @@ echo "Building conf-test-azure.bicep to ${ARM_TEMPLATE_FILE} ..."
|
|||
az bicep build --file conf-test-azure.bicep --outfile "${ARM_TEMPLATE_FILE}"
|
||||
|
||||
echo "Creating azure deployment ${DEPLOY_NAME} in ${DEPLOY_LOCATION} and resource prefix ${PREFIX}-* ..."
|
||||
az deployment sub create --name "${DEPLOY_NAME}" --location "${DEPLOY_LOCATION}" --template-file "${ARM_TEMPLATE_FILE}" -p namePrefix="${PREFIX}" -p adminId="${ADMIN_ID}" -p certAuthSpId="${CERT_AUTH_SP_ID}" -p sdkAuthSpId="${SDK_AUTH_SP_ID}" -p rgLocation="${DEPLOY_LOCATION}"
|
||||
az deployment sub create --name "${DEPLOY_NAME}" --location "${DEPLOY_LOCATION}" --template-file "${ARM_TEMPLATE_FILE}" -p namePrefix="${PREFIX}" -p adminId="${ADMIN_ID}" -p certAuthSpId="${CERT_AUTH_SP_ID}" -p sdkAuthSpId="${SDK_AUTH_SP_ID}" -p rgLocation="${DEPLOY_LOCATION}" -p sqlServerAdminPassword="${SQL_SERVER_ADMIN_PASSWORD}"
|
||||
|
||||
echo "Sleeping for 5s to allow created ARM deployment info to propagate to query endpoints ..."
|
||||
sleep 5s
|
||||
|
@ -281,6 +289,10 @@ IOT_HUB_BINDINGS_CONSUMER_GROUP_FULLNAME="$(az deployment sub show --name "${DEP
|
|||
echo "INFO: IOT_HUB_BINDINGS_CONSUMER_GROUP_FULLNAME=${IOT_HUB_BINDINGS_CONSUMER_GROUP_FULLNAME}"
|
||||
IOT_HUB_PUBSUB_CONSUMER_GROUP_FULLNAME="$(az deployment sub show --name "${DEPLOY_NAME}" --query "properties.outputs.iotHubPubsubConsumerGroupName.value" | sed -E 's/[[:space:]]|\"//g')"
|
||||
echo "INFO: IOT_HUB_PUBSUB_CONSUMER_GROUP_FULLNAME=${IOT_HUB_PUBSUB_CONSUMER_GROUP_FULLNAME}"
|
||||
SQL_SERVER_NAME="$(az deployment sub show --name "${DEPLOY_NAME}" --query "properties.outputs.sqlServerName.value" | sed -E 's/[[:space:]]|\"//g')"
|
||||
echo "INFO: SQL_SERVER_NAME=${SQL_SERVER_NAME}"
|
||||
SQL_SERVER_ADMIN_NAME="$(az deployment sub show --name "${DEPLOY_NAME}" --query "properties.outputs.sqlServerAdminName.value" | sed -E 's/[[:space:]]|\"//g')"
|
||||
echo "INFO: SQL_SERVER_ADMIN_NAME=${SQL_SERVER_ADMIN_NAME}"
|
||||
|
||||
# Update service principal credentials and roles for created resources
|
||||
echo "Creating ${CERT_AUTH_SP_NAME} certificate ..."
|
||||
|
@ -297,6 +309,11 @@ IOT_HUB_SCOPE="/subscriptions/${SUB_ID}/resourceGroups/${RESOURCE_GROUP_NAME}/pr
|
|||
echo "Assigning \"Contributor\" role to ${SDK_AUTH_SP_NAME} in scope \"${IOT_HUB_SCOPE}\"..."
|
||||
MSYS_NO_PATHCONV=1 az role assignment create --assignee "${SDK_AUTH_SP_ID}" --role "Contributor" --scope "${IOT_HUB_SCOPE}"
|
||||
|
||||
# Add SQL Server Contributor role to the SDK auth Service Principal so it can update firewall rules to run sqlserver state conformance tests.
|
||||
SQL_SERVER_SCOPE="/subscriptions/${SUB_ID}/resourceGroups/${RESOURCE_GROUP_NAME}/providers/Microsoft.Sql/servers/${SQL_SERVER_NAME}"
|
||||
echo "Assigning \"Contributor\" role to ${SDK_AUTH_SP_NAME} in scope \"${SQL_SERVER_SCOPE}\"..."
|
||||
MSYS_NO_PATHCONV=1 az role assignment create --assignee "${SDK_AUTH_SP_ID}" --role "Contributor" --scope "${SQL_SERVER_SCOPE}"
|
||||
|
||||
##==============================================================================
|
||||
##
|
||||
## Create output files for environment config and teardown of conformance tests
|
||||
|
@ -466,6 +483,23 @@ SERVICE_BUS_CONNECTION_STRING="$(az servicebus namespace authorization-rule keys
|
|||
echo export ${SERVICE_BUS_CONNECTION_STRING_VAR_NAME}=\"${SERVICE_BUS_CONNECTION_STRING}\" >> "${ENV_CONFIG_FILENAME}"
|
||||
az keyvault secret set --name "${SERVICE_BUS_CONNECTION_STRING_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${SERVICE_BUS_CONNECTION_STRING}"
|
||||
|
||||
# ----------------------------------
|
||||
# Populate SQL Server test settings
|
||||
# ----------------------------------
|
||||
echo "Configuring SQL Server test settings ..."
|
||||
|
||||
# Not specific to SQL server, but this is currently only consumed by setting SQL server firewall rules
|
||||
echo export ${RESOURCE_GROUP_NAME_VAR_NAME}=\"${RESOURCE_GROUP_NAME}\" >> "${ENV_CONFIG_FILENAME}"
|
||||
az keyvault secret set --name "${RESOURCE_GROUP_NAME_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${RESOURCE_GROUP_NAME}"
|
||||
|
||||
echo export ${SQL_SERVER_NAME_VAR_NAME}=\"${SQL_SERVER_NAME}\" >> "${ENV_CONFIG_FILENAME}"
|
||||
az keyvault secret set --name "${SQL_SERVER_NAME_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${SQL_SERVER_NAME}"
|
||||
|
||||
# Note that `az sql db show-connection-string` does not currently support a `go` --client type, so we construct our own here.
|
||||
SQL_SERVER_CONNECTION_STRING="Server=${SQL_SERVER_NAME}.database.windows.net;port=1433;User ID=${SQL_SERVER_ADMIN_NAME};Password=${SQL_SERVER_ADMIN_PASSWORD};Encrypt=true;"
|
||||
echo export ${SQL_SERVER_CONNECTION_STRING_VAR_NAME}=\"${SQL_SERVER_CONNECTION_STRING}\" >> "${ENV_CONFIG_FILENAME}"
|
||||
az keyvault secret set --name "${SQL_SERVER_CONNECTION_STRING_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${SQL_SERVER_CONNECTION_STRING}"
|
||||
|
||||
# ----------------------------------
|
||||
# Populate Event Hubs test settings
|
||||
# ----------------------------------
|
||||
|
|
|
@ -93,6 +93,8 @@ jobs:
|
|||
CRON_COMPONENTS=$(yq -I0 --tojson eval - << EOF
|
||||
- component: state.azure.cosmosdb
|
||||
required-secrets: AzureCosmosDBMasterKey,AzureCosmosDBUrl,AzureCosmosDB,AzureCosmosDBCollection
|
||||
- component: state.azure.sql
|
||||
required-secrets: AzureResourceGroupName, AzureSqlServerName, AzureSqlServerConnectionString
|
||||
- component: state.azure.tablestorage
|
||||
required-secrets: AzureBlobStorageAccessKey,AzureBlobStorageAccount
|
||||
- component: pubsub.azure.eventhubs
|
||||
|
@ -269,6 +271,18 @@ jobs:
|
|||
go mod download
|
||||
go install gotest.tools/gotestsum@latest
|
||||
|
||||
- name: Configure Azure SQL Firewall
|
||||
run: |
|
||||
set +e
|
||||
TEST_OUTPUT="$(go test -v -tags=conftests -count=1 -timeout=1m ./tests/conformance -run=TestStateConformance/azure.sql)"
|
||||
echo "Trial run result:\n\"$TEST_OUTPUT\""
|
||||
PUBLIC_IP=$(echo "$TEST_OUTPUT" | grep -Po "Client with IP address '\K[^']*")
|
||||
if [[ -n ${PUBLIC_IP} ]]; then
|
||||
echo "Setting Azure SQL firewall-rule AllowTestRunnerIP to allow $PUBLIC_IP..."
|
||||
az sql server firewall-rule create --resource-group ${{ env.AzureResourceGroupName }} --server ${{ env.AzureSqlServerName }} -n "AllowTestRunnerIP" --start-ip-address "$PUBLIC_IP" --end-ip-address "$PUBLIC_IP"
|
||||
fi
|
||||
if: contains(matrix.component, 'azure.sql')
|
||||
|
||||
- name: Run tests
|
||||
continue-on-error: true
|
||||
run: |
|
||||
|
@ -307,6 +321,13 @@ jobs:
|
|||
continue-on-error: true
|
||||
run: pkill ngrok; cat /tmp/ngrok.log
|
||||
|
||||
- name: Cleanup Azure SQL Firewall and test DB instance
|
||||
if: contains(matrix.component, 'azure.sql')
|
||||
continue-on-error: true
|
||||
run: |
|
||||
az sql server firewall-rule delete --resource-group ${{ env.AzureResourceGroupName }} --server ${{ env.AzureSqlServerName }} -n "AllowTestRunnerIP"
|
||||
az sql db delete --resource-group ${{ env.AzureResourceGroupName }} --server ${{ env.AzureSqlServerName }} -n dapr --yes
|
||||
|
||||
# Download the required certificates into files, and set env var pointing to their names
|
||||
- name: Clean up certs
|
||||
if: matrix.required-certs != ''
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: statestore
|
||||
spec:
|
||||
type: state.sqlserver
|
||||
metadata:
|
||||
- name: connectionString
|
||||
value: ${{AzureSqlServerConnectionString}}
|
||||
- name: tableName
|
||||
value: dapr_conf_test
|
||||
- name: keyType
|
||||
value: string
|
||||
- name: keyLength
|
||||
value: 120
|
||||
- name: schema
|
||||
value: proto
|
|
@ -7,6 +7,8 @@ components:
|
|||
allOperations: true
|
||||
- component: azure.cosmosdb
|
||||
allOperations: true
|
||||
- component: azure.sql
|
||||
allOperations: true
|
||||
- component: sqlserver
|
||||
allOperations: true
|
||||
- component: mysql
|
||||
|
|
|
@ -374,6 +374,8 @@ func loadStateStore(tc TestComponent) state.Store {
|
|||
store = s_cosmosdb.NewCosmosDBStateStore(testLogger)
|
||||
case "mongodb":
|
||||
store = s_mongodb.NewMongoDB(testLogger)
|
||||
case "azure.sql":
|
||||
fallthrough
|
||||
case "sqlserver":
|
||||
store = s_sqlserver.NewSQLServerStateStore(testLogger)
|
||||
case "mysql":
|
||||
|
|
Loading…
Reference in New Issue