PageRenderTime 49ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/boto-2.5.2/boto/cloudsearch/optionstatus.py

#
Python | 249 lines | 202 code | 3 blank | 44 comment | 4 complexity | 3efeb58ebc2470cd67472631cff1346f MD5 | raw file
  1. # Copyright (c) 2012 Mitch Garnaat http://garnaat.org/
  2. # Copyright (c) 2012 Amazon.com, Inc. or its affiliates.
  3. # All Rights Reserved
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a
  6. # copy of this software and associated documentation files (the
  7. # "Software"), to deal in the Software without restriction, including
  8. # without limitation the rights to use, copy, modify, merge, publish, dis-
  9. # tribute, sublicense, and/or sell copies of the Software, and to permit
  10. # persons to whom the Software is furnished to do so, subject to the fol-
  11. # lowing conditions:
  12. #
  13. # The above copyright notice and this permission notice shall be included
  14. # in all copies or substantial portions of the Software.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
  18. # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  19. # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. # IN THE SOFTWARE.
  23. #
  24. try:
  25. import simplejson as json
  26. except ImportError:
  27. import json
  28. class OptionStatus(dict):
  29. """
  30. Presents a combination of status field (defined below) which are
  31. accessed as attributes and option values which are stored in the
  32. native Python dictionary. In this class, the option values are
  33. merged from a JSON object that is stored as the Option part of
  34. the object.
  35. :ivar domain_name: The name of the domain this option is associated with.
  36. :ivar create_date: A timestamp for when this option was created.
  37. :ivar state: The state of processing a change to an option.
  38. Possible values:
  39. * RequiresIndexDocuments: the option's latest value will not
  40. be visible in searches until IndexDocuments has been called
  41. and indexing is complete.
  42. * Processing: the option's latest value is not yet visible in
  43. all searches but is in the process of being activated.
  44. * Active: the option's latest value is completely visible.
  45. :ivar update_date: A timestamp for when this option was updated.
  46. :ivar update_version: A unique integer that indicates when this
  47. option was last updated.
  48. """
  49. def __init__(self, domain, data=None, refresh_fn=None, save_fn=None):
  50. self.domain = domain
  51. self.refresh_fn = refresh_fn
  52. self.save_fn = save_fn
  53. self.refresh(data)
  54. def _update_status(self, status):
  55. self.creation_date = status['creation_date']
  56. self.status = status['state']
  57. self.update_date = status['update_date']
  58. self.update_version = int(status['update_version'])
  59. def _update_options(self, options):
  60. if options:
  61. self.update(json.loads(options))
  62. def refresh(self, data=None):
  63. """
  64. Refresh the local state of the object. You can either pass
  65. new state data in as the parameter ``data`` or, if that parameter
  66. is omitted, the state data will be retrieved from CloudSearch.
  67. """
  68. if not data:
  69. if self.refresh_fn:
  70. data = self.refresh_fn(self.domain.name)
  71. if data:
  72. self._update_status(data['status'])
  73. self._update_options(data['options'])
  74. def to_json(self):
  75. """
  76. Return the JSON representation of the options as a string.
  77. """
  78. return json.dumps(self)
  79. def startElement(self, name, attrs, connection):
  80. return None
  81. def endElement(self, name, value, connection):
  82. if name == 'CreationDate':
  83. self.created = value
  84. elif name == 'State':
  85. self.state = value
  86. elif name == 'UpdateDate':
  87. self.updated = value
  88. elif name == 'UpdateVersion':
  89. self.update_version = int(value)
  90. elif name == 'Options':
  91. self.update_from_json_doc(value)
  92. else:
  93. setattr(self, name, value)
  94. def save(self):
  95. """
  96. Write the current state of the local object back to the
  97. CloudSearch service.
  98. """
  99. if self.save_fn:
  100. data = self.save_fn(self.domain.name, self.to_json())
  101. self.refresh(data)
  102. def wait_for_state(self, state):
  103. """
  104. Performs polling of CloudSearch to wait for the ``state``
  105. of this object to change to the provided state.
  106. """
  107. while self.state != state:
  108. time.sleep(5)
  109. self.refresh()
  110. class IndexFieldStatus(OptionStatus):
  111. def _update_options(self, options):
  112. self.update(options)
  113. def save(self):
  114. pass
  115. class RankExpressionStatus(IndexFieldStatus):
  116. pass
  117. class ServicePoliciesStatus(OptionStatus):
  118. def new_statement(self, arn, ip):
  119. """
  120. Returns a new policy statement that will allow
  121. access to the service described by ``arn`` by the
  122. ip specified in ``ip``.
  123. :type arn: string
  124. :param arn: The Amazon Resource Notation identifier for the
  125. service you wish to provide access to. This would be
  126. either the search service or the document service.
  127. :type ip: string
  128. :param ip: An IP address or CIDR block you wish to grant access
  129. to.
  130. """
  131. return {
  132. "Effect":"Allow",
  133. "Action":"*", # Docs say use GET, but denies unless *
  134. "Resource": arn,
  135. "Condition": {
  136. "IpAddress": {
  137. "aws:SourceIp": [ip]
  138. }
  139. }
  140. }
  141. def _allow_ip(self, arn, ip):
  142. if 'Statement' not in self:
  143. s = self.new_statement(arn, ip)
  144. self['Statement'] = [s]
  145. self.save()
  146. else:
  147. add_statement = True
  148. for statement in self['Statement']:
  149. if statement['Resource'] == arn:
  150. for condition_name in statement['Condition']:
  151. if condition_name == 'IpAddress':
  152. add_statement = False
  153. condition = statement['Condition'][condition_name]
  154. if ip not in condition['aws:SourceIp']:
  155. condition['aws:SourceIp'].append(ip)
  156. if add_statement:
  157. s = self.new_statement(arn, ip)
  158. self['Statement'].append(s)
  159. self.save()
  160. def allow_search_ip(self, ip):
  161. """
  162. Add the provided ip address or CIDR block to the list of
  163. allowable address for the search service.
  164. :type ip: string
  165. :param ip: An IP address or CIDR block you wish to grant access
  166. to.
  167. """
  168. arn = self.domain.search_service_arn
  169. self._allow_ip(arn, ip)
  170. def allow_doc_ip(self, ip):
  171. """
  172. Add the provided ip address or CIDR block to the list of
  173. allowable address for the document service.
  174. :type ip: string
  175. :param ip: An IP address or CIDR block you wish to grant access
  176. to.
  177. """
  178. arn = self.domain.doc_service_arn
  179. self._allow_ip(arn, ip)
  180. def _disallow_ip(self, arn, ip):
  181. if 'Statement' not in self:
  182. return
  183. need_update = False
  184. for statement in self['Statement']:
  185. if statement['Resource'] == arn:
  186. for condition_name in statement['Condition']:
  187. if condition_name == 'IpAddress':
  188. condition = statement['Condition'][condition_name]
  189. if ip in condition['aws:SourceIp']:
  190. condition['aws:SourceIp'].remove(ip)
  191. need_update = True
  192. if need_update:
  193. self.save()
  194. def disallow_search_ip(self, ip):
  195. """
  196. Remove the provided ip address or CIDR block from the list of
  197. allowable address for the search service.
  198. :type ip: string
  199. :param ip: An IP address or CIDR block you wish to grant access
  200. to.
  201. """
  202. arn = self.domain.search_service_arn
  203. self._disallow_ip(arn, ip)
  204. def disallow_doc_ip(self, ip):
  205. """
  206. Remove the provided ip address or CIDR block from the list of
  207. allowable address for the document service.
  208. :type ip: string
  209. :param ip: An IP address or CIDR block you wish to grant access
  210. to.
  211. """
  212. arn = self.domain.doc_service_arn
  213. self._disallow_ip(arn, ip)