Masteries

技術的なことや仕事に関することを書いていきます.

「go-nature-remo」と「mackerel-plugin-nature-remo」で照度の取得に対応しました

先日, iPhone版のNature Remoのアプリがリニューアルされていたのですが, いろいろ触ってみているうちに, 温度と湿度に加えて照度を取得して表示されるようになっていることに気づきました.

f:id:papix:20180701000646p:plain

APIドキュメントにはまだ掲載されていませんが, 実際にAPIを叩いたところ照度が取得できたので, Nature RemoのGo言語向けクライアントのgo-nature-remoと, それを使ったMackerelプラグイン, mackerel-plugin-nature-remoでも対応しておきました.

github.com

github.com

実際に自宅にあるEdge Router Xで動いているmackerel-plugin-nature-remoの様子をお見せします. 最初は普通に部屋の明かりを付けていたので照度が160程度ありますが, 00:06頃に部屋の明かりを消してみたので, 照度がガクッと下がっていることがわかります.

...ちなみにこのグラフは, Mackerelのグラフ共有機能を使って埋めてみました. 便利ですね.

mackerel.io

Go言語でMixed Contentsをなるべく発見する

ウェブサービス/ウェブサイトのHTTPS化にあたっては, Mixed Contentsへの対応が求められます. 既にHTTPSを有効にする作業が完了している状態で, Mixed Contentsが発生していないかを確認したいのであれば, (Node.js製のツールですが)Mixed Contentsの発見のために mcdetect などを使うことができるでしょう.

www.npmjs.com

