def _request_admin_token(self): """Retrieve new token as admin user from keystone. :return token id upon success :raises ServerError when unable to communicate with keystone Irrespective of the auth version we are going to use for the user token, for simplicity we always use a v2 admin token to validate the user token. """ params = { 'auth': { 'passwordCredentials': { 'username': self.admin_user, 'password': self.admin_password, }, 'tenantName': self.admin_tenant_name, } } response, data = self._json_request(self.keystone_auth_host, self.keystone_auth_port, 'POST', '/v2.0/tokens', body=params) try: token = data['access']['token']['id'] expiry = data['access']['token']['expires'] assert token assert expiry datetime_expiry = timeutils.parse_isotime(expiry) return (token, timeutils.normalize_time(datetime_expiry)) except (AssertionError, KeyError): self.LOG.warn( "Unexpected response from keystone service: %s", data) raise ServiceError('invalid json response') except (ValueError): self.LOG.warn( "Unable to parse expiration time from token: %s", data) raise ServiceError('invalid json response')
def _make_conditions_from_filters(filters, is_public=None): #NOTE(venkatesh) make copy of the filters are to be altered in this method. filters = filters.copy() image_conditions = [] prop_conditions = [] tag_conditions = [] if is_public is not None: image_conditions.append(models.Image.is_public == is_public) if 'checksum' in filters: checksum = filters.pop('checksum') image_conditions.append(models.Image.checksum == checksum) if 'is_public' in filters: key = 'is_public' value = filters.pop('is_public') prop_filters = _make_image_property_condition(key=key, value=value) prop_conditions.append(prop_filters) for (k, v) in filters.pop('properties', {}).items(): prop_filters = _make_image_property_condition(key=k, value=v) prop_conditions.append(prop_filters) if 'changes-since' in filters: # normalize timestamp to UTC, as sqlalchemy doesn't appear to # respect timezone offsets changes_since = timeutils.normalize_time(filters.pop('changes-since')) image_conditions.append(models.Image.updated_at > changes_since) if 'deleted' in filters: deleted_filter = filters.pop('deleted') image_conditions.append(models.Image.deleted == deleted_filter) # TODO(bcwaldon): handle this logic in registry server if not deleted_filter: image_statuses = [s for s in STATUSES if s != 'killed'] image_conditions.append(models.Image.status.in_(image_statuses)) if 'tags' in filters: tags = filters.pop('tags') for tag in tags: tag_filters = [models.ImageTag.deleted == False] tag_filters.extend([models.ImageTag.value == tag]) tag_conditions.append(tag_filters) filters = dict([(k, v) for k, v in filters.items() if v is not None]) for (k, v) in filters.items(): key = k if k.endswith('_min') or k.endswith('_max'): key = key[0:-4] try: v = int(filters.pop(k)) except ValueError: msg = _("Unable to filter on a range " "with a non-numeric value.") raise exception.InvalidFilterRangeValue(msg) if k.endswith('_min'): image_conditions.append(getattr(models.Image, key) >= v) if k.endswith('_max'): image_conditions.append(getattr(models.Image, key) <= v) for (k, v) in filters.items(): value = filters.pop(k) if hasattr(models.Image, k): image_conditions.append(getattr(models.Image, k) == value) else: prop_filters = _make_image_property_condition(key=k, value=value) prop_conditions.append(prop_filters) return image_conditions, prop_conditions, tag_conditions
def image_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc'): """ Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties' key is present, it is treated as a dict of key/value filters on the image properties attribute :param marker: image id after which to start page :param limit: maximum number of images to return :param sort_key: image attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) """ filters = filters or {} session = get_session() query = session.query(models.Image)\ .options(sa_orm.joinedload(models.Image.properties)) # NOTE(markwash) treat is_public=None as if it weren't filtered if 'is_public' in filters and filters['is_public'] is None: del filters['is_public'] if not context.is_admin: visibility_filters = [models.Image.is_public == True] if context.owner is not None: visibility_filters.extend([ models.Image.owner == context.owner, models.Image.members.any(member=context.owner, deleted=False), ]) query = query.filter(sa_sql.or_(*visibility_filters)) showing_deleted = False if 'changes-since' in filters: # normalize timestamp to UTC, as sqlalchemy doesn't appear to # respect timezone offsets changes_since = timeutils.normalize_time(filters.pop('changes-since')) query = query.filter(models.Image.updated_at > changes_since) showing_deleted = True if 'deleted' in filters: deleted_filter = filters.pop('deleted') query = query.filter_by(deleted=deleted_filter) showing_deleted = deleted_filter # TODO(bcwaldon): handle this logic in registry server if not deleted_filter: query = query.filter(models.Image.status != 'killed') for (k, v) in filters.pop('properties', {}).items(): query = query.filter(models.Image.properties.any(name=k, value=v, deleted=False)) for (k, v) in filters.items(): if v is not None: key = k if k.endswith('_min') or k.endswith('_max'): key = key[0:-4] try: v = int(v) except ValueError: msg = _("Unable to filter on a range " "with a non-numeric value.") raise exception.InvalidFilterRangeValue(msg) if k.endswith('_min'): query = query.filter(getattr(models.Image, key) >= v) elif k.endswith('_max'): query = query.filter(getattr(models.Image, key) <= v) elif hasattr(models.Image, key): query = query.filter(getattr(models.Image, key) == v) else: query = query.filter(models.Image.properties.any(name=key, value=v)) marker_image = None if marker is not None: marker_image = image_get(context, marker, force_show_deleted=showing_deleted) query = paginate_query(query, models.Image, limit, [sort_key, 'created_at', 'id'], marker=marker_image, sort_dir=sort_dir) return query.all()
def image_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc'): """ Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties' key is present, it is treated as a dict of key/value filters on the image properties attribute :param marker: image id after which to start page :param limit: maximum number of images to return :param sort_key: image attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) """ filters = filters or {} session = get_session() query = session.query(models.Image)\ .options(sa_orm.joinedload(models.Image.properties)) if 'is_public' in filters and filters['is_public'] is not None: the_filter = [models.Image.is_public == filters['is_public']] if filters['is_public'] and context.owner is not None: the_filter.extend([(models.Image.owner == context.owner), models.Image.members.any(member=context.owner, deleted=False)]) if len(the_filter) > 1: query = query.filter(sa_sql.or_(*the_filter)) else: query = query.filter(the_filter[0]) del filters['is_public'] showing_deleted = False if 'changes-since' in filters: # normalize timestamp to UTC, as sqlalchemy doesn't appear to # respect timezone offsets changes_since = timeutils.normalize_time(filters.pop('changes-since')) query = query.filter(models.Image.updated_at > changes_since) showing_deleted = True if 'deleted' in filters: deleted_filter = filters.pop('deleted') query = query.filter_by(deleted=deleted_filter) showing_deleted = deleted_filter # TODO(bcwaldon): handle this logic in registry server if not deleted_filter: query = query.filter(models.Image.status != 'killed') for (k, v) in filters.pop('properties', {}).items(): query = query.filter( models.Image.properties.any(name=k, value=v, deleted=False)) for (k, v) in filters.items(): if v is not None: key = k if k.endswith('_min') or k.endswith('_max'): key = key[0:-4] try: v = int(v) except ValueError: msg = _("Unable to filter on a range " "with a non-numeric value.") raise exception.InvalidFilterRangeValue(msg) if k.endswith('_min'): query = query.filter(getattr(models.Image, key) >= v) elif k.endswith('_max'): query = query.filter(getattr(models.Image, key) <= v) elif hasattr(models.Image, key): query = query.filter(getattr(models.Image, key) == v) else: query = query.filter( models.Image.properties.any(name=key, value=v)) marker_image = None if marker is not None: marker_image = image_get(context, marker, force_show_deleted=showing_deleted) query = paginate_query(query, models.Image, limit, [sort_key, 'created_at', 'id'], marker=marker_image, sort_dir=sort_dir) return query.all()
def image_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc', member_status='accepted', is_public=None): """ Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties' key is present, it is treated as a dict of key/value filters on the image properties attribute :param marker: image id after which to start page :param limit: maximum number of images to return :param sort_key: image attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) :param member_status: only return shared images that have this membership status :param is_public: If true, return only public images. If false, return only private and shared images. """ filters = filters or {} session = _get_session() query = session.query(models.Image)\ .options(sa_orm.joinedload(models.Image.properties))\ .options(sa_orm.joinedload(models.Image.locations)) if not context.is_admin: visibility_filters = [models.Image.is_public == True] if context.owner is not None: if member_status == 'all': visibility_filters.extend([ models.Image.owner == context.owner, models.Image.members.any(member=context.owner, deleted=False), ]) else: visibility_filters.extend([ models.Image.owner == context.owner, models.Image.members.any(member=context.owner, deleted=False, status=member_status), ]) query = query.filter(sa_sql.or_(*visibility_filters)) if 'visibility' in filters: visibility = filters.pop('visibility') if visibility == 'public': query = query.filter(models.Image.is_public == True) elif visibility == 'private': query = query.filter(models.Image.is_public == False) if (not context.is_admin) and context.owner is not None: query = query.filter( models.Image.owner == context.owner) else: query = query.filter( models.Image.members.any(member=context.owner, deleted=False)) if is_public is not None: query = query.filter(models.Image.is_public == is_public) if 'is_public' in filters: spec = models.Image.properties.any(name='is_public', value=filters.pop('is_public'), deleted=False) query = query.filter(spec) showing_deleted = False if 'changes-since' in filters: # normalize timestamp to UTC, as sqlalchemy doesn't appear to # respect timezone offsets changes_since = timeutils.normalize_time(filters.pop('changes-since')) query = query.filter(models.Image.updated_at > changes_since) showing_deleted = True if 'deleted' in filters: deleted_filter = filters.pop('deleted') query = query.filter_by(deleted=deleted_filter) showing_deleted = deleted_filter # TODO(bcwaldon): handle this logic in registry server if not deleted_filter: query = query.filter(models.Image.status != 'killed') for (k, v) in filters.pop('properties', {}).items(): query = query.filter(models.Image.properties.any(name=k, value=v, deleted=False)) for (k, v) in filters.items(): if v is not None: key = k if k.endswith('_min') or k.endswith('_max'): key = key[0:-4] try: v = int(v) except ValueError: msg = _("Unable to filter on a range " "with a non-numeric value.") raise exception.InvalidFilterRangeValue(msg) if k.endswith('_min'): query = query.filter(getattr(models.Image, key) >= v) elif k.endswith('_max'): query = query.filter(getattr(models.Image, key) <= v) elif hasattr(models.Image, key): query = query.filter(getattr(models.Image, key) == v) else: query = query.filter(models.Image.properties.any(name=key, value=v)) marker_image = None if marker is not None: marker_image = _image_get(context, marker, force_show_deleted=showing_deleted) query = _paginate_query(query, models.Image, limit, [sort_key, 'created_at', 'id'], marker=marker_image, sort_dir=sort_dir) return [_normalize_locations(image.to_dict()) for image in query.all()]
def image_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc', member_status='accepted', is_public=None, admin_as_user=False): """ Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties' key is present, it is treated as a dict of key/value filters on the image properties attribute :param marker: image id after which to start page :param limit: maximum number of images to return :param sort_key: image attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) :param member_status: only return shared images that have this membership status :param is_public: If true, return only public images. If false, return only private and shared images. :param admin_as_user: For backwards compatibility. If true, then return to an admin the equivalent set of images which it would see if it were a regular user """ filters = filters or {} session = _get_session() query_image = session.query(models.Image) query_member = session.query(models.Image).join(models.Image.members) if (not context.is_admin) or admin_as_user == True: visibility_filters = [models.Image.is_public == True] member_filters = [models.ImageMember.deleted == False] if context.owner is not None: if member_status == 'all': visibility_filters.extend([ models.Image.owner == context.owner]) member_filters.extend([ models.ImageMember.member == context.owner]) else: visibility_filters.extend([ models.Image.owner == context.owner]) member_filters.extend([ models.ImageMember.member == context.owner, models.ImageMember.status == member_status]) query_image = query_image.filter(sa_sql.or_(*visibility_filters)) query_member = query_member.filter(sa_sql.and_(*member_filters)) query = query_image.union(query_member) if 'visibility' in filters: visibility = filters.pop('visibility') if visibility == 'public': query = query.filter(models.Image.is_public == True) elif visibility == 'private': query = query.filter(models.Image.is_public == False) if context.owner is not None and ((not context.is_admin) or admin_as_user == True): query = query.filter( models.Image.owner == context.owner) else: query_member = query_member.filter( models.ImageMember.member == context.owner, models.ImageMember.deleted == False) query = query_member if is_public is not None: query = query.filter(models.Image.is_public == is_public) if 'is_public' in filters: spec = models.Image.properties.any(name='is_public', value=filters.pop('is_public'), deleted=False) query = query.filter(spec) showing_deleted = False if 'checksum' in filters: checksum = filters.get('checksum') query = query.filter_by(checksum=checksum) if 'changes-since' in filters: # normalize timestamp to UTC, as sqlalchemy doesn't appear to # respect timezone offsets changes_since = timeutils.normalize_time(filters.pop('changes-since')) query = query.filter(models.Image.updated_at > changes_since) showing_deleted = True if 'deleted' in filters: deleted_filter = filters.pop('deleted') query = query.filter_by(deleted=deleted_filter) showing_deleted = deleted_filter # TODO(bcwaldon): handle this logic in registry server if not deleted_filter: query = query.filter(models.Image.status != 'killed') for (k, v) in filters.pop('properties', {}).items(): query = query.filter(models.Image.properties.any(name=k, value=v, deleted=False)) for (k, v) in filters.items(): if v is not None: key = k if k.endswith('_min') or k.endswith('_max'): key = key[0:-4] try: v = int(v) except ValueError: msg = _("Unable to filter on a range " "with a non-numeric value.") raise exception.InvalidFilterRangeValue(msg) if k.endswith('_min'): query = query.filter(getattr(models.Image, key) >= v) elif k.endswith('_max'): query = query.filter(getattr(models.Image, key) <= v) elif hasattr(models.Image, key): query = query.filter(getattr(models.Image, key) == v) else: query = query.filter(models.Image.properties.any(name=key, value=v)) marker_image = None if marker is not None: marker_image = _image_get(context, marker, force_show_deleted=showing_deleted) query = _paginate_query(query, models.Image, limit, [sort_key, 'created_at', 'id'], marker=marker_image, sort_dir=sort_dir) query = query.options(sa_orm.joinedload(models.Image.properties))\ .options(sa_orm.joinedload(models.Image.locations)) return [_normalize_locations(image.to_dict()) for image in query.all()]
def image_get_all(context, filters=None, marker=None, limit=None, sort_key="created_at", sort_dir="desc"): """ Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties' key is present, it is treated as a dict of key/value filters on the image properties attribute :param marker: image id after which to start page :param limit: maximum number of images to return :param sort_key: image attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) """ filters = filters or {} session = get_session() query = session.query(models.Image).options(sqlalchemy.orm.joinedload(models.Image.properties)) if "is_public" in filters and filters["is_public"] is not None: the_filter = [models.Image.is_public == filters["is_public"]] if filters["is_public"] and context.owner is not None: the_filter.extend( [(models.Image.owner == context.owner), models.Image.members.any(member=context.owner, deleted=False)] ) if len(the_filter) > 1: query = query.filter(sqlalchemy.sql.or_(*the_filter)) else: query = query.filter(the_filter[0]) del filters["is_public"] showing_deleted = False if "changes-since" in filters: # normalize timestamp to UTC, as sqlalchemy doesn't appear to # respect timezone offsets changes_since = timeutils.normalize_time(filters.pop("changes-since")) query = query.filter(models.Image.updated_at > changes_since) showing_deleted = True if "deleted" in filters: deleted_filter = filters.pop("deleted") query = query.filter_by(deleted=deleted_filter) showing_deleted = deleted_filter # TODO(bcwaldon): handle this logic in registry server if not deleted_filter: query = query.filter(models.Image.status != "killed") for (k, v) in filters.pop("properties", {}).items(): query = query.filter(models.Image.properties.any(name=k, value=v)) for (k, v) in filters.items(): if v is not None: key = k if k.endswith("_min") or k.endswith("_max"): key = key[0:-4] try: v = int(v) except ValueError: msg = _("Unable to filter on a range " "with a non-numeric value.") raise exception.InvalidFilterRangeValue(msg) if k.endswith("_min"): query = query.filter(getattr(models.Image, key) >= v) elif k.endswith("_max"): query = query.filter(getattr(models.Image, key) <= v) elif hasattr(models.Image, key): query = query.filter(getattr(models.Image, key) == v) else: query = query.filter(models.Image.properties.any(name=key, value=v)) marker_image = None if marker is not None: marker_image = image_get(context, marker, force_show_deleted=showing_deleted) query = paginate_query( query, models.Image, limit, [sort_key, "created_at", "id"], marker=marker_image, sort_dir=sort_dir ) return query.all()
def image_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc'): """ Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties' key is present, it is treated as a dict of key/value filters on the image properties attribute :param marker: image id after which to start page :param limit: maximum number of images to return :param sort_key: image attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) """ filters = filters or {} session = get_session() query = session.query(models.Image).\ options(sqlalchemy.orm.joinedload(models.Image.properties)) if 'size_min' in filters: query = query.filter(models.Image.size >= filters['size_min']) del filters['size_min'] if 'size_max' in filters: query = query.filter(models.Image.size <= filters['size_max']) del filters['size_max'] if 'is_public' in filters and filters['is_public'] is not None: the_filter = [models.Image.is_public == filters['is_public']] if filters['is_public'] and context.owner is not None: the_filter.extend([ (models.Image.owner == context.owner), models.Image.members.any(member=context.owner, deleted=False) ]) if len(the_filter) > 1: query = query.filter(sqlalchemy.sql.or_(*the_filter)) else: query = query.filter(the_filter[0]) del filters['is_public'] showing_deleted = False if 'changes-since' in filters: # normalize timestamp to UTC, as sqlalchemy doesn't appear to # respect timezone offsets changes_since = timeutils.normalize_time(filters.pop('changes-since')) query = query.filter(models.Image.updated_at > changes_since) showing_deleted = True if 'deleted' in filters: deleted_filter = filters.pop('deleted') query = query.filter_by(deleted=deleted_filter) showing_deleted = deleted_filter # TODO(bcwaldon): handle this logic in registry server if not deleted_filter: query = query.filter(models.Image.status != 'killed') for (k, v) in filters.pop('properties', {}).items(): query = query.filter(models.Image.properties.any(name=k, value=v)) for (k, v) in filters.items(): if v is not None: query = query.filter(getattr(models.Image, k) == v) marker_image = None if marker is not None: marker_image = image_get(context, marker, force_show_deleted=showing_deleted) query = paginate_query(query, models.Image, limit, [sort_key, 'created_at', 'id'], marker=marker_image, sort_dir=sort_dir) return query.all()