tech.guitarrapc.cóm

Technical updates

目まぐるしい変化を続ける会社 - 一休に行ってみた

このブログでは珍しい会社訪問記事第二弾です。

最近 C# で Windows な会社で良く話題を聞くのは?と聞かれた時に 高級旅館、レストランを中心とした予約ができる一休.comを運営されている 株式会社 一休様 の名前が上がってくることが多いのではないでしょうか。

www.ikyu.com

先日、噂の一休さんに訪問する機会をいただきました。

目次

一休さんとの初めての邂逅

実は昨年(2015年6月30日) に、当時良く一休さんの話題を耳にしていたときに、@kentana20@zimathon さん、@minato128 さんをはじめとするエンジニアの皆様がグラニに見学に来られたことがあります。その時に、「C# で頑張っていきます!」というお話を伺って私たちも頑張っていこうと気合を入れなおしたのでした。当時話題になっていたのが、以下の記事や発表でした。

https://tenshoku.mynavi.jp/it-engineer/knowhow/naoya_sushi/07tenshoku.mynavi.jp

https://tenshoku.mynavi.jp/it-engineer/knowhow/naoya_sushi/08tenshoku.mynavi.jp

speakerdeck.com

speakerdeck.com

会社訪問のお誘い

一年が過ぎる中、一休で取り組まれている様々な改善を耳にしていました。そして、とても嬉しいことに今度は id:kentana20 さんに会社見学へ誘っていただけたので 2016年8月26日 19:00~ グラニのメンバーと一緒に伺ってきた次第です。*1

なんて優しい...!

社内でメンバーを募ったところ、グラニからは、開発メンバー 7名 + インターンに来ている大学生1名 の8名という大所帯で伺うというなんともご迷惑をおかけする事態に....*2 快諾してくださったことに改めて感謝申し上げます。

訪問前の事前準備

さて、伺うとなれば事前情報集めです。何やら新しくされたということで、気になる記事が話題になっていましたね。めもめも。

blog.kushii.net

最近の雰囲気が良く伝わる素敵なブログです。

y-jima.hatenablog.com

あとは勉強会の様子とか。

座談会なので、進行の大枠と質問をざっくりと交換していざ出発です。

訪問当日

19:00 からのお約束だったので 18:30 に珍しく全員が集合完了して出発 *3 六本木から赤坂見附の移動なのですが、ルートがすさまじい回り道感.... ともかく赤坂見附迷路を抜けて出口11から外へ

やってきました。ビル 6F について入口へ。

受付が和風モダンでかっこいい.... 高級ホテルを思わせる安心感があります。

ここから id:kentana20 さんに案内をしていただきました。

期待に違わずこの扉が開いて恐る恐る中に入ります。と、早速入口脇に自販機!なんとゲスト用に無料とのこと...!! id:kentana20 さんのお心遣いで各人が一人思い思いにポチポチします *4

素敵な会議室がいくつもありいい感じでした。

皆様まだ働いていらっしゃるなか、オフィス内を見学させていただき...各開発チームの方とご挨拶しつつ、社内の階段で5Fにも訪問させていただきました。フロアが分かれている場合の社内階段いいですねー、メンバーがわくわく降りて行ってます。フロアが分かれる場合、こういうの大事だと思います。

エンジニアの方の写真は控えたのでツイートを拝借します。

