예제 #1
0
 def create(self, *args, **kwargs):
     varg = kwargs.get('pargs', None)
     if not varg:
         varg = kwargs
     group = None
     server = None
     type = varg.get('type', kwargs.get('type', None))
     resource = varg.get('resource', kwargs.get('resource', None))
     if type and type == 'delete':
         if not resource == 'service' or resource == 'server':
             servers = self._list_servers(kwargs, varg)
             for server in servers:
                 if not server is None:
                     group = Groups(self.config).find(
                         ref=server['_links']['group']['href'])
                     if not group is None:
                         break
         elif resource == 'service':
             services = self._list_services(kwargs, varg)
             for service in services:
                 if not service is None:
                     group = Groups(self.config).find(
                         ref=service['_links']['group']['href'])
                     if not group is None:
                         break
     if group is None:
         gid = varg.get('group', kwargs.get('group', None))
         if not gid:
             raise IaaSError(
                 'Server or Group is required to start an order.')
         groups = Groups(self.config).list(detailed=True)
         key = None
         try:
             if str(int(gid)) == gid:
                 key = 'id'
         except ValueError as e:
             if string.index(gid, '/') >= 0:
                 key = '_links/self/href'
         matches = groups._filter([[key, gid]])
         if isinstance(matches, list) and matches.__len__() > 0:
             group = matches[0]
     if not group is None:  # This is NOT the else: for the previous statement ;)
         name = "Server order for {}".format(group._href)
         if not server is None:
             name = "Server order for {}".format(server._href)
         order_init = {
             "name": name,
             "group": group._href,
             "submit-now": "false"
         }
         resp = self.client().post('/api/v2/orders/', order_init, raw=True)
         if resp.status_code >= 400 or resp.status_code < 200:
             raise IaaSCloudboltAPIError(resp.text)
         else:
             mash = json.loads(resp.text)
             self.update(mash)
             return self
     else:
         raise IaaSError('Cannot determine/validate group')
예제 #2
0
 def me(self):
     try:
         users = self.list()
         info = [user for user in users if string.lower(user['user.username']) == self.config.get('username')]
         if not isinstance(info, list):
             raise IaaSError('User info returned is incorrect type(%s): %s' % (info.__class__.__name__, info))
         if len(info) < 1:
             return None
         me = User(self.config, href=info[0]['_links']['self']['href'])
         return me
     except Exception as e:
         raise IaaSError(str(e.message))
예제 #3
0
    def submit(self, *args, **kwargs):
        def checkstatus(self):
            if not (self['status'] == 'PENDING' or self['status'] == 'CART'):
                resp = {
                    'status_code':
                    500,
                    'detail':
                    'Order status error',
                    'error':
                    "Order {}: Only orders that are in 'PENDING' state can be approved. Current state of order is {}"
                    .format(self._href, self['status'])
                }
                resp.update({'_links': self['_links']})
                return resp
            return None

        def checkresponse(self, resp):
            if resp.status_code == 200:
                mash = json.loads(resp.text)
                self.update(mash)
                return mash
            raise IaaSCloudboltAPIError(resp.status_code, resp.text)

        mash = self._action('submit', checkstatus, checkresponse)
        if not mash is None:
            return mash
        raise IaaSError('Order {} cannot be cancelled'.format(self._href))
예제 #4
0
 def _action(self, verb, checkstatus, checkresponse):
     if self['_links'].has_key('actions'):
         actions = [
             action for action in self['_links']['actions']
             if action.has_key(verb)
         ]
         if not len(actions) > 0:
             raise IaaSError('Order {} has no "{}" action'.format(
                 self._href, verb))
         action = actions[0]
     else:
         self.update(Order(self.config, href=self._href))
         action = {verb: {'href': self._href + '/actions/{}'.format(verb)}}
     if self.get('status', None):
         resp = checkstatus(self)
         if not resp is None:
             return resp
     resp = self.client().post(action[verb]['href'], raw=True)
     if resp.status_code >= 400 or resp.status_code < 200:
         return checkresponse(self, resp)
     else:
         # return json.loads(resp.text)
         mash = json.loads(resp.text)
         self.update(mash)
         return self
