bucket.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  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. package compute
  15. import (
  16. "net/http"
  17. "reflect"
  18. "time"
  19. "yunion.io/x/cloudmux/pkg/apis/compute"
  20. "yunion.io/x/cloudmux/pkg/cloudprovider"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/gotypes"
  23. "yunion.io/x/pkg/util/regutils"
  24. "yunion.io/x/pkg/utils"
  25. "yunion.io/x/onecloud/pkg/apis"
  26. "yunion.io/x/onecloud/pkg/httperrors"
  27. )
  28. const (
  29. BUCKET_OPS_STATS_CHANGE = "stats_change"
  30. BUCKET_STATUS_START_CREATE = "start_create"
  31. BUCKET_STATUS_CREATING = "creating"
  32. BUCKET_STATUS_READY = compute.BUCKET_STATUS_READY
  33. BUCKET_STATUS_CREATE_FAIL = "create_fail"
  34. BUCKET_STATUS_START_DELETE = "start_delete"
  35. BUCKET_STATUS_DELETING = "deleting"
  36. BUCKET_STATUS_DELETED = "deleted"
  37. BUCKET_STATUS_DELETE_FAIL = "delete_fail"
  38. BUCKET_STATUS_UNKNOWN = "unknown"
  39. BUCKET_UPLOAD_OBJECT_KEY_HEADER = "X-Yunion-Bucket-Upload-Key"
  40. BUCKET_UPLOAD_OBJECT_ACL_HEADER = "X-Yunion-Bucket-Upload-Acl"
  41. BUCKET_UPLOAD_OBJECT_STORAGECLASS_HEADER = "X-Yunion-Bucket-Upload-Storageclass"
  42. )
  43. type BucketCreateInput struct {
  44. apis.SharableVirtualResourceCreateInput
  45. CloudregionResourceInput
  46. CloudproviderResourceInput
  47. StorageClass string `json:"storage_class"`
  48. EnablePerfMon *bool `json:"enable_perf_mon"`
  49. }
  50. type BucketDetails struct {
  51. apis.SharableVirtualResourceDetails
  52. ManagedResourceInfo
  53. CloudregionResourceInfo
  54. SBucket
  55. // 访问URL列表
  56. AccessUrls []cloudprovider.SBucketAccessUrl `json:"access_urls"`
  57. }
  58. func (bucket BucketDetails) GetMetricTags() map[string]string {
  59. ret := map[string]string{
  60. "id": bucket.Id,
  61. "brand": bucket.Brand,
  62. "cloudregion": bucket.Cloudregion,
  63. "cloudregion_id": bucket.CloudregionId,
  64. "domain_id": bucket.DomainId,
  65. "oss_id": bucket.Id,
  66. "oss_name": bucket.Name,
  67. "project_domain": bucket.ProjectDomain,
  68. "region_ext_id": bucket.RegionExtId,
  69. "status": bucket.Status,
  70. "tenant": bucket.Project,
  71. "tenant_id": bucket.ProjectId,
  72. "account": bucket.Account,
  73. "account_id": bucket.AccountId,
  74. "external_id": bucket.ExternalId,
  75. }
  76. return AppendMetricTags(ret, bucket.MetadataResourceInfo, bucket.ProjectizedResourceInfo)
  77. }
  78. func (bucket BucketDetails) GetMetricPairs() map[string]string {
  79. ret := map[string]string{}
  80. return ret
  81. }
  82. type BucketObjectsActionInput struct {
  83. Key []string `json:"key"`
  84. }
  85. type BucketAclInput struct {
  86. BucketObjectsActionInput
  87. Acl cloudprovider.TBucketACLType
  88. }
  89. func (input *BucketAclInput) Validate() error {
  90. switch input.Acl {
  91. case cloudprovider.ACLPrivate, cloudprovider.ACLAuthRead, cloudprovider.ACLPublicRead, cloudprovider.ACLPublicReadWrite:
  92. // do nothing
  93. default:
  94. return errors.Wrap(httperrors.ErrInputParameter, "acl")
  95. }
  96. return nil
  97. }
  98. type BucketMetadataInput struct {
  99. BucketObjectsActionInput
  100. Metadata http.Header
  101. }
  102. func (input *BucketMetadataInput) Validate() error {
  103. if len(input.Key) == 0 {
  104. return errors.Wrap(httperrors.ErrEmptyRequest, "key")
  105. }
  106. if len(input.Metadata) == 0 {
  107. return errors.Wrap(httperrors.ErrEmptyRequest, "metadata")
  108. }
  109. return nil
  110. }
  111. type BucketListInput struct {
  112. apis.SharableVirtualResourceListInput
  113. apis.ExternalizedResourceBaseListInput
  114. ManagedResourceListInput
  115. RegionalFilterListInput
  116. // STORAGE_CLASS
  117. StorageClass []string `json:"storage_class"`
  118. // 位置
  119. Location []string `json:"location"`
  120. // ACL
  121. Acl []string `json:"acl"`
  122. }
  123. type BucketSyncstatusInput struct {
  124. }
  125. type BucketUpdateInput struct {
  126. apis.SharableVirtualResourceBaseUpdateInput
  127. EnablePerfMon *bool `json:"enable_perf_mon"`
  128. }
  129. type BucketPerformTempUrlInput struct {
  130. // 访问对象方法
  131. Method string `json:"method"`
  132. // 对象KEY
  133. // required:true
  134. Key string `json:"key"`
  135. // 过期时间,单位秒
  136. ExpireSeconds *int `json:"expire_seconds"`
  137. }
  138. type BucketPerformTempUrlOutput struct {
  139. // 生成的临时URL
  140. Url string `json:"url"`
  141. }
  142. type BucketPerformMakedirInput struct {
  143. // 目录对象KEY
  144. // required:true
  145. Key string `json:"key"`
  146. }
  147. type BucketPerformDeleteInput struct {
  148. // 待删除对象KEY
  149. // required:true
  150. Keys []string `json:"keys"`
  151. }
  152. type BucketGetAclInput struct {
  153. // 对象KEY
  154. // required:false
  155. Key string `json:"key"`
  156. }
  157. type BucketGetAclOutput struct {
  158. // ACL
  159. Acl string `json:"acl"`
  160. }
  161. type BucketGetObjectsInput struct {
  162. // Prefix
  163. Prefix string `json:"prefix"`
  164. // 是否模拟列举目录模式
  165. Recursive *bool `json:"recursive"`
  166. // 分页标识
  167. PagingMarker string `json:"paging_marker"`
  168. // 最大输出条目数
  169. Limit *int `json:"limit"`
  170. }
  171. type BucketGetObjectsOutput struct {
  172. // 对象列表
  173. Data []cloudprovider.SCloudObject `json:"data"`
  174. // 排序字段,总是key
  175. // example: key
  176. MarkerField string `json:"marker_field"`
  177. // 排序顺序,总是降序
  178. // example: DESC
  179. MarkerOrder string `json:"marker_order"`
  180. // 下一页请求的paging_marker标识
  181. NextMarker string `json:"next_marker"`
  182. }
  183. type BucketWebsiteRoutingRule struct {
  184. ConditionErrorCode string `json:"condition_error_code"`
  185. ConditionPrefix string `json:"condition_prefix"`
  186. RedirectProtocol string `json:"redirect_protocol"`
  187. RedirectReplaceKey string `json:"redirect_replace_key"`
  188. RedirectReplaceKeyPrefix string `json:"redirect_replace_key_prefix"`
  189. }
  190. type BucketWebsiteConf struct {
  191. // 主页
  192. Index string `json:"index"`
  193. // 错误时返回的文档
  194. ErrorDocument string `json:"error_document"`
  195. // http或https
  196. Protocol string `json:"protocol"`
  197. Rules []BucketWebsiteRoutingRule `json:"rules"`
  198. // 访问网站url
  199. Url string `json:"url"`
  200. }
  201. func (input *BucketWebsiteConf) Validate() error {
  202. if len(input.Index) == 0 {
  203. return httperrors.NewMissingParameterError("index")
  204. }
  205. if len(input.ErrorDocument) == 0 {
  206. return httperrors.NewMissingParameterError("error_document")
  207. }
  208. if len(input.Protocol) == 0 {
  209. return httperrors.NewMissingParameterError("protocol")
  210. }
  211. return nil
  212. }
  213. type BucketCORSRule struct {
  214. AllowedMethods []string `json:"allowed_methods"`
  215. // 允许的源站,可以是*
  216. AllowedOrigins []string `json:"allowed_origins"`
  217. AllowedHeaders []string `json:"allowed_headers"`
  218. MaxAgeSeconds int `json:"max_age_seconds"`
  219. ExposeHeaders []string `json:"expose_headers"`
  220. // 规则区别标识
  221. Id string `json:"id"`
  222. }
  223. type BucketCORSRules struct {
  224. Data []BucketCORSRule `json:"data"`
  225. }
  226. type BucketCORSRuleDeleteInput struct {
  227. Id []string `json:"id"`
  228. }
  229. type BucketPolicy struct {
  230. Data []BucketPolicyStatement `json:"data"`
  231. }
  232. type BucketPolicyStatement struct {
  233. // 授权的目标主体
  234. Principal map[string][]string `json:"Principal,omitempty"`
  235. // 授权的行为
  236. Action []string `json:"Action,omitempty"`
  237. // Allow|Deny
  238. Effect string `json:"Effect,omitempty"`
  239. // 被授权的资源地址
  240. Resource []string `json:"Resource,omitempty"`
  241. // 触发授权的条件
  242. Condition map[string]map[string]interface{} `json:"Condition,omitempty"`
  243. // 解析字段,主账号id:子账号id
  244. PrincipalId []string `json:"principal_id"`
  245. // map[主账号id:子账号id]子账号name
  246. PrincipalNames map[string]string `json:"principal_names"`
  247. // Read|ReadWrite|FullControl
  248. CannedAction string `json:"canned_action"`
  249. // 资源路径
  250. ResourcePath []string `json:"resource_path"`
  251. // 根据index 生成
  252. Id string `json:"id"`
  253. }
  254. type BucketPolicyStatementInput struct {
  255. // 主账号id:子账号id
  256. PrincipalId []string `json:"principal_id"`
  257. // Read|ReadWrite|FullControl
  258. CannedAction string `json:"canned_action"`
  259. // Allow|Deny
  260. Effect string `json:"effect"`
  261. // 被授权的资源地址,/*
  262. ResourcePath []string `json:"resource_path"`
  263. // ip 条件
  264. IpEquals []string `json:"ip_equals"`
  265. IpNotEquals []string `json:"ip_not_equals"`
  266. }
  267. func (input *BucketPolicyStatementInput) Validate() error {
  268. cannedAction := []string{"Read", "ReadWrite", "FullControl"}
  269. if !utils.IsInStringArray(input.CannedAction, cannedAction) {
  270. return httperrors.NewInputParameterError("invalid CannedAction %s ", input.CannedAction)
  271. }
  272. if input.Effect != "Allow" && input.Effect != "Deny" {
  273. return httperrors.NewInputParameterError("invalid Effect %s ", input.Effect)
  274. }
  275. for i := range input.IpEquals {
  276. if !regutils.MatchIP4Addr(input.IpEquals[i]) && !regutils.MatchCIDR(input.IpEquals[i]) {
  277. return httperrors.NewInputParameterError("invalid ipv4 %s ", input.IpEquals[i])
  278. }
  279. }
  280. for i := range input.IpNotEquals {
  281. if !regutils.MatchIP4Addr(input.IpNotEquals[i]) && !regutils.MatchCIDR(input.IpNotEquals[i]) {
  282. return httperrors.NewInputParameterError("invalid ipv4 %s ", input.IpNotEquals[i])
  283. }
  284. }
  285. return nil
  286. }
  287. type BucketPolicyDeleteInput struct {
  288. Id []string `json:"id"`
  289. }
  290. func (input *BucketCORSRules) Validate() error {
  291. for i := range input.Data {
  292. if len(input.Data[i].AllowedOrigins) == 0 {
  293. return httperrors.NewMissingParameterError("allowed_origins")
  294. }
  295. if len(input.Data[i].AllowedMethods) == 0 {
  296. return httperrors.NewMissingParameterError("allowed_methods")
  297. }
  298. }
  299. return nil
  300. }
  301. type BucketRefererConf struct {
  302. // Referer Type
  303. // enmu: Black-List, White-List
  304. RefererType string `json:"referer_type"`
  305. // 域名列表
  306. DomainList []string `json:"domain_list"`
  307. // 是否允许空referer 访问
  308. AllowEmptyRefer bool `json:"allow_empty_refer"`
  309. // 是否开启
  310. Enabled bool `json:"enabled"`
  311. }
  312. func (input *BucketRefererConf) Validate() error {
  313. return nil
  314. }
  315. func init() {
  316. gotypes.RegisterSerializable(reflect.TypeOf(&SBackupStorageAccessInfo{}), func() gotypes.ISerializable {
  317. return &SBackupStorageAccessInfo{}
  318. })
  319. }
  320. type BucketProbeResult struct {
  321. UploadTime time.Duration `json:"upload_time"`
  322. DownloadTime time.Duration `json:"download_time"`
  323. DeleteTime time.Duration `json:"delete_time"`
  324. }
  325. func (result BucketProbeResult) UploadDelayMs() float64 {
  326. return float64(result.UploadTime) / float64(time.Millisecond)
  327. }
  328. func (result BucketProbeResult) DownloadDelayMs() float64 {
  329. return float64(result.DownloadTime) / float64(time.Millisecond)
  330. }
  331. func (result BucketProbeResult) DeleteDelayMs() float64 {
  332. return float64(result.DeleteTime) / float64(time.Millisecond)
  333. }
  334. func (result BucketProbeResult) UploadThroughputMbps(sizeMBytes int) float64 {
  335. return float64(sizeMBytes) * 8 / float64(result.UploadTime.Seconds())
  336. }
  337. func (result BucketProbeResult) DownloadThroughputMbps(sizeMBytes int) float64 {
  338. return float64(sizeMBytes) * 8 / float64(result.DownloadTime.Seconds())
  339. }