diff --git a/muranodashboard/environments/tables.py b/muranodashboard/environments/tables.py
index 75b55f86a..3ff79a5ab 100644
--- a/muranodashboard/environments/tables.py
+++ b/muranodashboard/environments/tables.py
@@ -48,6 +48,16 @@ def _get_environment_status_and_version(request, table):
return status, version
+def _check_row_actions_allowed(action, request):
+ envs = action.table.data
+ if not envs:
+ return False
+ for env in envs:
+ if action.allowed(request, env):
+ return True
+ return False
+
+
class AddApplication(tables.LinkAction):
name = 'AddApplication'
verbose_name = _('Add Component')
@@ -107,10 +117,13 @@ class DeleteEnvironment(tables.DeleteAction):
)
def allowed(self, request, environment):
- if environment:
- return environment.status not in (consts.STATUS_ID_DEPLOYING,
- consts.STATUS_ID_DELETING)
- return True
+ # table action case: action allowed if any row action allowed
+ if not environment:
+ return _check_row_actions_allowed(self, request)
+
+ # row action case
+ return environment.status not in (consts.STATUS_ID_DEPLOYING,
+ consts.STATUS_ID_DELETING)
def action(self, request, environment_id):
try:
@@ -152,6 +165,12 @@ class AbandonEnvironment(tables.DeleteAction):
* environment is new
* app added to env, but not deploy is not started
"""
+
+ # table action case: action allowed if any row action allowed
+ if not environment:
+ return _check_row_actions_allowed(self, request)
+
+ # row action case
status = getattr(environment, 'status', None)
if status in [consts.STATUS_ID_NEW, consts.STATUS_ID_PENDING]:
return False
@@ -234,6 +253,12 @@ class DeployEnvironment(tables.BatchAction):
* no new services added to the environment (after env creation
or successful deploy or delete failure)
"""
+
+ # table action case: action allowed if any row action allowed
+ if not environment:
+ return _check_row_actions_allowed(self, request)
+
+ # row action case
status = getattr(environment, 'status', None)
if (status != consts.STATUS_ID_DEPLOY_FAILURE and
not environment.has_new_services):
@@ -371,10 +396,10 @@ class EnvironmentsTable(tables.DataTable):
row_class = UpdateEnvironmentRow
status_columns = ['status']
no_data_message = _('NO ENVIRONMENTS')
- table_actions = (CreateEnvironment,)
+ table_actions = (CreateEnvironment, DeployEnvironment,
+ DeleteEnvironment, AbandonEnvironment)
row_actions = (ShowEnvironmentServices, DeployEnvironment,
DeleteEnvironment, AbandonEnvironment)
- multi_select = False
def get_service_details_link(service):
diff --git a/muranodashboard/static/muranodashboard/js/environments-in-place.js b/muranodashboard/static/muranodashboard/js/environments-in-place.js
index 114b9fd8e..15e8e25d9 100644
--- a/muranodashboard/static/muranodashboard/js/environments-in-place.js
+++ b/muranodashboard/static/muranodashboard/js/environments-in-place.js
@@ -46,7 +46,7 @@ $(function() {
}
var $newEnvTr = $('
' +
- ' | ' +
+ ' | ' +
'New | ' +
'' +
' ' +
diff --git a/muranodashboard/tests/functional/consts.py b/muranodashboard/tests/functional/consts.py
index 67f766cc3..22b4d1459 100644
--- a/muranodashboard/tests/functional/consts.py
+++ b/muranodashboard/tests/functional/consts.py
@@ -17,6 +17,7 @@ DeleteImageMeta = TestImage + "//td//button[contains(text(), 'Delete Metadata')]
ImageMeta = "//dl[dt[contains(text(), 'murano_image_info')]]/dd"
More = "//tr[contains(@id, '{0}__row__{1}')]//a[contains(@class, dropdown-toggle) and @href='#']" # noqa
Status = "//td[contains(text(), '{0}')]"
+EnvStatus = "//tr[contains(@data-display, '{0}')]/td[contains(text(), '{1}')]"
CellStatus = "//td[contains(@class, 'status_{0}')]"
Row = "//tr[contains(@id, 'services__row__{0}')]"
ErrorMessage = '//span[contains(@class, "help-block") and contains(text(), "{0}")]' # noqa
@@ -31,11 +32,15 @@ HotFlavorField = '//div[contains(@class, "has-error")]//input'
ButtonSubmit = ".//*[@name='wizard_goto_step'][2]"
InputSubmit = "//input[@type='submit']"
ConfirmDeletion = "//div[@class='modal-footer']//a[contains(text(), 'Delete')]" # noqa
+ConfirmAbandon = "//div[@class='modal-footer']//a[contains(text(), 'Abandon')]" # noqa
UploadPackage = 'packages__action_upload_package'
ImportBundle = 'packages__action_import_bundle'
CreateEnvironment = ".add_env .btn"
DeployEnvironment = "services__action_deploy_env"
DeleteEnvironment = "//button[contains(@id, 'action_delete')]"
+DeployEnvironments = ".btn#environments__action_deploy"
+DeleteEnvironments = ".btn#environments__action_delete"
+AbandonEnvironments = ".btn#environments__action_abandon"
ConfirmCreateEnvironment = 'confirm_create_env'
AddComponent = "services__action_AddApplication"
AddCategory = "categories__action_add_category"
diff --git a/muranodashboard/tests/functional/sanity_check.py b/muranodashboard/tests/functional/sanity_check.py
index da5414c52..eaa7b4730 100644
--- a/muranodashboard/tests/functional/sanity_check.py
+++ b/muranodashboard/tests/functional/sanity_check.py
@@ -2071,3 +2071,81 @@ class TestSuiteCategoriesPagination(base.PackageTestCase):
self.check_element_on_page(by.By.XPATH, c.Status.format(name))
if i != len(pages_itself):
self.driver.find_element_by_xpath(c.PrevBtn).click()
+
+
+class TestSuiteMultipleEnvironments(base.ApplicationTestCase):
+ def test_create_two_environments_and_delete_them_at_once(self):
+ """Test check ability to create and delete multiple environments
+
+ Scenario:
+ 1. Create two environments
+ 2. Navigate to environment list
+ 3. Check created environments
+ 4. Delete created environments at once
+ """
+ self.go_to_submenu('Environments')
+ self.create_environment('test_create_del_env_1')
+ self.go_to_submenu('Environments')
+ self.create_environment('test_create_del_env_2', by_id=True)
+ self.go_to_submenu('Environments')
+ self.driver.find_element_by_css_selector(
+ "label[for=ui-id-1]").click()
+ self.driver.find_element_by_css_selector(
+ c.DeleteEnvironments).click()
+ self.driver.find_element_by_xpath(c.ConfirmDeletion).click()
+ self.wait_for_alert_message()
+ self.check_element_not_on_page(by.By.LINK_TEXT,
+ 'test_create_del_env_1')
+ self.check_element_not_on_page(by.By.LINK_TEXT,
+ 'test_create_del_env_2')
+
+ def test_deploy_two_environments_at_once(self):
+ """Test check ability to deploy multiple environments
+
+ Scenario:
+ 1. Add two apps to different environments
+ 2. Navigate to environment list
+ 3. Check created environments
+ 4. Deploy created environments at once
+ """
+ self.add_app_to_env(self.mockapp_id)
+ self.add_app_to_env(self.mockapp_id)
+ self.go_to_submenu('Environments')
+ self.driver.find_element_by_css_selector(
+ "label[for=ui-id-1]").click()
+ self.driver.find_element_by_css_selector(
+ c.DeployEnvironments).click()
+ # check statuses of two environments
+ self.check_element_on_page(by.By.XPATH,
+ c.EnvStatus.format('quick-env-1', 'Ready'),
+ sec=90)
+ self.check_element_on_page(by.By.XPATH,
+ c.EnvStatus.format('quick-env-2', 'Ready'),
+ sec=90)
+
+ def test_abandon_two_environments_at_once(self):
+ """Test check ability to abandon multiple environments
+
+ Scenario:
+ 1. Add two apps to different environments
+ 2. Navigate to environment list
+ 3. Check created environments
+ 4. Deploy created environments at once
+ 5. Abandon environments before they are deployed
+ """
+ self.add_app_to_env(self.mockapp_id)
+ self.add_app_to_env(self.mockapp_id)
+ self.go_to_submenu('Environments')
+ self.driver.find_element_by_css_selector(
+ "label[for=ui-id-1]").click()
+ self.driver.find_element_by_css_selector(
+ c.DeployEnvironments).click()
+ self.go_to_submenu('Environments')
+ self.driver.find_element_by_css_selector(
+ "label[for=ui-id-1]").click()
+ self.driver.find_element_by_css_selector(
+ c.AbandonEnvironments).click()
+ self.driver.find_element_by_xpath(c.ConfirmAbandon).click()
+ self.wait_for_alert_message()
+ self.check_element_not_on_page(by.By.LINK_TEXT, 'quick-env-1')
+ self.check_element_not_on_page(by.By.LINK_TEXT, 'quick-env-2')
diff --git a/releasenotes/notes/manage-multiple-envs-e587c2e9432e39d7.yaml b/releasenotes/notes/manage-multiple-envs-e587c2e9432e39d7.yaml
new file mode 100644
index 000000000..39713c2ad
--- /dev/null
+++ b/releasenotes/notes/manage-multiple-envs-e587c2e9432e39d7.yaml
@@ -0,0 +1,6 @@
+---
+
+features:
+ - Added possibility for user to select several environments and execute
+ one of the three actions to all of them at once (delete, abandon or
+ deploy).
|