예제 #5
0
 def _evaluate(self, flt, against=None):
     if against is None:
         against = self
     if isinstance(flt, basestring):
         try:
             if isinstance(against, dict):
                 idx = string.index(flt, '/')
                 parts = string.split(flt, '/')
                 return self._match_parts(parts, against)
             else:
                 if isinstance(against, list):
                     val = [o._evaluate(flt) for o in against]
                     val = [o for o in val if o]
                     return val
                 else:
                     if isinstance(against, basestring):
                         return against
                     else:
                         raise IaaSError('What to do about a {}'.format(
                             against.__class__.__name__))
         except ValueError as e:
             return self._match_parts([flt], against)
     else:
         if isinstance(flt, basestring):
             return against.has_key(flt)
     return None
예제 #6
0
 def list(self, *args, **kw):
     try:
         if not self.__len__() > 0:
             self.get('/{}'.format(string.lower(self.__class__.__name__)),
                      *args, **kw)
         return self
     except Exception as e:
         raise IaaSError(str(e.message))
예제 #7
0
 def _environment(self, kwargs, varg):
     envref = varg.get('environment', kwargs.get('environment', None))
     if not envref:
         raise IaaSError('Environment is required to add to an order.')
     if not isinstance(envref, Environment):
         environment = Environment(self.config)
         environment.href(ref=envref)
     else:
         environment = envref
     return environment
예제 #8
0
 def _list_servers(self, kwargs, varg):
     if not getattr(self, '_servers', None):
         entries = re.split(',\s*',
                            varg.get('server', kwargs.get('server', None)))
         servers = [
             self._server(kwargs, varg, ref=srvref) for srvref in entries
         ]
         servers = [server for server in servers if not server is None]
         if servers.__len__() <= 0:
             raise IaaSError(
                 'Unable to find servers that match {}'.format(entries))
         self._servers = servers
     return self._servers
예제 #9
0
 def _list_services(self, kwargs, varg):
     if not getattr(self, '_services', None):
         entries = re.split(
             ',\s*', varg.get('service', kwargs.get('service', None)))
         services = [
             self._service(kwargs, varg, ref=svc) for svc in entries
         ]
         services = [service for service in services if not service is None]
         if services.__len__() <= 0:
             raise IaaSError(
                 'Unable to find services that match {}'.format(entries))
         self._services = services
     return self._services
예제 #10
0
 def info(self):
     groups = Groups(self.app.config.get_section_dict('cloudbolt')).list()
     info = [
         group for group in groups
         if string.lower(group['group.groupname']) == self.app.config.get(
             'cloudbolt', 'groupname')
     ]
     if not isinstance(info, list):
         raise IaaSError('Group info returned is incorrect type(%s): %s' %
                         (info.__class__, info))
     me = Group(self.app.config.get_section_dict('cloudbolt'),
                href=info[0]['_links']['self']['href'])
     self.render([me])
예제 #11
0
    def api_client(self):
        try:
            config = self.config
            protocol = config.get('protocol') or 'https'
            port = config.get('port') or 443

            domain = config.get('domain')
            username = config.get('username') + '@' + domain
            password = config.get('password')
            hostname = config.get('hostname')

            return CloudBoltAPIClient(username, password, host=hostname, port=port, protocol=protocol)
        except NoOptionError as e:
            raise IaaSError(str(e.message))
예제 #12
0
 def _service(self, kwargs, varg, ref=None):
     if ref is None:
         ref = varg.get('service', kwargs.get('service', None))
     if not ref:
         raise IaaSError('service is required to add to a delete order.')
     if not isinstance(ref, Server):
         if not getattr(self, '_collection', None):
             self._collection = Servers(self.config)
         service = Service(self.config, ref=ref)
         if not (service is None or service.href()):
             service = self._collection.find(ref=ref)
             # if not (service is None or service.href()):
             #     raise IaaSError('Unable to find service {}'.format(srvref))
         ref = service
     return ref
