【问题标题】:Azure ARM uniqueString function mimicAzure ARM uniqueString 函数模拟
【发布时间】:2017-04-08 15:08:26
【问题描述】:

我需要使用 to 方式将 Sql 数据库部署到 Azure Sql Server 中:ARM 模板方式和使用 C# 代码的更自定义方式。有一个名为uniqueString(string) 的ARM 模板函数可以生成给定字符串的伪随机散列。这是一个确定性的纯函数。

我需要找到一种方法来从我的 C# 代码中完全模仿此函数的行为。即我需要将此函数复制到我的 C# 代码中。

在哪里可以找到 ARM Api 使用的算法?

MSDN reference for uniqueString()

【问题讨论】:

  • 我仍然希望通过不涉及获取 Azure 堆栈集线器套件的方式来实现这一点。

标签: arm-template azure-resource-manager


【解决方案1】:

我自己断断续续地研究了这几年,我终于打到了paydirt...

// "zcztcwvu6iyg6"
var unique = ArmUniqueString("tyeth");

我的ArmUniqueString 函数是一些与Azure Stack Hub Development Kit 一起分发的dll 的包装器,Azure Stack Hub Development Kit 基本上是一个包含可以在本地运行的 Azure 服务器端平台的虚拟机映像...

private static string ArmUniqueString(string originalString)
{

    var assembly = Assembly.GetAssembly(
        typeof(Microsoft.WindowsAzure.ResourceStack.Frontdoor.Templates.Engines.TemplateEngine)
    );

    var functions = assembly.GetType(
        "Microsoft.WindowsAzure.ResourceStack.Frontdoor.Templates.Expressions.TemplateExpressionBuiltInFunctions"
    );

    var uniqueString = functions.GetMethod(
        "UniqueString",
        BindingFlags.Static | BindingFlags.NonPublic
    );

    var parameters = new object[] {
        "uniqueString",
        new JToken[] {
            (JToken)originalString
        }
    };

    var result = uniqueString.Invoke(null, parameters).ToString();

    return result;

}

您需要下载 Azure Stack Hub 开发工具包并将其解压缩以获取 dll:

  • 下载 Azure Stack Hub Development Kit - 警告:大约 22Gb!
  • 运行安装程序解压 55Gb *.vhdx
  • 安装 *.vhdx,或在本地展开/解压
  • 在 *.vhdx 中,找到此文件并将其解压缩到某个位置:
    • CloudBuilder\CloudDeployment\NuGetStore\Microsoft.AzureStack.Setup.Services.ResourceManager.5.20.1335.300.nupkg
  • *.nupkg 内的 content\Website\bin 文件夹包含必要的 dll

要使用它们,请添加对 Microsoft.WindowsAzure.ResourceStack.Frontdoor.Templates.dll 的程序集引用(它对 bin 文件夹中的其他文件有一些依赖关系)并包含 TemplateExpressionBuiltInFunctions 类。上面的代码只是使用反射从该程序集中调用私有 UniqueString 函数,并通过一些工作将参数编组为适当的 JToken 类型。

如果您想深入了解实现细节,您可以对程序集运行反编译器以找出它在幕后所做的事情...

注意 - 这篇博客文章为我指明了正确的方向:

https://the.agilesql.club/2017/12/azure-arm-template-function-internals/

【讨论】:

  • 这太可怕了,太棒了,谢谢
【解决方案2】:

我在这里找到了一些 PowerShell 代码:https://blogs.technet.microsoft.com/389thoughts/2017/12/23/get-uniquestring-generate-unique-id-for-azure-deployments/

我将此代码转换为 C#:

public string GetUniqueString(string id, int length = 13)
{
    string result = "";
    var buffer = System.Text.Encoding.UTF8.GetBytes(id);
    var hashArray = new System.Security.Cryptography.SHA512Managed().ComputeHash(buffer);
    for(int i = 1; i <= length; i++)
    {
        var b = hashArray[i];
        var c = Convert.ToChar((b % 26) + (byte)'a');
        result = result + c;
    }

    return result;
}

【讨论】:

  • 这与 ARM 部署模板的预期结果不匹配。尝试将 uniqueString('tyeth') 作为 arm 模板中的单个输出参数,然后测试此函数或任何类似的堆栈溢出建议。我从 Azure 取回“zcztcwvu6iyg6”
  • 对我来说,这个功能和原来发布的 Powershell 都不能解决问题......
【解决方案3】:

该功能在nuget中发布:https://www.nuget.org/packages/Azure.Deployments.Expression/ 实施: https://msazure.visualstudio.com/One/_git/AzureUX-Deployments?path=%2Fsrc%2FExpressions%2FExpressions%2FExpressionBuiltInFunctions.cs&version=GBmaster&_a=contents

例子:

using Azure.Deployments.Expression.Expressions;
using Newtonsoft.Json.Linq;

var funcs = ExpressionBuiltInFunctions.Functions;
var jt = new JTokenExpression("test");
var output = funcs.EvaluateFunction("uniqueString", new JToken[] { jt.Value }).ToString();

【讨论】:

  • 我不确定您是否应该在 Microsoft 之外共享 msazure.visualstudio.com 链接...
【解决方案4】:

我终于找到了解决方法。我使用了一个非常简单的 ARM 模板,其目标是仅输出 uniqueStringcommand 的结果。然后我在我的 C# 代码中获取这个输出。此解决方案并不是真正最快的解决方案 ;-),但它可以按需要工作。

【讨论】:

  • 愿意分享它的样子吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多