Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/boto/gs/lifecycle.py @ 2:6af9afd405e9 draft
"planemo upload commit 0a63dd5f4d38a1f6944587f52a8cd79874177fc1"
author | shellac |
---|---|
date | Thu, 14 May 2020 14:56:58 -0400 |
parents | 26e78fe6e8c4 |
children |
comparison
equal
deleted
inserted
replaced
1:75ca89e9b81c | 2:6af9afd405e9 |
---|---|
1 # Copyright 2013 Google Inc. | |
2 # | |
3 # Permission is hereby granted, free of charge, to any person obtaining a | |
4 # copy of this software and associated documentation files (the | |
5 # "Software"), to deal in the Software without restriction, including | |
6 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
7 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
8 # persons to whom the Software is furnished to do so, subject to the fol- | |
9 # lowing conditions: | |
10 # | |
11 # The above copyright notice and this permission notice shall be included | |
12 # in all copies or substantial portions of the Software. | |
13 # | |
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
20 # IN THE SOFTWARE. | |
21 | |
22 from boto.exception import InvalidLifecycleConfigError | |
23 | |
24 # Relevant tags for the lifecycle configuration XML document. | |
25 LIFECYCLE_CONFIG = 'LifecycleConfiguration' | |
26 RULE = 'Rule' | |
27 ACTION = 'Action' | |
28 DELETE = 'Delete' | |
29 SET_STORAGE_CLASS = 'SetStorageClass' | |
30 CONDITION = 'Condition' | |
31 AGE = 'Age' | |
32 CREATED_BEFORE = 'CreatedBefore' | |
33 NUM_NEWER_VERSIONS = 'NumberOfNewerVersions' | |
34 IS_LIVE = 'IsLive' | |
35 MATCHES_STORAGE_CLASS = 'MatchesStorageClass' | |
36 | |
37 # List of all action elements. | |
38 LEGAL_ACTIONS = [DELETE, SET_STORAGE_CLASS] | |
39 # List of all condition elements. | |
40 LEGAL_CONDITIONS = [AGE, CREATED_BEFORE, NUM_NEWER_VERSIONS, IS_LIVE, | |
41 MATCHES_STORAGE_CLASS] | |
42 # List of conditions elements that may be repeated. | |
43 LEGAL_REPEATABLE_CONDITIONS = [MATCHES_STORAGE_CLASS] | |
44 | |
45 class Rule(object): | |
46 """ | |
47 A lifecycle rule for a bucket. | |
48 | |
49 :ivar action: Action to be taken. | |
50 | |
51 :ivar action_text: The text value for the specified action, if any. | |
52 | |
53 :ivar conditions: A dictionary of conditions that specify when the action | |
54 should be taken. Each item in the dictionary represents the name and | |
55 value (or a list of multiple values, if applicable) of a condition. | |
56 """ | |
57 | |
58 def __init__(self, action=None, action_text=None, conditions=None): | |
59 self.action = action | |
60 self.action_text = action_text | |
61 self.conditions = conditions or {} | |
62 | |
63 # Name of the current enclosing tag (used to validate the schema). | |
64 self.current_tag = RULE | |
65 | |
66 def validateStartTag(self, tag, parent): | |
67 """Verify parent of the start tag.""" | |
68 if self.current_tag != parent: | |
69 raise InvalidLifecycleConfigError( | |
70 'Invalid tag %s found inside %s tag' % (tag, self.current_tag)) | |
71 | |
72 def validateEndTag(self, tag): | |
73 """Verify end tag against the start tag.""" | |
74 if tag != self.current_tag: | |
75 raise InvalidLifecycleConfigError( | |
76 'Mismatched start and end tags (%s/%s)' % | |
77 (self.current_tag, tag)) | |
78 | |
79 def startElement(self, name, attrs, connection): | |
80 if name == ACTION: | |
81 self.validateStartTag(name, RULE) | |
82 elif name in LEGAL_ACTIONS: | |
83 self.validateStartTag(name, ACTION) | |
84 # Verify there is only one action tag in the rule. | |
85 if self.action is not None: | |
86 raise InvalidLifecycleConfigError( | |
87 'Only one action tag is allowed in each rule') | |
88 self.action = name | |
89 elif name == CONDITION: | |
90 self.validateStartTag(name, RULE) | |
91 elif name in LEGAL_CONDITIONS: | |
92 self.validateStartTag(name, CONDITION) | |
93 # Verify there is no duplicate conditions. | |
94 if (name in self.conditions and | |
95 name not in LEGAL_REPEATABLE_CONDITIONS): | |
96 raise InvalidLifecycleConfigError( | |
97 'Found duplicate non-repeatable conditions %s' % name) | |
98 else: | |
99 raise InvalidLifecycleConfigError('Unsupported tag ' + name) | |
100 self.current_tag = name | |
101 | |
102 def endElement(self, name, value, connection): | |
103 self.validateEndTag(name) | |
104 if name == RULE: | |
105 # We have to validate the rule after it is fully populated because | |
106 # the action and condition elements could be in any order. | |
107 self.validate() | |
108 elif name == ACTION: | |
109 self.current_tag = RULE | |
110 elif name in LEGAL_ACTIONS: | |
111 if name == SET_STORAGE_CLASS and value is not None: | |
112 self.action_text = value.strip() | |
113 self.current_tag = ACTION | |
114 elif name == CONDITION: | |
115 self.current_tag = RULE | |
116 elif name in LEGAL_CONDITIONS: | |
117 self.current_tag = CONDITION | |
118 # Some conditions specify a list of values. | |
119 if name in LEGAL_REPEATABLE_CONDITIONS: | |
120 if name not in self.conditions: | |
121 self.conditions[name] = [] | |
122 self.conditions[name].append(value.strip()) | |
123 else: | |
124 self.conditions[name] = value.strip() | |
125 else: | |
126 raise InvalidLifecycleConfigError('Unsupported end tag ' + name) | |
127 | |
128 def validate(self): | |
129 """Validate the rule.""" | |
130 if not self.action: | |
131 raise InvalidLifecycleConfigError( | |
132 'No action was specified in the rule') | |
133 if not self.conditions: | |
134 raise InvalidLifecycleConfigError( | |
135 'No condition was specified for action %s' % self.action) | |
136 | |
137 def to_xml(self): | |
138 """Convert the rule into XML string representation.""" | |
139 s = ['<' + RULE + '>'] | |
140 s.append('<' + ACTION + '>') | |
141 if self.action_text: | |
142 s.extend(['<' + self.action + '>', | |
143 self.action_text, | |
144 '</' + self.action + '>']) | |
145 else: | |
146 s.append('<' + self.action + '/>') | |
147 s.append('</' + ACTION + '>') | |
148 s.append('<' + CONDITION + '>') | |
149 for condition_name in self.conditions: | |
150 if condition_name not in LEGAL_CONDITIONS: | |
151 continue | |
152 if condition_name in LEGAL_REPEATABLE_CONDITIONS: | |
153 condition_values = self.conditions[condition_name] | |
154 else: | |
155 # Wrap condition value in a list, allowing us to iterate over | |
156 # all condition values using the same logic. | |
157 condition_values = [self.conditions[condition_name]] | |
158 for condition_value in condition_values: | |
159 s.extend(['<' + condition_name + '>', | |
160 condition_value, | |
161 '</' + condition_name + '>']) | |
162 s.append('</' + CONDITION + '>') | |
163 s.append('</' + RULE + '>') | |
164 return ''.join(s) | |
165 | |
166 class LifecycleConfig(list): | |
167 """ | |
168 A container of rules associated with a lifecycle configuration. | |
169 """ | |
170 | |
171 def __init__(self): | |
172 # Track if root tag has been seen. | |
173 self.has_root_tag = False | |
174 | |
175 def startElement(self, name, attrs, connection): | |
176 if name == LIFECYCLE_CONFIG: | |
177 if self.has_root_tag: | |
178 raise InvalidLifecycleConfigError( | |
179 'Only one root tag is allowed in the XML') | |
180 self.has_root_tag = True | |
181 elif name == RULE: | |
182 if not self.has_root_tag: | |
183 raise InvalidLifecycleConfigError('Invalid root tag ' + name) | |
184 rule = Rule() | |
185 self.append(rule) | |
186 return rule | |
187 else: | |
188 raise InvalidLifecycleConfigError('Unsupported tag ' + name) | |
189 | |
190 def endElement(self, name, value, connection): | |
191 if name == LIFECYCLE_CONFIG: | |
192 pass | |
193 else: | |
194 raise InvalidLifecycleConfigError('Unsupported end tag ' + name) | |
195 | |
196 def to_xml(self): | |
197 """Convert LifecycleConfig object into XML string representation.""" | |
198 s = ['<?xml version="1.0" encoding="UTF-8"?>'] | |
199 s.append('<' + LIFECYCLE_CONFIG + '>') | |
200 for rule in self: | |
201 s.append(rule.to_xml()) | |
202 s.append('</' + LIFECYCLE_CONFIG + '>') | |
203 return ''.join(s) | |
204 | |
205 def add_rule(self, action, action_text, conditions): | |
206 """ | |
207 Add a rule to this Lifecycle configuration. This only adds the rule to | |
208 the local copy. To install the new rule(s) on the bucket, you need to | |
209 pass this Lifecycle config object to the configure_lifecycle method of | |
210 the Bucket object. | |
211 | |
212 :type action: str | |
213 :param action: Action to be taken. | |
214 | |
215 :type action_text: str | |
216 :param action_text: Value for the specified action. | |
217 | |
218 :type conditions: dict | |
219 :param conditions: A dictionary of conditions that specify when the | |
220 action should be taken. Each item in the dictionary represents the name | |
221 and value of a condition. | |
222 """ | |
223 rule = Rule(action, action_text, conditions) | |
224 self.append(rule) |