зеркало из https://github.com/microsoft/SynapseML.git
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:
Родитель
a72b94bc62
Коммит
7b54e8900b
|
@ -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'
|
||||||
|
|
Загрузка…
Ссылка в новой задаче