Story #7127
closedAdd object labels
100%
Description
Proposal¶
As a developer, it would be nice to be able to label pulp objects such as repositories. To accomplish this, I propose adding Kubernetes style labels to pulp objects (more information on kubernetes labels here: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/).
Labels are arbitrary key value pairs that can be applied to objects and used to query them. For example, I could attach a label1=foo
, label2=foo
, and label3=foobar
to a repository. The repository could then be queried by any of the following methods
-
foo=bar
: select all objects that have the foo label set to bar -
foo!=bar
: select all objects that have the foo label set to anything except bar -
foo in (bar, foobar)
: selects all objects with the foo label that contain either the values for bar or foobar -
foo notin (bar, foobar)
: selects all objects with the foo label that don't contain bar or foobar -
foo
: selects all objects that contain the label foo (regardless of value) -
!foo
: selects all objects that don't contain the label foo
Use cases¶
In galaxy_ng we need a way to filter repositories based on what they are used for. For example we are going to have the following repositories
-
published
- contains locally published collections. Should be searchable. Is the default repo if no repo is provided -
staging
- content waiting for approval. Not searchable -
rejected
- content that has been rejected. Not searchable -
rh-certified
- content synced from automation hub. Contains red hat certified content. Searchable -
community
- content synced from galaxy. Searchable
As well as an arbitrary number of repositories named inbound-<namespace_name> for uploading collections. Not searchable.
Right now the names for these repos are hard coded as a way for the API to identify which content should go where, however with label support we could add the following labels
- searchable= true | false
- default=true | false
- content-readiness= production | inbound | staging
- certification= community | rh-certified | local
With these labels we can:
- limit search results to repos that match
searchable=true
- separate inbound repos with
content-readiness!=inbound
- identify which repositories contain certified content with
certification=rh-certified
Design¶
API Design¶
Filtering¶
Labels can be filtered by passing a urlencoded string to a label_selector
parameter.
Some examples based on the kubernetes documentation:
-
?label_selector=environment%3Dproduction,tier%3Dfrontend
- Evaluates to
environment=production,tier=frontend
- Evaluates to
-
?label_selector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29
- Evaluates to
environment in (production,qa),tier in (frontend)
- Evaluates to
Note: Ansible Galaxy and RHUI have agreed that for a first pass, we could just support a subset of operators (ie =
and !=
).
LabelSelectFilter¶
LabelSelectFilter
would be a django_filter.Filter
that parses the label_select parameter and then filters the queryset. It can be applied to a Queryset of any model with labels.
Note: for an example of a complex Filter
, see the RepositoryVersionFilter
.
LabelSerializer¶
Create a new LabelSerializer
that can be nested into other model serializers as a field (much like the CreatedResourceSerializer
). This serializer should be both readable and writable and should enable the following API calls.
Reading¶
# GET /pulp/api/v3/repositories/file/file/
{
...
"labels": {"foo": "bar", "foo2": "baz"},
...
}
Setting/Updating¶
# POST /pulp/api/v3/repositories/file/file/ name=test labels:='{"foo": "bar"}'
{
...
"labels": {"foo": "bar"},
...
}
# PATCH /pulp/api/v3/repositories/file/file/<uuid>/ labels:='{"something": "else"}'
{
...
"labels": {"something": "else"},
...
}
# PATCH /pulp/api/v3/repositories/file/file/<uuid>/ labels:='{}'
{
...
"labels": {},
...
}
Database Design¶
Label (extends GenericRelationModel)¶
- resource - generic foreign key
- key (CharField) - the key of the label
- value (TextField) - the value for a label
Notes
-
Label
resource
andkey
are unique together - We should also limit
key
to alphanumerics - The
Label
gets deleted when the resource gets deleted (whichGenericRelationModel
does) -
key
andvalue
should be indexed (db_index=True
)
Related issues