3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

IBM Cloud Functions を使って IBM Cloud Object Storage (ICOS) オブジェクトの Content-Type を自動修正する

Last updated at Posted at 2020-09-24

概要

ICOS にオブジェクトをアップロードすると、特に何もしなければ Content-Typeapplication/octet-stream に設定され、ただのバイナリ扱いになります。
今回はサーバーレスサービスを使って、アップロードされるオブジェクトの拡張子から適切な Content-Type に自動修正します。
この操作を行うことで、ブラウザからアクセスするときに画像や HTML などが正しく認識され、コンテンツが正しく表示されます。

Content-Type の修正には、「Object operations - Copy an object」(ICOS サーバーサイドでのコピー処理)を活用し、Functions (クライアント)に一度ダウンロードして再アップロードするといった動作はさせません
また、Functions からは ICOS プライベートエンドポイントを経由してオペレーションがおこなえます。

Kobito.gTVsxZ.png

事前準備

CLI プラグインインストール


ibmcloud plugin install cloud-functions
ibmcloud plugin show cloud-functions

CLI ログイン


export REGION="jp-tok"
export RESOURCE_GROUP="khayama-rg"
ibmcloud login -a cloud.ibm.com -r $REGION -g $RESOURCE_GROUP

環境設定


export FN_NAMESPACE="khayama-fn"
export COS_INSTANCE_NAME="khayama-cos" # 既存の ICOS インスタンスを使います

Functions Namespace 設定

namespace を作成してプロパティをセットします。


ibmcloud fn namespace create $FN_NAMESPACE
ibmcloud fn namespace target $FN_NAMESPACE

Functions から ICOS へのアクセスを許可

ICOS の変更通知を受信してトリガーできるように以下の許可設定をおこないます。


ibmcloud iam authorization-policy-create \
functions \
--source-service-instance-name $FN_NAMESPACE \
cloud-object-storage \
--target-service-instance-name $COS_INSTANCE_NAME \
"Notifications Manager" 

Functions ServiceID に Writer 権限を付与

namespace を作成すると、ServiceID (API Key) が自動で発行されます。
Functions では、__OW_IAM_NAMESPACE_API_KEY の環境変数にセットされるので、これを使って他のサービス認証をおこなうことができます。

その ServiceID (API Key) に Writer 権限を付与して Functions からオブジェクトを書き込めるようにします。


export COS_INSTANCE_ID=$(ibmcloud resource service-instance --output JSON $COS_INSTANCE_NAME | jq -r '.[].guid')
echo $COS_INSTANCE_ID

ibmcloud iam service-id-unlock $FN_NAMESPACE -f

ibmcloud iam service-policy-create $FN_NAMESPACE \
      --roles "Writer" \
      --service-name cloud-object-storage \
      --service-instance $COS_INSTANCE_ID 

ibmcloud iam service-id-lock $FN_NAMESPACE -f

GitHub からダウンロード

GitHub にあるファイルをダウンロードします。


git clone https://github.com/khayama/fn-setCosContentType.git
cd fn-setCosContentType

今回の Functions デプロイ用 yaml では以下のように定義しています。
Functions 実行パラメータは、環境変数の値を取得して埋め込む形で定義しています。

setCosContentType.yml
packages:
  setCosContentType:
    version: 1.0
    license: Apache-2.0
    actions:
      setCosContentType:
        version: 1.0
        description: replace with reference content type
        docker: openwhisk/dockerskeleton
        function: setCosContentType.sh
        inputs:

    triggers:
      cos-object-write:
        feed: /whisk.system/cos/changes
        inputs:
          bucket: $MY_BUCKET # The COS bucket must be regional and exist in the same location as the namespace
          event_types: write # https://cloud.ibm.com/docs/openwhisk?topic=openwhisk-pkg_obstorage#pkg_obstorage_ev_ch_ref_trig

    rules:
      cos-object-write-setCosContentType:
        description: Action is triggered by object-write operation
        action: setCosContentType
        trigger: cos-object-write

Functions デプロイ

環境変数セット

以下のように環境変数をセットします。


export MY_BUCKET=khayama-mime

yaml ファイルを指定してデプロイ


ibmcloud fn deploy --manifest setCosContentType.yml
# 削除するには ibmcloud fn undeploy --manifest setCosContentType.yml

動作確認

実際に ICOS にファイルアップロードをおこない、Functions がトリガーされたかは以下の Monitor 画面で確認できます。

  • 1回のオブジェクトアップロードで2回トリガーが起動したことが確認できます。
  • アクションのスクリプト内で、 REF_CONTENT_TYPE と照合し、修正済みかどうかを判断した上で処理が実行されます。
  • そのため、1 度目のアクションで Content-Type が修正され、その書き込みによって 2 度目が起動しますが、処理は実行されず終了します。
  • REF_CONTENT_TYPE に存在しない拡張子については、スクリプト内で何も実行されません。

https://cloud.ibm.com/functions/dashboard
貼り付けた画像_2020_09_24_10_17.png

Content-Type を確認する

AWS CLI を使ってオブジェクトとコンテンツタイプの一覧を確認できます。


export BUCKET_NAME=khayama-mime
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud

for KEY in $(aws --endpoint-url https://$ENDPOINT s3api list-objects \
  --bucket $BUCKET_NAME \
  --query "Contents[].[Key]" \
  --output text)
do
  aws --endpoint-url https://$ENDPOINT s3api head-object \
    --bucket $BUCKET_NAME \
    --key $KEY \
    --query "[\`$KEY\`,ContentType]" \
    --output text
done
result

5MB.zip application/zip
ibmcloud_logo.png       image/png
index.html      text/html

参考

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?