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:
parent
1fa2c1358d
commit
ae8d6fb2de
@ -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.
|
||||
|
@ -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
|
||||
----------------
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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}
|
||||
|
@ -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):
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
)
|
@ -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):
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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'
|
||||
|
@ -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',
|
||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user