diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 2acabdbfc79..1ef2d84f7b4 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -3241,6 +3241,7 @@ div.toolbar div.button.main-action, height: 12px; } +div.toolbar div.button.export:hover, div.toolbar div.button.add:hover, div.toolbar div.button.refresh:hover, div.toolbar div.button.main-action:hover, @@ -13414,3 +13415,32 @@ div.panel.copy-template-destination-list div.list-view div.fixed-header{ .multi-edit-add-list .ui-button.copytemplatecancel { left: 310px; } + +div.button.export { + position: relative; + left: 0px; + top: 5px; + font-size: 12px; + font-weight: 100; + color: #000000; + margin: 0 10px 0 0; + cursor: pointer; + text-shadow: 0px 1px 1px #DEE5EA; + padding: 5px 5px 5px 5px; + background: linear-gradient(to bottom, rgba(247,247,247,1) 1%,rgba(234,234,234,1) 100%); + border: 1px solid #B7B7B7; + float: right; + border-radius: 4px 4px 4px 4px; + height: 12px; +} + +div.button.export a { + padding: 0px 0 3px 20px; + background: url(../images/exportCsvIcon.png) no-repeat; + position: relative; + left: 0px; + top: 0px; + background-size: 15.5px; + text-decoration: none; + color: black; +} \ No newline at end of file diff --git a/ui/images/exportCsvIcon.png b/ui/images/exportCsvIcon.png new file mode 100644 index 00000000000..cc486ec1735 Binary files /dev/null and b/ui/images/exportCsvIcon.png differ diff --git a/ui/l10n/ar.js b/ui/l10n/ar.js index f6927437017..db0dab01ce0 100644 --- a/ui/l10n/ar.js +++ b/ui/l10n/ar.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Accounts", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL List Rules", "label.acl.name": "ACL Name", "label.acl.replaced": "ACL replaced", diff --git a/ui/l10n/ca.js b/ui/l10n/ca.js index 276b3e51bfc..5d9846723be 100644 --- a/ui/l10n/ca.js +++ b/ui/l10n/ca.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Accounts", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL List Rules", "label.acl.name": "ACL Name", "label.acl.replaced": "ACL replaced", diff --git a/ui/l10n/de_DE.js b/ui/l10n/de_DE.js index 76374f63459..4decf808448 100644 --- a/ui/l10n/de_DE.js +++ b/ui/l10n/de_DE.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Benutzerkonten", "label.acl": "ACL", "label.acl.id": "ACL-Kennung", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL-Listenregeln", "label.acl.name": "ACL-Name", "label.acl.replaced": "ACL ersetzt", diff --git a/ui/l10n/en.js b/ui/l10n/en.js index 6d994303f1a..ae7ca7ba866 100644 --- a/ui/l10n/en.js +++ b/ui/l10n/en.js @@ -102,6 +102,7 @@ var dictionary = { "label.accounts":"Accounts", "label.acl":"ACL", "label.acl.id":"ACL ID", +"label.acl.export": "Export ACLs", "label.acl.list.rules":"ACL List Rules", "label.acl.name":"ACL Name", "label.acl.replaced":"ACL replaced", diff --git a/ui/l10n/es.js b/ui/l10n/es.js index 37f8425ac05..cbdf7878844 100644 --- a/ui/l10n/es.js +++ b/ui/l10n/es.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Cuentas", "label.acl": "ACL", "label.acl.id": "ID de ACL", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "Lista de Reglas ACL", "label.acl.name": "Nombre de ACL", "label.acl.replaced": "ACL reemplazada", diff --git a/ui/l10n/fr_FR.js b/ui/l10n/fr_FR.js index 2d03b64dcaa..42f93c0534b 100644 --- a/ui/l10n/fr_FR.js +++ b/ui/l10n/fr_FR.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Comptes", "label.acl": "ACL", "label.acl.id": "ID ACL", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "Liste règles ACL", "label.acl.name": "Nom ACL", "label.acl.replaced": "ACL remplacée", diff --git a/ui/l10n/hu.js b/ui/l10n/hu.js index f4d20e5be1c..41edd47fdc7 100644 --- a/ui/l10n/hu.js +++ b/ui/l10n/hu.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Számlák", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL List Rules", "label.acl.name": "ACL név", "label.acl.replaced": "ACL lehelyettesítve", diff --git a/ui/l10n/it_IT.js b/ui/l10n/it_IT.js index bcc3a0fa661..30d0b32ff03 100644 --- a/ui/l10n/it_IT.js +++ b/ui/l10n/it_IT.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Utenti", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL List Rules", "label.acl.name": "ACL Name", "label.acl.replaced": "ACL replaced", diff --git a/ui/l10n/ja_JP.js b/ui/l10n/ja_JP.js index efa937a4856..24f99e7a905 100644 --- a/ui/l10n/ja_JP.js +++ b/ui/l10n/ja_JP.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "アカウント", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL ルールのリスト", "label.acl.name": "ACL 名", "label.acl.replaced": "ACL が置き換えられました", diff --git a/ui/l10n/ko_KR.js b/ui/l10n/ko_KR.js index de2d6ba9c98..19d80fb1613 100644 --- a/ui/l10n/ko_KR.js +++ b/ui/l10n/ko_KR.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "계정 정보", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL List Rules", "label.acl.name": "ACL Name", "label.acl.replaced": "ACL replaced", diff --git a/ui/l10n/nb_NO.js b/ui/l10n/nb_NO.js index 57fda63e7e1..6adc9958f4c 100644 --- a/ui/l10n/nb_NO.js +++ b/ui/l10n/nb_NO.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Kontoer", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL Liste Regler", "label.acl.name": "ACL Navn", "label.acl.replaced": "ACL erstattet", diff --git a/ui/l10n/nl_NL.js b/ui/l10n/nl_NL.js index 4bf253dd074..f460214e6ce 100644 --- a/ui/l10n/nl_NL.js +++ b/ui/l10n/nl_NL.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Accounts", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL lijst regels", "label.acl.name": "ACL naam", "label.acl.replaced": "ACL vervangen", diff --git a/ui/l10n/pl.js b/ui/l10n/pl.js index 7b7a89b316a..0d89f1e0f93 100644 --- a/ui/l10n/pl.js +++ b/ui/l10n/pl.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Konta", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL List Rules", "label.acl.name": "ACL Name", "label.acl.replaced": "ACL replaced", diff --git a/ui/l10n/pt_BR.js b/ui/l10n/pt_BR.js index 45de2067fa7..52066c30a72 100644 --- a/ui/l10n/pt_BR.js +++ b/ui/l10n/pt_BR.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Contas", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "Lista de regas de ACL", "label.acl.name": "Nome da ACL", "label.acl.replaced": "ACL trocado", diff --git a/ui/l10n/ru_RU.js b/ui/l10n/ru_RU.js index 0321f710cee..b297b4074b0 100644 --- a/ui/l10n/ru_RU.js +++ b/ui/l10n/ru_RU.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "Учётные записи", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL List Rules", "label.acl.name": "ACL Name", "label.acl.replaced": "ACL replaced", diff --git a/ui/l10n/zh_CN.js b/ui/l10n/zh_CN.js index 1d617d6f630..c6965c642c2 100644 --- a/ui/l10n/zh_CN.js +++ b/ui/l10n/zh_CN.js @@ -101,6 +101,7 @@ var dictionary = { "label.accounts": "帐户", "label.acl": "ACL", "label.acl.id": "ACL ID", + "label.acl.export": "Export ACLs", "label.acl.list.rules": "ACL列表策略", "label.acl.name": "ACL 名称", "label.acl.replaced": "ACL 已替换", diff --git a/ui/scripts/vpc.js b/ui/scripts/vpc.js index 7a2a30205d0..dcf8e38e09b 100644 --- a/ui/scripts/vpc.js +++ b/ui/scripts/vpc.js @@ -15,6 +15,53 @@ // specific language governing permissions and limitations // under the License. (function($, cloudStack) { + var isNumeric = function (n) { + return !isNaN(parseFloat(n)); + }; + var createSafeCsvValue = function(value){ + if(value){ + return '"' + value + '"'; + } + return ""; + }; + + var generateCsvForAclRules = function(aclRules){ + var csv = createSafeCsvValue('id') + ','; + for(var field in aclRuleFields){ + var fieldLabel = aclRuleFields[field].label; + var fieldLabelTranslated = _l(fieldLabel); + csv = csv + createSafeCsvValue(fieldLabelTranslated) + ','; + } + csv = csv.substr(0, csv.length - 1) + '\n'; + if(!aclRules){ + return csv; + } + aclRules.forEach(function(entry){ + csv = csv + + createSafeCsvValue(entry.id) + ',' + + createSafeCsvValue(entry.number) + ',' + + createSafeCsvValue(entry.cidrlist) + ',' + + createSafeCsvValue(entry.action) + ',' ; + + if(isNumeric(entry.protocol)){ + csv = csv + + createSafeCsvValue(_l('label.protocol.number')) + ',' + + createSafeCsvValue(entry.protocol) + ','; + }else{ + csv = csv + + createSafeCsvValue(entry.protocol) + ',' + + createSafeCsvValue('') + ','; + } + csv = csv + + createSafeCsvValue(entry.startport) + ',' + + createSafeCsvValue(entry.endport) + ',' + + createSafeCsvValue(entry.icmptype) + ',' + + createSafeCsvValue(entry.icmpcode) + ',' + + createSafeCsvValue(entry.traffictype) + ',' + + createSafeCsvValue(entry.reason) + '\n'; + }); + return csv; + }; var assignVMAction = function() { return { label: 'label.assign.vms', @@ -1327,8 +1374,9 @@ networkid: false }, dataProvider: function(args) { + var aclListId = args.context.aclLists[0].id; $.ajax({ - url: createURL('listNetworkACLs&aclid=' + args.context.aclLists[0].id), + url: createURL('listNetworkACLs&aclid=' + aclListId), success: function(json) { var items = json.listnetworkaclsresponse.networkacl; @@ -1369,6 +1417,9 @@ } if(data.protocol != 'protocolnumber'){ data.protocolnumber = undefined; + }else{ + data.protocol = data.protocolnumber; + data.protocolnumber = undefined; } if(data.protocol === 'all'){ data.startport = undefined; @@ -1389,6 +1440,32 @@ }); jQuery('#details-tab-aclRules').siblings('div.toolbar').append($addAclRuleDivButton); } + if(jQuery('#details-tab-aclRules').siblings('div.toolbar').children('div.export').size() === 0){ + var $exportAclsDivButton = jQuery('