From 902a9ac65bcd94834bbebe83d571381f811b7205 Mon Sep 17 00:00:00 2001 From: Zhenguo Niu Date: Mon, 31 Jul 2017 17:06:44 +0800 Subject: [PATCH] Add resource aggregates filed to flavor This addes a new aggregates field to flavor including aggregates metadata key/value pairs. Then we can extract resources quantitive, qualative and group informations from flavors. Change-Id: Ia85ff44fa9aabf2ef172c65c9ba9a3f0ce611b50 --- api-ref/source/v1/flavors.inc | 5 +++++ api-ref/source/v1/parameters.yaml | 9 ++++++++- .../v1/samples/flavors/flavor-create-post-req.json | 3 +++ .../v1/samples/flavors/flavor-create-post-resp.json | 3 +++ api-ref/source/v1/samples/flavors/flavor-get-resp.json | 3 +++ .../v1/samples/flavors/flavor-update-put-resp.json | 3 +++ api-ref/source/v1/samples/flavors/flavors-list-resp.json | 6 ++++++ mogan/api/controllers/v1/flavors.py | 3 +++ mogan/api/controllers/v1/schemas/flavor.py | 1 + .../alembic/versions/91941bf1ebc9_initial_migration.py | 1 + mogan/db/sqlalchemy/models.py | 1 + mogan/objects/flavor.py | 1 + mogan/tests/functional/api/v1/test_flavors.py | 4 +++- mogan/tests/tempest/api/test_flavors.py | 5 ++++- mogan/tests/unit/db/utils.py | 1 + mogan/tests/unit/objects/test_objects.py | 2 +- 16 files changed, 47 insertions(+), 4 deletions(-) diff --git a/api-ref/source/v1/flavors.inc b/api-ref/source/v1/flavors.inc index ecf9e44b..163658d0 100644 --- a/api-ref/source/v1/flavors.inc +++ b/api-ref/source/v1/flavors.inc @@ -36,6 +36,7 @@ Response - description: flavor_description - resources: flavor_resources - resource_traits: flavor_resource_traits + - resource_aggregates: flavor_aggregates - uuid: flavor_uuid - created_at: created_at - updated_at: updated_at @@ -71,6 +72,7 @@ Request - description: flavor_description - resources: flavor_resources - resource_traits: flavor_resource_traits + - resource_aggregates: flavor_aggregates - is_public: flavor_is_public_not_required - disabled: flavor_disabled @@ -89,6 +91,7 @@ Response - description: flavor_description - resources: flavor_resources - resource_traits: flavor_resource_traits + - resource_aggregates: flavor_aggregates - uuid: flavor_uuid - created_at: created_at - updated_at: updated_at @@ -140,6 +143,7 @@ Response - description: flavor_description - resources: flavor_resources - resource_traits: flavor_resource_traits + - resource_aggregates: flavor_aggregates - uuid: flavor_uuid - created_at: created_at - updated_at: updated_at @@ -179,6 +183,7 @@ Response - description: flavor_description - resources: flavor_resources - resource_traits: flavor_resource_traits + - resource_aggregates: flavor_aggregates - uuid: flavor_uuid - created_at: created_at - updated_at: updated_at diff --git a/api-ref/source/v1/parameters.yaml b/api-ref/source/v1/parameters.yaml index efe4ec09..f4466478 100644 --- a/api-ref/source/v1/parameters.yaml +++ b/api-ref/source/v1/parameters.yaml @@ -232,6 +232,13 @@ flavor_access: in: body required: true type: array +flavor_aggregates: + description: | + A dict of key and value pairs associate with the flavor including the resources + aggregate metadata. + in: body + required: true + type: object flavor_description: description: | The description of the flavor. @@ -277,7 +284,7 @@ flavor_resources: name and the quantity. in: body required: true - type: string + type: object flavor_uuid: description: | The UUID of the flavor. diff --git a/api-ref/source/v1/samples/flavors/flavor-create-post-req.json b/api-ref/source/v1/samples/flavors/flavor-create-post-req.json index 0ab8c806..c9866463 100644 --- a/api-ref/source/v1/samples/flavors/flavor-create-post-req.json +++ b/api-ref/source/v1/samples/flavors/flavor-create-post-req.json @@ -7,6 +7,9 @@ "resource_traits": { "CUSTOM_BAREMETAL_GOLD": "FPGA" }, + "resource_aggregates": { + "high_mem": "true" + }, "is_public": true, "disabled": true } diff --git a/api-ref/source/v1/samples/flavors/flavor-create-post-resp.json b/api-ref/source/v1/samples/flavors/flavor-create-post-resp.json index fe61540a..240d98b9 100644 --- a/api-ref/source/v1/samples/flavors/flavor-create-post-resp.json +++ b/api-ref/source/v1/samples/flavors/flavor-create-post-resp.json @@ -16,6 +16,9 @@ "resource_traits": { "CUSTOM_BAREMETAL_GOLD": "FPGA" }, + "resource_aggregates": { + "high_mem": "true" + }, "created_at": "2016-09-27T02:37:21.966342+00:00", "uuid": "7de2859d-ec6d-42c7-bb86-9d630ba5ac94", "updated_at": null, diff --git a/api-ref/source/v1/samples/flavors/flavor-get-resp.json b/api-ref/source/v1/samples/flavors/flavor-get-resp.json index 4ad7631f..16bacd20 100644 --- a/api-ref/source/v1/samples/flavors/flavor-get-resp.json +++ b/api-ref/source/v1/samples/flavors/flavor-get-resp.json @@ -16,6 +16,9 @@ "resource_traits": { "CUSTOM_BAREMETAL_GOLD": "FPGA" }, + "resource_aggregates": { + "high_mem": "true" + }, "created_at": "2016-09-27T02:37:21.966342+00:00", "uuid": "7de2859d-ec6d-42c7-bb86-9d630ba5ac94", "updated_at": null, diff --git a/api-ref/source/v1/samples/flavors/flavor-update-put-resp.json b/api-ref/source/v1/samples/flavors/flavor-update-put-resp.json index 99fddfc2..644be357 100644 --- a/api-ref/source/v1/samples/flavors/flavor-update-put-resp.json +++ b/api-ref/source/v1/samples/flavors/flavor-update-put-resp.json @@ -16,6 +16,9 @@ "resource_traits": { "CUSTOM_BAREMETAL_GOLD": "FPGA" }, + "resource_aggregates": { + "high_mem": "true" + }, "created_at": "2016-09-27T02:37:21.966342+00:00", "uuid": "7de2859d-ec6d-42c7-bb86-9d630ba5ac94", "updated_at": null, diff --git a/api-ref/source/v1/samples/flavors/flavors-list-resp.json b/api-ref/source/v1/samples/flavors/flavors-list-resp.json index f50f0c4c..7ad83fdd 100644 --- a/api-ref/source/v1/samples/flavors/flavors-list-resp.json +++ b/api-ref/source/v1/samples/flavors/flavors-list-resp.json @@ -18,6 +18,9 @@ "resource_traits": { "CUSTOM_BAREMETAL_GOLD": "FPGA" }, + "resource_aggregates": { + "high_mem": "true" + }, "created_at": "2016-09-22T03:21:57+00:00", "uuid": "2ce3df6b-f571-42e8-b6a8-8f7fa1c019ce", "updated_at": null, @@ -43,6 +46,9 @@ "resource_traits": { "CUSTOM_BAREMETAL_GOLD": "FPGA" }, + "resource_aggregates": { + "high_mem": "true" + }, "created_at": "2016-09-27T02:37:21+00:00", "uuid": "7de2859d-ec6d-42c7-bb86-9d630ba5ac94", "updated_at": null, diff --git a/mogan/api/controllers/v1/flavors.py b/mogan/api/controllers/v1/flavors.py index f5589aa8..2af2861a 100644 --- a/mogan/api/controllers/v1/flavors.py +++ b/mogan/api/controllers/v1/flavors.py @@ -69,6 +69,9 @@ class Flavor(base.APIBase): resource_traits = {wtypes.text: types.jsontype} """The resource traits of the flavor""" + resource_aggregates = {wtypes.text: types.jsontype} + """The resource aggregates of the flavor""" + links = wsme.wsattr([link.Link], readonly=True) """A list containing a self link""" diff --git a/mogan/api/controllers/v1/schemas/flavor.py b/mogan/api/controllers/v1/schemas/flavor.py index 9c809348..25a97c70 100644 --- a/mogan/api/controllers/v1/schemas/flavor.py +++ b/mogan/api/controllers/v1/schemas/flavor.py @@ -24,6 +24,7 @@ create_flavor = { 'description': {'type': 'string', 'minLength': 1}, 'resources': parameter_types.resources, 'resource_traits': parameter_types.resource_traits, + 'resource_aggregates': parameter_types.metadata, 'is_public': parameter_types.boolean, 'disabled': parameter_types.boolean, }, diff --git a/mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py b/mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py index ad60fe25..818dbfeb 100644 --- a/mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py +++ b/mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py @@ -38,6 +38,7 @@ def upgrade(): sa.Column('description', sa.Text(), nullable=True), sa.Column('resources', sa.Text(), nullable=True), sa.Column('resource_traits', sa.Text(), nullable=True), + sa.Column('resource_aggregates', sa.Text(), nullable=True), sa.Column('is_public', sa.Boolean(), nullable=False), sa.Column('disabled', sa.Boolean(), nullable=False), sa.PrimaryKeyConstraint('id'), diff --git a/mogan/db/sqlalchemy/models.py b/mogan/db/sqlalchemy/models.py index 3209407d..ba1533c1 100644 --- a/mogan/db/sqlalchemy/models.py +++ b/mogan/db/sqlalchemy/models.py @@ -148,6 +148,7 @@ class Flavors(Base): description = Column(MediumText()) resources = Column(db_types.JsonEncodedDict) resource_traits = Column(db_types.JsonEncodedDict) + resource_aggregates = Column(db_types.JsonEncodedDict) is_public = Column(Boolean, default=True) disabled = Column(Boolean, default=False) servers = orm.relationship( diff --git a/mogan/objects/flavor.py b/mogan/objects/flavor.py index 8fc9d549..f372d3c8 100644 --- a/mogan/objects/flavor.py +++ b/mogan/objects/flavor.py @@ -39,6 +39,7 @@ class Flavor(base.MoganObject, object_base.VersionedObjectDictCompat): 'disabled': object_fields.BooleanField(), 'resources': object_fields.FlexibleDictField(nullable=True), 'resource_traits': object_fields.FlexibleDictField(nullable=True), + 'resource_aggregates': object_fields.FlexibleDictField(nullable=True), 'projects': object_fields.ListOfStringsField(), } diff --git a/mogan/tests/functional/api/v1/test_flavors.py b/mogan/tests/functional/api/v1/test_flavors.py index 599ce414..89dd94b3 100644 --- a/mogan/tests/functional/api/v1/test_flavors.py +++ b/mogan/tests/functional/api/v1/test_flavors.py @@ -41,7 +41,8 @@ class TestFlavor(v1_test.APITestV1): def test_flavor_post(self): body = {"name": "test", "description": "just test", "resources": {"CUSTOM_GOLD": 1}, - "resource_traits": {"CUSTOM_GOLD": "FPGA"}} + "resource_traits": {"CUSTOM_GOLD": "FPGA"}, + "resource_aggregates": {"high_mem": "true"}} resp = self.post_json( '/flavors', body, headers=self.headers, status=201) resp = resp.json @@ -50,6 +51,7 @@ class TestFlavor(v1_test.APITestV1): self.assertTrue(resp['is_public']) self.assertEqual({'CUSTOM_GOLD': 1}, resp['resources']) self.assertEqual({'CUSTOM_GOLD': 'FPGA'}, resp['resource_traits']) + self.assertEqual({'high_mem': 'true'}, resp['resource_aggregates']) self.assertIn('uuid', resp) self.assertIn('links', resp) diff --git a/mogan/tests/tempest/api/test_flavors.py b/mogan/tests/tempest/api/test_flavors.py index 02ec6514..702cfaf7 100644 --- a/mogan/tests/tempest/api/test_flavors.py +++ b/mogan/tests/tempest/api/test_flavors.py @@ -29,6 +29,7 @@ class BaremetalComputeAPITest(base.BaseBaremetalComputeTest): body = {"name": "mogan_flavor_" + {0: 'public', 1: 'private'}[i], "description": "mogan flavor description", "resources": {"CUSTOM_GOLD": 1}, + "resource_aggregates": {"high_mem": "true"}, 'is_public': not bool(i)} resp = cls.baremetal_compute_client.create_flavor(**body) cls.flavor_ids.append(resp['uuid']) @@ -52,7 +53,8 @@ class BaremetalComputeAPITest(base.BaseBaremetalComputeTest): body = {"name": 'mogan_flavor_create', "description": "mogan flavor description", 'is_public': True, 'resources': {'gold': 1}, - 'resource_traits': {'gold': 'foo'}} + 'resource_traits': {'gold': 'foo'}, + 'resource_aggregates': {'high_mem': 'true'}} resp = self.baremetal_compute_client.create_flavor(**body) self.assertEqual('mogan_flavor_create', resp['name']) self.assertEqual('mogan flavor description', @@ -61,6 +63,7 @@ class BaremetalComputeAPITest(base.BaseBaremetalComputeTest): self.assertFalse(resp['disabled']) self.assertEqual({'gold': 1}, resp['resources']) self.assertEqual({'gold': 'foo'}, resp['resource_traits']) + self.assertEqual({'high_mem': 'true'}, resp['resource_aggregates']) self.assertIn('uuid', resp) self.assertIn('links', resp) self.flavor_ids.append(resp['uuid']) diff --git a/mogan/tests/unit/db/utils.py b/mogan/tests/unit/db/utils.py index 1f6c0cc8..a08f6442 100644 --- a/mogan/tests/unit/db/utils.py +++ b/mogan/tests/unit/db/utils.py @@ -92,6 +92,7 @@ def get_test_flavor(**kw): 'description': kw.get('description', 'test'), 'resources': kw.get('resources', {}), 'resource_traits': kw.get('resource_traits', {}), + 'resource_aggregates': kw.get('resource_aggregates', {}), 'is_public': kw.get('is_public', 1), 'disabled': kw.get('disabled', 0), 'updated_at': kw.get('updated_at'), diff --git a/mogan/tests/unit/objects/test_objects.py b/mogan/tests/unit/objects/test_objects.py index a49a46dd..e5d4e42b 100644 --- a/mogan/tests/unit/objects/test_objects.py +++ b/mogan/tests/unit/objects/test_objects.py @@ -385,7 +385,7 @@ expected_object_fingerprints = { 'Server': '1.0-dc54162c0cc91fac43fed5304cd2c968', 'ServerFault': '1.0-74349ff701259e4834b4e9dc2dac1b12', 'ServerFaultList': '1.0-43e8aad0258652921f929934e9e048fd', - 'Flavor': '1.0-f53b71bd4aaaadea0d9284b811a82bb5', + 'Flavor': '1.0-9f7166aa387d89ec40cd699019d0c9a9', 'MyObj': '1.1-aad62eedc5a5cc8bcaf2982c285e753f', 'ServerNic': '1.0-0494306157ef437802260ff8b51cf5cf', 'ServerNics': '1.0-33a2e1bb91ad4082f9f63429b77c1244',