噂の43インチモニターは、噂通り大きい....!! エクセルが捗るとのこと (あれ、プログラミングは...?

話題の CTO @naoya_itoさんにもお会いしました。もしかしてディナーショーを拝見できるかと思いましたが、ちらっとご挨拶で終わっちゃいました。*5

さて、途中の鐘やマグロに心を惹かれつつ 最後に案内していただいたのがリラックスルーム。全社員200名で集まったりもされるとのことで、とても広いのにすごいリラックス感です。まるで、リゾートホテルのライブラリのような居心地の良さがありました。

プロジェクタが3つあるなど 色々説明を受ける横で..。

さっそく座って馴染んでいるメンバー達....*6

という感じで社内を案内していただき、メインの座談会へ。

座談会

広い会議室に通され、うきうきしていたのですが、このあと名刺交換会で名刺を切らす程の一休エンジニアの皆さんに囲まれ戦々恐々となります。

組織に関すること、開発の体制、ブランディング/採用、勉強会の状況からざくっと始まり、テクノロジのトレンド、今後の選択、ロギング、インフラ基盤、モニタリングなどなど座談会では色々なお話を交わしました。

個人的にとても心強かったのは、メイン言語は 今後も C# で行くことに変わりがないというお言葉でした。様々な変化の中で、どうされるのかなと気にしていただけに、今後も負けじと頑張っていきます!

インフラの環境変化といえば、気になるのが..。

Azure、AWS、GCP どれも特徴ありますよねー、という話もしつつ、個人的に GCP を激推しした*7のですが、その日の夜にこんな記事が出てオチ要員の役割は果たしました。記事は不正確なのか、7月中に一部使っただけのようですし今でもポケモンGO はGCP のようです。

今後の選択になんの影響も与えていない雑魚発言で終わりましたが、一休さんがどのクラウドを選択するのかは非常に興味があります。お話の中で、インフラ面でのマルチOS、マルチプラットフォームを視野に入れていらっしゃるのが現実的ですごいと思いました。負けてられません。

あとは、せっかくなので Fastly も激烈に推しておきました。これは正真正銘 Fastly 最高ですからね、*8

まとめ

胸をお借りに行ったのですが、一休さんがあまりに素敵なので今週も月曜から負けてられません。メンバーも刺激を受けているので、今後もコツコツ大胆に開発を続けていきたいと思います。

一休シールいただきました!激かわです!

グラニからも手土産もお渡ししたので、ミッション完了!です。

おまけ

一休マスコットがかわいかったので、絵描きの知人に TiltBrush でVRお絵かきしてもらいました。

上アングル

下アングルも*9

*1:なんと訪問は夜!申し訳ない反面、お心遣いありがとうございます。

*2:ぞろぞろ行ってしまって申し訳ありません

*3:初めてじゃないかしら...ヒドイ

*4:そういえば写真に夢中で押し忘れた

*5:行ったメンバーにファンもいたので残念でした。わたしもファンです。

*6:自重はどうした

*7:GCPを50回は言った気がします、GCP営業に負けないぐらい猛烈プッシュしました

*8:Fastly のみなさんよろしくお願いします(なにが)

*9:少し乱れました。マスコットの質感 VR だと難しいです....

第24回◯◯o◯裏番組シェル芸勉強会 を PowerShell と C# でやってみる #シェル芸

久々のシェル芸です。

Bsh on Ubuntu on Windows でやろうと思ったのですが、手元の環境が入らないのでそっとじ..。

今回は途中で飽きるまでということで、やってみました。

目次

問題

安定の一撃サイトです。

https://blog.ueda.asia/?p=8639

コード全体

今回の回答です。BoUW かなぁと思いつつ、PowerShell がインストールできなかったのでやめました*1

6問まで回答しています。

言語 回答数 環境
C# 1,2,3 問 LinqPad
PowerShell 1,2,3,5,6 問 PowerShell.exe on Windows 10

gist.github.com

回答

縛りは2つ、「ワンライナー」、「ファイル読み込み」、「複数行になっても問題ない」、です。

Q1. Q1ファイルについて、次のような出力を得てください。

Q1 ファイル

玉子 卵 玉子 玉子 玉子 玉子
玉子 玉子 卵 卵 卵 玉子
卵 玉子 卵 玉子 玉子 玉子
卵 玉子 卵 卵 卵 卵
玉子 卵 玉子

出力

玉子:5 卵:1 
玉子:3 卵:3 
玉子:4 卵:2 
玉子:1 卵:5 
玉子:2 卵:1 

PowerShell / C# ともに行ごとに読み取ってほげもげでした。

C# だと、Select して GroupBy して数をまとめて、OrderBy して並びを整えて、Selectで成形した文字列出力です。

PowerShell も同様です。オペレータの挙動が微妙に違うのですが大枠同じです。

Q2. 次のようなテキストについて、繰り返し出てきた文字の2つ目以降を省いて出力してください。

例えばQ2のファイル

へのへのもへじ

の場合、「へのもじ」が正解の出力になります。

これは、C#では .Distinct() を使えば一瞬です。

PowerShell でも同様ですが、2つ一応用意しました。一つはHashtable のキーが重複不許可なことを利用しているのと、同様に Distinct() です。Hashset でもなんでもいいと思いました。

ちなみに using NameSpace を使っていいなら、

using Namespace System.Linq;
cat .\Q2.txt -Encoding utf8 | %{[string]::new([Enumerable]::Distinct([char[]]$_))}

です。

Q3. 第一フィールドをキーにして%%でレコードを区切ってください。
金 日成
キム ワイプ
金 正日
キム タオル
金 正男

というデータを、

%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%

区切りをテキストで出す意味...は、おいておいてやります。

C# では、初期化変数を用意しちゃいました。なしで書くとどうなるか思いつかない当りできない子です。あと、ずるいと思いつつTuple使ってます。

PowerShell は、awk と同じ要領ですね。

Q4. Q4.xlsxのA1のセルには数字が書いてあります。その数字を出力してください。A4には文字列が書いてあるので余裕がある人はそれも特定してみましょう。

やりません*2

Q5. ファイルQ5について、xに好きな数を代入して各行の式を計算してください。
x + x^2
x + 1/x
x*x*x

余裕のある人は、例えばxに2を代入したければ、

$ echo 2 | ...

というようにecho <代入したい数>から始めてワンライナーで解いてみてください。

echo から初めてと言われた時点で C# はやめて、PowerShell のみで。また、2^2 という構文がないため、Math.Pow(x,2) に書き換えています。

PowerShell の場合、ScriptBlock を Invoke という手と Invoke-Expression を使うのが楽です。C# も似たようなものですね。

今回は Invoke-Expression (iex) を使っています。

Q6. 「玉子」と「卵」の数を数えて、数が少ない方を数が大きい方で置換してください。
卵卵玉子玉子玉子玉子玉子卵卵卵玉子玉子卵玉子玉子玉子玉子卵卵玉子卵玉子卵卵玉子卵玉子

ずるしちゃいました。汎用性がないのであまり好きじゃないのですが。

Q7. 飽きました
Q8. 飽きました

まとめ

C# というか、Linq できれいにつながると楽しいですね。PowerShell でつないでいくよりも可読性が圧倒的に高いのはいいなぁと。

ただ、コードは長くなりがちというのは仕方ないとはいえ感じました。

雑魚回答なので、もっと良い回答をぜひ。

*1:bashではやりません

*2:COM使ったら怒られそうだし。PowerShell はモジュール使っていいなら1 Cmdletでできちゃいます

Azure Web Apps を使ったReference Source による ブラウザ上でのコード追跡

2014年2月に Microsoft がブラウザ上におけるソースコード閲覧の新しい体験を提供しました。今でも使うことが多い、Reference Source です!! 個人的にこの時の衝撃はすさまじいものがありました。

blogs.msdn.microsoft.com

http://referencesource.microsoft.com/

※ Reference Source で閲覧可能なソースは、現在の 4.6.2 までの全ソースを zip でダウンロードすることもできます。

Download the entire reference source

さて、今回はこの Reference Source を自分のソースコードにも適用できますよ。というお話です。こんな感じで!

目次

Roslyn を使った Reference Source のジェネレータ

Reference Source 以外にも実は Roslyn も同様のフォーマットで公開されています。

Roslyn Reference Source

これらはMicrosoft のエンジニアである KirillOsenkov がOSSとして 2015年に公開した SourceBrowser を使って生成されています。

github.com

SourceBrowser は非常に強力で、既存のC# プロジェクトの Solution ファイルを食わせるだけで自動的に静的サイトのdll やhtml を生成します。

早速見てみましょう。

サンプル

今回は、UniRx をリファレンスソースとして参照可能にしてみます。事前に、Visual Studio Tools for Unity をインストールしておきましょう。

visualstudiogallery.msdn.microsoft.com

SourceBrowser のビルド

SourceBrowser に含まれる HtmlGenerator で、ソースコードをHtml に変換、生成します。まずは、Github からクローンしたら、SourceBrowser.sln を開き HtmlGenerator をDebugビルドしましょう。

ビルドできましたね?

静的Html の生成

では、次に HtmlGenerator のプロジェクトプロパティ > Debug で、Command line arguments に Reference Source を生成したいプロジェクトの .sln ファイルを食わせましょう。今回、D:\GitHub\UniRx\UniRx.sln に、UniRx を置いたので指定して実行します。これで Htmlが生成されます。

が、CI を前提にビルドされた .exe を使っても生成してみましょう。SourceBrowser\bin\Debug\HtmlGeneratorHtmlGenerator.exe が生成されているので次の書式で実行します。

HtmlGenerator.exe <生成したいプロジェクトの.sln> <生成先パス>

今回、私は HtmlGenerator.exe "D:\GitHub\UniRx\UniRx.sln" "D:\GitHub\UniRx.ReferenceSource\src" としました。

実行すると、さくさく生成されます。

中略

生成されました。非常に高速です。

Writing referencing assemblies complete. Took: 00:00:00.0277302
04:16:02 Finalizing references complete. Took: 00:00:08.6732978
04:16:02 Generating website complete. Took: 00:00:31.2171024

生成されたファイルは、HtmlGenerator.exe と同パスにある Index フォルダにあります。

Azure Web Apps にデプロイ

生成された中身は Web.config や Global.asax をはじめ、各種dll まで含まれており Roslyn ベースで動いています。そのため、ホスティングするサーバーは .NET 4.6 が動いている必要があります。まさに Azure Web Sites 向けですね!

生成したファイルを Github 経由でデプロイして閲覧できるようにしました。個人的に、こういう大量のファイルをただデプロイする場合は、Github -> Azure Web Apps 連携がいいと思います。くれぐれも MSBuild + Deploy Package や MSDeploy は無駄なのでやめたいところです。

github.com

できました!Azure Web Apps も無料プランでお財布に優しいです。

UniRx.ReferenceSource

ということで、どうぞ。UniRx のソースをブラウザ上で閲覧できます。

UniRx.ReferenceSource

できることはReference Source 同様です。定義へのジャンプ、コード検索、シンタックスハイライト、コード選択でURL共有、などなどちょっとしたIDEよりも高性能です。

CI

ちなみにVSTS を使うと、ビルドパイプラインをガシガシ重ねることで特別なスクリプトなどもなしにCI/CD が可能です。

同期ツール

イミュータブルなビルドパイプラインを作っていると、ローカルで同期をしたくなることがあります。しかし、RoboCopy は最終更新時間で判定、MSDeploy はチェックサム検証コピーが可能ですが遅いと従来のツールでは問題があります。しかし、同じくKirillOsenkov が作成した CotentSync を使うと爆速で同期できます。最高です。このツール、コードもきれいでシンプルで、本当に感動を覚えます。

github.com

まとめ

グラニでは、実際にプロダクションコードを Github 以外にもブラウザから追跡可能なように提供しています。*1 この記事が、皆様のコード共有の役に立つことを願っています。

*1:AzureAD 認証を付けることで SSOも担保できます

AWS の新ELB である Application Load Balancer を .NET SDK で作成してみる

AWS のロードバランサーといえば ELB です。これはEC2 をバックエンドに置いたときの負荷分散として多くで採用されることが多いものです。

しかし従来の ELB は Google LoadBalancer と比べてもいろいろできなくてもんにょりします。これはGoogle LoadBalancer が優れているのもありますが、ここ数年細かな設定サポート追加はあったものの、目立った機能改善がなかったこともあります。

さて、2016年8月12日 AWS Application Load Balancer が発表されました。全リージョンですぐに利用可能です。

New – AWS Application Load Balancer | AWS News Blog

これはずいぶん前からGAを待っていたもので、ようやくGA としてプロダクションで使うことができます!早速見てみましょう。

目次

Application Load Balancer でできること

従来の ELBはレイヤー4 と レイヤー7 で動いていました。これは今後 Classic Load Balancer (CLB) と呼称されます。今回リリースされたのは レイヤー7 専用のロードバランサーで Application Load Balancer (ALB)と呼称されます。

ALBは従来に比べて多くのサポートが入りました。

  • コンテンツベースルーティング
  • WebSocket サポート
  • HTTP/2 サポート

コンテンツベースルーティングサポートが入ったことで、自前API サーバーがある場合の制御がかなり楽になったと触りながら感じています。

例 : https://api.hoge.jp/api/v1/hogehttps://api.hoge.jp/api/v2/hoge など

あるいは、従来は Route53 で環境別にドメインを取得してバックエンドを振り分けていた場合、1つのELB からバックエンド振り分けが可能になります。ただしそれぞれがパスに対応した入口を持っている必要があります。

例 : https://hoge.jp/devhttps://hoge.jp/prod など

Classic Load Balancer の移行

Python製の移行ツールが公開されています。

github.com

以下の状況がサポートされていないようなので注意です。

  • Classic load balancer has TCP or SSL listeners
  • Classic load balancer is in EC2-Classic
  • Classic load balancer has only one enabled subnet
  • Classic load balancer has TCP or SSL health check configured
  • Classic load balancer has an unsupported policy (please note that this utility does not currently support sticky sessions)
  • Classic load balancer has more than 50 unique backend ports
  • Classic load balancer has more than 10 listeners

価格

既存の Elastic Load Balancing の価格ページが Classic Load Balancer と Application Load Balancer に分かれています。

aws.amazon.com

aws.amazon.com

ELB 自体の価格は10% 既存より安くなっています。

The hourly rate for the use of an Application Load Balancer is 10% lower than the cost of a Classic Load Balancer.

東京の場合、現時点は以下のようです。

ELB 価格
Classic Load Balancer $0.027 per Elastic Load Balancer-hour (or partial hour)
Application Load Balancer $0.0243 per Application Load Balancer-hour (or partial hour)

一方でデータ処理に関しては従来と変わっています。

ELB 価格
Classic Load Balancer $0.008 per GB of data processed by an Elastic Load Balancer
Application Load Balancer $0.008 per LCU-hour (or partial hour)

LCU になってことで計算がずいぶん変わります。1LCU は以下です。

  • Up to 25 new connections per second
  • Up to 3,000 active connections per minute
  • Up to 2.22 Mbps

試算例が載っています。

AWSSDK.NET の対応状況

すでに対応SDKが nuget でリリースされています。すぐに試すことができます。

www.nuget.org

github.com

早速、Amazon Certificate Manager で用意した証明書を使った HTTPS を HTTP に流す ELB を作成してみましょう。適当に必要な nuget パッケージを取得しておいてください。

www.nuget.org

www.nuget.org

www.nuget.org

ザックリこんな感じです。

gist.github.com

作成直後は、provisioning というステータスですが数分で利用可能になります。

従来の CLB との違い

Listener と TargetGroups

まず作成時に気付くのが、Listener です。CLB では、IN-OUT(Instance) の Protocol / Port を Listener で設定していました。こんな感じですね。

ALB では IN を Load Balancer の Listener、OUT(Instance) を TargetGroup で設定することになります。例えば、上記コードで作成した段階では、HTTPS 443 で待ち受けなので以下のようになります。

そして Load Balancer がルーティングした先の TargetGroups を見てみると、作成したTestTargetGroups は、HTTP 80 で待ち受けます。もちろん stickness なども TargetGroups 単位で設定可能です。

TestTargetGroups は、ヘルスチェックを/ に対して HTTP : 80 で行います。(override port で別ポートも指定可能です)

TargetGroup は明らかにこれまでより良いやり方です。コンテンツベースでどこにルーティングするかを TargetGroup で指定することになります。そのため、インスタンスの紐づけも従来の Load Balancer 直接ではなく TargetGroup に変更となりました。

Rule 設定

コンテンツベースルーティングの設定は、Load Balancer の Listernersにある各リスナーに設定します。ここで、指定したパスのアクセスをどの TargetGroups にフォワードするか設定するだけです。非常に簡単です。

バックエンドインスタンスがない場合のエラー画面

これまでは真っ白画面でしたが、503 Service Temporarily Unavailable awselb/2.0 が帰ってきます。

Swagger UI

Stickness を有効にしても無効でも、ブラウザ上での Swagger UI でのAPIテストで content が空で返ってくるようなのでちょっと確認が必要のようです。

cUrl などでのAPIレスポンスは返ってきています。

ALB の削除防止

従来の CLB では削除防止がなく、事故で削除がありえました。が、ALB でようやく Deletion protection が設定可能鳴りました。

安心です。

Load Balancer の種別表記

従来のものが Classic、ALB が Application になりました。

まとめ

ようやく待ちに待った レイヤー7 ロードバランサーが誕生です。次は、できれば従来のL4ロードバランサーである Classic Load Balancer に Persistent TCP サポートを入れてほしいところです。Google Load Balancer なら.... げふ。

Windows 資格情報マネージャーをPowerShell DSC で構成管理するリソースを公開しました

PowerShell DSC は PowerShell が目指してきた姿の1つの目標であり、強力な技術基盤です。

PowerShell は DSC を提供にするにあたり、OMI の実装を WMI から クロスプラットフォームな CIMに移してきました。実際 Linux で PowerShell DSC を利用する PowerShell-DSC-for-Linux も公開されています。

github.com

また WMF5.1 からは、PowerShell Core、つまり .NET Core 実装のクロスプラットフォーム PowerShell も提供されます。シェルとして使い心地に課題は残るものの、着実にPowerShell でやると楽な部分、という意味での存在価値は間違いなく存在します。

さて、そんな PowerShell ですが WMF5 からは、DSC の実行ユーザーが BuiltIn/SYSTEM だけでなく任意のユーザー指定が可能になりました。これによりユーザープロファイルに依存する処理も管理可能になりました。

ということで、先日 資格情報マネージャーのリソースを公開したのでご紹介です。*1

目次

資格情報マネージャーの操作

以前 資格情報マネージャーを PowerShell で操作する方法を示しました。

tech.guitarrapc.com

現在はもう少しコードを修正していますが、ようはこれを PowerShell DSC でやれるようにします。

PowerShell Gallery からの導入

WMF5 以降の環境ではワンライナーでDSCリソースを利用できます。

Install-Module -Name GraniResource -Scope AllUsers

幸いにも PowerShell Team が公開している以外のリソースとして上位に位置するダウンロード数のようで嬉しい限りです。

www.powershellgallery.com

実はリポジトリ名を DSCResources から GraniResource へこっそり変えていますが、ソースコードも変わらず公開しています。*2

github.com

利用

Grani_CredentialManager を利用することで、資格情報マネージャーを管理できます。デフォルトは、DSCの実行ユーザー、つまり SYSTEM アカウントが対象です。このアカウントができるということは、SYSTEM で動作するサービスの資格情報を管理できます。

gist.github.com

また、PsRunAsCredential を指定することで任意のアカウントの資格情報も操作できます。

gist.github.com

Grani_CredentialManager について

前回のリソース作成から、PowerShell チームへの今トリビュートを重ねる中で得た知見を使って少し書き方を変えました。

本体とヘルパーの分離

いわゆる *-TargetResource が PowerShell DSC を関数で記述したときの本体です。*3

今回のリソースは、ロジックを C# に閉じ込めていたこともあり本体の処理は非常にシンプルです。が、それでもヘルパーとなる補助関数は *helper.psm1 として分離しました。

ポイントは .psm1、つまりモジュールとしての分離です。本体の Grani_CredentialManager.psm1 で公開していないので内部モジュール扱いなのですが、Pester テストを含めた取り扱いの良さから .ps1 ではなく .psm1 にしています。この手法は、xTimeZone リソースでも行っておりPowerShell におけるプライベートな関数を閉じ込めるにあたりとてもいい手法だと思います。

github.com

呼び出しもシンプルですしね。

Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath "Grani_CredentialManagerHelper.psm1") -Verbose:$false -Force
PowerShell のまずいポイント対策

