bucket-notification.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Minio Go Library for Amazon S3 Compatible Cloud Storage
  3. * Copyright 2015-2017 Minio, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package minio
  18. import (
  19. "encoding/xml"
  20. "reflect"
  21. )
  22. // NotificationEventType is a S3 notification event associated to the bucket notification configuration
  23. type NotificationEventType string
  24. // The role of all event types are described in :
  25. // http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-event-types-and-destinations
  26. const (
  27. ObjectCreatedAll NotificationEventType = "s3:ObjectCreated:*"
  28. ObjectCreatedPut = "s3:ObjectCreated:Put"
  29. ObjectCreatedPost = "s3:ObjectCreated:Post"
  30. ObjectCreatedCopy = "s3:ObjectCreated:Copy"
  31. ObjectCreatedCompleteMultipartUpload = "s3:ObjectCreated:CompleteMultipartUpload"
  32. ObjectAccessedGet = "s3:ObjectAccessed:Get"
  33. ObjectAccessedHead = "s3:ObjectAccessed:Head"
  34. ObjectAccessedAll = "s3:ObjectAccessed:*"
  35. ObjectRemovedAll = "s3:ObjectRemoved:*"
  36. ObjectRemovedDelete = "s3:ObjectRemoved:Delete"
  37. ObjectRemovedDeleteMarkerCreated = "s3:ObjectRemoved:DeleteMarkerCreated"
  38. ObjectReducedRedundancyLostObject = "s3:ReducedRedundancyLostObject"
  39. )
  40. // FilterRule - child of S3Key, a tag in the notification xml which
  41. // carries suffix/prefix filters
  42. type FilterRule struct {
  43. Name string `xml:"Name"`
  44. Value string `xml:"Value"`
  45. }
  46. // S3Key - child of Filter, a tag in the notification xml which
  47. // carries suffix/prefix filters
  48. type S3Key struct {
  49. FilterRules []FilterRule `xml:"FilterRule,omitempty"`
  50. }
  51. // Filter - a tag in the notification xml structure which carries
  52. // suffix/prefix filters
  53. type Filter struct {
  54. S3Key S3Key `xml:"S3Key,omitempty"`
  55. }
  56. // Arn - holds ARN information that will be sent to the web service,
  57. // ARN desciption can be found in http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
  58. type Arn struct {
  59. Partition string
  60. Service string
  61. Region string
  62. AccountID string
  63. Resource string
  64. }
  65. // NewArn creates new ARN based on the given partition, service, region, account id and resource
  66. func NewArn(partition, service, region, accountID, resource string) Arn {
  67. return Arn{Partition: partition,
  68. Service: service,
  69. Region: region,
  70. AccountID: accountID,
  71. Resource: resource}
  72. }
  73. // Return the string format of the ARN
  74. func (arn Arn) String() string {
  75. return "arn:" + arn.Partition + ":" + arn.Service + ":" + arn.Region + ":" + arn.AccountID + ":" + arn.Resource
  76. }
  77. // NotificationConfig - represents one single notification configuration
  78. // such as topic, queue or lambda configuration.
  79. type NotificationConfig struct {
  80. ID string `xml:"Id,omitempty"`
  81. Arn Arn `xml:"-"`
  82. Events []NotificationEventType `xml:"Event"`
  83. Filter *Filter `xml:"Filter,omitempty"`
  84. }
  85. // NewNotificationConfig creates one notification config and sets the given ARN
  86. func NewNotificationConfig(arn Arn) NotificationConfig {
  87. return NotificationConfig{Arn: arn}
  88. }
  89. // AddEvents adds one event to the current notification config
  90. func (t *NotificationConfig) AddEvents(events ...NotificationEventType) {
  91. t.Events = append(t.Events, events...)
  92. }
  93. // AddFilterSuffix sets the suffix configuration to the current notification config
  94. func (t *NotificationConfig) AddFilterSuffix(suffix string) {
  95. if t.Filter == nil {
  96. t.Filter = &Filter{}
  97. }
  98. newFilterRule := FilterRule{Name: "suffix", Value: suffix}
  99. // Replace any suffix rule if existing and add to the list otherwise
  100. for index := range t.Filter.S3Key.FilterRules {
  101. if t.Filter.S3Key.FilterRules[index].Name == "suffix" {
  102. t.Filter.S3Key.FilterRules[index] = newFilterRule
  103. return
  104. }
  105. }
  106. t.Filter.S3Key.FilterRules = append(t.Filter.S3Key.FilterRules, newFilterRule)
  107. }
  108. // AddFilterPrefix sets the prefix configuration to the current notification config
  109. func (t *NotificationConfig) AddFilterPrefix(prefix string) {
  110. if t.Filter == nil {
  111. t.Filter = &Filter{}
  112. }
  113. newFilterRule := FilterRule{Name: "prefix", Value: prefix}
  114. // Replace any prefix rule if existing and add to the list otherwise
  115. for index := range t.Filter.S3Key.FilterRules {
  116. if t.Filter.S3Key.FilterRules[index].Name == "prefix" {
  117. t.Filter.S3Key.FilterRules[index] = newFilterRule
  118. return
  119. }
  120. }
  121. t.Filter.S3Key.FilterRules = append(t.Filter.S3Key.FilterRules, newFilterRule)
  122. }
  123. // TopicConfig carries one single topic notification configuration
  124. type TopicConfig struct {
  125. NotificationConfig
  126. Topic string `xml:"Topic"`
  127. }
  128. // QueueConfig carries one single queue notification configuration
  129. type QueueConfig struct {
  130. NotificationConfig
  131. Queue string `xml:"Queue"`
  132. }
  133. // LambdaConfig carries one single cloudfunction notification configuration
  134. type LambdaConfig struct {
  135. NotificationConfig
  136. Lambda string `xml:"CloudFunction"`
  137. }
  138. // BucketNotification - the struct that represents the whole XML to be sent to the web service
  139. type BucketNotification struct {
  140. XMLName xml.Name `xml:"NotificationConfiguration"`
  141. LambdaConfigs []LambdaConfig `xml:"CloudFunctionConfiguration"`
  142. TopicConfigs []TopicConfig `xml:"TopicConfiguration"`
  143. QueueConfigs []QueueConfig `xml:"QueueConfiguration"`
  144. }
  145. // AddTopic adds a given topic config to the general bucket notification config
  146. func (b *BucketNotification) AddTopic(topicConfig NotificationConfig) {
  147. newTopicConfig := TopicConfig{NotificationConfig: topicConfig, Topic: topicConfig.Arn.String()}
  148. for _, n := range b.TopicConfigs {
  149. if reflect.DeepEqual(n, newTopicConfig) {
  150. // Avoid adding duplicated entry
  151. return
  152. }
  153. }
  154. b.TopicConfigs = append(b.TopicConfigs, newTopicConfig)
  155. }
  156. // AddQueue adds a given queue config to the general bucket notification config
  157. func (b *BucketNotification) AddQueue(queueConfig NotificationConfig) {
  158. newQueueConfig := QueueConfig{NotificationConfig: queueConfig, Queue: queueConfig.Arn.String()}
  159. for _, n := range b.QueueConfigs {
  160. if reflect.DeepEqual(n, newQueueConfig) {
  161. // Avoid adding duplicated entry
  162. return
  163. }
  164. }
  165. b.QueueConfigs = append(b.QueueConfigs, newQueueConfig)
  166. }
  167. // AddLambda adds a given lambda config to the general bucket notification config
  168. func (b *BucketNotification) AddLambda(lambdaConfig NotificationConfig) {
  169. newLambdaConfig := LambdaConfig{NotificationConfig: lambdaConfig, Lambda: lambdaConfig.Arn.String()}
  170. for _, n := range b.LambdaConfigs {
  171. if reflect.DeepEqual(n, newLambdaConfig) {
  172. // Avoid adding duplicated entry
  173. return
  174. }
  175. }
  176. b.LambdaConfigs = append(b.LambdaConfigs, newLambdaConfig)
  177. }
  178. // RemoveTopicByArn removes all topic configurations that match the exact specified ARN
  179. func (b *BucketNotification) RemoveTopicByArn(arn Arn) {
  180. var topics []TopicConfig
  181. for _, topic := range b.TopicConfigs {
  182. if topic.Topic != arn.String() {
  183. topics = append(topics, topic)
  184. }
  185. }
  186. b.TopicConfigs = topics
  187. }
  188. // RemoveQueueByArn removes all queue configurations that match the exact specified ARN
  189. func (b *BucketNotification) RemoveQueueByArn(arn Arn) {
  190. var queues []QueueConfig
  191. for _, queue := range b.QueueConfigs {
  192. if queue.Queue != arn.String() {
  193. queues = append(queues, queue)
  194. }
  195. }
  196. b.QueueConfigs = queues
  197. }
  198. // RemoveLambdaByArn removes all lambda configurations that match the exact specified ARN
  199. func (b *BucketNotification) RemoveLambdaByArn(arn Arn) {
  200. var lambdas []LambdaConfig
  201. for _, lambda := range b.LambdaConfigs {
  202. if lambda.Lambda != arn.String() {
  203. lambdas = append(lambdas, lambda)
  204. }
  205. }
  206. b.LambdaConfigs = lambdas
  207. }