Skip to content

Instantly share code, notes, and snippets.

@jimbaker
Created October 11, 2016 06:00
Show Gist options
  • Select an option

  • Save jimbaker/2ac685f97c5c08a8566783558d986ba7 to your computer and use it in GitHub Desktop.

Select an option

Save jimbaker/2ac685f97c5c08a8566783558d986ba7 to your computer and use it in GitHub Desktop.
Add host label PUT support
diff --git a/craton/api/v1/resources/inventory/hosts.py b/craton/api/v1/resources/inventory/hosts.py
index 39264a5..39be56a 100644
--- a/craton/api/v1/resources/inventory/hosts.py
+++ b/craton/api/v1/resources/inventory/hosts.py
@@ -97,10 +97,10 @@ class HostsLabels(base.Resource):
Update existing device label entirely, or add if it does
not exist.
"""
- print(request.json)
+ import sys; print(request.json, file=sys.stderr)
context = request.environ.get('context')
- dbapi.hosts_labels_update(context, id, request.json)
- return request.json, 200, None
+ labels_obj = dbapi.hosts_labels_update(context, id, request.json)
+ return jsonutils.to_primitive(labels_obj), 200, None
@base.http_codes
def delete(self, id):
diff --git a/craton/db/sqlalchemy/alembic/versions/ffdc1a500db1_craton_inventory_init.py b/craton/db/sqlalchemy/alembic/versions/ffdc1a500db1_craton_inventory_init.py
index 1308830..74350b4 100644
--- a/craton/db/sqlalchemy/alembic/versions/ffdc1a500db1_craton_inventory_init.py
+++ b/craton/db/sqlalchemy/alembic/versions/ffdc1a500db1_craton_inventory_init.py
@@ -55,6 +55,7 @@ def upgrade():
sa.Column('variable_association_id', sa.Integer),
sa.Column('label', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('id'),
+ sa.UniqueConstraint('label'),
sa.ForeignKeyConstraint(
['variable_association_id'], ['variable_association.id'],
'fk_labels_variable_association')
diff --git a/craton/db/sqlalchemy/api.py b/craton/db/sqlalchemy/api.py
index 3827c97..aefdf4e 100644
--- a/craton/db/sqlalchemy/api.py
+++ b/craton/db/sqlalchemy/api.py
@@ -9,6 +9,7 @@ from oslo_db.sqlalchemy import utils as db_utils
from oslo_log import log
import sqlalchemy.orm.exc as sa_exc
+from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import with_polymorphic
from craton import exceptions
@@ -457,6 +458,7 @@ def hosts_data_delete(context, host_id, data):
def hosts_labels_update(context, host_id, labels):
"""Update labels for host. Add the label if it is not present
in host labels list, otherwise do nothing."""
+ print('host_id', host_id)
session = get_session()
with session.begin():
host_devices = with_polymorphic(models.Device, '*')
@@ -466,14 +468,32 @@ def hosts_labels_update(context, host_id, labels):
query = query.filter_by(id=host_id)
try:
host = query.one()
- except sa_exc.NoResultFound:
- raise exceptions.NotFound()
-
- present_labels = [l.label for l in host.labels]
- to_update = [i for i in labels["labels"] if i not in present_labels]
- _labels = [models.Label(i) for i in to_update]
- host.labels.update(_labels)
+ print('host', host)
+ except sa_exc.NoResultFound as e:
+ raise exceptions.NotFound() from e
+
+ labels = set(labels)
+ add_to_host_labels = labels - set(host.associated_labels)
+
+ if not add_to_host_labels:
+ return set()
+
+ # Get existing labels from the database in the context of this
+ # transaction. NOTE: it is possible that another session could
+ # be updating simultaneously, in which case this query -- and
+ # corresponding REST API call -- would have to be re-applied
+ # again.
+ existing_label_objs = session.query(models.Label).filter(
+ models.Label.label.in_(add_to_host_labels)).all()
+ new_label_obs = set()
+ existing_labels = {label.label for label in existing_label_objs}
+ for label in add_to_host_labels:
+ if label not in existing_labels:
+ label_obj = models.Label(label)
+ host.labels.add(label_obj)
+ host.labels.update(existing_label_objs)
host.save(session)
+ return add_to_host_labels
def hosts_labels_delete(context, host_id, labels):
diff --git a/craton/db/sqlalchemy/models.py b/craton/db/sqlalchemy/models.py
index 920663e..ee0d2a8 100644
--- a/craton/db/sqlalchemy/models.py
+++ b/craton/db/sqlalchemy/models.py
@@ -425,7 +425,7 @@ class Label(Base, VariableMixin):
"""
__tablename__ = 'labels'
id = Column(Integer, primary_key=True)
- label = Column(String(255), unique=False)
+ label = Column(String(255), unique=True)
_repr_columns = [label]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment