Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
"features": {
"ghcr.io/devcontainers/features/azure-cli:1": {
"installBicep": true,
"version": "latest",
"bicepVersion": "latest"
},
"ghcr.io/jlaundry/devcontainer-features/mssql-odbc-driver:1": {
"version": "18"
},
"ghcr.io/azure/azure-dev/azd:0": {
"version": "stable"
}
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-azuretools.vscode-azcli",
"ms-azuretools.vscode-bicep",
"ms-azuretools.azure-dev"
]
}
},
"postCreateCommand": "chmod +x ./.devcontainer/setup_env.sh && bash ./.devcontainer/setup_env.sh",
"remoteUser": "vscode",
"hostRequirements": {
"memory": "4gb"
}
}
21 changes: 21 additions & 0 deletions .devcontainer/setup_env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

git fetch
git pull

# provide execute permission to quotacheck script
chmod +x ./infra/scripts/checkquota.sh

# Add the path to ~/.bashrc for persistence
if ! grep -q '/opt/mssql-tools18/bin' ~/.bashrc; then
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
fi

# Export the path for the current session
export PATH="$PATH:/opt/mssql-tools18/bin"

# Verify sqlcmd is available
if ! command -v sqlcmd &> /dev/null; then
echo "sqlcmd is not available in the PATH. Please check the installation."
exit 1
fi
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,8 @@ FodyWeavers.xsd

# JetBrains Rider
*.sln.iml

.venv

scriptenv
.azure
45 changes: 45 additions & 0 deletions app-azure.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json

name: sample-app-aoai-chatgpt
metadata:
template: sample-app-aoai-chatgpt@0.0.1-beta
services:
backend:
project: .
language: py
host: appservice
hooks:
prepackage:
windows:
shell: pwsh
run: cd ./frontend;npm install;npm run build
interactive: true
continueOnError: false
posix:
shell: sh
run: cd ./frontend;npm install;npm run build
interactive: true
continueOnError: false
hooks:
preprovision:
windows:
shell: pwsh
run: ./scripts/auth_init.ps1
interactive: true
continueOnError: false
posix:
shell: sh
run: ./scripts/auth_init.sh
interactive: true
continueOnError: false
postprovision:
windows:
shell: pwsh
run: ./scripts/auth_update.ps1;./scripts/prepdocs.ps1;
interactive: true
continueOnError: false
posix:
shell: sh
run: ./scripts/auth_update.sh;./scripts/prepdocs.sh;
interactive: true
continueOnError: false
71 changes: 30 additions & 41 deletions azure.yaml
Original file line number Diff line number Diff line change
@@ -1,45 +1,34 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json

name: sample-app-aoai-chatgpt
name: build-your-own-copilot-solution-accelerator

metadata:
template: sample-app-aoai-chatgpt@0.0.1-beta
services:
backend:
project: .
language: py
host: appservice
hooks:
prepackage:
windows:
shell: pwsh
run: cd ./frontend;npm install;npm run build
interactive: true
continueOnError: false
posix:
shell: sh
run: cd ./frontend;npm install;npm run build
interactive: true
continueOnError: false
template: build-your-own-copilot-solution-accelerator@1.0
name: build-your-own-copilot-solution-accelerator@1.0

infra:
provider: bicep
path: infra/bicep
module: main