예제 #13
0
 def post_a_object(self, href, parameters=None):
     if parameters is None:
         parameters = {}
     resp = self.client().post(href,
                               self,
                               headers=parameters.get('headers', None),
                               raw=parameters.get('raw', None))
     try:
         if resp.status_code == 403:
             raise IaaSCloudboltAPIError(
                 resp.status_code, 'GET {}: {}'.format(href, resp.text))
         if resp.status_code == 200:
             mash = json.loads(resp.text)
             return mash
         raise IaaSError('GET {}: {}'.format(href, resp.text))
     except Exception as e:
         raise e
예제 #14
0
    def show(self):
        def getid(rec):
            pass

        groups = Groups(self.app.config.get_section_dict('cloudbolt')).list()
        info = [
            group for group in groups
            if string.lower(group['group.groupname']) == self.app.config.get(
                'cloudbolt', 'groupname')
        ]
        if not isinstance(info, list):
            raise IaaSError('Group info returned is incorrect type(%s): %s' %
                            (info.__class__, info))
        me = [
            Group(self.app.config.get_section_dict('cloudbolt'),
                  href=info[0]['_links']['self']['href'])
        ]
        if len(me) > 0:
            attributes = []
            if self.app.pargs.self:
                attributes.append('_links/self')
            if self.app.pargs.groups:
                # attributes.append('_links/groups/(href;title)')
                attributes.append('_links/groups')
            if self.app.pargs.id:
                attributes.append(getid)
            if len(attributes) > 0:
                if self.app.pargs.attributes:
                    self.app.pargs.attributes += ','.join(attributes)
                else:
                    self.app.pargs.attributes = ','.join(attributes)

            if self.app.pargs.attributes:
                nume = self._prune(me, 'attributes')
                if len(nume) > 0:
                    me = nume
                else:
                    me = [{
                        "message":
                        'No group attributes matched from "{}"'.format(
                            self.app.pargs.attributes)
                    }]
        else:
            me = [{"message": 'No groups found'}]
        self.render(me)
예제 #15
0
 def __init__(self, *args, **kw):
     if self.__class__.__name__ != 'CloudboltPluginController':
         if not getattr(self.Meta, 'arguments_inherited', False):
             self.Meta.arguments = self.Meta.arguments + CloudboltPluginController.Meta.common_arguments
             self.Meta.arguments_inherited = True
             seen = {}
             for arg in self.Meta.arguments:
                 if arg[0].__len__() >= 2:
                     word = arg[0][1]
                 else:
                     word = arg[0][0]
                 if not seen.get(word, False):
                     seen[word] = True
                 else:
                     raise IaaSError("arg {} is duplicated in {}".format(
                         arg, self.__class__.__name__))
         else:
             pass
     super(CloudboltPluginController, self).__init__(*args, **kw)
     self._client = None
예제 #16
0
 def _match_parts(self, parts, against):
     if against is None:
         against = self
     matches = re.match('^\((.*?)\)$', parts[0])
     if matches:
         flds = string.split(matches.group(1), ';')
         if isinstance(against, dict):
             no = self.__class__(self.config, parameters=self.parameters)
             for k in flds:
                 if against.has_key(k):
                     no[k] = against[k]
             if len(no) <= 0:
                 return None
             return no
         else:
             raise IaaSError('TODO {}'.format(against.__class__.__name__))
     else:
         if not against.has_key(parts[0]):
             return None
         if len(parts) == 1:
             return against[parts[0]]
         return self._evaluate('/'.join(parts[1:]),
                               against=against[parts[0]])
