PageRenderTime 37ms CodeModel.GetById 11ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

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

#
Python | 249 lines | 202 code | 3 blank | 44 comment | 3 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
 25try:
 26    import simplejson as json
 27except ImportError:
 28    import json
 29
 30class OptionStatus(dict):
 31    """
 32    Presents a combination of status field (defined below) which are
 33    accessed as attributes and option values which are stored in the
 34    native Python dictionary.  In this class, the option values are
 35    merged from a JSON object that is stored as the Option part of
 36    the object.
 37
 38    :ivar domain_name: The name of the domain this option is associated with.
 39    :ivar create_date: A timestamp for when this option was created.
 40    :ivar state: The state of processing a change to an option.
 41        Possible values:
 42
 43        * RequiresIndexDocuments: the option's latest value will not
 44          be visible in searches until IndexDocuments has been called
 45          and indexing is complete.
 46        * Processing: the option's latest value is not yet visible in
 47          all searches but is in the process of being activated.
 48        * Active: the option's latest value is completely visible.
 49
 50    :ivar update_date: A timestamp for when this option was updated.
 51    :ivar update_version: A unique integer that indicates when this
 52        option was last updated.
 53    """
 54
 55    def __init__(self, domain, data=None, refresh_fn=None, save_fn=None):
 56        self.domain = domain
 57        self.refresh_fn = refresh_fn
 58        self.save_fn = save_fn
 59        self.refresh(data)
 60
 61    def _update_status(self, status):
 62        self.creation_date = status['creation_date']
 63        self.status = status['state']
 64        self.update_date = status['update_date']
 65        self.update_version = int(status['update_version'])
 66
 67    def _update_options(self, options):
 68        if options:
 69            self.update(json.loads(options))
 70
 71    def refresh(self, data=None):
 72        """
 73        Refresh the local state of the object.  You can either pass
 74        new state data in as the parameter ``data`` or, if that parameter
 75        is omitted, the state data will be retrieved from CloudSearch.
 76        """
 77        if not data:
 78            if self.refresh_fn:
 79                data = self.refresh_fn(self.domain.name)
 80        if data:
 81            self._update_status(data['status'])
 82            self._update_options(data['options'])
 83
 84    def to_json(self):
 85        """
 86        Return the JSON representation of the options as a string.
 87        """
 88        return json.dumps(self)
 89
 90    def startElement(self, name, attrs, connection):
 91        return None
 92
 93    def endElement(self, name, value, connection):
 94        if name == 'CreationDate':
 95            self.created = value
 96        elif name == 'State':
 97            self.state = value
 98        elif name == 'UpdateDate':
 99            self.updated = value
100        elif name == 'UpdateVersion':
101            self.update_version = int(value)
102        elif name == 'Options':
103            self.update_from_json_doc(value)
104        else:
105            setattr(self, name, value)
106
107    def save(self):
108        """
109        Write the current state of the local object back to the
110        CloudSearch service.
111        """
112        if self.save_fn:
113            data = self.save_fn(self.domain.name, self.to_json())
114            self.refresh(data)
115
116    def wait_for_state(self, state):
117        """
118        Performs polling of CloudSearch to wait for the ``state``
119        of this object to change to the provided state.
120        """
121        while self.state != state:
122            time.sleep(5)
123            self.refresh()
124
125
126class IndexFieldStatus(OptionStatus):
127
128    def _update_options(self, options):
129        self.update(options)
130
131    def save(self):
132        pass
133
134
135class RankExpressionStatus(IndexFieldStatus):
136
137    pass
138
139class ServicePoliciesStatus(OptionStatus):
140
141    def new_statement(self, arn, ip):
142        """
143        Returns a new policy statement that will allow
144        access to the service described by ``arn`` by the
145        ip specified in ``ip``.
146
147        :type arn: string
148        :param arn: The Amazon Resource Notation identifier for the
149            service you wish to provide access to.  This would be
150            either the search service or the document service.
151
152        :type ip: string
153        :param ip: An IP address or CIDR block you wish to grant access
154            to.
155        """
156        return {
157                    "Effect":"Allow",
158                    "Action":"*",  # Docs say use GET, but denies unless *
159                    "Resource": arn,
160                    "Condition": {
161                        "IpAddress": {
162                            "aws:SourceIp": [ip]
163                            }
164                        }
165                    }
166
167    def _allow_ip(self, arn, ip):
168        if 'Statement' not in self:
169            s = self.new_statement(arn, ip)
170            self['Statement'] = [s]
171            self.save()
172        else:
173            add_statement = True
174            for statement in self['Statement']:
175                if statement['Resource'] == arn:
176                    for condition_name in statement['Condition']:
177                        if condition_name == 'IpAddress':
178                            add_statement = False
179                            condition = statement['Condition'][condition_name]
180                            if ip not in condition['aws:SourceIp']:
181                                condition['aws:SourceIp'].append(ip)
182
183            if add_statement:
184                s = self.new_statement(arn, ip)
185                self['Statement'].append(s)
186            self.save()
187
188    def allow_search_ip(self, ip):
189        """
190        Add the provided ip address or CIDR block to the list of
191        allowable address for the search service.
192
193        :type ip: string
194        :param ip: An IP address or CIDR block you wish to grant access
195            to.
196        """
197        arn = self.domain.search_service_arn
198        self._allow_ip(arn, ip)
199
200    def allow_doc_ip(self, ip):
201        """
202        Add the provided ip address or CIDR block to the list of
203        allowable address for the document service.
204
205        :type ip: string
206        :param ip: An IP address or CIDR block you wish to grant access
207            to.
208        """
209        arn = self.domain.doc_service_arn
210        self._allow_ip(arn, ip)
211
212    def _disallow_ip(self, arn, ip):
213        if 'Statement' not in self:
214            return
215        need_update = False
216        for statement in self['Statement']:
217            if statement['Resource'] == arn:
218                for condition_name in statement['Condition']:
219                    if condition_name == 'IpAddress':
220                        condition = statement['Condition'][condition_name]
221                        if ip in condition['aws:SourceIp']:
222                            condition['aws:SourceIp'].remove(ip)
223                            need_update = True
224        if need_update:
225            self.save()
226
227    def disallow_search_ip(self, ip):
228        """
229        Remove the provided ip address or CIDR block from the list of
230        allowable address for the search service.
231
232        :type ip: string
233        :param ip: An IP address or CIDR block you wish to grant access
234            to.
235        """
236        arn = self.domain.search_service_arn
237        self._disallow_ip(arn, ip)
238
239    def disallow_doc_ip(self, ip):
240        """
241        Remove the provided ip address or CIDR block from the list of
242        allowable address for the document service.
243
244        :type ip: string
245        :param ip: An IP address or CIDR block you wish to grant access
246            to.
247        """
248        arn = self.domain.doc_service_arn
249        self._disallow_ip(arn, ip)