Skip to content

Commit

Permalink
Added objects Tag and TagList
Browse files Browse the repository at this point in the history
Also field 'tags' was added to the instance object.
These objects will be used in new instance-tags API extension.

Implements: blueprint tag-instances
Change-Id: I34ec32f0b3704b01aaca9c0cb2b34eb6d3107513
  • Loading branch information
niksv committed Dec 2, 2014
1 parent 9ccad00 commit 5783c04
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 18 deletions.
1 change: 1 addition & 0 deletions nova/objects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def register_all():
__import__('nova.objects.network_request')
__import__('nova.objects.numa')
__import__('nova.objects.pci_device')
__import__('nova.objects.tag')
__import__('nova.objects.quotas')
__import__('nova.objects.security_group')
__import__('nova.objects.security_group_rule')
Expand Down
7 changes: 5 additions & 2 deletions nova/objects/block_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class BlockDeviceMapping(base.NovaPersistentObject, base.NovaObject):
# Version 1.2: Instance version 1.14
# Version 1.3: Instance version 1.15
# Version 1.4: Instance version 1.16
VERSION = '1.4'
# Version 1.5: Instance version 1.17
VERSION = '1.5'

fields = {
'id': fields.IntegerField(),
Expand Down Expand Up @@ -211,7 +212,8 @@ class BlockDeviceMappingList(base.ObjectListBase, base.NovaObject):
# Version 1.3: BlockDeviceMapping <= version 1.2
# Version 1.4: BlockDeviceMapping <= version 1.3
# Version 1.5: BlockDeviceMapping <= version 1.4
VERSION = '1.5'
# Version 1.6: BlockDeviceMapping <= version 1.5
VERSION = '1.6'

fields = {
'objects': fields.ListOfObjectsField('BlockDeviceMapping'),
Expand All @@ -223,6 +225,7 @@ class BlockDeviceMappingList(base.ObjectListBase, base.NovaObject):
'1.3': '1.2',
'1.4': '1.3',
'1.5': '1.4',
'1.6': '1.5',
}

@base.remotable_classmethod
Expand Down
7 changes: 5 additions & 2 deletions nova/objects/fixed_ip.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class FixedIP(obj_base.NovaPersistentObject, obj_base.NovaObject):
# Version 1.4: Added default_route field
# Version 1.5: Added floating_ips field
# Version 1.6: Instance 1.16
VERSION = '1.6'
# Version 1.7: Instance 1.17
VERSION = '1.7'

fields = {
'id': fields.IntegerField(),
Expand Down Expand Up @@ -209,7 +210,8 @@ class FixedIPList(obj_base.ObjectListBase, obj_base.NovaObject):
# Version 1.4: FixedIP <= version 1.4
# Version 1.5: FixedIP <= version 1.5, added expected attrs to gets
# Version 1.6: FixedIP <= version 1.6
VERSION = '1.6'
# Version 1.7: FixedIP <= version 1.7
VERSION = '1.7'

fields = {
'objects': fields.ListOfObjectsField('FixedIP'),
Expand All @@ -222,6 +224,7 @@ class FixedIPList(obj_base.ObjectListBase, obj_base.NovaObject):
'1.4': '1.4',
'1.5': '1.5',
'1.6': '1.6',
'1.7': '1.7',
}

@obj_base.remotable_classmethod
Expand Down
20 changes: 17 additions & 3 deletions nova/objects/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# List of fields that can be joined in DB layer.
_INSTANCE_OPTIONAL_JOINED_FIELDS = ['metadata', 'system_metadata',
'info_cache', 'security_groups',
'pci_devices']
'pci_devices', 'tags']
# These are fields that are optional but don't translate to db columns
_INSTANCE_OPTIONAL_NON_COLUMN_FIELDS = ['fault']
# These are fields that are optional and in instance_extra
Expand Down Expand Up @@ -86,7 +86,8 @@ class Instance(base.NovaPersistentObject, base.NovaObject):
# Version 1.14: Added numa_topology
# Version 1.15: PciDeviceList 1.1
# Version 1.16: Added pci_requests
VERSION = '1.16'
# Version 1.17: Added tags
VERSION = '1.17'

fields = {
'id': fields.IntegerField(),
Expand Down Expand Up @@ -176,6 +177,7 @@ class Instance(base.NovaPersistentObject, base.NovaObject):
nullable=True),
'pci_requests': fields.ObjectField('InstancePCIRequests',
nullable=True),
'tags': fields.ObjectField('TagList'),
}

obj_extra_fields = ['name']
Expand Down Expand Up @@ -248,6 +250,10 @@ def obj_make_compatible(self, primitive, target_version):
del primitive['pci_devices']
if target_version < (1, 16) and 'pci_requests' in primitive:
del primitive['pci_requests']
if target_version < (1, 17):
# NOTE(snikitin): Before 1.17 there was no tags list
if 'tags' in primitive:
del primitive['tags']

