IBM Cloud Object Storage (ICOS) のオブジェクト単位でパブリック公開する


# アップロード時に設定

## curl

```shell:createPublicCosObject.sh
#!/bin/bash

export BUCKET_NAME=khayama-icos
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud
export ACCESS_TOKEN=$(ibmcloud iam oauth-tokens --output JSON | jq -r '.iam_token')
export OBJECT_NAME=index.html

# ibmcloud cos create-bucket --bucket $BUCKET_NAME --region jp-tok --class SMART
# ibmcloud cos list-buckets

curl -X PUT "https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME" \
-H "x-amz-acl: public-read" \
-H "Authorization: $ACCESS_TOKEN" \
-H "Content-Type: text/html" -T $OBJECT_NAME

# open https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME
```

## aws cli

```shell

export BUCKET_NAME=khayama-icos
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud
export OBJECT_NAME=index.html

aws --endpoint-url https://$ENDPOINT s3api put-object \
--bucket $BUCKET_NAME \
--key $OBJECT_NAME \
--acl public-read \
--content-type text/html \
--body $OBJECT_NAME

# open https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME
```

# 既存オブジェクトに設定
## curl

```shell:enablePublicCosObject.sh
#!/bin/bash

export BUCKET_NAME=khayama-icos
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud
export ACCESS_TOKEN=$(ibmcloud iam oauth-tokens --output JSON | jq -r '.iam_token')
export OBJECT_NAME=index.html

curl -X PUT "https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME?acl" \
-H "x-amz-acl: public-read" \
-H "Authorization: $ACCESS_TOKEN"

# コンテンツタイプを指定してしないと、単なるファイルダウンロードとなってしまうため
curl -X PUT "https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME" \
-H "x-amz-copy-source: /$BUCKET_NAME/$OBJECT_NAME" \
-H "x-amz-metadata-directive: REPLACE" \
-H "Authorization: $ACCESS_TOKEN" \
-H "Content-Type: text/html"

# open https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME
```

## aws cli
```shell

export BUCKET_NAME=khayama-icos
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud
export OBJECT_NAME=index.html

aws --endpoint-url https://$ENDPOINT s3api put-object-acl \
--bucket $BUCKET_NAME \
--key $OBJECT_NAME \
--acl public-read

# コンテンツタイプを指定してしないと、単なるファイルダウンロードとなってしまうため
aws --endpoint-url https://$ENDPOINT s3api copy-object \
--bucket $BUCKET_NAME \
--copy-source $BUCKET_NAME/$OBJECT_NAME \
--key $OBJECT_NAME \
--metadata-directive "REPLACE" \
--content-type text/html 

# open https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME
```

# パブリック公開されているかの確認
## curl
```shell:checkPublicCosObject.sh
#!/bin/bash

export BUCKET_NAME=khayama-icos
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud
export ACCESS_TOKEN=$(ibmcloud iam oauth-tokens --output JSON | jq -r '.iam_token')

export xml=`curl -sL "https://$BUCKET_NAME.$ENDPOINT" -H "Authorization: $ACCESS_TOKEN" | xmllint --format -`
export obj_num=`echo "$xml" | xpath "count(/ListBucketResult/Contents/Key)" 2>/dev/null`

for ((i=1; i<=$obj_num; i++))
do
  obj=`echo "$xml" | xpath "/ListBucketResult/Contents[$i]/Key/text()" 2>/dev/null`
  echo $obj
  curl -sL -X GET "https://$BUCKET_NAME.$ENDPOINT/$obj?acl" -H "Authorization: $ACCESS_TOKEN" \
  | xmllint --format - | xpath "/AccessControlPolicy/AccessControlList/Grant/Permission/text()" 2>/dev/null
  echo
done
```

```
ibmcloud_logo.png
FULL_CONTROL
index.html
READ
```

## aws cli
```shell

export BUCKET_NAME=khayama-icos
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud
export OBJECT_NAME=index.html

aws --endpoint-url https://$ENDPOINT s3api get-object-acl \
--bucket $BUCKET_NAME \
--key $OBJECT_NAME
```

```
{
    "Owner": {
        "DisplayName": "74c0783c-c36b-4cc0-80ff-ddf97c0e3d8f",
        "ID": "74c0783c-c36b-4cc0-80ff-ddf97c0e3d8f"
    },
    "Grants": [
        {
            "Grantee": {
                "Type": "Group",
                "URI": "http://acs.amazonaws.com/groups/global/AllUsers"
            },
            "Permission": "READ"
        },
        {
            "Grantee": {
                "DisplayName": "74c0783c-c36b-4cc0-80ff-ddf97c0e3d8f",
                "ID": "74c0783c-c36b-4cc0-80ff-ddf97c0e3d8f",
                "Type": "CanonicalUser"
            },
            "Permission": "FULL_CONTROL"
        }
    ]
}
```

# パブリック公開をやめる
## curl
```shell:disablePublicCosObject.sh
#!/bin/bash

export BUCKET_NAME=khayama-icos
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud
export ACCESS_TOKEN=$(ibmcloud iam oauth-tokens --output JSON | jq -r '.iam_token')
export OBJECT_NAME=index.html

curl -X PUT "https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME?acl" \
-H "x-amz-acl: private" \
-H "Authorization: $ACCESS_TOKEN"

# open https://$BUCKET_NAME.$ENDPOINT/$OBJECT_NAME
```

## aws cli
```shell

export BUCKET_NAME=khayama-icos
export ENDPOINT=s3.jp-tok.cloud-object-storage.appdomain.cloud
export OBJECT_NAME=index.html

aws --endpoint-url https://$ENDPOINT s3api put-object-acl \
--bucket $BUCKET_NAME \
--key $OBJECT_NAME \
--acl private
```

# 参考

- [Allowing public access on individual objects](https://cloud.ibm.com/docs/cloud-object-storage/iam?topic=cloud-object-storage-iam-public-access&locale=en#public-access-object)
- [Content-Typeの一覧 - Qiita](https://qiita.com/AkihiroTakamura/items/b93fbe511465f52bffaa)
- [Use the AWS CLI](https://cloud.ibm.com/docs/cloud-object-storage/iam?topic=cloud-object-storage-aws-cli&locale=en)
- [Access Control List (ACL) Overview - Amazon Simple Storage Service](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL)
- [【小ネタ】S3オブジェクトのContent-TypeをAWS CLIで一括で変更する | Developers.IO](https://dev.classmethod.jp/articles/change-content-type-by-aws-cli/)