예제 #17
0
    def cancel(self):
        def checkstatus(self):
            if not (self['status'] == 'PENDING' or self['status'] == 'CART'):
                resp = {
                    'status_code':
                    500,
                    'detail':
                    'Order status error',
                    'error':
                    "Order {}: Only orders that are in 'PENDING' state can be approved. Current state of order is {}"
                    .format(self._href, self['status'])
                }
                resp.update({'_links': self['_links']})
                return resp
            return None

        def checkresponse(self, resp):
            if resp.status_code == 200 or (resp.status_code == 500
                                           and verb == 'submit'):
                # A failed submit is ok when we 'cancel'
                mash = json.loads(resp.text)
                mash.update({'_links': self['_links']})
                mash['detail'] = "Order {} was {}'ed".format(self._href, verb)
                mash['status_code'] = 200  # Fake it
                mash.pop('error')
                return mash
            if resp.status_code == 404:
                # Ok the first link does not work ...
                return None
            else:
                raise IaaSCloudboltAPIError(resp.text)

        for verb in ['cancel', 'submit']:
            mash = self._action(verb, checkstatus, checkresponse)
            if not mash is None:
                return mash
        raise IaaSError('Order {} cannot be cancelled'.format(self._href))
예제 #18
0
    def check_recipe(self, recipe=None):
        if recipe is None:
            if not hasattr(self._meta, 'recipe'):
                msg = '{} does not have a recipe!'.format(
                    self.__class__.__name__)
                self.app.log.fatal(msg)
                raise IaaSError(msg)
            recipe = self._meta.recipe
        msg = ''
        for ingredient in recipe:
            if not getattr(self.app.pargs, ingredient['parameter'], None):
                if not is_true(self.setting('batch')) and self.setting(
                        'prompt') and ingredient['ask']:
                    self.app.log.info('Prompt here for {}'.format(
                        ingredient['parameter']))
                    prompt = ArgPrompt()
                    if ingredient.get('options', None):
                        prompt._meta.numbered = True
                        options = ingredient['options']
                        if options.get('values', None):
                            prompt._meta.options = options['values']
                        elif options.get('class', None):
                            columns = getattr(self, '_columns', None)
                            ignored = getattr(self, '_ignored', None)
                            try:
                                if options['module'] not in sys.modules:
                                    try:
                                        __import__(options['module'],
                                                   globals(), locals(), [], 0)
                                    except ImportError as e:
                                        raise IaaSError(
                                            'Unable to import class needed to pull list of options for {} ({})'
                                            .format(ingredient, e.message))
                                klass = getattr(sys.modules[options['module']],
                                                options['class'])
                                instance = klass(
                                    self.app.config.get_section_dict(
                                        options['section']))
                                print('Obtaining a {} of {} ...'.format(
                                    options['method'], options['class']))
                                if options['attribute'].get('filters', None):
                                    filters = getattr(self, '_filters', None)
                                    self._filters = options['attribute'][
                                        'filters']
                                    self.app.log.info('Filter {}.{}.{}'.format(
                                        options['section'], options['class'],
                                        options['method']))
                                    values = getattr(instance,
                                                     options['method'])(
                                                         _filter=self._weigh,
                                                         _collection=instance)
                                    if filters:
                                        self._filters = filters
                                else:
                                    values = getattr(
                                        instance,
                                        options['method'])(detailed=True)

                                if not values.__len__() > 0:
                                    raise FrameworkError(
                                        'There are no {}!'.format(
                                            options['class']))
                                if not isinstance(options['attribute']['show'],
                                                  list):
                                    options['attribute']['show'] = [
                                        options['attribute']['show']
                                    ]
                                self._columns = options['attribute']['show']
                                selection = self._prune(values)
                                i = 0
                                while i < selection.__len__():
                                    for show in options['attribute']['show']:
                                        if not selection[i].get(show, None):
                                            for attr in options['attribute'][
                                                    'alternatives']:
                                                sub = values[i]._evaluate(attr)
                                                if sub:
                                                    selection[i][
                                                        show] = '{}:{}'.format(
                                                            attr, sub)
                                                    break
                                    i += 1

                                prompt._meta.options = [
                                    ','.join(dict(obj).values())
                                    for obj in selection
                                ]
                                self._meta.values = instance
                            except KeyError as e:
                                # raise IaaSError('Ingredient {} options for recipe {}.{} requires an unknown class'.format(ingredient,self.__class__.__name__, self._meta.label))
                                # except ValueError as e:
                                raise IaaSError(
                                    'Ingredient {} for recipe {}.{} requires a "{}" attribute'
                                    .format(ingredient,
                                            self.__class__.__name__,
                                            self._meta.label, e.message))
                            except FrameworkError as e:
                                self.app.log.fatal("'{}': '{}'".format(
                                    e.message, e.msg))
                                print('FATAL error: {}'.format(e.msg))
                                raise e
                            except Exception as e:
                                self.app.log.fatal(e.message)
                                print('FATAL error: {}'.format(e.message))
                                raise e

                            if not columns is None:
                                self._columns = columns
                            if not ignored is None:
                                self._ignored = ignored
                        else:
                            raise IaaSError(
                                'Ingredient {} options for recipe {}.{} are not valid'
                                .format(ingredient, self.__class__.__name__,
                                        self._meta.label))
                        prompt._meta.text = 'Choose {}:'.format(
                            ingredient['description'])
                    else:
                        prompt._meta.numbered = False
                        prompt._meta.options = None
                        prompt._meta.text = 'Enter {}: '.format(
                            ingredient['description'])
                    # prompt._meta.selection_text = 'Enter the {}:'.format(ingredient['parameter'])
                    try:
                        answer = prompt.prompt()
                        if ingredient.get('options', None):
                            options = ingredient['options']
                            if options.get('values', None):
                                setattr(self.app.pargs,
                                        ingredient['parameter'], prompt.input)
                            elif options.get('class', None):
                                index = prompt._meta.options.index(answer)
                                values = [self._meta.values[index]]

                                columns = getattr(self, '_columns', None)
                                ignored = getattr(self, '_ignored', None)
                                self._columns = [options['attribute']['use']]
                                selection = self._prune(values)
                                if not columns is None:
                                    self._columns = columns
                                if not ignored is None:
                                    self._ignored = ignored

                                setattr(
                                    self.app.pargs, ingredient['parameter'],
                                    '{}:{}'.format(
                                        options['attribute']['use'],
                                        selection[0].get(
                                            options['attribute']['use'],
                                            None)))
                                print('{} value will be "{}"'.format(
                                    ingredient['parameter'],
                                    getattr(self.app.pargs,
                                            ingredient['parameter'])))

                                # if string.index(options['attribute']['use'], '/') < 0:
                                #     pass
                                # else:
                                #     setattr(self.app.pargs, ingredient['parameter'], selection[0].get(options['attribute']['use'], None))
                        else:
                            setattr(self.app.pargs, ingredient['parameter'],
                                    prompt.input)
                    except FrameworkError as e:
                        self.app.log.fatal("'{}': '{}'".format(
                            e.message, e.msg))
                        print('FATAL error: {}'.format(e.msg))
                        raise e
                if not getattr(self.app.pargs, ingredient['parameter'], None):
                    msg += "'{}' is required. ({})\n".format(
                        ingredient['parameter'], ingredient['description'])
        if msg.__len__() > 0:
            raise IaaSError(msg)
