Add compute_flavor field for amphora api

Operators want to have the ability to see amphora flavor information.
But they haven't access permisson of octavia configuration file. So
it is necessary to show amphora flavor information as part of command
'openstack loadbalancer amphora list/show'.

Story: 2002896
Task: 22986

Change-Id: Ib3ca05d816747d08ef7055ec532b81746468cbf9
This commit is contained in:
Yang JianFeng 2018-07-16 10:33:48 +00:00 committed by yangjianfeng
parent 1fa2c1358d
commit ae8d6fb2de
17 changed files with 87 additions and 14 deletions

View File

@ -221,6 +221,13 @@ cert-expiration:
in: body
required: true
type: string
compute-flavor:
description: |
The ID of the compute flavor used for the amphora.
in: body
min_version: 2.3
required: true
type: string
compute-id:
description: |
The ID of the amphora resource in the compute system.

View File

@ -70,6 +70,7 @@ Response Parameters
- created_at: created_at
- updated_at: updated_at
- image_id: image-id
- compute_flavor: compute-flavor
Response Example
----------------
@ -144,6 +145,7 @@ Response Parameters
- created_at: created_at
- updated_at: updated_at
- image_id: image-id
- compute_flavor: compute-flavor
Response Example
----------------

View File

@ -19,7 +19,8 @@
"cached_zone": "zone1",
"created_at": "2017-05-10T18:14:44",
"updated_at": "2017-05-10T23:08:12",
"image_id": "c1c2ad6f-1c1e-4744-8d1a-d0ef36289e74"
"image_id": "c1c2ad6f-1c1e-4744-8d1a-d0ef36289e74",
"compute_flavor": "5446a14a-abec-4455-bc0e-a34e5ff001a3"
},
{
"id": "89c186a3-cb16-497b-b099-c4bd40316642",
@ -40,7 +41,8 @@
"cached_zone": "zone2",
"created_at": "2017-06-11T19:15:45",
"updated_at": "2017-06-11T24:09:13",
"image_id": "1014292d-cbaa-4ad6-b38b-2e138389f87f"
"image_id": "1014292d-cbaa-4ad6-b38b-2e138389f87f",
"compute_flavor": "5446a14a-abec-4455-bc0e-a34e5ff001a3"
}
]
}

View File

@ -18,6 +18,7 @@
"cached_zone": "zone1",
"created_at": "2017-05-10T18:14:44",
"updated_at": "2017-05-10T23:08:12",
"image_id": "c1c2ad6f-1c1e-4744-8d1a-d0ef36289e74"
"image_id": "c1c2ad6f-1c1e-4744-8d1a-d0ef36289e74",
"compute_flavor": "5446a14a-abec-4455-bc0e-a34e5ff001a3"
}
}

View File

@ -75,6 +75,8 @@ class RootController(rest.RestController):
'2016-12-11T00:00:00Z', host_url)
self._add_a_version(versions, 'v2.1', 'v2', 'SUPPORTED',
'2018-04-20T00:00:00Z', host_url)
self._add_a_version(versions, 'v2.2', 'v2', 'CURRENT',
self._add_a_version(versions, 'v2.2', 'v2', 'SUPPORTED',
'2018-07-31T00:00:00Z', host_url)
self._add_a_version(versions, 'v2.3', 'v2', 'CURRENT',
'2018-12-18T00:00:00Z', host_url)
return {'versions': versions}

View File

@ -43,6 +43,7 @@ class AmphoraResponse(BaseAmphoraType):
created_at = wtypes.wsattr(wtypes.datetime.datetime)
updated_at = wtypes.wsattr(wtypes.datetime.datetime)
image_id = wtypes.wsattr(wtypes.UuidType())
compute_flavor = wtypes.wsattr(wtypes.StringType())
@classmethod
def from_data_model(cls, data_model, children=False):

View File

@ -527,7 +527,7 @@ class Amphora(BaseDataModel):
load_balancer=None, role=None, cert_expiration=None,
cert_busy=False, vrrp_interface=None, vrrp_id=None,
vrrp_priority=None, cached_zone=None, created_at=None,
updated_at=None, image_id=None):
updated_at=None, image_id=None, compute_flavor=None):
self.id = id
self.load_balancer_id = load_balancer_id
self.compute_id = compute_id
@ -548,6 +548,7 @@ class Amphora(BaseDataModel):
self.created_at = created_at
self.updated_at = updated_at
self.image_id = image_id
self.compute_flavor = compute_flavor
def delete(self):
for amphora in self.load_balancer.amphorae:

