fix(frontend) prevent notification showing Object Object EE-1745 (#5778)

* fix(frontend) prevent notification showing Object Object EE-1745

* fix(frontend) fix notification args in wrong order EE-1745

* fix(rbac) add metrics rbac for regular users EE-1745

Co-authored-by: Simon Meng <simon.meng@portainer.io>
pull/5877/head
cong meng 2021-10-12 10:37:07 +13:00 committed by GitHub
parent d93d88fead
commit 6a67e8142d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 45 additions and 35 deletions

View File

@ -18,6 +18,11 @@ func getPortainerUserDefaultPolicies() []rbacv1.PolicyRule {
Resources: []string{"storageclasses"},
APIGroups: []string{"storage.k8s.io"},
},
{
Verbs: []string{"list"},
Resources: []string{"namespaces", "pods"},
APIGroups: []string{"metrics.k8s.io"},
},
}
}

View File

@ -68,7 +68,7 @@ angular.module('portainer.docker').controller('ServicesDatatableActionsControlle
Notifications.success('Service successfully updated', service.Name);
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to force update service', service.Name);
Notifications.error('Failure', err, 'Unable to force update service' + service.Name);
})
.finally(function final() {
--actionCount;

View File

@ -501,7 +501,7 @@ angular.module('portainer.docker').controller('ServiceController', [
ServiceService.update(service, config, 'previous')
.then(function (data) {
if (data.message && data.message.match(/^rpc error:/)) {
Notifications.error(data.message, 'Error');
Notifications.error('Failure', data, 'Error');
} else {
Notifications.success('Success', 'Service successfully rolled back');
$scope.cancelChanges({});
@ -550,7 +550,7 @@ angular.module('portainer.docker').controller('ServiceController', [
ServiceService.update(service, config).then(
function (data) {
if (data.message && data.message.match(/^rpc error:/)) {
Notifications.error(data.message, 'Error');
Notifications.error('Failure', data, 'Error');
} else {
Notifications.success('Service successfully updated', 'Service updated');
}

View File

@ -95,7 +95,7 @@ class KubernetesClusterController {
await this.getResourceUsage(this.endpoint.Id);
}
} catch (err) {
this.Notifications.error('Failure', 'Unable to retrieve applications', err);
this.Notifications.error('Failure', err, 'Unable to retrieve applications');
} finally {
this.state.applicationsLoading = false;
}
@ -116,7 +116,7 @@ class KubernetesClusterController {
}, new KubernetesResourceReservation());
this.resourceUsage = clusterResourceUsage;
} catch (err) {
this.Notifications.error('Failure', 'Unable to retrieve cluster resource usage', err);
this.Notifications.error('Failure', err, 'Unable to retrieve cluster resource usage');
}
}

View File

@ -345,7 +345,7 @@ class KubernetesNodeController {
this.resourceUsage.CPU = KubernetesResourceReservationHelper.parseCPU(node.usage.cpu);
this.resourceUsage.Memory = KubernetesResourceReservationHelper.megaBytesValue(node.usage.memory);
} catch (err) {
this.Notifications.error('Failure', 'Unable to retrieve node resource usage', err);
this.Notifications.error('Failure', err, 'Unable to retrieve node resource usage');
}
}

View File

@ -361,7 +361,7 @@ class KubernetesResourcePoolController {
}, new KubernetesResourceReservation());
this.state.resourceUsage = namespaceResourceUsage;
} catch (err) {
this.Notifications.error('Failure', 'Unable to retrieve namespace resource usage', err);
this.Notifications.error('Failure', err, 'Unable to retrieve namespace resource usage');
}
}

View File

@ -1,5 +1,6 @@
import _ from 'lodash-es';
import toastr from 'toastr';
import lodash from 'lodash-es';
angular.module('portainer.app').factory('Notifications', [
'$sanitize',
@ -15,31 +16,35 @@ angular.module('portainer.app').factory('Notifications', [
toastr.warning($sanitize(_.escape(text)), $sanitize(title), { timeOut: 6000 });
};
function pickErrorMsg(e) {
const props = [
'err.data.details',
'err.data.message',
'data.details',
'data.message',
'data.content',
'data.error',
'message',
'err.data[0].message',
'err.data.err',
'data.err',
'msg',
];
let msg = '';
lodash.forEach(props, (prop) => {
const val = lodash.get(e, prop);
if (typeof val === 'string') {
msg = msg || val;
}
});
return msg;
}
service.error = function (title, e, fallbackText) {
var msg = fallbackText;
if (e.err && e.err.data && e.err.data.details && typeof e.err.data.details === 'string') {
msg = e.err.data.details;
} else if (e.err && e.err.data && e.err.data.message) {
msg = e.err.data.message;
} else if (e.data && e.data.details) {
msg = e.data.details;
} else if (e.data && e.data.message) {
msg = e.data.message;
} else if (e.data && e.data.content) {
msg = e.data.content;
} else if (e.data && e.data.error) {
msg = e.data.error;
} else if (e.message) {
msg = e.message;
} else if (e.err && e.err.data && e.err.data.length > 0 && e.err.data[0].message) {
msg = e.err.data[0].message;
} else if (e.err && e.err.data && e.err.data.err) {
msg = e.err.data.err;
} else if (e.data && e.data.err) {
msg = e.data.err;
} else if (e.msg) {
msg = e.msg;
}
const msg = pickErrorMsg(e) || fallbackText;
// eslint-disable-next-line no-console
console.error(e);

View File

@ -61,7 +61,7 @@ class InitEndpointController {
case PortainerEndpointConnectionTypes.AGENT:
return this.createAgentEndpoint();
default:
this.Notifications.error('Failure', 'Unable to determine which action to do to create environment');
this.Notifications.error('Failure', null, 'Unable to determine which action to do to create environment');
}
}

View File

@ -20,7 +20,7 @@ export default class WizardAciController {
// Check name is duplicated or not
let nameUsed = await this.NameValidator.validateEnvironmentName(name);
if (nameUsed) {
this.Notifications.error('Failure', true, 'This name is been used, please try another one');
this.Notifications.error('Failure', null, 'This name is been used, please try another one');
return;
}
await this.EndpointService.createAzureEndpoint(name, azureApplicationId, azureTenantId, azureAuthenticationKey, groupId, tagIds);

View File

@ -65,7 +65,7 @@ export default class WizardDockerController {
// Check name is duplicated or not
const nameUsed = await this.NameValidator.validateEnvironmentName(name);
if (nameUsed) {
this.Notifications.error('Failure', true, 'This name is been used, please try another one');
this.Notifications.error('Failure', null, 'This name is been used, please try another one');
return;
}
switch (type) {

View File

@ -33,7 +33,7 @@ export default class WizardKubernetesController {
// Check name is duplicated or not
let nameUsed = await this.NameValidator.validateEnvironmentName(name);
if (nameUsed) {
this.Notifications.error('Failure', true, 'This name is been used, please try another one');
this.Notifications.error('Failure', null, 'This name is been used, please try another one');
return;
}
await this.addRemoteEndpoint(name, creationType, url, publicUrl, groupId, tagIds, tls, tlsSkipVerify, tlsSkipClientVerify, tlsCaFile, tlsCertFile, tlsKeyFile);