@property
def name(self):
Expand Down Expand Up @@ -333,6 +339,12 @@ def _from_db_object(context, instance, db_inst, expected_attrs=None):
objects.SecurityGroup, db_inst['security_groups'])
instance['security_groups'] = sec_groups

if 'tags' in expected_attrs:
tags = base.obj_make_list(
context, objects.TagList(context),
objects.Tag, db_inst['tags'])
instance['tags'] = tags

instance.obj_reset_changes()
return instance

Expand Down Expand Up @@ -715,7 +727,8 @@ class InstanceList(base.ObjectListBase, base.NovaObject):
# Version 1.10: Instance <= version 1.16
# Version 1.11: Added sort_keys and sort_dirs to get_by_filters
# Version 1.12: Pass expected_attrs to instance_get_active_by_window_joined
VERSION = '1.12'
# Version 1.13: Instance <= version 1.17
VERSION = '1.13'

fields = {
'objects': fields.ListOfObjectsField('Instance'),
Expand All @@ -734,6 +747,7 @@ class InstanceList(base.ObjectListBase, base.NovaObject):
'1.10': '1.16',
'1.11': '1.16',
'1.12': '1.16',
'1.13': '1.17',
}

@base.remotable_classmethod
Expand Down
69 changes: 69 additions & 0 deletions nova/objects/tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from nova import db
from nova import objects
from nova.objects import base
from nova.objects import fields


class Tag(base.NovaObject):
# Version 1.0: Initial version
VERSION = '1.0'

fields = {
'resource_id': fields.StringField(),
'tag': fields.StringField(),
}

@staticmethod
def _from_db_object(context, tag, db_tag):
for key in tag.fields:
tag[key] = db_tag[key]
tag.obj_reset_changes()
tag._context = context
return tag

@base.remotable
def create(self, context):
db_tag = db.instance_tag_add(context, self.resource_id, self.tag)
self._from_db_object(context, self, db_tag)

@base.remotable_classmethod
def destroy(cls, context, resource_id, name):
db.instance_tag_delete(context, resource_id, name)


class TagList(base.ObjectListBase, base.NovaObject):
# Version 1.0: Initial version
VERSION = '1.0'

fields = {
'objects': fields.ListOfObjectsField('Tag'),
}
child_versions = {
'1.0': '1.0',
}

@base.remotable_classmethod
def get_by_resource_id(cls, context, resource_id):
db_tags = db.instance_tag_get_by_instance_uuid(context, resource_id)
return base.obj_make_list(context, cls(), objects.Tag, db_tags)

@base.remotable_classmethod
def create(cls, context, resource_id, tags):
db_tags = db.instance_tag_set(context, resource_id, tags)
return base.obj_make_list(context, cls(), objects.Tag, db_tags)

@base.remotable_classmethod
def destroy(cls, context, resource_id):
db.instance_tag_delete_all(context, resource_id)
1 change: 1 addition & 0 deletions nova/tests/unit/fake_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def fake_db_instance(**updates):
'ephemeral_gb': 0,
'extra': {'pci_requests': None,
'numa_topology': None},
'tags': []
}

for name, field in objects.Instance.fields.items():
Expand Down
5 changes: 3 additions & 2 deletions nova/tests/unit/objects/test_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def fake_instance(self):
fake_instance['pci_devices'] = []
fake_instance['user_id'] = self.context.user_id
fake_instance['project_id'] = self.context.project_id
fake_instance['tags'] = []
return fake_instance

