chore: switch to msi based tokens (#2221)

* chore: switch to msi based tokens

* chore: fix style

* chore: add docker msi token

* fix blob upload to use msi

* wip

* wip

* continue removing code
This commit is contained in:
Mark Hamilton 2024-05-03 02:07:39 -04:00 коммит произвёл GitHub
Родитель a72b94bc62
Коммит 7b54e8900b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 38 добавлений и 41 удалений

Просмотреть файл

@ -4,9 +4,9 @@
package com.microsoft.azure.synapse.ml.services.anomaly package com.microsoft.azure.synapse.ml.services.anomaly
import com.microsoft.azure.synapse.ml.Secrets import com.microsoft.azure.synapse.ml.Secrets
import com.microsoft.azure.synapse.ml.Secrets.getAccessToken
import com.microsoft.azure.synapse.ml.core.test.base.TestBase import com.microsoft.azure.synapse.ml.core.test.base.TestBase
import com.microsoft.azure.synapse.ml.core.test.fuzzing.{TestObject, TransformerFuzzing} import com.microsoft.azure.synapse.ml.core.test.fuzzing.{TestObject, TransformerFuzzing}
import com.microsoft.azure.synapse.ml.nbtest.SynapseUtilities.getAccessToken
import org.apache.spark.ml.util.MLReadable import org.apache.spark.ml.util.MLReadable
import org.apache.spark.sql.functions._ import org.apache.spark.sql.functions._
import org.apache.spark.sql.{DataFrame, Row} import org.apache.spark.sql.{DataFrame, Row}
@ -88,9 +88,7 @@ class DetectLastAnomalySuite extends TransformerFuzzing[DetectLastAnomaly] with
} }
test("Basic usage with AAD auth") { test("Basic usage with AAD auth") {
val aadToken = getAccessToken(Secrets.ServicePrincipalClientId, val aadToken = getAccessToken("https://cognitiveservices.azure.com/")
Secrets.ServiceConnectionSecret,
"https://cognitiveservices.azure.com/")
val ad = new DetectLastAnomaly() val ad = new DetectLastAnomaly()
.setAADToken(aadToken) .setAADToken(aadToken)
.setCustomServiceName("synapseml-ad-custom") .setCustomServiceName("synapseml-ad-custom")

Просмотреть файл

@ -4,9 +4,9 @@
package com.microsoft.azure.synapse.ml.services.openai package com.microsoft.azure.synapse.ml.services.openai
import com.microsoft.azure.synapse.ml.Secrets import com.microsoft.azure.synapse.ml.Secrets
import com.microsoft.azure.synapse.ml.Secrets.getAccessToken
import com.microsoft.azure.synapse.ml.core.test.base.Flaky import com.microsoft.azure.synapse.ml.core.test.base.Flaky
import com.microsoft.azure.synapse.ml.core.test.fuzzing.{TestObject, TransformerFuzzing} import com.microsoft.azure.synapse.ml.core.test.fuzzing.{TestObject, TransformerFuzzing}
import com.microsoft.azure.synapse.ml.nbtest.SynapseUtilities.getAccessToken
import org.apache.spark.ml.util.MLReadable import org.apache.spark.ml.util.MLReadable
import org.apache.spark.sql.{DataFrame, Row} import org.apache.spark.sql.{DataFrame, Row}
import org.scalactic.Equality import org.scalactic.Equality
@ -26,6 +26,12 @@ class OpenAICompletionSuite extends TransformerFuzzing[OpenAICompletion] with Op
import spark.implicits._ import spark.implicits._
override def beforeAll(): Unit = {
val aadToken = getAccessToken("https://cognitiveservices.azure.com/")
println(s"Triggering token creation early ${aadToken.length}")
super.beforeAll()
}
def newCompletion: OpenAICompletion = new OpenAICompletion() def newCompletion: OpenAICompletion = new OpenAICompletion()
.setDeploymentName(deploymentName) .setDeploymentName(deploymentName)
.setCustomServiceName(openAIServiceName) .setCustomServiceName(openAIServiceName)
@ -60,10 +66,7 @@ class OpenAICompletionSuite extends TransformerFuzzing[OpenAICompletion] with Op
} }
test("Basic usage with AAD auth") { test("Basic usage with AAD auth") {
val aadToken = getAccessToken( val aadToken = getAccessToken("https://cognitiveservices.azure.com/")
Secrets.ServicePrincipalClientId,
Secrets.ServiceConnectionSecret,
"https://cognitiveservices.azure.com/")
val completion = new OpenAICompletion() val completion = new OpenAICompletion()
.setAADToken(aadToken) .setAADToken(aadToken)

Просмотреть файл

@ -3,6 +3,7 @@
package com.microsoft.azure.synapse.ml.services.openai package com.microsoft.azure.synapse.ml.services.openai
import com.microsoft.azure.synapse.ml.Secrets.getAccessToken
import com.microsoft.azure.synapse.ml.core.test.base.Flaky import com.microsoft.azure.synapse.ml.core.test.base.Flaky
import com.microsoft.azure.synapse.ml.core.test.fuzzing.{TestObject, TransformerFuzzing} import com.microsoft.azure.synapse.ml.core.test.fuzzing.{TestObject, TransformerFuzzing}
import org.apache.spark.ml.util.MLReadable import org.apache.spark.ml.util.MLReadable
@ -14,6 +15,12 @@ class OpenAIPromptSuite extends TransformerFuzzing[OpenAIPrompt] with OpenAIAPIK
import spark.implicits._ import spark.implicits._
override def beforeAll(): Unit = {
val aadToken = getAccessToken("https://cognitiveservices.azure.com/")
println(s"Triggering token creation early ${aadToken.length}")
super.beforeAll()
}
lazy val prompt: OpenAIPrompt = new OpenAIPrompt() lazy val prompt: OpenAIPrompt = new OpenAIPrompt()
.setSubscriptionKey(openAIAPIKey) .setSubscriptionKey(openAIAPIKey)
.setDeploymentName(deploymentName) .setDeploymentName(deploymentName)

Просмотреть файл

@ -47,6 +47,12 @@ object Secrets {
secretJson.parseJson.asJsObject().fields("value").convertTo[String] secretJson.parseJson.asJsObject().fields("value").convertTo[String]
} }
def getAccessToken(reqResource: String): String = {
println(s"[info] token for perms: $reqResource from $AccountString")
val json = exec(s"az account get-access-token --resource $reqResource --output json")
json.parseJson.asJsObject().fields("accessToken").convertTo[String]
}
lazy val CognitiveApiKey: String = getSecret("cognitive-api-key") lazy val CognitiveApiKey: String = getSecret("cognitive-api-key")
lazy val OpenAIApiKey: String = getSecret("openai-api-key") lazy val OpenAIApiKey: String = getSecret("openai-api-key")
lazy val OpenAIApiKeyGpt4: String = getSecret("openai-api-key-2") lazy val OpenAIApiKeyGpt4: String = getSecret("openai-api-key-2")
@ -68,7 +74,5 @@ object Secrets {
lazy val ArtifactStore: String = getSecret("synapse-artifact-store") lazy val ArtifactStore: String = getSecret("synapse-artifact-store")
lazy val Platform: String = getSecret("synapse-platform") lazy val Platform: String = getSecret("synapse-platform")
lazy val AadResource: String = getSecret("synapse-internal-aad-resource") lazy val AadResource: String = getSecret("synapse-internal-aad-resource")
lazy val ServiceConnectionSecret: String = getSecret("service-connection-secret")
lazy val ServicePrincipalClientId: String = getSecret("service-principal-clientId")
} }