예제 #19
0
 def list(self):
     try:
         respns = self.get('/users')
         return respns
     except Exception as e:
         raise IaaSError(str(e.message))
예제 #20
0
    def show(self):
        if not self.app.pargs.order:
            raise IaaSError('Order ref is required')

        self._show(Orders(self.app.config.get_section_dict('cloudbolt')),
                   ref=self.app.pargs.order)
예제 #21
0
    def add(self, *args, **kwargs):
        varg = kwargs.get('pargs', None)
        if not varg:
            varg = kwargs
        bpref = varg.get('blueprint', kwargs.get('blueprint', None))
        if not bpref:
            raise IaaSError('blueprint is required to add to an order.')
        if not isinstance(bpref, Blueprint):
            blueprint = Blueprint(self.config, ref=bpref)
            if not blueprint:
                raise IaaSError('Unable to find blueprint {}'.format(bpref))
        else:
            blueprint = bpref

        if not blueprint.get('is-orderable', False):
            raise IaaSError('Blueprint {} is not orderable'.format(bpref))

        parameters = varg.get('parameters', kwargs.get('parameters', None))
        sections = {}
        if parameters and len(string.lstrip(string.rstrip(parameters))) > 0:
            kv = lambda x: re.split('=\s*', x)
            # pm = lambda x: re.split(',\s*', x)
            sn = lambda x: re.split(':\s*', x)
            if string.find(parameters, ':') < 0:
                raise IaaSError(
                    'Invalid blueprint parameters: {} (Missing : so not able to identify build item)'
                    .format(parameters))
            if string.find(parameters, '=') < 0:
                raise IaaSError(
                    'Invalid blueprint parameters: {} (Missing = so not able to identify key/value pairs)'
                    .format(parameters))
            raw_sects = re.split(';\s*', parameters)
            raw_sects = dict(map(sn, raw_sects))
            for sect, pars in raw_sects.items():
                assigns = re.split(',\s*', pars)
                parameters = map(kv, assigns)
                parameters = dict(parameters)
                sections[sect] = parameters
        service_name = varg.get('service', kwargs.get('service', None))
        if not service_name:
            raise IaaSError('Service name is required to add to an order.')
        environment = self._environment(kwargs, varg)
        password = varg.get('password', kwargs.get('password', None))
        if not password:
            raise IaaSError('Password is required to add to a service order.')
        if password.__len__() < 8:
            raise IaaSError(
                'Password must be 8 characters or more to add to a service order.'
            )

        blueprint_items_arguments = {}

        for item in blueprint['build-items']:
            name = "build-item-{}".format(item['name'])
            parameters = sections.get(item['name'], {})
            if item['type'] == 'provserver':
                parameters.update({"new-password": password})
                build_item = {
                    "environment": environment._href,
                    "attributes": {
                        "quantity": varg.get('quantity',
                                             kwargs.get('quantity', 1))
                    },
                    "parameters": parameters
                }
            else:
                build_item = {
                    "parameters": parameters,
                }
            blueprint_items_arguments[name] = build_item

        order_service_item = {
            "blueprint": blueprint._href,
            "blueprint-items-arguments": blueprint_items_arguments,
            "service-name": service_name
        }

        resp = self.client().post(self.href() + '/deploy-items/',
                                  order_service_item,
                                  raw=True)
        if resp.status_code >= 400 or resp.status_code < 200:
            raise IaaSCloudboltAPIError(resp.text)
        else:
            mash = json.loads(resp.text)
            self.update(mash)
            return self