PowerShell には致命的なポイントがあります。それが、バイナリモジュールを利用する場合 DLL をロックしてしまうということです。つまり、C# で書いてビルドしたDLL を DSC などで利用すると、DSC実行中はファイルロックされます。これはデプロイの観点からみると非常に問題で、Windows 嫌いになります。その対策として、以前 Assembly.Load を利用したダイナミックモジュールによるロック回避も提示しました。

tech.guitarrapc.com

tech.guitarrapc.com

しかし PowerShell DSC に限らず、この手法は正直いやです。人道的とか言いながら逆説的な複雑性を増しています。

そこで今回をはじめとして、PowerShell の Add-Type Cmdlet を利用した C# コードのオンザフライコンパイルによるコード注入を好んで使っています。これならばファイルロックを回避できます。問題になりえるのは、同一AppDomain への 同一名前空間、クラス、シグネチャの多重インポートですが PowerShell DSC は毎回の実行で別AppDomain を起動するので問題ありません。

具体的にはこのC#コード を、ヘルパーとして差し込んでいます。

    $code = Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath "CredentialManager.cs") -Raw
    $referenceAssemblies = @("System", "System.Linq", "System.ComponentModel", "System.Management.Automation", "System.Runtime.InteropServices")
    Add-Type -TypeDefinition $code -ReferencedAssemblies $referenceAssemblies -ErrorAction SilentlyContinue;