Просмотреть файл

@ -4,6 +4,7 @@
package com.microsoft.azure.synapse.ml.nbtest package com.microsoft.azure.synapse.ml.nbtest
import com.microsoft.azure.synapse.ml.Secrets import com.microsoft.azure.synapse.ml.Secrets
import com.microsoft.azure.synapse.ml.Secrets.getAccessToken
import com.microsoft.azure.synapse.ml.build.BuildInfo import com.microsoft.azure.synapse.ml.build.BuildInfo
import com.microsoft.azure.synapse.ml.core.env.PackageUtils.{SparkMavenPackageList, SparkMavenRepositoryList} import com.microsoft.azure.synapse.ml.core.env.PackageUtils.{SparkMavenPackageList, SparkMavenRepositoryList}
import com.microsoft.azure.synapse.ml.io.http.RESTHelpers import com.microsoft.azure.synapse.ml.io.http.RESTHelpers
@ -118,18 +119,14 @@ object SynapseUtilities {
import SynapseJsonProtocol._ import SynapseJsonProtocol._
lazy val SynapseToken: String = getAccessToken(ClientId, Secrets.ServiceConnectionSecret, lazy val SynapseToken: String = getAccessToken("https://dev.azuresynapse.net/")
"https://dev.azuresynapse.net/") lazy val ArmToken: String = getAccessToken("https://management.azure.com/")
lazy val ArmToken: String = getAccessToken(ClientId, Secrets.ServiceConnectionSecret,
"https://management.azure.com/")
val LineSeparator: String = sys.props("line.separator").toLowerCase // Platform agnostic (\r\n:windows, \n:linux) val LineSeparator: String = sys.props("line.separator").toLowerCase // Platform agnostic (\r\n:windows, \n:linux)
val Folder = s"build_${BuildInfo.version}/scripts" val Folder = s"build_${BuildInfo.version}/scripts"
val TimeoutInMillis: Int = 30 * 60 * 1000 // 30 minutes val TimeoutInMillis: Int = 30 * 60 * 1000 // 30 minutes
val StorageAccount: String = "mmlsparkbuildsynapse" val StorageAccount: String = "mmlsparkbuildsynapse"
val StorageContainer: String = "synapse" val StorageContainer: String = "synapse"
val TenantId: String = "72f988bf-86f1-41af-91ab-2d7cd011db47"
val ClientId: String = Secrets.ServicePrincipalClientId
val PoolNodeSize: String = "Small" val PoolNodeSize: String = "Small"
val PoolLocation: String = "eastus2" val PoolLocation: String = "eastus2"
val WorkspaceName: String = "mmlsparkbuild" val WorkspaceName: String = "mmlsparkbuild"
@ -176,8 +173,11 @@ object SynapseUtilities {
def uploadAndSubmitNotebook(poolName: String, notebook: File): LivyBatch = { def uploadAndSubmitNotebook(poolName: String, notebook: File): LivyBatch = {
val dest = s"$Folder/${notebook.getName}" val dest = s"$Folder/${notebook.getName}"
exec(s"az storage fs file upload " + exec(s"az storage fs file upload " +
s" -s ${notebook.getAbsolutePath} -p $dest -f $StorageContainer " + s" -s ${notebook.getAbsolutePath}" +
" --overwrite true " + s" -p $dest" +
s" -f $StorageContainer" +
s" --auth-mode login" +
s" --overwrite true" +
s" --account-name $StorageAccount") s" --account-name $StorageAccount")
val abfssPath = s"abfss://$StorageContainer@$StorageAccount.dfs.core.windows.net/$dest" val abfssPath = s"abfss://$StorageContainer@$StorageAccount.dfs.core.windows.net/$dest"
@ -317,19 +317,4 @@ object SynapseUtilities {
safeSend(deleteRequest) safeSend(deleteRequest)
} }
def getAccessToken(clientId: String, clientSecret: String, reqResource: String): String = {
val createRequest = new HttpPost(s"https://login.microsoftonline.com/$TenantId/oauth2/token")
createRequest.setHeader("Content-Type", "application/x-www-form-urlencoded")
createRequest.setEntity(
new UrlEncodedFormEntity(
List(
("grant_type", "client_credentials"),
("client_id", clientId),
("client_secret", clientSecret),
("resource", reqResource)
).map(p => new BasicNameValuePair(p._1, p._2)).asJava, "UTF-8")
)
RESTHelpers.sendAndParseJson(createRequest).asJsObject()
.fields("access_token").convertTo[String]
}
} }

Просмотреть файл

@ -200,7 +200,7 @@ jobs:
- task: Docker@2 - task: Docker@2
displayName: Demo Image Build displayName: Demo Image Build
inputs: inputs:
containerRegistry: 'SynapseML MCR' containerRegistry: 'SynapseML MCR MSI'
repository: 'public/mmlspark/build-demo' repository: 'public/mmlspark/build-demo'
command: 'build' command: 'build'
buildContext: "." buildContext: "."
@ -210,14 +210,14 @@ jobs:
- task: Docker@2 - task: Docker@2
displayName: Demo Image Push displayName: Demo Image Push
inputs: inputs:
containerRegistry: 'SynapseML MCR' containerRegistry: 'SynapseML MCR MSI'
repository: 'public/mmlspark/build-demo' repository: 'public/mmlspark/build-demo'
command: 'push' command: 'push'
tags: $(version) tags: $(version)
- task: Docker@2 - task: Docker@2
displayName: Minimal Image Build displayName: Minimal Image Build
inputs: inputs:
containerRegistry: 'SynapseML MCR' containerRegistry: 'SynapseML MCR MSI'
repository: 'public/mmlspark/build-minimal' repository: 'public/mmlspark/build-minimal'
command: 'build' command: 'build'
buildContext: "." buildContext: "."
@ -227,7 +227,7 @@ jobs:
- task: Docker@2 - task: Docker@2
displayName: Minimal Image Push displayName: Minimal Image Push
inputs: inputs:
containerRegistry: 'SynapseML MCR' containerRegistry: 'SynapseML MCR MSI'
repository: 'public/mmlspark/build-minimal' repository: 'public/mmlspark/build-minimal'
command: 'push' command: 'push'
tags: $(version) tags: $(version)
@ -235,7 +235,7 @@ jobs:
condition: and(eq(variables.isMaster, true), startsWith(variables['gittag'], 'v')) condition: and(eq(variables.isMaster, true), startsWith(variables['gittag'], 'v'))
displayName: Release Image Build displayName: Release Image Build
inputs: inputs:
containerRegistry: 'SynapseML MCR' containerRegistry: 'SynapseML MCR MSI'
repository: 'public/mmlspark/release' repository: 'public/mmlspark/release'
command: 'build' command: 'build'
buildContext: "." buildContext: "."
@ -248,7 +248,7 @@ jobs:
condition: and(eq(variables.isMaster, true), startsWith(variables['gittag'], 'v')) condition: and(eq(variables.isMaster, true), startsWith(variables['gittag'], 'v'))
displayName: Release Image Push displayName: Release Image Push
inputs: inputs:
containerRegistry: 'SynapseML MCR' containerRegistry: 'SynapseML MCR MSI'
repository: 'public/mmlspark/release' repository: 'public/mmlspark/release'
command: 'push' command: 'push'
tags: | tags: |

Просмотреть файл

@ -8,5 +8,5 @@ steps:
versionSpec: '8' versionSpec: '8'
jdkArchitectureOption: 'x64' jdkArchitectureOption: 'x64'
jdkSourceOption: 'PreInstalled' jdkSourceOption: 'PreInstalled'
- bash: pip install azure-cli==2.58.0 - bash: pip install azure-cli==2.60.0
displayName: 'Upgrade Azure CLI' displayName: 'Upgrade Azure CLI'