はじめに
ポインコ兄と高橋です。 今回は AWS SDK for Python (Boto3) で S3 のオブジェクトの所有者情報を取得する際に気をつけたいことをまとめました。
AWS SDK for Python (Boto3) とは
簡単に言うと、 Python で AWS の各種サービスを簡単に扱えるようにするライブラリです。 aws.amazon.com
S3 のオブジェクトの所有者情報とは
マネコン上でのこれのことです。 業務で所有者情報を調べる必要があり、全てをマネコン上で確認するのは気が遠くなるため、スクリプトを組むことにしました。
また、バケットをパブリックにしてAWSアカウントを持っていない人がオブジェクトをアップロードすると、所有者は「65a011a29cdf8ec533ec3d1ccaae921c」となります。これは匿名ユーザーのことです。 docs.aws.amazon.com
気をつけること その1
Boto3 のドキュメントを見ると、どうやら所有者情報は owner で取れそう... ということで、「ObjectSummary」クラスを使って取得してみると「None」になってしまいました。 なぜなのかと思って調べてみると既に Issue として登録されているようで、現状この方法ではダメそうなことが分かりました。 boto3.amazonaws.com github.com
気をつけること その2
では「ObjectAcl」クラスにも同じ owner がいるので、もしかしてこっちなら... と試してみたところ今度は取得できました。 ...が、所有者が匿名ユーザーのオブジェクトについては、ウォッチで値を確認すると「ClientError: An error occurred (AccessDenied) when calling the GetObjectAcl operation: Access Denied」となり、 Boto3 が古いのかな? とか (最新だった)、権限が足りてないのかな? (Admin だった) などと調べましたが解決せずでした。。
どうしたのか
「Bucket」クラスの objects.filter() を利用することにしました。 filter() の戻りの型は「ObjectSummary」となるんですが、こちらではちゃんと取得できるようです。 以下のサンプルコードでは、対象バケット一覧から全オブジェクトのうち、匿名ユーザーのみを抽出しています。
def s3_get_anonymous_objlist(s3BucketList): objList = [["AccountID", "BucketName", "Key", "owner"]] s3r = boto3.resource('s3') for s3BucketName in s3BucketList: for obj in s3r.Bucket(s3BucketName).objects.filter(): if obj.owner['ID'] == '65a011a29cdf8ec533ec3d1ccaae921c': tmp = [str(id_info['Account']), str(s3BucketName), str(obj.key), str(obj.owner)] objList.append(tmp) return objList
匿名ユーザーの場合は owner の「DisplayName」キーは存在しなくなるため、その点は注意です。
気をつけること その3 (おまけ)
オブジェクトの所有者を匿名ユーザーにするにはバケットをパブリックにする必要がありますが、AWS 非推奨のためか、マネコン上でパブリックにすることはできません。 そのため、もし所有者が匿名ユーザーのオブジェクトについてのテストなどをしたい場合には CLI を使いましょう。 docs.aws.amazon.com docs.aws.amazon.com
あとがき
まとめると「オブジェクトの所有者情報を取得する場合は objects.filter() を使いましょう」という話でした。
オブジェクトの所有者情報を取得する際の一助になれば幸いです。
寒くなってきて鍋が食べたい兄でした。
それではまた、ごきげんよう。
高橋 悠佑 (ポインコ兄) (執筆記事一覧)
健康志向です