あとは、PowerShell から扱いやすいように薄くラッパを作って、DSC本体から呼び出すだけです。

PowerShell Team 公式リソースのテスト

PoweShell Team は、DSC リソースに関して、DscResources/CONTRIBUTING.mdにコントリビューションガイドラインを公開しています。

Grani_CredentialManager は、ガイドラインに沿うようにテストを組んであります。今後 DSC リソースを書いて公開する場合のサンプルにでもなれば幸いです。

https://github.com/guitarrapc/GraniResource/tree/master/Test/Grani_CredentialManagergithub.com

特にこの辺りは基礎となります。

$global:dscModuleName = 'GraniResource'

# Import
$modulePath = (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)).Replace("Test","DSCResources")
$global:dscResourceName = (Split-Path -Path $modulePath -leaf)
$moduleFileName = $global:dscResourceName + ".psm1"
Import-Module -Name (Join-Path -Path $modulePath -ChildPath $moduleFileName) -Force

# Prerequisite for Initialize-TestEnvironment in Domain Environment
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process

# Initialize
[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path))
if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or `
     (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) )
{
    & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'))
}
else
{
    & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull')
}
Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force
$TestEnvironment = Initialize-TestEnvironment -DSCModuleName $global:dscModuleName -DSCResourceName $global:dscResourceName -TestType Unit

# Begin Test
try
{
    InModuleScope $global:dscResourceName {
        # テストロジック
    }
}
finaly
{
    Restore-TestEnvironment -TestEnvironment $TestEnvironment
}

コントリビューションガイドの通り、PesterDscResource.Tests を使うのがいいでしょう。もう少し パイプラインベースでテストを組めると書きやすいんですが、まだまだフレームワークもなく事実上 Pester しか確立したテスト手法がないですね。

DscResource.Testsは AppVeyor でのテストを通すことを前提で組んでるのか、ローカルでは妙な挙動をするのでバグ報告もしておきました。とりあえず現状でもふつーに使えるはずです。*4

github.com

github.com

まとめ

これで資格情報マネージャーも PowerShell DSC でハンドルできました。そもそも 資格情報が必要になる処理は RunDeck のように外から管理したところですが、なかなか難しいです。

悩ましいものの、いったんは目指した課題解決はできたので試していただけると幸いです。

*1:資格情報マネージャーは当然 Windows 固有実装なんですけどね。

*2:git からの直接ダウンロードで利用しやするための変更です。ご理解いただければと思います。

*3:ちなみにSet/Get/Test がクラスで書いたときの本体です

*4:ゴミカス残したりするのでアレですが