まったりするmatayu

ツイートにゴミがついた感じのブログ

Google Cloud PlatformのService account

google adminで新規のgoogle accountを作成するAPIを叩くには,いくつか方法があるのですが,今回はservice accountを利用した方法をやってみました. 実際に叩いたAPIはこれです.

developers.google.com

Guidesの

Prerequisites -> Authorize Requests -> Perform Google Workspace Domain-Wide Delegation of Authority

の順にひとつずつやっていけば,google developer consoleでアプリケーションを作成したり,service accountを作成したり,google adminの方でservice accountを登録したりできます. (変に手順飛ばすと詰まるよ)

コードをみる

今回は具体的なコードをみて使い方を確かめたいと思います.if err != nil {}的なのとコメントは省略してます.

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"

    "golang.org/x/net/context"
    "golang.org/x/oauth2/google"

    admin "google.golang.org/api/admin/directory/v1"
    "google.golang.org/api/option"
)


var ServiceAccountFilePath = "private_key_file.json"

var UsersJson = "./users.json"

var AdminUser = "example@aaa.com"

func CreateDirectoryService() (*admin.Service, error) {
    ctx := context.Background()

    jsonCredentials, _ := ioutil.ReadFile(ServiceAccountFilePath)

    config, _ := google.JWTConfigFromJSON(jsonCredentials, admin.AdminDirectoryUserScope)
    
    config.Subject = AdminUser

    ts := config.TokenSource(ctx)

    srv, _ := admin.NewService(ctx, option.WithTokenSource(ts))
    
    return srv, nil
}

func main() {
    service, _ := CreateDirectoryService()

    file, _ := ioutil.ReadFile("./users.json")
    var users []admin.User
    json.Unmarshal(file, &users)

    for _, user := range users {
        service.Users.Insert(&user).Do()
    }
}

importするやつと,CreateDirectoryService()はここから丸コピです.

developers.google.com

ServiceAccountFilePath

サービスアカウントを作成後,それに割り当てる鍵を作成する手順があると思います. そのときに生成された秘密鍵ファイルをここで指定しています. 秘密鍵ファイルには鍵以外にも認証に必要な情報がまとめて入っています. このファイルが流出するとサービスアカウントがほぼ自由に使えてしまうので取り扱いには注意する必要があります. (具体的にはこのファイルとadminのアカウント名がセットになると使えてしまいます.そのはずです.)

UsersJson

下記のような,作成したいgoogleアカウントの情報が入ったJsonを指定します.

[
    {
        "name": {
            "familyName": "test",
            "givenName": "matac"
        },
        "password": "hogehoge",
        "primaryEmail": "matactest@example.com"
    },
    {
        "name": {
            "familyName": "test2",
            "givenName": "matac"
        },
        "password": "hogehoge",
        "primaryEmail": "matactest2@example.com"
    }
]

APIリファレンスを参照して生成するなり手書きするなり?します.

developers.google.com

AdminUser

developer consoleで指定したユーザーをここで指定してあげます.(基本的には自分のアカウント) consoleで何も指定していなくても,google adminのsuper admin accountは使えるみたいです. (それ以下の権限の場合は未検証)

CreateDirectoryService()

鍵ファイルを利用して,APIのメソッドをたくさん抱えた*admin.Service型を返します. APIを叩くにはこいつを使います. 関数の処理としては,鍵ファイルのJsonからJWTという証明書付きの改竄不可能なJsonを生成し,設定を入力してServiceを生成している感じです. JWTを生成するときに,admin.AdminDirectoryUserScopeスコープを指定していますが, サービスアカウントを使用する時は,ここでの指定とgoogle admin consoleでのスコープの追加が必要になります.(Guidesの手順にあります.)

main()

admin.Serviceインスタンスを生成し,作成したいaccountの情報が記述されたJsonを開いて[]admin.Userのusersを作成しています. 実際にAPIを叩いている部分はservice.Users.Insert(&user).Do()で,Insertメソッドを使用して新規アカウントを作成しています. リファレンスを見れば他にどんなメソッドがあるかわかります.

developers.google.com

利点

GuidesのQuickstartsをやるとわかりますが,途中で認証windowが出てくると思います. それが出てくると自動化する場合などに困ります. そこで鍵ファイルを使用して認証するservice accountを使うことで,認証windowを出さずに処理を完了することができるようになります. また,引き継ぎの際にもservice accountに処理を任せていれば属人化が軽減されるとかなんとか.

あとがき

なんか間違ってたら,遠慮なくコメントに書いてもらえると喜びます. Golangはこんな書き方しない!とかでも.