例えば, このブログ(https://papix.hatenablog.com/)を mcdetect でチェックすると, 次のような結果になります:

$ mcdetect https://papix.hatenablog.com/
Checking https://papix.hatenablog.com/ ...

Targets checked: 1
Errors (blockable content): 0
Warnings (optionally blockable content): 0

ここでの Errors (blockable content)Warnings (optionally blockable content) は, どちらもHTTPSのページでHTTPのコンテンツを読み込んでいる状態ですが, 前者はそのコンテンツがHTTPのみで配信されている状態, 後者はそのコンテンツがHTTPとHTTPSの両方で配信されている状態(= コンテンツを読み込むときのURLを, http://... から https://... にすればMixed Contentsが解決できる)を指します.

mcdetect の課題

mcdetect は, 実際にHeadless Chromeを利用してMixed Contentsの検出を行います. そのため, Mixed Contentsを検索する対象ページは, (前述の通り)HTTPS化が有効になっている必要があります. 実際, mcdetect にHTTPのURLを与えると, Mixed Contentsを見つけるために, 自動的にHTTPSのURLとしてアクセスを行い, Mixed Contentsの検出を行います:

$ mcdetect http://example.com/
Checking https://example.com/ ...

Targets checked: 1
Errors (blockable content): 0
Warnings (optionally blockable content): 0

そのため, 実際にHTTPS化を有効にする前に, なるべくMixed Contentsを見つけたい! という用途には利用できません.

Go言語でMixed Contentsをなるべく発見する

※ "なるべく"とあるように, 以下のコードで全てのMixed Contentsが発見出来るわけではありません. あくまでMixed Contentsを見るける上での参考情報としてお使い下さい.

そこで, Go言語でMixed Contentsを"なるべく"見つけるコードを書きました:

package main

import (
    "fmt"
    "log"
    "regexp"
    "strings"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    doc, err := goquery.NewDocument("https://papix.hatenablog.com/")
    if err != nil {
        log.Fatal(err)
    }

    for _, tag := range []string{"img", "audio", "video", "script", "iframe"} {
        doc.Find(tag).Each(func(i int, s *goquery.Selection) {
            src, _ := s.Attr("src")
            if strings.HasPrefix(src, "http://") {
                fmt.Printf("error\t%s\t%s\n", tag, src)
            }
        })
    }

    doc.Find("link").Each(func(i int, s *goquery.Selection) {
        rel, _ := s.Attr("rel")
        if strings.HasPrefix(rel, "stylesheet") {
            href, _ := s.Attr("href")
            if strings.HasPrefix(href, "http://") {
                fmt.Printf("error\tlink\t%s\n", href)
            }
        }
    })
}

前述の通り, "なるべく"なので100%のMixed Contentsを見つけられる訳ではないですが, これである程度のMixed Contentsを見つけることができます. ここでは,

  • img, audio, video, script, iframeタグのsrcにHTTPのURLがないか
  • linkタグで, かつrelstylesheetのときに, hrefにHTTPのURLがないか

を見ています. 加えて目視で,

  • style タグの中でHTTPのコンテンツを呼び出していないか
  • scriptタグで呼び出しているJavaScriptや, linkタグで呼び出しているスタイルシートでHTTPのコンテンツを呼び出していないか

...辺りを確認しておくと, 更に良さそうです.

まとめ

Go言語のgithub.com/PuerkitoBio/goqueryを使って, なるべくMixed Contentsを見つけるコードを紹介しました.

前述の通り, 実際にHTTPS化した後にMixed Contentsの対応を出来るのであれば, mcdetect を利用する方が確実ではありますが, そうもいかない場合はこういうったスクリプトである程度Mixed Contentsを潰した後, HTTPS化を実施して, mcdetectで最終チェックをする, という手が有効になるかもしれません.

「Hatena Engineer Seminar #10」ではてなブログのHTTPS化についてトークをしました

hatena.connpass.com

ご参加頂いた皆様, ありがとうございました!

当日の発表資料です. サービスのHTTPS化に際してはMixed Contentsの解決が最大の壁になりますが, それに対してただひたすらに, 丁寧に立ち向かって行った... という, 割と地味な話をしました.

id:aereal さんが当日発表された, AWSを活用した証明書の自動取得システムも順調に開発が進んでいます. 独自ドメインのHTTPS対応を提供できるまで, もう少しお待ち下さい.

宣伝

はてなでは, 一緒にはてなブログを開発する仲間を募集しています!!! 「思いは言葉に」するプラットフォームの"次"を, 一緒にやっていきましょう!!!!!!

hatenacorp.jp

「カイゼン・ジャーニー」読んだ

最近話題の「カイゼン・ジャーニー」を読みました. ...だいぶ前に. 感想エントリ書いたつもりだったのだけれど下書き状態のままで, 公開されていなかったのでした... そしてこの本ですが, Twitterとかで id:daiksy さん等たくさんの方々が絶賛していたので, サクッと買っていました.

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

この本は3部構成の物語仕立てになっていて, 1人の主人公を中心に, 1部では「一人で」, 2部では「チームで」, そして3部では「チームを越えて」, アジャイルのプラクティスを活用することで, チームを"カイゼン"していく様子が描かれています. 1つの部には, それぞれ複数の話があり, そこでは最初に主人公が直面した課題の紹介と, それに対してアジャイルのプラクティスで立ち向かっていく様子が小説で綴られていて, その後に, そこで取り入れられたプラクティスについて詳解するというスタイルになっています

それぞれのプラクティスの説明も丁寧ですし, 何より小説パート(?)の出来がものすごく良くて, 特に終盤の, (自主検閲)が(自主検閲)の(自主検閲)だったシーンはちょっと胸が熱くなってしまいました(?). そういう意味では, 以前読んだ「アジャイルサムライ」よりも, (オタクにとっては)とっつきやすさがある(?)ように思います.

papix.hatenablog.com

...次はこれまた各所で評判だった, 「エンジニアリング組織論への招待」を読み進めていく予定です.

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

ところで...

最近こういった本を読んでいたのは, 今期から「テックリード」という役割を任されることになったのが大きいです. はてなにおけるテックリードの役割は, "チームの技術的な窓口"と定義されていますが, とはいえそれに留まらず, これまでよりも一つ上の視点で, チームを客観的に捉えようと思って, チームを見つめ直した結果, 今の自分たちのチームにはたくさん改善出来る所があり, それができれば自分たちはもっとやっていけるのでは? と思ったのでした. 「アジャイルサムライ」とか, 「カイゼンジャーニー」とかは, その改善のヒントを見つけられれば... という気持ちで読んでいたのです.

...で, こういった本で得た知識をそのまま今のチームに導入すると当然うまくいかないパターンが多いので, チームの状況に応じてアレンジをして, 「こういう取り組みをやってみませんか?」という提案を続けた結果, 最終的に「一通り任せてみよう」という話になり, 来週から実験的にチームのスクラムマスターをやることになりました. 前職でスクラムマスターと一緒にスクラムを回した経験はあるものの, 言うまでもなくスクラムマスターという役割を担うのは初めてです. そういう意味で, 現時点では正直不安しかないのですが, とはいえ社内には id:daiksy さんといった有識者がいますし, チームとしても現状維持で良いという意見は全くなくて, スクラムの導入に対してプラスの印象を持ってもらっているので, そういった後押しを力に変えて, うまくスクラムを回していきたいという気持ちです.

というわけで, 今後はそういった領域の気付きや知見なども, ブログに書いていけたらと思っています. 頑張るぞ!!!

AWS::CLIWrapperにPull Requestを投げた

AWSの機能を任意の言語から利用するためのSDKですが, 悲しいことにPerl向けのものはありません. 従って, Perl Monger達はAWSのCLIであるawsコマンドをラップしてPerlから実行する, AWS::CLIWrapperというモジュールを駆使しています.

metacpan.org

さまざまな事情があって, AWSに最近追加された機能をPerlから使いたかったので, さっくりとPull Requestを投げました.

github.com

即座にマージ頂いて, 1.13としてリリースされました. 対応ありがとうございました!

おもしろポイント

AWS::CLIWrapper, たくさんあるAWSの機能に対してどのようにして対応しているのだろう...? と前々から思ったのですが, 今回Pull Requestを出すにあたって眺めてみたところ, aws helpコマンドを使ってAWSの各機能を利用するためのコードを, 自動的に生成していました: https://github.com/hirose31/AWS-CLIWrapper/blob/master/lib/AWS/CLIWrapper.pm#L259-L261

# aws help | col -b | perl -ne 'if (/^AVAILABLE/.../^[A-Z]/) {  s/^\s+o\s+// or next; chomp; next if $_ eq 'help'; my $sn = $_; $sn =~ s/-/_/g; printf "sub %-18s { shift->_execute('"'"'%s'"'"', \@_) }\n", $sn, $_ }'
# aws help | col -b | perl -ne 'if (/^AVAILABLE/.../^[A-Z]/) {  s/^\s+o\s+// or next; chomp; next if $_ eq 'help'; my $sn = $_; $sn =~ s/-/_/g; printf "=item B<%s>(\$operation:Str, \$param:HashRef, %%opt:Hash)\n\n", $sn}'
# =item B<s3>($operation:Str, $path:ArrayRef, $param:HashRef, %opt:Hash)

ドキュメント(ヘルプ)から自動生成すれば漏れがないので, 「なるほど賢い!」と思いました.