Merge "Add image_id to amphora table"
This commit is contained in:
commit
0e54dce5f5
@ -423,6 +423,12 @@ id:
|
|||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: uuid
|
type: uuid
|
||||||
|
image-id:
|
||||||
|
description: |
|
||||||
|
The ID of the glance image used for the amphora.
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
type: uuid
|
||||||
insert_headers:
|
insert_headers:
|
||||||
description: |
|
description: |
|
||||||
A dictionary of optional headers to insert into the request before it is
|
A dictionary of optional headers to insert into the request before it is
|
||||||
|
@ -69,6 +69,7 @@ Response Parameters
|
|||||||
- cached_zone: cached-zone
|
- cached_zone: cached-zone
|
||||||
- created_at: created_at
|
- created_at: created_at
|
||||||
- updated_at: updated_at
|
- updated_at: updated_at
|
||||||
|
- image_id: image-id
|
||||||
|
|
||||||
Response Example
|
Response Example
|
||||||
----------------
|
----------------
|
||||||
@ -142,6 +143,7 @@ Response Parameters
|
|||||||
- cached_zone: cached-zone
|
- cached_zone: cached-zone
|
||||||
- created_at: created_at
|
- created_at: created_at
|
||||||
- updated_at: updated_at
|
- updated_at: updated_at
|
||||||
|
- image_id: image-id
|
||||||
|
|
||||||
Response Example
|
Response Example
|
||||||
----------------
|
----------------
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
"vrrp_priority": 100,
|
"vrrp_priority": 100,
|
||||||
"cached_zone": "zone1",
|
"cached_zone": "zone1",
|
||||||
"created_at": "2017-05-10T18:14:44",
|
"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",
|
"id": "89c186a3-cb16-497b-b099-c4bd40316642",
|
||||||
@ -38,7 +39,8 @@
|
|||||||
"vrrp_priority": 200,
|
"vrrp_priority": 200,
|
||||||
"cached_zone": "zone2",
|
"cached_zone": "zone2",
|
||||||
"created_at": "2017-06-11T19:15:45",
|
"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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"vrrp_priority": 100,
|
"vrrp_priority": 100,
|
||||||
"cached_zone": "zone1",
|
"cached_zone": "zone1",
|
||||||
"created_at": "2017-05-10T18:14:44",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ class AmphoraResponse(BaseAmphoraType):
|
|||||||
cached_zone = wtypes.wsattr(wtypes.StringType())
|
cached_zone = wtypes.wsattr(wtypes.StringType())
|
||||||
created_at = wtypes.wsattr(wtypes.datetime.datetime)
|
created_at = wtypes.wsattr(wtypes.datetime.datetime)
|
||||||
updated_at = wtypes.wsattr(wtypes.datetime.datetime)
|
updated_at = wtypes.wsattr(wtypes.datetime.datetime)
|
||||||
|
image_id = wtypes.wsattr(wtypes.UuidType())
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_data_model(cls, data_model, children=False):
|
def from_data_model(cls, data_model, children=False):
|
||||||
|
@ -501,7 +501,7 @@ class Amphora(BaseDataModel):
|
|||||||
load_balancer=None, role=None, cert_expiration=None,
|
load_balancer=None, role=None, cert_expiration=None,
|
||||||
cert_busy=False, vrrp_interface=None, vrrp_id=None,
|
cert_busy=False, vrrp_interface=None, vrrp_id=None,
|
||||||
vrrp_priority=None, cached_zone=None, created_at=None,
|
vrrp_priority=None, cached_zone=None, created_at=None,
|
||||||
updated_at=None):
|
updated_at=None, image_id=None):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.load_balancer_id = load_balancer_id
|
self.load_balancer_id = load_balancer_id
|
||||||
self.compute_id = compute_id
|
self.compute_id = compute_id
|
||||||
@ -521,6 +521,7 @@ class Amphora(BaseDataModel):
|
|||||||
self.cached_zone = cached_zone
|
self.cached_zone = cached_zone
|
||||||
self.created_at = created_at
|
self.created_at = created_at
|
||||||
self.updated_at = updated_at
|
self.updated_at = updated_at
|
||||||
|
self.image_id = image_id
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
for amphora in self.load_balancer.amphorae:
|
for amphora in self.load_balancer.amphorae:
|
||||||
|
@ -245,7 +245,8 @@ class VirtualMachineManager(compute_base.ComputeBase):
|
|||||||
compute_id=nova_response.id,
|
compute_id=nova_response.id,
|
||||||
status=nova_response.status,
|
status=nova_response.status,
|
||||||
lb_network_ip=lb_network_ip,
|
lb_network_ip=lb_network_ip,
|
||||||
cached_zone=availability_zone
|
cached_zone=availability_zone,
|
||||||
|
image_id=nova_response.image.get("id")
|
||||||
)
|
)
|
||||||
return response, fault
|
return response, fault
|
||||||
|
|
||||||
|
@ -876,7 +876,8 @@ class UpdateAmphoraInfo(BaseDatabaseTask):
|
|||||||
self.amphora_repo.update(
|
self.amphora_repo.update(
|
||||||
db_apis.get_session(), amphora_id,
|
db_apis.get_session(), amphora_id,
|
||||||
lb_network_ip=compute_obj.lb_network_ip,
|
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)
|
return self.amphora_repo.get(db_apis.get_session(), id=amphora_id)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
)
|
@ -518,6 +518,7 @@ class Amphora(base_models.BASE, base_models.IdMixin, models.TimestampMixin):
|
|||||||
vrrp_id = sa.Column(sa.Integer(), nullable=True)
|
vrrp_id = sa.Column(sa.Integer(), nullable=True)
|
||||||
vrrp_priority = sa.Column(sa.Integer(), nullable=True)
|
vrrp_priority = sa.Column(sa.Integer(), nullable=True)
|
||||||
cached_zone = sa.Column(sa.String(255), 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):
|
class AmphoraHealth(base_models.BASE):
|
||||||
|
@ -55,6 +55,7 @@ class TestAmphora(base.BaseAPITest):
|
|||||||
'cached_zone': None,
|
'cached_zone': None,
|
||||||
'created_at': datetime.datetime.now(),
|
'created_at': datetime.datetime.now(),
|
||||||
'updated_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 = self.amphora_repo.create(self.session, **self.amp_args)
|
||||||
self.amp_id = self.amp.id
|
self.amp_id = self.amp.id
|
||||||
|
@ -17,6 +17,7 @@ import datetime
|
|||||||
|
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from octavia.common import constants
|
||||||
from octavia.common import data_models
|
from octavia.common import data_models
|
||||||
import octavia.tests.unit.base as base
|
import octavia.tests.unit.base as base
|
||||||
|
|
||||||
@ -36,6 +37,9 @@ class TestDataModels(base.TestCase):
|
|||||||
self.VIP_PORT_ID = uuidutils.generate_uuid()
|
self.VIP_PORT_ID = uuidutils.generate_uuid()
|
||||||
self.VIP_QOS_ID = uuidutils.generate_uuid()
|
self.VIP_QOS_ID = uuidutils.generate_uuid()
|
||||||
self.POOL_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(
|
self.LB_obj = data_models.LoadBalancer(
|
||||||
id=self.LB_ID,
|
id=self.LB_ID,
|
||||||
@ -89,6 +93,29 @@ class TestDataModels(base.TestCase):
|
|||||||
cookie_name='chocolate',
|
cookie_name='chocolate',
|
||||||
pool=None)
|
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()
|
super(TestDataModels, self).setUp()
|
||||||
|
|
||||||
def test_LoadBalancer_update(self):
|
def test_LoadBalancer_update(self):
|
||||||
@ -336,3 +363,52 @@ class TestDataModels(base.TestCase):
|
|||||||
test_Pool_obj.update(update_dict)
|
test_Pool_obj.update(update_dict)
|
||||||
|
|
||||||
self.assertEqual(reference_SP_obj, test_Pool_obj.session_persistence)
|
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)
|
||||||
|
@ -100,7 +100,8 @@ class TestNovaClient(base.TestCase):
|
|||||||
self.amphora = models.Amphora(
|
self.amphora = models.Amphora(
|
||||||
compute_id=uuidutils.generate_uuid(),
|
compute_id=uuidutils.generate_uuid(),
|
||||||
status='ACTIVE',
|
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()
|
self.nova_response = mock.Mock()
|
||||||
@ -108,6 +109,7 @@ class TestNovaClient(base.TestCase):
|
|||||||
self.nova_response.status = 'ACTIVE'
|
self.nova_response.status = 'ACTIVE'
|
||||||
self.nova_response.fault = 'FAKE_FAULT'
|
self.nova_response.fault = 'FAKE_FAULT'
|
||||||
setattr(self.nova_response, 'OS-EXT-AZ:availability_zone', None)
|
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 = mock.MagicMock()
|
||||||
self.interface_list.net_id = '1'
|
self.interface_list.net_id = '1'
|
||||||
|
@ -49,6 +49,8 @@ HA_IP = '192.0.5.4'
|
|||||||
AMP_ROLE = 'FAKE_ROLE'
|
AMP_ROLE = 'FAKE_ROLE'
|
||||||
VRRP_ID = random.randrange(255)
|
VRRP_ID = random.randrange(255)
|
||||||
VRRP_PRIORITY = random.randrange(100)
|
VRRP_PRIORITY = random.randrange(100)
|
||||||
|
CACHED_ZONE = 'zone1'
|
||||||
|
IMAGE_ID = uuidutils.generate_uuid()
|
||||||
|
|
||||||
_amphora_mock = mock.MagicMock()
|
_amphora_mock = mock.MagicMock()
|
||||||
_amphora_mock.id = AMP_ID
|
_amphora_mock.id = AMP_ID
|
||||||
@ -116,6 +118,10 @@ zfJ3Bo+P7In9fsHbyDAqIhMwDQYJKoZIhvcNAQELBQADQQBenkZ2k7RgZqgj+dxA
|
|||||||
D7BF8MN1oUAOpyYqAjkGddSEuMyNmwtHKZI1dyQ0gBIQdiU9yAG2oTbUIK4msbBV
|
D7BF8MN1oUAOpyYqAjkGddSEuMyNmwtHKZI1dyQ0gBIQdiU9yAG2oTbUIK4msbBV
|
||||||
uJIQ
|
uJIQ
|
||||||
-----END CERTIFICATE-----"""
|
-----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')
|
@mock.patch('octavia.db.repositories.AmphoraRepository.delete')
|
||||||
@ -862,6 +868,31 @@ class TestDatabaseTasks(base.TestCase):
|
|||||||
compute_id=COMPUTE_ID,
|
compute_id=COMPUTE_ID,
|
||||||
lb_network_ip=LB_NET_IP)
|
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,
|
def test_mark_listener_active_in_db(self,
|
||||||
mock_generate_uuid,
|
mock_generate_uuid,
|
||||||
mock_LOG,
|
mock_LOG,
|
||||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user