hooks:
preprovision:
windows:
shell: pwsh
run: ./scripts/auth_init.ps1
interactive: true
continueOnError: false
posix:
shell: sh
run: ./scripts/auth_init.sh
interactive: true
continueOnError: false
postprovision:
windows:
shell: pwsh
run: ./scripts/auth_update.ps1;./scripts/prepdocs.ps1;
interactive: true
continueOnError: false
posix:
shell: sh
run: ./scripts/auth_update.sh;./scripts/prepdocs.sh;
interactive: true
continueOnError: false
postprovision:
windows:
run: |
Write-Host "Web app URL: "
Write-Host "$env:WEB_APP_URL" -ForegroundColor Cyan
Write-Host "`nRun the following command in your Bash terminal. It will grant the necessary permissions between resources and your user account, and also process and load the sample data into the application."
Write-Host "bash ./infra/scripts/process_sample_data.sh" -ForegroundColor Cyan
shell: pwsh
continueOnError: false
interactive: true
posix:
run: |
echo "Web app URL: "
echo $WEB_APP_URL
echo ""
echo "Run the following command in your Bash terminal. It will grant the necessary permissions between resources and your user account, and also process and load the sample data into the application."
echo "bash ./infra/scripts/process_sample_data.sh"
shell: sh
continueOnError: false
interactive: true
2 changes: 1 addition & 1 deletion infra/bicep/deploy_post_deployment_scripts.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ resource containerApp 'Microsoft.App/containerApps@2022-03-01' = {
memory: '4.0Gi'
}
command: [
'/bin/sh', '-c', 'mkdir -p /scripts && apk add --no-cache curl bash jq py3-pip gcc musl-dev libffi-dev openssl-dev python3-dev && pip install --upgrade azure-cli && apk add --no-cache --virtual .build-deps build-base unixodbc-dev && curl -s -o msodbcsql18_18.4.1.1-1_amd64.apk https://download.microsoft.com/download/7/6/d/76de322a-d860-4894-9945-f0cc5d6a45f8/msodbcsql18_18.4.1.1-1_amd64.apk && curl -s -o mssql-tools18_18.4.1.1-1_amd64.apk https://download.microsoft.com/download/7/6/d/76de322a-d860-4894-9945-f0cc5d6a45f8/mssql-tools18_18.4.1.1-1_amd64.apk && apk add --allow-untrusted msodbcsql18_18.4.1.1-1_amd64.apk && apk add --allow-untrusted mssql-tools18_18.4.1.1-1_amd64.apk && curl -s -o /scripts/copy_kb_files.sh ${setupCopyKbFiles} && chmod +x /scripts/copy_kb_files.sh && sh -x /scripts/copy_kb_files.sh ${storageAccountName} ${containerName} ${baseUrl} ${managedIdentityClientId} && curl -s -o /scripts/run_create_index_scripts.sh ${setupCreateIndexScriptsUrl} && chmod +x /scripts/run_create_index_scripts.sh && sh -x /scripts/run_create_index_scripts.sh ${baseUrl} ${keyVaultName} ${managedIdentityClientId} && apk add --no-cache ca-certificates less ncurses-terminfo-base krb5-libs libgcc libintl libssl3 libstdc++ tzdata userspace-rcu zlib icu-libs curl && apk -X https://dl-cdn.alpinelinux.org/alpine/edge/main add --no-cache lttng-ust openssh-client && curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell-7.5.0-linux-musl-x64.tar.gz -o /tmp/powershell.tar.gz && mkdir -p /opt/microsoft/powershell/7 && tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && chmod +x /opt/microsoft/powershell/7/pwsh && ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && curl -s -o /scripts/create-sql-user-and-role.ps1 ${createSqlUserAndRoleScriptsUrl} && chmod +x /scripts/create-sql-user-and-role.ps1 && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[0].principalId} -DisplayName ${sqlUsers[0].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[0].databaseRoles[0]} && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[1].principalId} -DisplayName ${sqlUsers[1].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[1].databaseRoles[0]} && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[1].principalId} -DisplayName ${sqlUsers[1].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[1].databaseRoles[1]} && az login --identity --client-id ${managedIdentityClientId} && az containerapp update --name ${containerAppName} --resource-group ${resourceGroupName} --min-replicas 0 --cpu 0.25 --memory 0.5Gi && az containerapp revision deactivate -g ${resourceGroupName} --revision $(az containerapp revision list -n ${containerAppName} -g ${resourceGroupName} --query "[0].name" -o tsv) && echo "Container app setup completed successfully."'
'/bin/sh', '-c', 'mkdir -p /scripts && apk add --no-cache curl bash jq py3-pip gcc musl-dev libffi-dev openssl-dev python3-dev && pip install --upgrade azure-cli && apk add --no-cache --virtual .build-deps build-base unixodbc-dev && curl -s -o msodbcsql18_18.4.1.1-1_amd64.apk https://download.microsoft.com/download/7/6/d/76de322a-d860-4894-9945-f0cc5d6a45f8/msodbcsql18_18.4.1.1-1_amd64.apk && curl -s -o mssql-tools18_18.4.1.1-1_amd64.apk https://download.microsoft.com/download/7/6/d/76de322a-d860-4894-9945-f0cc5d6a45f8/mssql-tools18_18.4.1.1-1_amd64.apk && apk add --allow-untrusted msodbcsql18_18.4.1.1-1_amd64.apk && apk add --allow-untrusted mssql-tools18_18.4.1.1-1_amd64.apk && curl -s -o /scripts/copy_kb_files.sh ${setupCopyKbFiles} && chmod +x /scripts/copy_kb_files.sh && sh -x /scripts/copy_kb_files.sh ${storageAccountName} ${containerName} ${baseUrl} ${managedIdentityClientId} && curl -s -o /scripts/run_create_index_scripts.sh ${setupCreateIndexScriptsUrl} && chmod +x /scripts/run_create_index_scripts.sh && sh -x /scripts/run_create_index_scripts.sh ${keyVaultName} ${baseUrl} ${managedIdentityClientId} && apk add --no-cache ca-certificates less ncurses-terminfo-base krb5-libs libgcc libintl libssl3 libstdc++ tzdata userspace-rcu zlib icu-libs curl && apk -X https://dl-cdn.alpinelinux.org/alpine/edge/main add --no-cache lttng-ust openssh-client && curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell-7.5.0-linux-musl-x64.tar.gz -o /tmp/powershell.tar.gz && mkdir -p /opt/microsoft/powershell/7 && tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && chmod +x /opt/microsoft/powershell/7/pwsh && ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && curl -s -o /scripts/create-sql-user-and-role.ps1 ${createSqlUserAndRoleScriptsUrl} && chmod +x /scripts/create-sql-user-and-role.ps1 && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[0].principalId} -DisplayName ${sqlUsers[0].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[0].databaseRoles[0]} && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[1].principalId} -DisplayName ${sqlUsers[1].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[1].databaseRoles[0]} && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[1].principalId} -DisplayName ${sqlUsers[1].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[1].databaseRoles[1]} && az login --identity --client-id ${managedIdentityClientId} && az containerapp update --name ${containerAppName} --resource-group ${resourceGroupName} --min-replicas 0 --cpu 0.25 --memory 0.5Gi && az containerapp revision deactivate -g ${resourceGroupName} --revision $(az containerapp revision list -n ${containerAppName} -g ${resourceGroupName} --query "[0].name" -o tsv) && echo "Container app setup completed successfully."'
]
env: [
{
Expand Down
2 changes: 1 addition & 1 deletion infra/bicep/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"_generator": {
"name": "bicep",
"version": "0.34.44.8038",
"templateHash": "7940000667981168161"
"templateHash": "13074623986840466778"
}
},
"parameters": {
Expand Down
51 changes: 51 additions & 0 deletions infra/scripts/add_cosmosdb_access.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash

# Variables
resource_group="$1"
account_name="$2"
managedIdentityClientId="$3"

# Authenticate with Azure
if az account show &> /dev/null; then
echo "Already authenticated with Azure."
else
if [ -n "$managedIdentityClientId" ]; then
# Use managed identity if running in Azure
echo "Authenticating with Managed Identity..."
az login --identity --client-id ${managedIdentityClientId}
else
# Use Azure CLI login if running locally
echo "Authenticating with Azure CLI..."
az login
fi
echo "Not authenticated with Azure. Attempting to authenticate..."
fi

echo "Getting signed in user id"
signed_user_id=$(az ad signed-in-user show --query id -o tsv)

# Check if the user has the Cosmos DB Built-in Data Contributor role
echo "Checking if user has the Cosmos DB Built-in Data Contributor role"
roleExists=$(az cosmosdb sql role assignment list \
--resource-group $resource_group \
--account-name $account_name \
--query "[?roleDefinitionId.ends_with(@, '00000000-0000-0000-0000-000000000002') && principalId == '$signed_user_id']" -o tsv)

# Check if the role exists
if [ -n "$roleExists" ]; then
echo "User already has the Cosmos DB Built-in Data Contributer role."
else
echo "User does not have the Cosmos DB Built-in Data Contributer role. Assigning the role."
MSYS_NO_PATHCONV=1 az cosmosdb sql role assignment create \
--resource-group $resource_group \
--account-name $account_name \
--role-definition-id 00000000-0000-0000-0000-000000000002 \
--principal-id $signed_user_id \
--scope "/" \
--output none
if [ $? -eq 0 ]; then
echo "Cosmos DB Built-in Data Contributer role assigned successfully."
else
echo "Failed to assign Cosmos DB Built-in Data Contributer role."
fi
fi
127 changes: 127 additions & 0 deletions infra/scripts/add_user_scripts/create_sql_user_and_role.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/bin/bash

# Parameters
SqlServerName="$1"
SqlDatabaseName="$2"
UserRoleJSONArray="$3"
ManagedIdentityClientId="$6"

# Function to check if a command exists or runs successfully
function check_command() {
if ! eval "$1" &> /dev/null; then
echo "Error: Command '$1' failed or is not installed."
exit 1
fi
}

# Ensure required commands are available
check_command "az --version"
check_command "sqlcmd '-?'"

# Authenticate with Azure
if az account show &> /dev/null; then
echo "Already authenticated with Azure."
else
if [ -n "$ManagedIdentityClientId" ]; then
# Use managed identity if running in Azure
echo "Authenticating with Managed Identity..."
az login --identity --client-id ${ManagedIdentityClientId}
else
# Use Azure CLI login if running locally
echo "Authenticating with Azure CLI..."
az login
fi
echo "Not authenticated with Azure. Attempting to authenticate..."
fi

SQL_QUERY=""
#loop through the JSON array and create users and assign roles using grep and sed
count=1
while read -r json_object; do
# Extract fields from the JSON object using grep and sed
clientId=$(echo "$json_object" | grep -o '"clientId": *"[^"]*"' | sed 's/"clientId": *"\([^"]*\)"/\1/')
displayName=$(echo "$json_object" | grep -o '"displayName": *"[^"]*"' | sed 's/"displayName": *"\([^"]*\)"/\1/')
role=$(echo "$json_object" | grep -o '"role": *"[^"]*"' | sed 's/"role": *"\([^"]*\)"/\1/')

# Append to SQL_QUERY with dynamic variable names
SQL_QUERY+="
DECLARE @username$count nvarchar(max) = N'$displayName';
DECLARE @clientId$count uniqueidentifier = '$clientId';
DECLARE @sid$count NVARCHAR(max) = CONVERT(VARCHAR(max), CONVERT(VARBINARY(16), @clientId$count), 1);
DECLARE @cmd$count NVARCHAR(max) = N'CREATE USER [' + @username$count + '] WITH SID = ' + @sid$count + ', TYPE = E;';
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = @username$count)
BEGIN
EXEC(@cmd$count)
END
EXEC sp_addrolemember '$role', @username$count;
"

# Increment the count
count=$((count + 1))
done < <(echo "$UserRoleJSONArray" | grep -o '{[^}]*}')

#create heredoc for the SQL query
SQL_QUERY_FINAL=$(cat <<EOF
$SQL_QUERY
EOF
)



# SQL query to create the user and assign the role
# SQL_QUERY=$(cat <<EOF
# DECLARE @username nvarchar(max) = N'$DisplayName';
# DECLARE @clientId uniqueidentifier = '$ClientId';
# DECLARE @sid NVARCHAR(max) = CONVERT(VARCHAR(max), CONVERT(VARBINARY(16), @clientId), 1);
# DECLARE @cmd NVARCHAR(max) = N'CREATE USER [' + @username + '] WITH SID = ' + @sid + ', TYPE = E;';
# IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = @username)
# BEGIN
# EXEC(@cmd)
# END
# EXEC sp_addrolemember '$DatabaseRole', @username;
# EOF
# )

# # Output the SQL query for debugging
# echo "SQL Query:"
# echo "$SQL_QUERY_FINAL"

# Check if OS is Windows
OS=$(uname | tr '[:upper:]' '[:lower:]')

if [[ "$OS" == "mingw"* || "$OS" == "cygwin"* || "$OS" == "msys"* ]]; then
echo "Running on Windows OS, will use interactive login"
echo "Getting signed in user email"
UserEmail=$(az ad signed-in-user show --query userPrincipalName -o tsv)
# Execute the SQL query
echo "Executing SQL query..."
sqlcmd -S "$SqlServerName" -d "$SqlDatabaseName" -G -U "$UserEmail" -Q "$SQL_QUERY_FINAL" || {
echo "Failed to execute SQL query."
exit 1
}
else
echo "Running on Linux or macOS, will use access token"
mkdir -p usersql
# Get an access token for the Azure SQL Database
echo "Retrieving access token..."
az account get-access-token --resource https://database.windows.net --output tsv | cut -f 1 | tr -d '\n' | iconv -f ascii -t UTF-16LE > usersql/tokenFile
if [ $? -ne 0 ]; then
echo "Failed to retrieve access token."
exit 1
fi
errorFlag=false
# Execute the SQL query
echo "Executing SQL query..."
sqlcmd -S "$SqlServerName" -d "$SqlDatabaseName" -G -P usersql/tokenFile -Q "$SQL_QUERY_FINAL" || {
echo "Failed to execute SQL query."
errorFlag=true
}
#delete the usersql directory
rm -rf usersql
if [ "$errorFlag" = true ]; then
exit 1
fi
fi


echo "SQL user and role assignment completed successfully."
Loading