yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/google/s3object.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Copyright 2019 Yunion 16 17 // 18 // Licensed under the Apache License, Version 2.0 (the "License"); 19 // you may not use this file except in compliance with the License. 20 // You may obtain a copy of the License at 21 // 22 // http://www.apache.org/licenses/LICENSE-2.0 23 // 24 // Unless required by applicable law or agreed to in writing, software 25 // distributed under the License is distributed on an "AS IS" BASIS, 26 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 27 // See the License for the specific language governing permissions and 28 // limitations under the License. 29 30 package google 31 32 import ( 33 "context" 34 "fmt" 35 "net/http" 36 "net/url" 37 "strings" 38 "time" 39 40 "cloud.google.com/go/storage" 41 42 "yunion.io/x/jsonutils" 43 "yunion.io/x/log" 44 "yunion.io/x/pkg/errors" 45 46 "yunion.io/x/cloudmux/pkg/cloudprovider" 47 ) 48 49 type SBucketObjects struct { 50 Prefixes []string 51 Items []SObject 52 NextPageToken string 53 } 54 55 type SObject struct { 56 bucket *SBucket 57 58 Id string 59 Name string 60 SelfLink string 61 MediaLink string 62 Bucket string 63 Generation string 64 Metageneration string 65 ContentType string 66 ContentEncoding string 67 ContentDisposition string 68 ContentLanguage string 69 CacheControl string 70 StorageClass string 71 Size int64 72 Md5Hash string 73 Metadata map[string]string 74 Crc32c string 75 Etag string 76 TimeCreated time.Time 77 Updated time.Time 78 TimeStorageClassUpdated time.Time 79 } 80 81 func (region *SRegion) GetObjects(bucket string, prefix string, nextPageToken string, delimiter string, maxCount int) (*SBucketObjects, error) { 82 if maxCount <= 0 { 83 maxCount = 20 84 } 85 resource := fmt.Sprintf("b/%s/o", bucket) 86 params := map[string]string{"maxResults": fmt.Sprintf("%d", maxCount)} 87 if len(prefix) > 0 { 88 params["prefix"] = prefix 89 } 90 if len(delimiter) > 0 { 91 params["delimiter"] = delimiter 92 } 93 if len(nextPageToken) > 0 { 94 params["pageToken"] = nextPageToken 95 } 96 objs := SBucketObjects{} 97 resp, err := region.client.storageList(resource, params) 98 if err != nil { 99 return nil, errors.Wrap(err, "storageList") 100 } 101 err = resp.Unmarshal(&objs) 102 if err != nil { 103 return nil, errors.Wrap(err, "Unmarshal") 104 } 105 return &objs, nil 106 } 107 108 func (region *SRegion) ConvertAcl(acls []GCSAcl) cloudprovider.TBucketACLType { 109 ret := cloudprovider.ACLPrivate 110 for _, acl := range acls { 111 if acl.Entity == string(storage.AllUsers) { 112 if acl.Role == string(storage.RoleOwner) || acl.Role == string(storage.RoleWriter) { 113 ret = cloudprovider.ACLPublicReadWrite 114 } 115 if acl.Role == string(storage.RoleReader) && ret != cloudprovider.ACLPublicReadWrite { 116 ret = cloudprovider.ACLPublicRead 117 } 118 } 119 if !(ret == cloudprovider.ACLPublicRead || ret == cloudprovider.ACLPublicReadWrite) && acl.Entity == string(storage.AllAuthenticatedUsers) { 120 ret = cloudprovider.ACLAuthRead 121 } 122 } 123 return ret 124 } 125 126 func (o *SObject) GetAcl() cloudprovider.TBucketACLType { 127 if strings.HasSuffix(o.Name, "/") { 128 return cloudprovider.ACLPrivate 129 } 130 acls, err := o.bucket.region.GetObjectAcl(o.bucket.Name, o.Name) 131 if err != nil { 132 log.Errorf("failed to get object %s acls error: %v", o.Name, err) 133 return cloudprovider.ACLUnknown 134 } 135 return o.bucket.region.ConvertAcl(acls) 136 } 137 138 func (o *SObject) SetAcl(acl cloudprovider.TBucketACLType) error { 139 return o.bucket.region.SetObjectAcl(o.bucket.Name, o.Name, acl) 140 } 141 142 func (o *SObject) GetIBucket() cloudprovider.ICloudBucket { 143 return o.bucket 144 } 145 146 func (o *SObject) GetKey() string { 147 return o.Name 148 } 149 150 func (o *SObject) GetSizeBytes() int64 { 151 return o.Size 152 } 153 154 func (o *SObject) GetLastModified() time.Time { 155 return o.Updated 156 } 157 158 func (o *SObject) GetStorageClass() string { 159 return o.StorageClass 160 } 161 162 func (o *SObject) GetETag() string { 163 return o.Etag 164 } 165 166 func (o *SObject) GetMeta() http.Header { 167 meta := http.Header{} 168 for k, v := range o.Metadata { 169 meta.Set(k, v) 170 } 171 for k, v := range map[string]string{ 172 cloudprovider.META_HEADER_CONTENT_TYPE: o.ContentType, 173 cloudprovider.META_HEADER_CONTENT_ENCODING: o.ContentEncoding, 174 cloudprovider.META_HEADER_CONTENT_DISPOSITION: o.ContentDisposition, 175 cloudprovider.META_HEADER_CONTENT_LANGUAGE: o.ContentLanguage, 176 cloudprovider.META_HEADER_CACHE_CONTROL: o.CacheControl, 177 } { 178 meta.Set(k, v) 179 } 180 return meta 181 } 182 183 func (region *SRegion) SetObjectMeta(bucket, object string, meta http.Header) error { 184 body := map[string]string{} 185 for k := range meta { 186 switch k { 187 case cloudprovider.META_HEADER_CONTENT_TYPE: 188 body["contentType"] = meta.Get(k) 189 case cloudprovider.META_HEADER_CONTENT_ENCODING: 190 body["contentEncoding"] = meta.Get(k) 191 case cloudprovider.META_HEADER_CONTENT_DISPOSITION: 192 body["contentDisposition"] = meta.Get(k) 193 case cloudprovider.META_HEADER_CONTENT_LANGUAGE: 194 body["contentLanguage"] = meta.Get(k) 195 case cloudprovider.META_HEADER_CACHE_CONTROL: 196 body["cacheControl"] = meta.Get(k) 197 default: 198 body[fmt.Sprintf("metadata.%s", k)] = meta.Get(k) 199 } 200 } 201 resource := fmt.Sprintf("b/%s/o/%s", bucket, url.PathEscape(object)) 202 return region.StoragePut(resource, jsonutils.Marshal(body), nil) 203 } 204 205 func (o *SObject) SetMeta(ctx context.Context, meta http.Header) error { 206 return o.bucket.region.SetObjectMeta(o.bucket.Name, o.Name, meta) 207 }