View File

@ -247,7 +247,8 @@ class VirtualMachineManager(compute_base.ComputeBase):
status=nova_response.status,
lb_network_ip=lb_network_ip,
cached_zone=availability_zone,
image_id=nova_response.image.get("id")
image_id=nova_response.image.get("id"),
compute_flavor=nova_response.flavor.get("id")
)
return response, fault

View File

@ -876,7 +876,8 @@ class UpdateAmphoraInfo(BaseDatabaseTask):
db_apis.get_session(), amphora_id,
lb_network_ip=compute_obj.lb_network_ip,
cached_zone=compute_obj.cached_zone,
image_id=compute_obj.image_id)
image_id=compute_obj.image_id,
compute_flavor=compute_obj.compute_flavor)
return self.amphora_repo.get(db_apis.get_session(), id=amphora_id)

View File

@ -0,0 +1,36 @@
# Copyright (c) 2018 China Telecom Corporation
# All Rights Reserved.
#
# 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.
"""amphora add flavor id
Revision ID: 4f65b4f91c39
Revises: 80dba23a159f
Create Date: 2018-07-16 09:59:07.169894
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '4f65b4f91c39'
down_revision = '80dba23a159f'
def upgrade():
op.add_column(
u'amphora',
sa.Column(u'compute_flavor', sa.String(255), nullable=True)
)

View File

@ -575,6 +575,7 @@ class Amphora(base_models.BASE, base_models.IdMixin, models.TimestampMixin):
image_id = sa.Column(sa.String(36), nullable=True)
load_balancer = orm.relationship("LoadBalancer", uselist=False,
back_populates='amphorae')
compute_flavor = sa.Column(sa.String(255), nullable=True)
class AmphoraHealth(base_models.BASE):

View File

@ -46,11 +46,12 @@ class TestRootController(base_db_test.OctaviaDBTestBase):
versions = self._get_versions_with_config(
api_v1_enabled=True, api_v2_enabled=True)
version_ids = tuple(v.get('id') for v in versions)
self.assertEqual(4, len(version_ids))
self.assertEqual(5, len(version_ids))
self.assertIn('v1', version_ids)
self.assertIn('v2.0', version_ids)
self.assertIn('v2.1', version_ids)
self.assertIn('v2.2', version_ids)
self.assertIn('v2.3', version_ids)
# Each version should have a 'self' 'href' to the API version URL
# [{u'rel': u'self', u'href': u'http://localhost/v2'}]
@ -70,10 +71,11 @@ class TestRootController(base_db_test.OctaviaDBTestBase):
def test_api_v1_disabled(self):
versions = self._get_versions_with_config(
api_v1_enabled=False, api_v2_enabled=True)
self.assertEqual(3, len(versions))
self.assertEqual(4, len(versions))
self.assertEqual('v2.0', versions[0].get('id'))
self.assertEqual('v2.1', versions[1].get('id'))
self.assertEqual('v2.2', versions[2].get('id'))
self.assertEqual('v2.3', versions[3].get('id'))
def test_api_v2_disabled(self):
versions = self._get_versions_with_config(

View File

@ -56,6 +56,7 @@ class TestAmphora(base.BaseAPITest):
'created_at': datetime.datetime.now(),
'updated_at': datetime.datetime.now(),
'image_id': uuidutils.generate_uuid(),
'compute_flavor': uuidutils.generate_uuid(),
}
self.amp = self.amphora_repo.create(self.session, **self.amp_args)
self.amp_id = self.amp.id

View File

@ -40,6 +40,7 @@ class TestDataModels(base.TestCase):
self.AMP_ID = uuidutils.generate_uuid()
self.COMPUTE_ID = uuidutils.generate_uuid()
self.IMAGE_ID = uuidutils.generate_uuid()
self.COMPUTE_FLAVOR = uuidutils.generate_uuid()
self.LB_obj = data_models.LoadBalancer(
id=self.LB_ID,
@ -113,7 +114,8 @@ class TestDataModels(base.TestCase):
cached_zone=None,
created_at=self.CREATED_AT,
updated_at=self.UPDATED_AT,
image_id=self.IMAGE_ID
image_id=self.IMAGE_ID,
compute_flavor=self.COMPUTE_FLAVOR
)
super(TestDataModels, self).setUp()
@ -373,6 +375,7 @@ class TestDataModels(base.TestCase):
new_created_at = self.CREATED_AT + datetime.timedelta(minutes=5)
new_updated_at = self.UPDATED_AT + datetime.timedelta(minutes=10)
new_image_id = uuidutils.generate_uuid()
new_compute_flavor = uuidutils.generate_uuid()
update_dict = {
'id': new_id,
@ -381,7 +384,8 @@ class TestDataModels(base.TestCase):
'vrrp_priority': new_vrrp_priority,
'created_at': new_created_at,
'updated_at': new_updated_at,
'image_id': new_image_id
'image_id': new_image_id,
'compute_flavor': new_compute_flavor
}
test_Amp_obj = copy.deepcopy(self.AMP_obj)
@ -406,7 +410,8 @@ class TestDataModels(base.TestCase):
cached_zone=None,
created_at=new_created_at,
updated_at=new_updated_at,
image_id=new_image_id
image_id=new_image_id,
compute_flavor=new_compute_flavor
)
test_Amp_obj.update(update_dict)

View File

@ -101,7 +101,8 @@ class TestNovaClient(base.TestCase):
compute_id=uuidutils.generate_uuid(),
status='ACTIVE',
lb_network_ip='10.0.0.1',
image_id=uuidutils.generate_uuid()
image_id=uuidutils.generate_uuid(),
compute_flavor=uuidutils.generate_uuid()
)
self.nova_response = mock.Mock()
@ -110,6 +111,7 @@ class TestNovaClient(base.TestCase):
self.nova_response.fault = 'FAKE_FAULT'
setattr(self.nova_response, 'OS-EXT-AZ:availability_zone', None)
self.nova_response.image = {'id': self.amphora.image_id}
self.nova_response.flavor = {'id': self.amphora.compute_flavor}
self.interface_list = mock.MagicMock()
self.interface_list.net_id = '1'

View File

@ -51,6 +51,7 @@ VRRP_ID = random.randrange(255)
VRRP_PRIORITY = random.randrange(100)
CACHED_ZONE = 'zone1'
IMAGE_ID = uuidutils.generate_uuid()
COMPUTE_FLAVOR = uuidutils.generate_uuid()
_amphora_mock = mock.MagicMock()
_amphora_mock.id = AMP_ID
@ -122,6 +123,7 @@ _compute_mock = mock.MagicMock()
_compute_mock.lb_network_ip = LB_NET_IP
_compute_mock.cached_zone = CACHED_ZONE
_compute_mock.image_id = IMAGE_ID
_compute_mock.compute_flavor = COMPUTE_FLAVOR
@mock.patch('octavia.db.repositories.AmphoraRepository.delete')
@ -887,7 +889,8 @@ class TestDatabaseTasks(base.TestCase):
AMP_ID,
lb_network_ip=LB_NET_IP,
cached_zone=CACHED_ZONE,
image_id=IMAGE_ID)
image_id=IMAGE_ID,
compute_flavor=COMPUTE_FLAVOR)
repo.AmphoraRepository.get.assert_called_once_with(
'TEST',

View File

@ -0,0 +1,5 @@
---
features:
- |
Amphora API now can return the field `compute_flavor` which is the ID of
the compute instance flavor used to boot the amphora.