예제 #22
0
    def delete(self, *args, **kwargs):
        varg = kwargs.get('pargs', None)
        if not varg:
            varg = kwargs

        environment = None
        servers = None
        services = None
        resource = varg.get('resource', kwargs.get('resource', None))
        if not resource == 'service' or resource == 'server':
            servers = self._list_servers(kwargs, varg)
            for server in servers:
                if not server.get('status', None) in ['ACTIVE', 'PROV']:
                    raise IaaSError('Server {} is not ACTIVE'.format(
                        server._href))

                if server:
                    environment = Environments(self.config).find(
                        ref=server['_links']['environment']['href'])
                if environment is None:
                    if not kwargs['environment']:
                        raise IaaSError(
                            'Server or Environment is required to start a delete order.'
                        )
                    environment = self._environment(kwargs, varg)
                if not environment is None:
                    break
        elif resource == 'service':
            services = self._list_services(kwargs, varg)
            for service in services:
                if not service.get('status', None) in ['Active']:
                    raise IaaSError('Service {} is not Active'.format(
                        service._href))

                if service:
                    server = None
                    if service['_links']['servers'].__len__() > 0:
                        server = Servers(self.config).find(
                            ref=service['_links']['servers'][0]['href'])
                    else:
                        servers = Servers(self.config).list(detailed=True)
                        if servers.__len__() > 0:
                            server = servers[0]
                    if server:
                        environment = Environments(self.config).find(
                            ref=server['_links']['environment']['href'])
                    if environment is None:
                        if not kwargs['environment']:
                            raise IaaSError(
                                'Service or Environment is required to start a delete order.'
                            )
                        environment = self._environment(kwargs, varg)
                    if not environment is None:
                        break

        if not environment is None:

            decom_item = {}
            decom_item['environment'] = environment._href
            if not resource == 'service' or resource == 'server':
                decom_item['servers'] = [server._href for server in servers]
            elif resource == 'service':
                decom_item['services'] = [
                    service._href for service in services
                ]

            resp = self.client().post(self.href() + '/decom-items/',
                                      decom_item,
                                      raw=True)
            if resp.status_code >= 400 or resp.status_code < 200:
                raise IaaSCloudboltAPIError(resp.text)
            else:
                mash = json.loads(resp.text)
                self.update(mash)
                return self
        else:
            raise IaaSError('Cannot determine/validate environment')
