寝ても覚めてもこんぴうた

プログラム書いたり、ネットワーク設計したり、サーバ構築したり、車いじったり、ゲームしたり。そんなひとにわたしはなりたい。 投げ銭は kyash_id : chidakiyo マデ

figmaよく使う/使いたいショートカット(備忘録)

最近figmaを使い始めようとしていますが、やはりこの手のツールはショートカットを使いこなしてなんぼ、みたいなところもあると思います。
昔はイラレ、フォトショをもりもり使ってはいたけど改めてfigmaでヨチヨチスタートするために便利そうなショートカットをメモしていきます。

なんかvimを使い始めたあの頃のアレを思い出します...

とても使いそう

space で手のひらツールにして画面をスクロール

手のひらツールに変更するのは「H」キーでも変更できるのですが、「space」を利用した場合には「押している間だけ手のひらツールになる」という挙動になります。
個人的には、illustratorの「ctrl + space」のズームツールと「command + 0」の全体表示を多用していたので、そういう操作感のあるショートカットを求めていたのですが、一旦、目的のものを画面上から探す際にはこれも便利と思って使っています。
また、トラックパッドの人はこのあたり困らずにトラックパッドで自由に拡大縮小移動ができるかと思いますが、私はマウスを利用しています(補足)

うっ、急に眠気が・・・

<また追記します>

Google Dominから移行する際に注意したほうが良さそうなDNSSECの話

こんにちは。
GoogleGoogle Domains を Squarespace 社に売却してしまいますよ、というニュースが数日まえに発表され、界隈がざわめいていますね。

既存の Google Domains を利用しているアカウントの人はそのまま Squarespace へ移行され、特に何もする必要はないとアナウンスされていますが、
個別で移行を検討されている場合、DNSSECの設定がされていると問題が発生しそうだったので少し調べてみました。

DNSSEC とは

DNS応答に添付された署名を受信側で検証することにより、正しい相手から届いた正しいデータであることを確認できるようにするための技術

らしいです。

DNSSEC 何が嬉しい?

受信側で送った人が正しいということを検証するため、キャッシュポイズニングなどに対する耐性があります。(すごくざっくり)

DNSSEC 使っているかの確認

コマンドで調べる場合

dig コマンドで確認できます。

実行例

dig +dnssec group.ntt

ANSER SECTION で RRSIG レコードが帰ってきている場合、DNSSEC が有効化されていると判断できます。

例:

;; ANSWER SECTION:
group.ntt.      3473    IN  A   45.60.83.32
group.ntt.      3473    IN  A   45.60.134.32
group.ntt.      3473    IN  RRSIG   A 13 2 3600 20230709032542 20230608032542 39982 group.ntt. 985m3NeuAmDoxge696yATY6DawqYk8MkUeP7uHbv13hqLnCHdamcmbYb hLvrnzPQW2DCTdMKmAcblArVaWu8ww==

WEB で調べる場合

https://dnsviz.net/ などを利用して調べることができます。
以下の図のような感じで、 group.nttDNS サーバ(レコードを返却している末端のサーバ)に DNSKEY の設定が見えている場合には DNSSEC が有効化されていると思って良さそうです。

DNSSEC が有効になっているドメインGoogle Domains から他のレジストラに移行する場合。

DNSSEC の設定を 移行前に無効化し 移行を行う必要があるようです。

これが漏れていると、見かけ上 DNS の移行が済んでいても、名前解決ができないという罠にハマってしまいます。

きをつけましょう。

参考

重要技術 DNSSECって何?

DNSViz | A DNS visualization tool

Google Domains終了へ!移管の際はご注意ください - Value Note - わかる、なるほどなIT知識。

gcloud コマンドの統計情報の設定を変更する

gcloud コマンドを gcloud components update コマンドを実行しようとした際に、
統計情報のoptinをうっかり Y してしまったので、無効化するコマンドを調べた。

gcloud コマンドの統計情報の取得を有効化/無効化するコマンド

コマンド自体は gcloud config set の中にあり、

無効化する場合(送ってほしくない場合)

gcloud config set disable_usage_reporting true

有効化する場合(送っても良い場合)

gcloud config set disable_usage_reporting false

となっています。

disableに対してのフラグなので truefalse が気持ち逆な感じもありますが、
そういうものだと思って実行しましょう。

ではでは。

参考

Usage statistics  |  Google Cloud CLI Documentation

GCPのIAMのプリンシパルって?

