Associate tenants as memeber list to shared image
Change-Id: I297c9a9ec77a64b07b3ad6a8c59121c7381bfd97
This commit is contained in:
parent
68a500b3de
commit
84c23a4781
@ -91,13 +91,14 @@ def add_to_parser(service_sub):
|
|||||||
parser_get_image.add_argument('imageid', type=str, help=h2)
|
parser_get_image.add_argument('imageid', type=str, help=h2)
|
||||||
|
|
||||||
h1, h2 = '[<"X-RANGER-Client" header>]', \
|
h1, h2 = '[<"X-RANGER-Client" header>]', \
|
||||||
'[--visibility <public|private>] ' \
|
'[--visibility <public|private|community|shared>] ' \
|
||||||
'[--region <name>] [--customer <id>]'
|
'[--region <name>] [--customer <id>]'
|
||||||
parser_list_images = subparsers.add_parser('list_images',
|
parser_list_images = subparsers.add_parser('list_images',
|
||||||
help='%s %s' % (h1, h2))
|
help='%s %s' % (h1, h2))
|
||||||
parser_list_images.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
parser_list_images.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||||
parser_list_images.add_argument('--visibility', type=str,
|
parser_list_images.add_argument('--visibility', type=str,
|
||||||
choices=['public', 'private'])
|
choices=['public', 'private',
|
||||||
|
'community', 'shared'])
|
||||||
parser_list_images.add_argument('--region', type=str, help='region name')
|
parser_list_images.add_argument('--region', type=str, help='region name')
|
||||||
parser_list_images.add_argument('--customer', type=str, help='customer id')
|
parser_list_images.add_argument('--customer', type=str, help='customer id')
|
||||||
|
|
||||||
|
@ -324,8 +324,9 @@ def add_customers(image_uuid, customers, transaction_id):
|
|||||||
raise ErrorStatus(404, 'image with id: {0} not found'.format(
|
raise ErrorStatus(404, 'image with id: {0} not found'.format(
|
||||||
image_uuid))
|
image_uuid))
|
||||||
|
|
||||||
if sql_image.visibility == "public":
|
if sql_image.visibility != "shared":
|
||||||
raise ErrorStatus(400, 'Cannot add Customers to public Image')
|
raise ErrorStatus(400,
|
||||||
|
'Customer can only be added to shared image.')
|
||||||
|
|
||||||
existing_region_names = sql_image.get_existing_region_names()
|
existing_region_names = sql_image.get_existing_region_names()
|
||||||
|
|
||||||
@ -362,8 +363,8 @@ def replace_customers(image_uuid, customers, transaction_id):
|
|||||||
if not sql_image:
|
if not sql_image:
|
||||||
raise ErrorStatus(404, 'image {0} not found'.format(image_uuid))
|
raise ErrorStatus(404, 'image {0} not found'.format(image_uuid))
|
||||||
|
|
||||||
if sql_image.visibility == "public":
|
if sql_image.visibility != "shared":
|
||||||
raise ValueError('Cannot add Customers to public Image')
|
raise ValueError('Customer can only be replaced with shared Image')
|
||||||
|
|
||||||
existing_region_names = sql_image.get_existing_region_names()
|
existing_region_names = sql_image.get_existing_region_names()
|
||||||
sql_image.remove_all_customers()
|
sql_image.remove_all_customers()
|
||||||
@ -400,15 +401,11 @@ def delete_customer(image_uuid, customer_id, transaction_id):
|
|||||||
sql_image = image_rec.get_image_by_id(image_uuid)
|
sql_image = image_rec.get_image_by_id(image_uuid)
|
||||||
if not sql_image:
|
if not sql_image:
|
||||||
raise ErrorStatus(404, 'image {0} not found'.format(image_uuid))
|
raise ErrorStatus(404, 'image {0} not found'.format(image_uuid))
|
||||||
# if trying to delete the only one Customer then return value error
|
|
||||||
if sql_image.visibility == "public":
|
|
||||||
raise ValueError(
|
|
||||||
"Image {} is public, no customers".format(image_uuid))
|
|
||||||
|
|
||||||
if len(sql_image.customers) == 1 and \
|
if sql_image.visibility != "shared":
|
||||||
sql_image.customers[0].customer_id == customer_id:
|
raise ValueError(
|
||||||
raise ValueError('Private Image must have at least one Customer - '
|
"Customer can only be deleted from shared image {}".format(
|
||||||
'You are trying to delete the only one Customer')
|
image_uuid))
|
||||||
|
|
||||||
existing_region_names = sql_image.get_existing_region_names()
|
existing_region_names = sql_image.get_existing_region_names()
|
||||||
sql_image.remove_customer(customer_id)
|
sql_image.remove_customer(customer_id)
|
||||||
|
@ -220,24 +220,20 @@ class Image(Model):
|
|||||||
def validate_model(self, context=None):
|
def validate_model(self, context=None):
|
||||||
|
|
||||||
if self.name.strip() == '':
|
if self.name.strip() == '':
|
||||||
raise ErrorStatus(400, "Image name is required.")
|
raise ErrorStatus(400, 'Image name is required.')
|
||||||
|
|
||||||
if self.url.strip() == '':
|
if self.url.strip() == '':
|
||||||
raise ErrorStatus(400, "Image location URL is required.")
|
raise ErrorStatus(400, 'Image location URL is required.')
|
||||||
|
|
||||||
# Validate visibility
|
# Validate visibility
|
||||||
if self.visibility == 'public' and self.customers:
|
if self.visibility not in ["private", "public", "community", "shared"]:
|
||||||
raise ErrorStatus(400,
|
raise ErrorStatus(400,
|
||||||
'Visibility is public but some customers were'
|
'Image visibility can only be public, private,'
|
||||||
' specified!')
|
' community, or shared')
|
||||||
elif self.visibility == 'private' and not self.customers:
|
elif self.customers and self.visibility != "shared":
|
||||||
raise ErrorStatus(400,
|
raise ErrorStatus(400,
|
||||||
'Visibility is private but no customers were'
|
'Customers can only be specified with shared'
|
||||||
' specified!')
|
' image!')
|
||||||
elif self.visibility not in ["private", "public"]:
|
|
||||||
raise ErrorStatus(
|
|
||||||
400,
|
|
||||||
"Image visibility can only be 'public' or 'private'")
|
|
||||||
|
|
||||||
# Validate disk format
|
# Validate disk format
|
||||||
valid_disk_formats = ('ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw',
|
valid_disk_formats = ('ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw',
|
||||||
@ -262,15 +258,15 @@ class Image(Model):
|
|||||||
|
|
||||||
if int(self.min_ram) not in list(range(0, self.min_ram + 1, 1024)):
|
if int(self.min_ram) not in list(range(0, self.min_ram + 1, 1024)):
|
||||||
raise ErrorStatus(
|
raise ErrorStatus(
|
||||||
400, "mininum RAM value must be a multiple of 1024")
|
400, 'mininum RAM value must be a multiple of 1024')
|
||||||
|
|
||||||
if context == "update":
|
if context == "update":
|
||||||
for region in self.regions:
|
for region in self.regions:
|
||||||
if region.type == "group":
|
if region.type == "group":
|
||||||
raise ErrorStatus(
|
raise ErrorStatus(
|
||||||
400,
|
400,
|
||||||
"region {} type is invalid for update, \'group\' can"
|
'region {} type is invalid for update, \'group\' can'
|
||||||
" be only in create".format(region.name))
|
' be only in create'.format(region.name))
|
||||||
|
|
||||||
def to_db_model(self):
|
def to_db_model(self):
|
||||||
image = db_models.Image()
|
image = db_models.Image()
|
||||||
|
@ -18,7 +18,6 @@ def create_full_yaml(title, resources, description, outputs):
|
|||||||
|
|
||||||
|
|
||||||
def _properties(alldata, region):
|
def _properties(alldata, region):
|
||||||
public = alldata['visibility']
|
|
||||||
protected = {0: False, 1: True}[alldata['protected']]
|
protected = {0: False, 1: True}[alldata['protected']]
|
||||||
members = [member['customer_id'] for member in alldata['customers']]
|
members = [member['customer_id'] for member in alldata['customers']]
|
||||||
properties = dict(
|
properties = dict(
|
||||||
@ -32,7 +31,8 @@ def _properties(alldata, region):
|
|||||||
protected=protected,
|
protected=protected,
|
||||||
location=alldata["url"],
|
location=alldata["url"],
|
||||||
owner=alldata["owner"],
|
owner=alldata["owner"],
|
||||||
visibility=alldata['visibility']
|
visibility=alldata['visibility'],
|
||||||
|
members=members
|
||||||
)
|
)
|
||||||
|
|
||||||
if region['action'] != 'create':
|
if region['action'] != 'create':
|
||||||
|
@ -325,7 +325,7 @@ image_json = \
|
|||||||
{
|
{
|
||||||
"name": "abcde1e236",
|
"name": "abcde1e236",
|
||||||
"url": "https://mirrors.it.att.com/images/image-name",
|
"url": "https://mirrors.it.att.com/images/image-name",
|
||||||
"visibility": "private",
|
"visibility": "shared",
|
||||||
"disk-format": "raw",
|
"disk-format": "raw",
|
||||||
"container-format": "bare",
|
"container-format": "bare",
|
||||||
"min-disk": 1,
|
"min-disk": 1,
|
||||||
|
@ -64,7 +64,7 @@ class RdsResponse(object):
|
|||||||
|
|
||||||
resolved_regions = [{'type': 'single', 'name': 'rdm1'}]
|
resolved_regions = [{'type': 'single', 'name': 'rdm1'}]
|
||||||
|
|
||||||
visibility = "private"
|
visibility = "shared"
|
||||||
regions = []
|
regions = []
|
||||||
|
|
||||||
image_status_dict = {'regions': [{
|
image_status_dict = {'regions': [{
|
||||||
@ -572,7 +572,7 @@ class TestAddCustomers(FunctionalTest):
|
|||||||
self.assertRaises(image_logic.ErrorStatus, image_logic.add_customers,
|
self.assertRaises(image_logic.ErrorStatus, image_logic.add_customers,
|
||||||
'uuid', mock.MagicMock(),
|
'uuid', mock.MagicMock(),
|
||||||
'transaction')
|
'transaction')
|
||||||
visibility = 'private'
|
visibility = 'shared'
|
||||||
|
|
||||||
@mock.patch.object(image_logic, 'get_image_by_uuid',
|
@mock.patch.object(image_logic, 'get_image_by_uuid',
|
||||||
return_value=ImageWrapperTest(
|
return_value=ImageWrapperTest(
|
||||||
@ -604,7 +604,7 @@ class TestReplaceCustomers(FunctionalTest):
|
|||||||
mock_send_to_rds_if_needed,
|
mock_send_to_rds_if_needed,
|
||||||
mock_get_image_by_uuid):
|
mock_get_image_by_uuid):
|
||||||
global visibility
|
global visibility
|
||||||
visibility = 'private'
|
visibility = 'shared'
|
||||||
rds_proxy, mock_data_manager = get_data_manager_mock()
|
rds_proxy, mock_data_manager = get_data_manager_mock()
|
||||||
mock_di.resolver.unpack.return_value = mock_data_manager
|
mock_di.resolver.unpack.return_value = mock_data_manager
|
||||||
customers_wrapper = models.CustomerWrapper(['customer'])
|
customers_wrapper = models.CustomerWrapper(['customer'])
|
||||||
@ -646,7 +646,7 @@ class TestReplaceCustomers(FunctionalTest):
|
|||||||
image_logic.replace_customers,
|
image_logic.replace_customers,
|
||||||
'uuid', mock.MagicMock(),
|
'uuid', mock.MagicMock(),
|
||||||
'transaction')
|
'transaction')
|
||||||
visibility = 'private'
|
visibility = 'shared'
|
||||||
|
|
||||||
@mock.patch.object(image_logic, 'get_image_by_uuid',
|
@mock.patch.object(image_logic, 'get_image_by_uuid',
|
||||||
return_value=ImageWrapperTest(
|
return_value=ImageWrapperTest(
|
||||||
|
@ -14,7 +14,8 @@ class TestModels(FunctionalTest):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
FunctionalTest.setUp(self)
|
FunctionalTest.setUp(self)
|
||||||
models.get_regions_of_group = mock.MagicMock(return_value=GROUP_REGIONS)
|
models.get_regions_of_group = mock.MagicMock(
|
||||||
|
return_value=GROUP_REGIONS)
|
||||||
models.set_utils_conf = mock.MagicMock()
|
models.set_utils_conf = mock.MagicMock()
|
||||||
|
|
||||||
def test_handle_group_success(self):
|
def test_handle_group_success(self):
|
||||||
@ -37,7 +38,7 @@ class TestWsmeModels(FunctionalTest):
|
|||||||
|
|
||||||
image_wrapper.image.name = 'name'
|
image_wrapper.image.name = 'name'
|
||||||
image_wrapper.image.url = 'http://aic.att.com'
|
image_wrapper.image.url = 'http://aic.att.com'
|
||||||
image_wrapper.image.visibility = 'private'
|
image_wrapper.image.visibility = 'shared'
|
||||||
image_wrapper.image.disk_format = 'raw'
|
image_wrapper.image.disk_format = 'raw'
|
||||||
image_wrapper.image.container_format = 'bare'
|
image_wrapper.image.container_format = 'bare'
|
||||||
image_wrapper.image.min_ram = 1024
|
image_wrapper.image.min_ram = 1024
|
||||||
@ -53,6 +54,7 @@ def get_image_model():
|
|||||||
:return: new customer object
|
:return: new customer object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
image = models.Image(id='a', regions=[models.Region(name='r1', type='group')])
|
image = models.Image(id='a',
|
||||||
|
regions=[models.Region(name='r1', type='group')])
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
@ -8,7 +8,7 @@ json_input = {
|
|||||||
'status': 'complete', 'name': 'Ubuntu', 'internal_id': 1,
|
'status': 'complete', 'name': 'Ubuntu', 'internal_id': 1,
|
||||||
'url': 'https://mirrors.it.att.com/images/image-name',
|
'url': 'https://mirrors.it.att.com/images/image-name',
|
||||||
'disk_format': 'raw', 'min_ram': 0, 'enabled': 1,
|
'disk_format': 'raw', 'min_ram': 0, 'enabled': 1,
|
||||||
'visibility': 'public', 'owner': 'unknown',
|
'visibility': 'shared', 'owner': 'unknown',
|
||||||
'tags': ["abcd-efgh-ijkl-4567", "mnop-qrst-uvwx-0987"],
|
'tags': ["abcd-efgh-ijkl-4567", "mnop-qrst-uvwx-0987"],
|
||||||
'regions': [{
|
'regions': [{
|
||||||
'action': 'delete', 'image_internal_id': 1,
|
'action': 'delete', 'image_internal_id': 1,
|
||||||
@ -43,13 +43,14 @@ yaml_output = {
|
|||||||
'glance_image': {
|
'glance_image': {
|
||||||
'properties': {
|
'properties': {
|
||||||
'container_format': 'bare', 'disk_format': 'raw',
|
'container_format': 'bare', 'disk_format': 'raw',
|
||||||
'visibility': 'public',
|
'visibility': 'shared',
|
||||||
'location': 'https://mirrors.it.att.com/images/image-name',
|
'location': 'https://mirrors.it.att.com/images/image-name',
|
||||||
'active': True,
|
'active': True,
|
||||||
'min_disk': 2, 'min_ram': 0, 'name': 'Ubuntu', 'owner': 'unknown',
|
'min_disk': 2, 'min_ram': 0, 'name': 'Ubuntu', 'owner': 'unknown',
|
||||||
'protected': True,
|
'protected': True,
|
||||||
'id': '12345678-9012-3456-7890-123456789012',
|
'id': '12345678-9012-3456-7890-123456789012',
|
||||||
'tags': ['abcd-efgh-ijkl-4567', 'mnop-qrst-uvwx-0987'],
|
'tags': ['abcd-efgh-ijkl-4567', 'mnop-qrst-uvwx-0987'],
|
||||||
|
'members': ['abcd-efgh-ijkl-4567', 'opqr-stuv-wxyz-8901'],
|
||||||
'extra_properties': {
|
'extra_properties': {
|
||||||
'key_name': 'Key1', 'key_value': 'Key1.value',
|
'key_name': 'Key1', 'key_value': 'Key1.value',
|
||||||
'image_internal_id': 1
|
'image_internal_id': 1
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
- name: Publish images
|
- name: Publish images
|
||||||
block:
|
block:
|
||||||
|
- pip:
|
||||||
|
name: docker
|
||||||
|
version: 2.7.0
|
||||||
- docker_login:
|
- docker_login:
|
||||||
username: "{{ ranger_quay_io_credentials.username }}"
|
username: "{{ ranger_quay_io_credentials.username }}"
|
||||||
password: "{{ ranger_quay_io_credentials.password }}"
|
password: "{{ ranger_quay_io_credentials.password }}"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user