예제 #23
0
    def get_all_records(self, object, *args, **kwargs):

        try:
            parameters = kwargs.get('parameters', {})
            objs = []
            seen = 0
            try:
                pool = int(kwargs.get('pool', sys.maxint))
                if parameters.has_key('pool') and parameters['pool']:
                    pool = int(parameters['pool'])
            except ValueError as e:
                raise IaaSError("'limit' value is not an integer!?")
            try:
                total = int(kwargs.get(
                    'total', sys.maxint))  # Get all matches or the specified #
                if parameters.has_key('total') and parameters['total']:
                    total = int(parameters['total'])
            except ValueError as e:
                raise IaaSError("'limit' value is not an integer!?")
            # dater = parameters[:date_range] || 'all' # Get all matches or the specified #
            try:
                offset = int(kwargs.get('offset', 0))
                if parameters.has_key('offset') and parameters['offset']:
                    offset = int(parameters['offset'])
            except ValueError as e:
                raise IaaSError("'limit' value is not an integer!?")
            try:
                limit = int(kwargs.get('limit', 0))
                if parameters.has_key('limit') and parameters['limit']:
                    limit = int(parameters['limit'])
            except ValueError as e:
                raise IaaSError("'limit' value is not an integer!?")
            pn = 1
            try:
                if offset > 0:
                    pn = int(kwargs.get('page', offset / limit))
                if parameters.has_key('page') and parameters['page']:
                    pn = int(parameters['page'])
                else:
                    pn = int(kwargs.get('page', pn))
            except ValueError as e:
                raise IaaSError("'page' value is not an integer!?")

            page = self.get_a_page(object,
                                   action=kwargs.get('action', ''),
                                   pool=pool,
                                   total=total,
                                   page=pn,
                                   offset=offset,
                                   limit=limit)
            while page and isinstance(page, dict):
                if kwargs.get('_filter', None):
                    slice = []
                    for obj in page['_embedded']:
                        nobj = kwargs['_filter'](obj, kwargs['_collection'])
                        if not nobj is None:
                            slice.append(nobj)
                    objs.extend(slice)
                    seen += len(slice)
                else:
                    objs.extend(page['_embedded'])
                    seen += len(page['_embedded'])
                if page.has_key(
                        'count'
                ):  # Adjust limit (down or up) based on API feedback
                    limit = page['count']
                if page.has_key(
                        'total'):  # Total is what API says or _everything_
                    if page['total'] < total:
                        total = page['total']
                    if page['total'] < pool:
                        pool = page['total']
                # pgnos = total/limit # No of pages is obvious
                if total < len(objs):
                    if isinstance(objs[0], list):
                        raise StandardError("Should not slice array of arrays")
                    objs = objs[0:total]

                next = False
                if page.has_key('_links'):
                    if page['_links'].has_key('next'):
                        next = True

                if next and len(objs) < total and seen < pool:  # pn < pgnos &&
                    pn += 1
                    page = self.get_a_page(object,
                                           action=kwargs.get('action', ''),
                                           pool=pool,
                                           total=total,
                                           page=pn,
                                           offset=offset,
                                           limit=limit)
                else:
                    page = None
            return objs
        except IaaSError as e:
            raise e
        except Exception as e:
            traceback.print_exc(file=sys.stdout)