def test_datetime_deserialization(self):
Expand All @@ -74,7 +75,7 @@ def test_datetime_deserialization(self):
primitive = inst.obj_to_primitive()
expected = {'nova_object.name': 'Instance',
'nova_object.namespace': 'nova',
'nova_object.version': '1.16',
'nova_object.version': '1.17',
'nova_object.data':
{'uuid': 'fake-uuid',
'launched_at': '1955-11-05T00:00:00Z'},
Expand All @@ -90,7 +91,7 @@ def test_ip_deserialization(self):
primitive = inst.obj_to_primitive()
expected = {'nova_object.name': 'Instance',
'nova_object.namespace': 'nova',
'nova_object.version': '1.16',
'nova_object.version': '1.17',
'nova_object.data':
{'uuid': 'fake-uuid',
'access_ip_v4': '1.2.3.4',
Expand Down
21 changes: 12 additions & 9 deletions nova/tests/unit/objects/test_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1075,23 +1075,23 @@ def test_object_serialization_iterables(self):
'AggregateList': '1.2-4b02a285b8612bfb86a96ff80052fb0a',
'BandwidthUsage': '1.2-a9d7c2ba54995e48ce38688c51c9416d',
'BandwidthUsageList': '1.2-5b564cbfd5ae6e106443c086938e7602',
'BlockDeviceMapping': '1.4-9968ffe513e7672484b0f528b034cd0f',
'BlockDeviceMappingList': '1.5-83767968de6e91e9705bddaae02bc649',
'BlockDeviceMapping': '1.5-9968ffe513e7672484b0f528b034cd0f',
'BlockDeviceMappingList': '1.6-ee2ed2eb3f3f2f54d573ccea0ff2eeaa',
'ComputeNode': '1.6-d2ea9b8f4a6e95ff6a683266eebddbff',
'ComputeNodeList': '1.6-205aa2ea08d49f6ce87df1fcd2407b4e',
'DNSDomain': '1.0-5bdc288d7c3b723ce86ede998fd5c9ba',
'DNSDomainList': '1.0-cfb3e7e82be661501c31099523154db4',
'EC2InstanceMapping': '1.0-627baaf4b12c9067200979bdc4558a99',
'EC2SnapshotMapping': '1.0-26cf315be1f8abab4289d4147671c836',
'EC2VolumeMapping': '1.0-2f8c3bf077c65a425294ec2b361c9143',
'FixedIP': '1.6-2472964d39e50da67202109eb85cd173',
'FixedIPList': '1.6-f2f740de66bc2d90627004bd311690ad',
'FixedIP': '1.7-2472964d39e50da67202109eb85cd173',
'FixedIPList': '1.7-125de790b58cfb8c84ffc8c34db4a81e',
'Flavor': '1.1-096cfd023c35d07542cf732fb29b45e4',
'FlavorList': '1.1-a3d5551267cb8f62ff38ded125900721',
'FloatingIP': '1.6-27eb68b7c9c620dd5f0561b5a3be0e82',
'FloatingIPList': '1.7-f376f63ed99243f9d90841b7f6732bbf',
'HVSpec': '1.0-c4d8377cc4fe519930e60c1d8265a142',
'Instance': '1.16-b00c09fb92ae80b393943f56e84abd9c',
'Instance': '1.17-972cae223db35e88bb184bdf8c197229',
'InstanceAction': '1.1-6b1d0a6dbd522b5a83c20757ec659663',
'InstanceActionEvent': '1.1-42dbdba74bd06e0619ca75cd3397cd1b',
'InstanceActionEventList': '1.0-1d5cc958171d6ce07383c2ad6208318e',
Expand All @@ -1102,7 +1102,7 @@ def test_object_serialization_iterables(self):
'InstanceGroup': '1.9-95ece99f092e8f4f88327cdbb44162c9',
'InstanceGroupList': '1.6-c6b78f3c9d9080d33c08667e80589817',
'InstanceInfoCache': '1.5-ef64b604498bfa505a8c93747a9d8b2f',
'InstanceList': '1.12-f044d117e39478498e0d3124c5c4ef54',
'InstanceList': '1.13-179093360c48747a41694cc2f326d75d',
'InstanceNUMACell': '1.1-8d2a13c8360cc9ea1b68c9c6c4476857',
'InstanceNUMATopology': '1.1-86b95d263c4c68411d44c6741b8d2bb0',
'InstancePCIRequest': '1.1-e082d174f4643e5756ba098c47c1510f',
Expand Down Expand Up @@ -1131,22 +1131,25 @@ def test_object_serialization_iterables(self):
'Service': '1.5-82bbfd46a744a9c89bc44b47a1b81683',
'ServiceList': '1.3-4a1a5822dea268d0d7f892f5106bb2e1',
'TestSubclassedObject': '1.6-b9be83b5587fbca3c8570aab67cb3d02',
'Tag': '1.0-a11531f4e4e3166eef6243d6d58a18bd',
'TagList': '1.0-e89bf8c8055f1f1d654fb44f0abf1f53',
'VirtualInterface': '1.0-10fdac4c704102b6d57d6936d6d790d2',
'VirtualInterfaceList': '1.0-accbf02628a8063c1d885077a2bf49b6',
'VirtCPUTopology': '1.0-fc694de72e20298f7c6bab1083fd4563',
}


object_relationships = {
'BlockDeviceMapping': {'Instance': '1.16'},
'FixedIP': {'Instance': '1.16', 'Network': '1.2',
'BlockDeviceMapping': {'Instance': '1.17'},
'FixedIP': {'Instance': '1.17', 'Network': '1.2',
'VirtualInterface': '1.0',
'FloatingIPList': '1.7'},
'FloatingIP': {'FixedIP': '1.6'},
'FloatingIP': {'FixedIP': '1.7'},
'Instance': {'InstanceFault': '1.2',
'InstanceInfoCache': '1.5',
'InstanceNUMATopology': '1.1',
'PciDeviceList': '1.1',
'TagList': '1.0',
'SecurityGroupList': '1.0',
'InstancePCIRequests': '1.1'},
'MyObj': {'MyOwnedObject': '1.0'},
Expand Down
Loading

0 comments on commit 5783c04

Please sign in to comment.