Add 'subcloud deploy delete' command to dcmanager
This commit adds the subcloud deploy delete command to dcmanager. It is used to delete deploy files under /opt/platform/deploy. Test Cases: 1) PASS: dcmanager subcloud deploy delete with no release 2) PASS: dcmanager subcloud deploy delete --release 23.09 3) PASS: dcmanager subcloud deploy delete --release 22.12 4) PASS: dcmanager subcloud deploy delete --release 21.12 fails using the load 23.09 we support n-1. 5) PASS: dcmanager subcloud deploy delete --prestage-image 6) PASS: dcmanager subcloud deploy delete --deployment-files 7) PASS: dcmanager subcloud deploy delete fails when deploy files doesn't exist already. Story: 2010718 Task: 49190 Change-Id: I94d629009b185f67e3da45d010a6492b9b6d6f17 Signed-off-by: Swapna Gorre <swapna.gorre@windriver.com>
This commit is contained in:
parent
f9a86d7f8c
commit
eeb70d47c2
@ -1791,6 +1791,37 @@ Response Example
|
||||
:language: json
|
||||
|
||||
|
||||
************************************
|
||||
Delete Subcloud Deploy Files
|
||||
************************************
|
||||
|
||||
.. rest_method:: DELETE /v1.0/subcloud-deploy
|
||||
|
||||
**Normal response codes**
|
||||
|
||||
200
|
||||
|
||||
**Error response codes**
|
||||
|
||||
badRequest (400), unauthorized (401), forbidden (403), notFound (404),
|
||||
HTTPUnprocessableEntity (422), internalServerError (500),
|
||||
serviceUnavailable (503)
|
||||
|
||||
**Request parameters**
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- release: release_uri
|
||||
- deployment_files: delete_subcloud_deployment_files
|
||||
- prestage_images: delete_subcloud_deploy_prestage_images
|
||||
|
||||
Request Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/subcloud-deploy/subcloud-deploy-delete-request.json
|
||||
:language: json
|
||||
|
||||
|
||||
----------------------
|
||||
Phased Subcloud Deploy
|
||||
----------------------
|
||||
|
@ -233,6 +233,20 @@ default_instance_action:
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
delete_subcloud_deploy_prestage_images:
|
||||
description: |
|
||||
The flag to indicate the deployment manager prestage images
|
||||
file to be deleted.
|
||||
in: body
|
||||
required: false
|
||||
type: boolean
|
||||
delete_subcloud_deployment_files:
|
||||
description: |
|
||||
The flag to indicate the deploy playbook, deploy overrides,
|
||||
deploy chart files to be deleted.
|
||||
in: body
|
||||
required: false
|
||||
type: boolean
|
||||
deploy_config:
|
||||
description: |
|
||||
The content of a file containing the resource definitions describing
|
||||
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"release": 23.09,
|
||||
"prestage_images": false,
|
||||
"deployment_files": false
|
||||
}
|
@ -149,3 +149,44 @@ class SubcloudDeployController(object):
|
||||
filename = filename.replace(prefix, '', 1)
|
||||
deploy_dicts.update({f: filename})
|
||||
return dict(subcloud_deploy=deploy_dicts)
|
||||
|
||||
@index.when(method='DELETE', template='json')
|
||||
def delete(self, release=None):
|
||||
"""Delete the subcloud deploy files.
|
||||
|
||||
:param release: release version
|
||||
"""
|
||||
policy.authorize(subcloud_deploy_policy.POLICY_ROOT % "delete", {},
|
||||
restcomm.extract_credentials_for_policy())
|
||||
|
||||
is_prestage_images = request.params.get('prestage_images', '').lower() == 'true'
|
||||
is_deployment_files = request.params.get('deployment_files', '').lower() == 'true'
|
||||
|
||||
dir_path = os.path.join(dccommon_consts.DEPLOY_DIR, utils.get_sw_version(release))
|
||||
if not os.path.isdir(dir_path):
|
||||
pecan.abort(httpclient.NOT_FOUND,
|
||||
_("Directory not found: %s" % dir_path))
|
||||
try:
|
||||
file_options = []
|
||||
if is_prestage_images:
|
||||
file_options.append(consts.DEPLOY_PRESTAGE)
|
||||
|
||||
if is_deployment_files:
|
||||
file_options.extend([consts.DEPLOY_OVERRIDES, consts.DEPLOY_CHART,
|
||||
consts.DEPLOY_PLAYBOOK])
|
||||
|
||||
if not (is_deployment_files or is_prestage_images):
|
||||
file_options.extend(consts.DEPLOY_COMMON_FILE_OPTIONS)
|
||||
|
||||
for file_option in file_options:
|
||||
prefix = file_option + '_'
|
||||
file_name = utils.get_filename_by_prefix(dir_path, prefix)
|
||||
if file_name:
|
||||
os.remove(os.path.join(dir_path, file_name))
|
||||
else:
|
||||
LOG.warning('%s file not present' % file_option)
|
||||
|
||||
except Exception as e:
|
||||
pecan.abort(httpclient.INTERNAL_SERVER_ERROR,
|
||||
_("Failed to delete file: %s" % e))
|
||||
return None
|
||||
|
@ -36,6 +36,21 @@ subcloud_deploy_rules = [
|
||||
'path': '/v1.0/subcloud-deploy/{release}'
|
||||
}
|
||||
]
|
||||
),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=POLICY_ROOT % 'delete',
|
||||
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
|
||||
description="Delete subcloud deploy files.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/v1.0/subcloud-deploy'
|
||||
},
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/v1.0/subcloud-deploy/{release}'
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -14,8 +14,10 @@
|
||||
# under the License.
|
||||
#
|
||||
import os
|
||||
from os import path as os_path
|
||||
|
||||
import mock
|
||||
import six
|
||||
from six.moves import http_client
|
||||
import webtest
|
||||
|
||||
@ -30,7 +32,7 @@ from dcmanager.tests import utils
|
||||
|
||||
from tsconfig.tsconfig import SW_VERSION
|
||||
|
||||
FAKE_SOFTWARE_VERSION = '21.12'
|
||||
FAKE_SOFTWARE_VERSION = '22.12'
|
||||
FAKE_TENANT = utils.UUID1
|
||||
FAKE_ID = '1'
|
||||
FAKE_URL = '/v1.0/subcloud-deploy'
|
||||
@ -40,6 +42,7 @@ FAKE_HEADERS = {'X-Tenant-Id': FAKE_TENANT, 'X_ROLE': 'admin,member,reader',
|
||||
FAKE_DEPLOY_PLAYBOOK_PREFIX = consts.DEPLOY_PLAYBOOK + '_'
|
||||
FAKE_DEPLOY_OVERRIDES_PREFIX = consts.DEPLOY_OVERRIDES + '_'
|
||||
FAKE_DEPLOY_CHART_PREFIX = consts.DEPLOY_CHART + '_'
|
||||
FAKE_PRESTAGE_IMAGES_PREFIX = consts.DEPLOY_PRESTAGE + '_'
|
||||
FAKE_DEPLOY_PLAYBOOK_FILE = 'deployment-manager.yaml'
|
||||
FAKE_DEPLOY_OVERRIDES_FILE = 'deployment-manager-overrides-subcloud.yaml'
|
||||
FAKE_DEPLOY_CHART_FILE = 'deployment-manager.tgz'
|
||||
@ -48,6 +51,21 @@ FAKE_DEPLOY_FILES = {
|
||||
FAKE_DEPLOY_OVERRIDES_PREFIX: FAKE_DEPLOY_OVERRIDES_FILE,
|
||||
FAKE_DEPLOY_CHART_PREFIX: FAKE_DEPLOY_CHART_FILE,
|
||||
}
|
||||
FAKE_DEPLOY_DELETE_FILES = {
|
||||
FAKE_DEPLOY_PLAYBOOK_PREFIX: '/opt/platform/deploy/22.12/deployment-manager.yaml',
|
||||
FAKE_DEPLOY_OVERRIDES_PREFIX:
|
||||
'/opt/platform/deploy/22.12/deployment-manager-overrides-subcloud.yaml',
|
||||
FAKE_DEPLOY_CHART_PREFIX: '/opt/platform/deploy/22.12/deployment-manager.tgz',
|
||||
FAKE_PRESTAGE_IMAGES_PREFIX: '/opt/platform/deploy/22.12/prestage_images.yml'
|
||||
}
|
||||
|
||||
|
||||
def get_filename_by_prefix_side_effect(dir_path, prefix):
|
||||
filename = FAKE_DEPLOY_FILES.get(prefix)
|
||||
if filename:
|
||||
return prefix + FAKE_DEPLOY_FILES.get(prefix)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class TestSubcloudDeploy(testroot.DCManagerApiTest):
|
||||
@ -269,3 +287,127 @@ class TestSubcloudDeploy(testroot.DCManagerApiTest):
|
||||
f'{dccommon_consts.ANSIBLE_OVERRIDES_PATH}/subcloud1/install_values.yml')
|
||||
self.assertEqual(deploy_config,
|
||||
f'{dccommon_consts.ANSIBLE_OVERRIDES_PATH}/subcloud1_deploy_config.yml')
|
||||
|
||||
@mock.patch.object(os_path, 'isdir')
|
||||
@mock.patch.object(dutils, 'get_sw_version')
|
||||
def test_subcloud_deploy_delete_directory_not_found(self,
|
||||
mock_get_sw_version,
|
||||
mock_path_isdir):
|
||||
|
||||
mock_get_sw_version.return_value = '21.12'
|
||||
url = FAKE_URL + '?prestage_images=' + \
|
||||
str(False) + '&deployment_files=' + str(False)
|
||||
mock_path_isdir.side_effect = lambda x: True \
|
||||
if x == '/opt/platform/deploy/22.12' else False
|
||||
six.assertRaisesRegex(self, webtest.app.AppError, "404 *",
|
||||
self.app.delete, url,
|
||||
headers=FAKE_HEADERS)
|
||||
|
||||
@mock.patch.object(os_path, 'isdir')
|
||||
@mock.patch.object(dutils, 'get_sw_version')
|
||||
def test_subcloud_deploy_delete_internal_server_error(self,
|
||||
mock_get_sw_version,
|
||||
mock_path_isdir):
|
||||
|
||||
mock_get_sw_version.return_value = '22.12'
|
||||
mock_path_isdir.side_effect = lambda x: True \
|
||||
if x == '/opt/platform/deploy/22.12' else False
|
||||
six.assertRaisesRegex(self, webtest.app.AppError, "500 *",
|
||||
self.app.delete, FAKE_URL,
|
||||
headers=FAKE_HEADERS)
|
||||
|
||||
@mock.patch.object(os_path, 'isdir')
|
||||
@mock.patch.object(dutils, 'get_sw_version')
|
||||
@mock.patch.object(dutils, 'get_filename_by_prefix')
|
||||
@mock.patch.object(os, 'remove')
|
||||
def test_subcloud_deploy_delete_with_release(self, mock_os_remove,
|
||||
mock_get_filename_by_prefix,
|
||||
mock_get_sw_version,
|
||||
mock_path_isdir):
|
||||
|
||||
mock_os_remove.return_value = None
|
||||
mock_get_sw_version.return_value = '22.12'
|
||||
|
||||
mock_get_filename_by_prefix.side_effect = \
|
||||
get_filename_by_prefix_side_effect
|
||||
mock_path_isdir.return_value = True
|
||||
url = FAKE_URL + '/' + FAKE_SOFTWARE_VERSION + \
|
||||
'?prestage_images=' + str(False) + '&deployment_files=' + str(False)
|
||||
response = self.app.delete(url, headers=FAKE_HEADERS)
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
|
||||
@mock.patch.object(os_path, 'isdir')
|
||||
@mock.patch.object(dutils, 'get_sw_version')
|
||||
@mock.patch.object(dutils, 'get_filename_by_prefix')
|
||||
@mock.patch.object(os, 'remove')
|
||||
def test_subcloud_deploy_delete_without_release(self, mock_os_remove,
|
||||
mock_get_filename_by_prefix,
|
||||
mock_get_sw_version,
|
||||
mock_path_isdir):
|
||||
|
||||
mock_os_remove.return_value = None
|
||||
mock_get_sw_version.return_value = '22.12'
|
||||
url = FAKE_URL + '?prestage_images=' + \
|
||||
str(True) + '&deployment_files=' + str(True)
|
||||
mock_get_filename_by_prefix.side_effect = \
|
||||
get_filename_by_prefix_side_effect
|
||||
mock_path_isdir.return_value = True
|
||||
response = self.app.delete(url, headers=FAKE_HEADERS)
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
|
||||
@mock.patch.object(os_path, 'isdir')
|
||||
@mock.patch.object(dutils, 'get_sw_version')
|
||||
@mock.patch.object(dutils, 'get_filename_by_prefix')
|
||||
@mock.patch.object(os, 'remove')
|
||||
def test_subcloud_deploy_delete_deployment_files(self, mock_os_remove,
|
||||
mock_get_filename_by_prefix,
|
||||
mock_get_sw_version,
|
||||
mock_path_isdir):
|
||||
mock_os_remove.return_value = None
|
||||
mock_get_sw_version.return_value = '22.12'
|
||||
url = FAKE_URL + '?prestage_images=' + \
|
||||
str(False) + '&deployment_files=' + str(True)
|
||||
mock_get_filename_by_prefix.side_effect = \
|
||||
get_filename_by_prefix_side_effect
|
||||
mock_path_isdir.side_effect = lambda x: True \
|
||||
if x == '/opt/platform/deploy/22.12' else False
|
||||
response = self.app.delete(url, headers=FAKE_HEADERS)
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
|
||||
@mock.patch.object(os_path, 'isdir')
|
||||
@mock.patch.object(dutils, 'get_sw_version')
|
||||
@mock.patch.object(dutils, 'get_filename_by_prefix')
|
||||
@mock.patch.object(os, 'remove')
|
||||
def test_subcloud_deploy_delete_prestage_images(self, mock_os_remove,
|
||||
mock_get_filename_by_prefix,
|
||||
mock_get_sw_version,
|
||||
mock_path_isdir):
|
||||
mock_os_remove.return_value = None
|
||||
mock_get_sw_version.return_value = '22.12'
|
||||
url = FAKE_URL + '?prestage_images=' + \
|
||||
str(True) + '&deployment_files=' + str(False)
|
||||
mock_get_filename_by_prefix.side_effect = \
|
||||
get_filename_by_prefix_side_effect
|
||||
mock_path_isdir.side_effect = lambda x: True \
|
||||
if x == '/opt/platform/deploy/22.12' else False
|
||||
response = self.app.delete(url, headers=FAKE_HEADERS)
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
|
||||
@mock.patch.object(os_path, 'isdir')
|
||||
@mock.patch.object(dutils, 'get_sw_version')
|
||||
@mock.patch.object(dutils, 'get_filename_by_prefix')
|
||||
@mock.patch.object(os, 'remove')
|
||||
def test_subcloud_deploy_delete_with_both_parameters(self, mock_os_remove,
|
||||
mock_get_filename_by_prefix,
|
||||
mock_get_sw_version,
|
||||
mock_path_isdir):
|
||||
mock_os_remove.return_value = None
|
||||
mock_get_sw_version.return_value = '22.12'
|
||||
url = FAKE_URL + '?prestage_images=' + \
|
||||
str(True) + '&deployment_files=' + str(True)
|
||||
mock_get_filename_by_prefix.side_effect = \
|
||||
get_filename_by_prefix_side_effect
|
||||
mock_path_isdir.side_effect = lambda x: True \
|
||||
if x == '/opt/platform/deploy/22.12' else False
|
||||
response = self.app.delete(url, headers=FAKE_HEADERS)
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
|
Loading…
Reference in New Issue
Block a user