diff --git a/api/src/org/apache/cloudstack/acl/RoleService.java b/api/src/org/apache/cloudstack/acl/RoleService.java index 59eef51e782..98d170b5853 100644 --- a/api/src/org/apache/cloudstack/acl/RoleService.java +++ b/api/src/org/apache/cloudstack/acl/RoleService.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.acl; +import org.apache.cloudstack.acl.RolePermission.Permission; import org.apache.cloudstack.framework.config.ConfigKey; import java.util.List; @@ -36,13 +37,14 @@ public interface RoleService { RolePermission findRolePermission(final Long id); RolePermission findRolePermissionByUuid(final String uuid); - RolePermission createRolePermission(final Role role, final Rule rule, final RolePermission.Permission permission, final String description); + RolePermission createRolePermission(final Role role, final Rule rule, final Permission permission, final String description); /** * updateRolePermission updates the order/position of an role permission * @param role The role whose permissions needs to be re-ordered * @param newOrder The new list of ordered role permissions */ boolean updateRolePermission(final Role role, final List newOrder); + boolean updateRolePermission(final Role role, final RolePermission rolePermission, final Permission permission); boolean deleteRolePermission(final RolePermission rolePermission); List listRoles(); diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 10470b589be..6421fb3e66c 100644 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -373,6 +373,7 @@ public class ApiConstants { public static final String ROLE_NAME = "rolename"; public static final String PERMISSION = "permission"; public static final String RULE = "rule"; + public static final String RULE_ID = "ruleid"; public static final String RULE_ORDER = "ruleorder"; public static final String USER = "user"; public static final String ACTIVE_ONLY = "activeonly"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java b/api/src/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java index 055265c5ccc..045464eab79 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.api.command.admin.acl; import com.cloud.user.Account; import org.apache.cloudstack.acl.Role; import org.apache.cloudstack.acl.RolePermission; +import org.apache.cloudstack.acl.RolePermission.Permission; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiArgValidator; @@ -51,10 +52,18 @@ public class UpdateRolePermissionCmd extends BaseCmd { description = "ID of the role", validations = {ApiArgValidator.PositiveNumber}) private Long roleId; - @Parameter(name = ApiConstants.RULE_ORDER, type = CommandType.LIST, collectionType = CommandType.UUID, required = true, entityType = RolePermissionResponse.class, + @Parameter(name = ApiConstants.RULE_ORDER, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = RolePermissionResponse.class, description = "The parent role permission uuid, use 0 to move this rule at the top of the list") private List rulePermissionOrder; + @Parameter(name = ApiConstants.RULE_ID, type = CommandType.UUID, entityType = RolePermissionResponse.class, + description = "Role permission rule id", since="4.11") + private Long ruleId; + + @Parameter(name = ApiConstants.PERMISSION, type = CommandType.STRING, + description = "Rule permission, can be: allow or deny", since="4.11") + private String rulePermission; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -67,6 +76,21 @@ public class UpdateRolePermissionCmd extends BaseCmd { return rulePermissionOrder; } + public Long getRuleId() { + return ruleId; + } + + public Permission getRulePermission() { + if (this.rulePermission == null) { + return null; + } + if (!this.rulePermission.equalsIgnoreCase(Permission.ALLOW.toString()) && + !this.rulePermission.equalsIgnoreCase(Permission.DENY.toString())) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Values for permission parameter should be: allow or deny"); + } + return rulePermission.equalsIgnoreCase(Permission.ALLOW.toString()) ? Permission.ALLOW : Permission.DENY; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -84,19 +108,35 @@ public class UpdateRolePermissionCmd extends BaseCmd { @Override public void execute() { final Role role = roleService.findRole(getRoleId()); + boolean result = false; if (role == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role id provided"); } - CallContext.current().setEventDetails("Reordering permissions for role id: " + role.getId()); - final List rolePermissionsOrder = new ArrayList<>(); - for (Long rolePermissionId : getRulePermissionOrder()) { - final RolePermission rolePermission = roleService.findRolePermission(rolePermissionId); - if (rolePermission == null) { - throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Provided role permission(s) do not exist"); + if (getRulePermissionOrder() != null) { + if (getRuleId() != null || getRulePermission() != null) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder"); } - rolePermissionsOrder.add(rolePermission); + CallContext.current().setEventDetails("Reordering permissions for role id: " + role.getId()); + final List rolePermissionsOrder = new ArrayList<>(); + for (Long rolePermissionId : getRulePermissionOrder()) { + final RolePermission rolePermission = roleService.findRolePermission(rolePermissionId); + if (rolePermission == null) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Provided role permission(s) do not exist"); + } + rolePermissionsOrder.add(rolePermission); + } + result = roleService.updateRolePermission(role, rolePermissionsOrder); + } else if (getRuleId() != null && getRulePermission() != null) { + if (getRulePermissionOrder() != null) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder"); + } + RolePermission rolePermission = roleService.findRolePermission(getRuleId()); + if (rolePermission == null) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid rule id provided"); + } + CallContext.current().setEventDetails("Updating permission for rule id: " + getRuleId() + " to: " + getRulePermission().toString()); + result = roleService.updateRolePermission(role, rolePermission, getRulePermission()); } - boolean result = roleService.updateRolePermission(role, rolePermissionsOrder); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); setResponseObject(response); diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDao.java b/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDao.java index 37544919657..c9aeba1c599 100644 --- a/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDao.java +++ b/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDao.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.acl.dao; import com.cloud.utils.db.GenericDao; import org.apache.cloudstack.acl.Role; import org.apache.cloudstack.acl.RolePermission; +import org.apache.cloudstack.acl.RolePermission.Permission; import org.apache.cloudstack.acl.RolePermissionVO; import java.util.List; @@ -40,6 +41,15 @@ public interface RolePermissionsDao extends GenericDao { */ boolean update(final Role role, final List newOrder); + /** + * Updates existing role permission + * @param role role of which rule belongs + * @param rolePermission role permission + * @param permission permission + * @return true on success, false if not + */ + boolean update(final Role role, final RolePermission rolePermission, final Permission permission); + /** * Returns ordered linked-list of role permission for a given role * @param roleId the ID of the role diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDaoImpl.java index 8f6fa83f012..32faf4e9a8c 100644 --- a/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDaoImpl.java @@ -29,6 +29,7 @@ import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; import org.apache.cloudstack.acl.Role; import org.apache.cloudstack.acl.RolePermission; +import org.apache.cloudstack.acl.RolePermission.Permission; import org.apache.cloudstack.acl.RolePermissionVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -149,6 +150,19 @@ public class RolePermissionsDaoImpl extends GenericDaoBase findAllByRoleIdSorted(final Long roleId) { final SearchCriteria sc = RolePermissionsSearch.create(); diff --git a/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java b/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java index 27cb3d0238a..6cf8f9711b3 100644 --- a/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java +++ b/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java @@ -204,6 +204,12 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu return role != null && newOrder != null && rolePermissionsDao.update(role, newOrder); } + @Override + public boolean updateRolePermission(Role role, RolePermission rolePermission, RolePermission.Permission permission) { + checkCallerAccess(); + return role != null && rolePermissionsDao.update(role, rolePermission, permission); + } + @Override @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_DELETE, eventDescription = "deleting Role Permission") public boolean deleteRolePermission(final RolePermission rolePermission) { diff --git a/test/integration/smoke/test_dynamicroles.py b/test/integration/smoke/test_dynamicroles.py index 99614374553..5d105f6a427 100644 --- a/test/integration/smoke/test_dynamicroles.py +++ b/test/integration/smoke/test_dynamicroles.py @@ -394,6 +394,46 @@ class TestDynamicRoles(cloudstackTestCase): rule.update(self.apiclient, ruleorder=",".join(map(lambda x: x.id, permissions))) validate_permissions_list(permissions) + @attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False) + def test_rolepermission_lifecycle_update_permission(self): + """ + Tests update of Allow to Deny permission of a rule + """ + permissions = [self.rolepermission] + + rule = permissions.pop(0) + rule.update(self.apiclient, ruleid=rule.id, permission='deny') + + list_rolepermissions = RolePermission.list(self.apiclient, roleid=self.role.id) + self.assertEqual( + list_rolepermissions[0].permission, + 'deny', + msg="List of role permissions do not match created list of permissions" + ) + + rule.update(self.apiclient, ruleid=rule.id, permission='allow') + + list_rolepermissions = RolePermission.list(self.apiclient, roleid=self.role.id) + self.assertEqual( + list_rolepermissions[0].permission, + 'allow', + msg="List of role permissions do not match created list of permissions" + ) + + @attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False) + def test_rolepermission_lifecycle_update_permission_negative(self): + """ + Tests negative test for setting incorrect value as permission + """ + permissions = [self.rolepermission] + + rule = permissions.pop(0) + try: + rule.update(self.apiclient, ruleid=rule.id, permission='some_other_value') + except Exception: + pass + else: + self.fail("Negative test: Setting permission to 'some_other_value' should not be successful, failing") @attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False) def test_rolepermission_lifecycle_concurrent_updates(self): diff --git a/ui/l10n/ar.js b/ui/l10n/ar.js index 599db00e573..538fd4b3608 100644 --- a/ui/l10n/ar.js +++ b/ui/l10n/ar.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "يرجى تأكيد رغبتك في إعادة تشغيل الـVPN", "message.restart.vpc.remark": "Please confirm that you want to restart the VPC

Remark: making a non-redundant VPC redundant will force a clean up. The networks will not be available for a couple of minutes.

", "message.restoreVM": "Do you want to restore the VM ?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(Use Ctrl-click to select all applicable security groups)", "message.select.a.zone": "A zone typically corresponds to a single datacenter. Multiple zones help make the cloud more reliable by providing physical isolation and redundancy.", diff --git a/ui/l10n/ca.js b/ui/l10n/ca.js index a2f8fd4ce35..d97a948ef1b 100644 --- a/ui/l10n/ca.js +++ b/ui/l10n/ca.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Please confirm that you want to restart the VPC", "message.restart.vpc.remark": "Please confirm that you want to restart the VPC

Remark: making a non-redundant VPC redundant will force a clean up. The networks will not be available for a couple of minutes.

", "message.restoreVM": "Do you want to restore the VM ?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(Use Ctrl-click to select all applicable security groups)", "message.select.a.zone": "A zone typically corresponds to a single datacenter. Multiple zones help make the cloud more reliable by providing physical isolation and redundancy.", diff --git a/ui/l10n/de_DE.js b/ui/l10n/de_DE.js index 0df586116bf..f3d93bffec5 100644 --- a/ui/l10n/de_DE.js +++ b/ui/l10n/de_DE.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Bitte bestätigen Sie, dass Sie den VPC neu starten möchten", "message.restart.vpc.remark": "Bitte bestätigen Sie, dass Sie die VPC neu starten möchten

small>Hinweis: Ein nicht-redundante VPC redundant zu machen wird eine Bereinigung erzwingen. Die Netzwerke werden dadurch einige Minuten nicht verfügbar sein.

", "message.restoreVM": "Möchten Sie die VM wiederherstellen?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Die Neuordnung der Regelberechtigungen wurde abgebrochen, es sind Änderungen eingetreten während Sie an der Liste Arbeiten durchgeführt haben. Bitte versuchen Sie es erneut.", "message.security.group.usage": "(Verwenden Sie Ctrl-click um alle passenden Sicherheits Gruppen auszuwählen)", "message.select.a.zone": "Eine Zone steht typischerweise für ein einzelnes Rechenzentrum. Mehrere Zonen helfen dabei, die Cloud zuverlässiger zu machen durch physikalische Isolation und Redundanz.", diff --git a/ui/l10n/en.js b/ui/l10n/en.js index 3503296c69f..8cfa419e9b2 100644 --- a/ui/l10n/en.js +++ b/ui/l10n/en.js @@ -2207,6 +2207,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "message.restart.vpc":"Please confirm that you want to restart the VPC", "message.restart.vpc.remark":"Please confirm that you want to restart the VPC

Remark: making a non-redundant VPC redundant will force a clean up. The networks will not be available for a couple of minutes.

", "message.restoreVM":"Do you want to restore the VM ?", +"message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail":"Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage":"(Use Ctrl-click to select all applicable security groups)", "message.select.a.zone":"A zone typically corresponds to a single datacenter. Multiple zones help make the cloud more reliable by providing physical isolation and redundancy.", diff --git a/ui/l10n/es.js b/ui/l10n/es.js index eee421f41ed..38ec9c00ac2 100644 --- a/ui/l10n/es.js +++ b/ui/l10n/es.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Por favor confirme que usted quiere reiniciar el VPC", "message.restart.vpc.remark": "Por favor confirme que desea reiniciar el VPC

Atención: creando un VPC sin redundancia forzara la limpieza. Todas las redes dejaran de estar disponibles por unos minutos.

", "message.restoreVM": "¿Desea recuperar la MV?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordenación de permisos de reglas abortada ya que la lista ha cambiado mientras realizaba los cambios. Por favor, intente de nuevo. ", "message.security.group.usage": "(Use Ctrl-click para seleccionar todos los grupos de seguridad pertinentes)", "message.select.a.zone": "Una zona normalmente se corresponde con un solo datacenter. Múltiples zonas pueden ayudar a aumentar la disponibilidad del cloud al proveer aislamiento físico y redundancia.", diff --git a/ui/l10n/fr_FR.js b/ui/l10n/fr_FR.js index 8a03fb0ea35..0bb6a0dc8c9 100644 --- a/ui/l10n/fr_FR.js +++ b/ui/l10n/fr_FR.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Confirmer le redémarrage du VPC", "message.restart.vpc.remark": "Veuillez confirmer que vous voulez redémarrer le VPC

Note : transformer un VPC non-redondant en VPC redondant va forcer un nettoyage du routeur. Le réseau associé ne sera pas disponible durant quelques minutes.

", "message.restoreVM": "Voulez-vous restaurer la VM ?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "La réorganisation des règles d'autorisations a été abandonnée car la liste a changé pendant que vous apportez des modifications. Veuillez réessayer.", "message.security.group.usage": "(Utilisez Ctrl-clic pour sélectionner les groupes de sécurité visés)", "message.select.a.zone": "Une zone correspond typiquement à un seul centre de données. Des zones multiples peuvent permettre de rendre votre cloud plus fiable en apportant une isolation physique et de la redondance.", diff --git a/ui/l10n/hu.js b/ui/l10n/hu.js index 726cab8cb28..3da69417fca 100644 --- a/ui/l10n/hu.js +++ b/ui/l10n/hu.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Erősítsd meg, hogy újra akarod indítani a VPC-t!", "message.restart.vpc.remark": "Erősítsd meg, hogy újra akarod indítani a VPC-t!

Megjegyzés: egy nem redundáns VPC redundánssá tétele takarítást tesz szükségessé. A hálózatok nem lesznek elérhetőek egy pár percig..

", "message.restoreVM": "Helyre akarod állítani a VM-et?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(A Ctrl-kattintás használatával tudod az összes alkalmazható biztonsági csoportot kiválasztani)", "message.select.a.zone": "Egy zóna tipikusan egy adatközpontnak felel meg. Több zóna segíthet a felhőt megbízhatóbbá tenni fizikai izolációval és redundanciával.", diff --git a/ui/l10n/it_IT.js b/ui/l10n/it_IT.js index 71875a3d30d..247b8e04a73 100644 --- a/ui/l10n/it_IT.js +++ b/ui/l10n/it_IT.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Si prega di confermare di voler riavviare VPC", "message.restart.vpc.remark": "Please confirm that you want to restart the VPC

Remark: making a non-redundant VPC redundant will force a clean up. The networks will not be available for a couple of minutes.

", "message.restoreVM": "Do you want to restore the VM ?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(Use Ctrl-click to select all applicable security groups)", "message.select.a.zone": "Una zona corrisponde tipicamente ad un singolo datacenter. Zone multiple consentono di aumentare l'affidabilità creando isolamento fisico e ridondanza.", diff --git a/ui/l10n/ja_JP.js b/ui/l10n/ja_JP.js index 5a55e870d76..a5da1a37d77 100644 --- a/ui/l10n/ja_JP.js +++ b/ui/l10n/ja_JP.js @@ -2180,6 +2180,7 @@ var dictionary = { "message.restart.vpc": "VPC を再起動してもよろしいですか?", "message.restart.vpc.remark": "VPC を再起動してもよろしいですか?

注意: 非冗長 VPC の冗長化は強制的にクリーンアップされます. また、ネットワークは数分間利用出来なくなります.

", "message.restoreVM": "VM を復元してもよろしいですか?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(該当するセキュリティ グループをすべて選択するには、Ctrl キーを押しながらクリックしてください)", "message.select.a.zone": "ゾーンは通常、単一のデータセンターに相当します。複数のゾーンを設定し、物理的に分離して冗長性を持たせることにより、クラウドの信頼性を高めます。", diff --git a/ui/l10n/ko_KR.js b/ui/l10n/ko_KR.js index ca222386602..f592a7c1c87 100644 --- a/ui/l10n/ko_KR.js +++ b/ui/l10n/ko_KR.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "VPC를 재시작하시겠습니까?", "message.restart.vpc.remark": "Please confirm that you want to restart the VPC

Remark: making a non-redundant VPC redundant will force a clean up. The networks will not be available for a couple of minutes.

", "message.restoreVM": "Do you want to restore the VM ?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(해당하는 보안 그룹을 모두 선택하려면 Ctrl 키를 누르면서 클릭해 주십시오)", "message.select.a.zone": "Zone은 원래 단일 데이터 센터에 해당합니다. 복수 Zone을 설정하고 물리적으로 분리하는 방법으로 클라우드의 신뢰성을 높일 수 있습니다.", diff --git a/ui/l10n/nb_NO.js b/ui/l10n/nb_NO.js index 801ce7fa458..1ef414572c4 100644 --- a/ui/l10n/nb_NO.js +++ b/ui/l10n/nb_NO.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Vennligst bekreft at du ønsker å restarte VPC", "message.restart.vpc.remark": "Vennligst bekreft du at du vil restarte VPC

Merk: Å gjøre en ikke reduntant VPC redundant vil tvinge en opprydning. Nettverkene vil ikke være tilgjengelig i noen minutter.

", "message.restoreVM": "Vil du gjenopprette denne VMen?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(Bruk Ctrl-klikk for å velge alle aktuelle sikkerhetsgrupper)", "message.select.a.zone": "En sone er typisk sett på som et datasenter. Multiple soner gir CloudStack bedre pålitelighet gjennom isolasjon og redundans.", diff --git a/ui/l10n/nl_NL.js b/ui/l10n/nl_NL.js index 10456e86839..58465f377d4 100644 --- a/ui/l10n/nl_NL.js +++ b/ui/l10n/nl_NL.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Bevestig dat u deze VPC wilt herstarten", "message.restart.vpc.remark": "Bevestig altublieft dat U de VPC wilt herstarten

Opmerking: Een niet-redundante VPC redundant maken zal opschonen forceren. De netwerken zullen enige tijd niet beschikbaar zijn.

", "message.restoreVM": "Wilt u de VM herstellen?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(Gebruik Ctrl-klik om meerdere security groups te selecteren)", "message.select.a.zone": "Een zone correspondeert meestal met een enkel datacenter. Meerdere zones maken de cloud betrouwbaarder door fysiek isolatie en redunatie te verzorgen.", diff --git a/ui/l10n/pl.js b/ui/l10n/pl.js index 80bc1f334d6..1ba89b25cc1 100644 --- a/ui/l10n/pl.js +++ b/ui/l10n/pl.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Please confirm that you want to restart the VPC", "message.restart.vpc.remark": "Please confirm that you want to restart the VPC

Remark: making a non-redundant VPC redundant will force a clean up. The networks will not be available for a couple of minutes.

", "message.restoreVM": "Do you want to restore the VM ?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(Use Ctrl-click to select all applicable security groups)", "message.select.a.zone": "A zone typically corresponds to a single datacenter. Multiple zones help make the cloud more reliable by providing physical isolation and redundancy.", diff --git a/ui/l10n/pt_BR.js b/ui/l10n/pt_BR.js index bc34f156d88..77bfe53eed1 100644 --- a/ui/l10n/pt_BR.js +++ b/ui/l10n/pt_BR.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Favor confirmar que você deseja reiniciar a VPC", "message.restart.vpc.remark": "Por favor, confirme a reinicialização do VPC

Observação: fazendo um VPC redundante não redundante irá forçar uma limpeza. As redes não estarão disponíveis por alguns minutos.

", "message.restoreVM": "Quer restaurar a VM?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(Use Ctrl-clique para selecionar todos os Security Groups)", "message.select.a.zone": "A zone tipicamente corresponde a um único datacenter. Múltiplas zonas auxiliam a cloud a ser mais confiável provendo isolamento físico e redundância.", diff --git a/ui/l10n/ru_RU.js b/ui/l10n/ru_RU.js index f9fd5db64ce..aaa40b8f9a3 100644 --- a/ui/l10n/ru_RU.js +++ b/ui/l10n/ru_RU.js @@ -2176,6 +2176,7 @@ var dictionary = { "message.restart.vpc": "Подтвердите, что вы действительно хотите перезапустить VPC", "message.restart.vpc.remark": "Please confirm that you want to restart the VPC

Remark: making a non-redundant VPC redundant will force a clean up. The networks will not be available for a couple of minutes.

", "message.restoreVM": "Do you want to restore the VM ?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(Используйте Ctrl-click для выбора всех применимых security groups)", "message.select.a.zone": "Зона обычно соответствует единичному центру обработки данных. Несколько зон помогают создавать более надежные облака, обеспечивая физическую изоляцию и избыточность.", diff --git a/ui/l10n/zh_CN.js b/ui/l10n/zh_CN.js index 54646b02488..2131c985cff 100644 --- a/ui/l10n/zh_CN.js +++ b/ui/l10n/zh_CN.js @@ -2180,6 +2180,7 @@ var dictionary = { "message.restart.vpc": "请确认您确实要重新启动 VPC", "message.restart.vpc.remark": "请确定您要重启VPC

警告: 重启非冗余的VPC将会导致网络中断,直至VPC重启完成.

", "message.restoreVM": "是否要还原此 VM?", + "message.role.update.fail": "Failed updating rule permission", "message.role.ordering.fail": "Reordering of rule permissions aborted as the list has changed while you were making changes. Please try again.", "message.security.group.usage": "(按住 Ctrl 键并单击鼠标可选择所有适用的安全组)", "message.select.a.zone": "一个资源域通常与一个数据中心相对应。多个资源域可以提供物理隔离和冗余,有助于使云更加可靠。", diff --git a/ui/scripts/roles.js b/ui/scripts/roles.js index eae088fafa8..01700dfc9a5 100644 --- a/ui/scripts/roles.js +++ b/ui/scripts/roles.js @@ -171,6 +171,28 @@ context: context, noSelect: true, noHeaderActionsColumn: true, + selectPermission: { + action: function(args){ + $.ajax({ + url: createURL("updateRolePermission"), + data: { + roleid: args.roleid, + ruleid: args.ruleid, + permission: args.permission + }, + dataType: "json", + async: true, + success: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + }, + error: function(json) { + cloudStack.dialog.notice({ + message: 'message.role.update.fail' + }); + } + }); + } + }, reorder: { moveDrag: { action: function(args) { @@ -193,6 +215,7 @@ }); $.ajax({ + type: 'POST', url: createURL('updateRolePermission'), data: { roleid: rule.roleid, diff --git a/ui/scripts/ui/widgets/multiEdit.js b/ui/scripts/ui/widgets/multiEdit.js index 3e88b929394..48d597e6859 100755 --- a/ui/scripts/ui/widgets/multiEdit.js +++ b/ui/scripts/ui/widgets/multiEdit.js @@ -31,6 +31,7 @@ var $item = $('
').addClass('data-item'); var multiRule = data; var reorder = options.reorder; + var selectPermission = options.selectPermission; $item.append($('').append($(''))); $tr = $('').appendTo($item.find('tbody')); @@ -189,10 +190,34 @@ return $(this).val() == data[fieldName]; }); - var matchingValue = $matchingOption.size() ? - $matchingOption.html() : data[fieldName]; + if (selectPermission) { + // Wrap div to get its html code + selectedOptionHtml = $matchingOption.clone().wrap('
').parent().html(); + // Get html code from not matching option + $matchingSelect.find('option').each( + function() { + if ($(this).val() != data[fieldName]){ + selectedOptionHtml += $(this).clone().wrap('
').parent().html(); + } + } + ); + $select = $('
').appendTo( $('').appendTo($inputTable) @@ -1197,7 +1223,8 @@ preFilter: actionPreFilter, listView: listView, tags: tags, - reorder: reorder + reorder: reorder, + selectPermission: selectPermission } ).appendTo($dataBody); });