この記事 に書いてあることを実現するために、Azureのテンプレートファイルを生成する必要がある。
テンプレートファイルはJSON形式。例えば、WebAppsは以下のURLにある通り。(この記事を書いた時点でのURLなので、将来変わるかも)
そこで、要求されているパラメータをクラスのメンバーにして、Newtonsoft.Jsonを使ってモデルクラスをJSONにシリアライズすればいいかな、と考えた。
#0. (2020/05/24更新)結論を言うとうまく使えなかった
何日かいじってみたけど、結局SDKのモデルを使うのはやめて、独自でモデルクラスを定義することにした。
なんつっても、以下のような「properties.」が痛い。これいらない。
properties.isXenon": null
必要なのは「isXenon」だけなので、[Jsonproperty(name=)]みたいなやつで何とかしたい。しかし、SDKを継承しているだけなので手が出せない。
必須パラメーターだけに絞ればそんなに大した量でもないし、本来であればテンプレートの構造に従ったモデルクラスを定義すべきであると思ったので、この方式はやめた。。。。
以下は、一応備忘録ということで残しておくけど、もう使うことはない・・・さらば・・・
#1. SDKからモデルを拝借
でも、テンプレートファイルの形式に沿った自前でクラス作ると、Azure側の変更とかに追従しなきゃいけなくなったりして面倒。
なにか簡単な方法ないかな・・・・ということで、.NET SDKのモデルクラスを借りることにした。例えば以下。
これを見ると、テンプレートのMicrosoft.Web sites templateにかなり近い構造を持っていることがわかる。
なので、このクラスを継承した独自のクラスを作れば・・・・!
using Microsoft.Azure.Management.WebSites.Models;
//...(中略)...
class SiteModel : Microsoft.Azure.Management.WebSites.Models.Site
{
public string type = "Microsoft.Web/sites";
public string apiVersion = "2019-08-01";
public SiteModel()
{
}
#2. 発生した問題と解決法
継承したモデルを使ってWebAppsの名前を設定するプロパティに値を入れようとしたら、getしか認められていない・・・・
つまり、WebAppsに好きな名前を設定できない。
なので、外部からWebAppsの名前を設定したかったら、コンストラクタを生成する段階で名前を入れておく必要がある。
コンストラクタの引数はバカ多いものの、幸い必須なのはlocationだけのようなので、locationとnameだけを指定できるようコンストラクタを追加。
public SiteModel(string location, string name) : base(location: location, name: name)
{
}
#3. JSON形式にシリアライズ
準備はできた。早速シリアライズや!
using Newtonsoft.Json;
using System;
namespace jsontest2
{
class Program
{
static void Main(string[] args)
{
var site = new SiteModel(location: "Japan East", name: "testSite");
string json = JsonConvert.SerializeObject(site, Formatting.Indented);
Console.WriteLine(json);
}
}
}
出力は以下。
{
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"properties.state": null,
"properties.hostNames": null,
"properties.repositorySiteName": null,
"properties.usageState": null,
"properties.enabled": null,
"properties.enabledHostNames": null,
"properties.availabilityState": null,
"properties.hostNameSslStates": null,
"properties.serverFarmId": null,
"properties.reserved": null,
"properties.isXenon": null,
"properties.hyperV": null,
"properties.lastModifiedTimeUtc": null,
"properties.siteConfig": null,
"properties.trafficManagerHostNames": null,
"properties.scmSiteAlsoStopped": null,
"properties.targetSwapSlot": null,
"properties.hostingEnvironmentProfile": null,
"properties.clientAffinityEnabled": null,
"properties.clientCertEnabled": null,
"properties.clientCertExclusionPaths": null,
"properties.hostNamesDisabled": null,
"properties.outboundIpAddresses": null,
"properties.possibleOutboundIpAddresses": null,
"properties.containerSize": null,
"properties.dailyMemoryTimeQuota": null,
"properties.suspendedTill": null,
"properties.maxNumberOfWorkers": null,
"properties.cloningInfo": null,
"properties.resourceGroup": null,
"properties.isDefaultContainer": null,
"properties.defaultHostName": null,
"properties.slotSwapStatus": null,
"properties.httpsOnly": null,
"properties.redundancyMode": null,
"properties.inProgressOperationId": null,
"identity": null,
"id": null,
"name": "testSite",
"kind": null,
"location": "Japan East",
"tags": null
}
いやプロパティがバカ多いな。いらないやつは出さなくていいぞい。
実際、自前のWebAppsをテンプレート化してみたら「hostNameSslState」とか無かったし。
パラメータ自体はフルセットだから当然クソほどあるんだろうけど、実際すべてのパラメータをフルに使うなんてそうそうない気がする。
というわけで、シリアライズ時に引数を渡します。
string jsonExcludeNull = JsonConvert.SerializeObject(site, new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented });
こうすると、出力が以下のように。
{
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"name": "testSite",
"location": "Japan East"
}
いいんじゃないのこれー!?!?!?テンプレートファイルみたいにできるかも!!!
あとは階層構造みたいなんがうまくいけば、もうコレほぼ完成だろコレおい。
・・・・とテンションが上がったところで今日は終わります。
あと、全然関係ないけどAZ-103受けたら合格した。
PaaSばっか触っててあんまIaaSとか詳しくないけど、1か月くらいそれなりに勉強したら受かりました。
うぇい。