GCPのIAMのドキュメントにたびたび存在する プリンシパル
雰囲気では理解していたのだけど、実際にGCPのドキュメントでは同定義されているのか。

ドキュメントを見ると...

以下のように記述されています。

このアクセス管理モデルは、次の 3 つの主要な部分から構成されています。

  • プリンシパルプリンシパルは、リソースへのアクセスが許可されている Google アカウント(エンドユーザー)、サービス アカウント(アプリケーションまたはコンピューティング ワークロード)、Google グループ、Google Workspace アカウントまたは Cloud Identity ドメインです。各プリンシパルには、一意の識別子(通常はメールアドレス)があります。

  • ロール。ロールは権限のコレクションです。権限によって、リソースに対して許可されているオペレーションが決まります。プリンシパルにロールを付与すると、そのロールに含まれるすべての権限が付与されます。

  • ポリシー。許可ポリシーは、1 つ以上のプリンシパルを個々のロールにバインドするロール バインディングの集合です。リソースに対してどのようなアクセス権(ロール)を誰(プリンシパル)に許可するのかを定義する場合、許可ポリシーを作成して、そのポリシーをリソースに接続します。

つまり、

であり、
通常はメールアドレス である。

ということのようです。
そういうことだろうなと感覚的に把握していましたが、スッキリ把握できました。

ではでは。

GoのWebサービスのエラーハンドリングについてGoのblogに書かれていた内容を日本語でまとめてみた

GoでWebサービスを実装する際、Errorのログをどこで出すのかーという話、 少々古い記事になるけどGoのBlogに書かれていたのでサラッと日本語にしてみた。

GAEの実装を例にされているのと、2011年頃の記事なので、いろいろモダンなGo技術(?)を使うといい感じにできる部分もあるけど一旦そのまま。

内容としては https://go.dev/blog/error-handling-and-go#simplifying-repetitive-error-handling に書かれているものです。

何度もやるエラーハンドリングを簡素化する

Goはエラーハンドリングが重要。言語のデザインや習慣として発生した場所でエラーを明示的にチェックすることが推奨される。
(スローして場合によってキャッチする他の言語規則とは異なる)

場合によっては冗長になるが、度重なるエラー処理を最小限に抑える手法がある。
データストアからレコードを取得するAppEngineのコードで考えてみましょう。

func init() {
    http.HandleFunc("/view", viewRecord)
}

func viewRecord(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
    record := new(Record)
    if err := datastore.Get(c, key, record); err != nil {
        http.Error(w, err.Error(), 500)
        return
    }
    if err := viewTemplate.Execute(w, record); err != nil {
        http.Error(w, err.Error(), 500)
    }
}

この関数は datastore.Get/viewTemplate.Executeから返されるエラーを処理する。
いずれもHTTP 500のメッセージが表示される。

これらは扱いやすいコード量に見えるが、更にHTTPハンドラを追加するとエラーハンドリングコードがたくさん作られる。

繰り返しを減らすため、エラーの戻り値を含む appHandler 型を定義する

type appHandler func(http.ResponseWriter, *http.Request) error

そして、viewRecordがerrorを返すように変更する

func viewRecord(w http.ResponseWriter, r *http.Request) error {
    c := appengine.NewContext(r)
    key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
    record := new(Record)
    if err := datastore.Get(c, key, record); err != nil {
        return err
    }
    return viewTemplate.Execute(w, record)
}

これはオリジナルよりシンプルですが、httpパッケージはerrorを返す関数を利用できずないため、
http.HandlerインターフェースのServeHTTPをappHandlerに実装します

func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if err := fn(w, r); err != nil {
        http.Error(w, err.Error(), 500)
    }
}

ServeHTTPメソッドはappHandler関数を呼び出し、返されたエラーをユーザに表示します。

appHandlerはhttp.Handlerなので、viewRecordをhttpパッケージに登録する際にはhttp.Handle関数を利用します。

func init() {
    http.Handle("/view", appHandler(viewRecord))
}

このようなベーシックなエラーハンドリング基盤を配置することでユーザフレンドリーにすることができる。
エラーを表示するだけではなく、適切なHTTPステータスを含むシンプルなエラーメッセージを表示し、
デバッグのために完全なログを出力することもできる。

それを行うためには、エラーとその他のフィールドを含むappErrorを作成する

type appError struct {
    Error   error
    Message string
    Code    int
}

そして、 *appError を返すようにappHandler型を変更する

type appHandler func(http.ResponseWriter, *http.Request) *appError

