Add image_id to amphora table

Story: 2001491
Task: 6215
Change-Id: I5ab6707591c856e43a0e0f49c84e1e721f01893c
This commit is contained in:
Adam Harwell 2018-02-27 02:39:09 +00:00
parent 2e7d9c6cd1
commit 6ee20b272e
15 changed files with 173 additions and 7 deletions

View File

@ -423,6 +423,12 @@ id:
in: body
required: true
type: uuid
image-id:
description: |
The ID of the glance image used for the amphora.
in: body
required: true
type: uuid
insert_headers:
description: |
A dictionary of optional headers to insert into the request before it is

View File

@ -69,6 +69,7 @@ Response Parameters
- cached_zone: cached-zone
- created_at: created_at
- updated_at: updated_at
- image_id: image-id
Response Example
----------------
@ -142,6 +143,7 @@ Response Parameters
- cached_zone: cached-zone
- created_at: created_at
- updated_at: updated_at
- image_id: image-id
Response Example
----------------

View File

@ -18,7 +18,8 @@
"vrrp_priority": 100,
"cached_zone": "zone1",
"created_at": "2017-05-10T18:14:44",
"updated_at": "2017-05-10T23:08:12"
"updated_at": "2017-05-10T23:08:12",
"image_id": "c1c2ad6f-1c1e-4744-8d1a-d0ef36289e74"
},
{
"id": "89c186a3-cb16-497b-b099-c4bd40316642",
@ -38,7 +39,8 @@
"vrrp_priority": 200,
"cached_zone": "zone2",
"created_at": "2017-06-11T19:15:45",
"updated_at": "2017-06-11T24:09:13"
"updated_at": "2017-06-11T24:09:13",
"image_id": "1014292d-cbaa-4ad6-b38b-2e138389f87f"
}
]
}

View File

@ -17,6 +17,7 @@
"vrrp_priority": 100,
"cached_zone": "zone1",
"created_at": "2017-05-10T18:14:44",
"updated_at": "2017-05-10T23:08:12"
"updated_at": "2017-05-10T23:08:12",
"image_id": "c1c2ad6f-1c1e-4744-8d1a-d0ef36289e74"
}
}

View File

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

View File

@ -501,7 +501,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):
updated_at=None, image_id=None):
self.id = id
self.load_balancer_id = load_balancer_id
self.compute_id = compute_id
@ -521,6 +521,7 @@ class Amphora(BaseDataModel):
self.cached_zone = cached_zone
self.created_at = created_at
self.updated_at = updated_at
self.image_id = image_id
def delete(self):
for amphora in self.load_balancer.amphorae:

View File

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

View File

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

View File

@ -0,0 +1,35 @@
# Copyright 2017 GoDaddy
#
# 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 image id
Revision ID: 034756a182a2
Revises: 10d38216ad34
Create Date: 2018-02-26 17:38:37.971677
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '034756a182a2'
down_revision = '10d38216ad34'
def upgrade():
op.add_column(
u'amphora',
sa.Column(u'image_id', sa.String(36), nullable=True)
)

View File

@ -518,6 +518,7 @@ class Amphora(base_models.BASE, base_models.IdMixin, models.TimestampMixin):
vrrp_id = sa.Column(sa.Integer(), nullable=True)
vrrp_priority = sa.Column(sa.Integer(), nullable=True)
cached_zone = sa.Column(sa.String(255), nullable=True)
image_id = sa.Column(sa.String(36), nullable=True)
class AmphoraHealth(base_models.BASE):

View File

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

View File

@ -17,6 +17,7 @@ import datetime
from oslo_utils import uuidutils
from octavia.common import constants
from octavia.common import data_models
import octavia.tests.unit.base as base
@ -36,6 +37,9 @@ class TestDataModels(base.TestCase):
self.VIP_PORT_ID = uuidutils.generate_uuid()
self.VIP_QOS_ID = uuidutils.generate_uuid()
self.POOL_ID = uuidutils.generate_uuid()
self.AMP_ID = uuidutils.generate_uuid()
self.COMPUTE_ID = uuidutils.generate_uuid()
self.IMAGE_ID = uuidutils.generate_uuid()
self.LB_obj = data_models.LoadBalancer(
id=self.LB_ID,
@ -89,6 +93,29 @@ class TestDataModels(base.TestCase):
cookie_name='chocolate',
pool=None)
self.AMP_obj = data_models.Amphora(
id=self.AMP_ID,
load_balancer_id=self.LB_ID,
compute_id=self.COMPUTE_ID,
status=constants.ACTIVE,
lb_network_ip=None,
vrrp_ip=None,
ha_ip=None,
vrrp_port_id=None,
ha_port_id=self.VIP_PORT_ID,
load_balancer=self.LB_obj,
role=constants.ROLE_MASTER,
cert_expiration=None,
cert_busy=False,
vrrp_interface=None,
vrrp_id=None,
vrrp_priority=constants.ROLE_MASTER_PRIORITY,
cached_zone=None,
created_at=self.CREATED_AT,
updated_at=self.UPDATED_AT,
image_id=self.IMAGE_ID
)
super(TestDataModels, self).setUp()
def test_LoadBalancer_update(self):
@ -336,3 +363,52 @@ class TestDataModels(base.TestCase):
test_Pool_obj.update(update_dict)
self.assertEqual(reference_SP_obj, test_Pool_obj.session_persistence)
def test_Amphora_update(self):
new_id = uuidutils.generate_uuid()
new_status = constants.ERROR
new_role = constants.ROLE_BACKUP
new_vrrp_priority = constants.ROLE_BACKUP_PRIORITY
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()
update_dict = {
'id': new_id,
'status': new_status,
'role': new_role,
'vrrp_priority': new_vrrp_priority,
'created_at': new_created_at,
'updated_at': new_updated_at,
'image_id': new_image_id
}
test_Amp_obj = copy.deepcopy(self.AMP_obj)
reference_Amp_obj = data_models.Amphora(
id=new_id,
load_balancer_id=self.LB_ID,
compute_id=self.COMPUTE_ID,
status=new_status,
lb_network_ip=None,
vrrp_ip=None,
ha_ip=None,
vrrp_port_id=None,
ha_port_id=self.VIP_PORT_ID,
load_balancer=self.LB_obj,
role=new_role,
cert_expiration=None,
cert_busy=False,
vrrp_interface=None,
vrrp_id=None,
vrrp_priority=constants.ROLE_BACKUP_PRIORITY,
cached_zone=None,
created_at=new_created_at,
updated_at=new_updated_at,
image_id=new_image_id
)
test_Amp_obj.update(update_dict)
self.assertEqual(reference_Amp_obj, test_Amp_obj)

View File

@ -100,7 +100,8 @@ class TestNovaClient(base.TestCase):
self.amphora = models.Amphora(
compute_id=uuidutils.generate_uuid(),
status='ACTIVE',
lb_network_ip='10.0.0.1'
lb_network_ip='10.0.0.1',
image_id=uuidutils.generate_uuid()
)
self.nova_response = mock.Mock()
@ -108,6 +109,7 @@ class TestNovaClient(base.TestCase):
self.nova_response.status = 'ACTIVE'
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.interface_list = mock.MagicMock()
self.interface_list.net_id = '1'

View File

@ -49,6 +49,8 @@ HA_IP = '192.0.5.4'
AMP_ROLE = 'FAKE_ROLE'
VRRP_ID = random.randrange(255)
VRRP_PRIORITY = random.randrange(100)
CACHED_ZONE = 'zone1'
IMAGE_ID = uuidutils.generate_uuid()
_amphora_mock = mock.MagicMock()
_amphora_mock.id = AMP_ID
@ -116,6 +118,10 @@ zfJ3Bo+P7In9fsHbyDAqIhMwDQYJKoZIhvcNAQELBQADQQBenkZ2k7RgZqgj+dxA
D7BF8MN1oUAOpyYqAjkGddSEuMyNmwtHKZI1dyQ0gBIQdiU9yAG2oTbUIK4msbBV
uJIQ
-----END CERTIFICATE-----"""
_compute_mock = mock.MagicMock()
_compute_mock.lb_network_ip = LB_NET_IP
_compute_mock.cached_zone = CACHED_ZONE
_compute_mock.image_id = IMAGE_ID
@mock.patch('octavia.db.repositories.AmphoraRepository.delete')
@ -862,6 +868,31 @@ class TestDatabaseTasks(base.TestCase):
compute_id=COMPUTE_ID,
lb_network_ip=LB_NET_IP)
@mock.patch('octavia.db.repositories.AmphoraRepository.get')
def test_update_amphora_info(self,
mock_amphora_repo_get,
mock_generate_uuid,
mock_LOG,
mock_get_session,
mock_loadbalancer_repo_update,
mock_listener_repo_update,
mock_amphora_repo_update,
mock_amphora_repo_delete):
update_amphora_info = database_tasks.UpdateAmphoraInfo()
update_amphora_info.execute(AMP_ID, _compute_mock)
repo.AmphoraRepository.update.assert_called_once_with(
'TEST',
AMP_ID,
lb_network_ip=LB_NET_IP,
cached_zone=CACHED_ZONE,
image_id=IMAGE_ID)
repo.AmphoraRepository.get.assert_called_once_with(
'TEST',
id=AMP_ID)
def test_mark_listener_active_in_db(self,
mock_generate_uuid,
mock_LOG,

View File

@ -0,0 +1,5 @@
---
features:
- |
Amphora API now returns the field `image_id` which is the ID of the glance
image used to boot the amphora.