( こちら に書かれているように、errorではなくerrorのコンクリートタイプを返すことは通常は間違いですが、ServeHTTPは値を見てその内容を使用する唯一の場所になるためここで行うことは正しいといえます)

appHandlerのServeHTTPメソッドがappErrorのメッセージをとエラーコードをログにも落とせるようにします。

func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if e := fn(w, r); e != nil { // eは *appError、os.Errorではない。
        c := appengine.NewContext(r)
        c.Errorf("%v", e.Error)
        http.Error(w, e.Message, e.Code)
    }
}

最後に、viewRecordの関数シグネチャに変更し、エラーが発生した際には多くの情報を返すようにします。

func viewRecord(w http.ResponseWriter, r *http.Request) *appError {
    c := appengine.NewContext(r)
    key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
    record := new(Record)
    if err := datastore.Get(c, key, record); err != nil {
        return &appError{err, "Record not found", 404}
    }
    if err := viewTemplate.Execute(w, record); err != nil {
        return &appError{err, "Can't display record", 500}
    }
    return nil
}

この状態のviewRecordはオリジナルと同じようなながさになりますが、より使いやすいユーザエクスペリエンスを提供している。

  • エラーハンドラにわかりやすいHTMLテンプレートを与える
  • ユーザが管理者であればスタックトレースをレスポンスに含めるなどが可能(デバッグが容易になる)
  • デバッグを容易にするスタックトレースを持つappErrorコンストラクタを記述する
  • appHandler内のパニックからリカバーし、クリティカルのログを出力するし、重大なエラーが発生した旨をユーザに伝える。プログラミングエラーによって引き起こされる得体のしれないメッセージからユーザを守る

goでoapi-codegenを使ってopenapi 3.0してみた(chi-server)

OpenAPI何もわからんですが、
Go で OpenAPI 3.0 に対応したいと思ったのですが、swaggerはどうやら OpenAPI 2.0 とやららしいので、
oapi-codegen を利用してみました。

インストール

goがインストールされれている環境で

go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest

を実行すると oapi-codegen がインストールされます。

利用方法

今回は chi-server を利用しようと思います。
標準では echo サーバを生成したような記憶があります(ど忘れ)

また、READMEに書いてあるサンプルの静止コマンドでは、goのファイルが1つになってしまいますので、
運用も考え、server, types, spec の3ファイルに分かれるようにコマンドを実行します。

コマンドの引数がREADMEなどを読む感じでうまく適用できなかったのですが試行錯誤(やコードを読んで)以下で実行しています

oapi-codegen -package hoge -old-config-style -generate "chi-server" api.yaml > api.gen.go

oapi-codegen -package hoge -old-config-style -generate "types" api.yaml > types.gen.go

oapi-codegen -package hoge -old-config-style -generate "spec" api.yaml > spec.gen.go

このように実行することで、httpサーバとしての api.gen.go , リクエスト/レスポンスパラメータの型としての types.gen.go , oapiのspecファイルとしての spec.gen.go の3ファイルがそれぞれ生成されます。

httpサーバとしての組み込み

サーバとしての組み込みは難しいことはなく、 api.gen.go ファイルの中に Handler を生成する関数が複数用意されているので、
必要な項目て利用できるものを使いhttpサーバを起動しましょう。(詳細略:手抜き)

困ったこと

chi 以外の実装を試していないので、ほかがどうかはわかっていないのですが、chi 関しては、
swaggerを利用したバリデーションなどが標準的に生成されたコードの中で組み込まれず、自分でmiddlewareなどを実装する必要がありました。
これはもう少しよしなにやってくれるような期待をしていたのでびっくりしたのと、
security BearerAuth あたりも割と自分で実装する必要がありました。

最後に

openapi3.0 を使って実装するのが初だったので最初のYAMLの作成に結構手間取りましたが、
実際に開発の流れになると、yamlで変更したものがgoの実装に反映されたり、
webビューからリクエストを投げて動作確認をしたりということが気軽に行えるのでとても良かった。

YAMLを書く → 生成してみる → 生成された構造体/コードを見る(gitのdiff)

というのを繰り返すことで、YAMLで表現したことがどういう意味を持っているのかということが理解しやすい、
しかも生成が速いということで非常に良い感じでした。

ではでは。

参考(ツールの評価のためにも色々参考にしました)

github.com

future-architect.github.io

future-architect.github.io

future-architect.github.io

future-architect.github.io

github.com

zenn.dev

github.com

rinoguchi.net

github.com

times.hrbrain.co.jp

github.com

blog.ebiiim.com

github.com

ツール

editor.swagger.io