diff --git a/app/kubernetes/component-status/converter.js b/app/kubernetes/component-status/converter.js
new file mode 100644
index 000000000..730cf60b7
--- /dev/null
+++ b/app/kubernetes/component-status/converter.js
@@ -0,0 +1,21 @@
+import _ from 'lodash-es';
+import { KubernetesComponentStatus } from './models';
+
+export class KubernetesComponentStatusConverter {
+ /**
+ * Convert API data to KubernetesComponentStatus model
+ */
+ static apiToModel(data) {
+ const res = new KubernetesComponentStatus();
+ res.ComponentName = data.metadata.name;
+
+ const healthyCondition = _.find(data.conditions, { type: 'Healthy' });
+ if (healthyCondition && healthyCondition.status === 'True') {
+ res.Healthy = true;
+ } else if (healthyCondition && healthyCondition.status === 'False') {
+ res.ErrorMessage = healthyCondition.message;
+ }
+
+ return res;
+ }
+}
diff --git a/app/kubernetes/component-status/models.js b/app/kubernetes/component-status/models.js
new file mode 100644
index 000000000..a73862c08
--- /dev/null
+++ b/app/kubernetes/component-status/models.js
@@ -0,0 +1,14 @@
+/**
+ * KubernetesComponentStatus Model
+ */
+const _KubernetesComponentStatus = Object.freeze({
+ ComponentName: '',
+ Healthy: false,
+ ErrorMessage: '',
+});
+
+export class KubernetesComponentStatus {
+ constructor() {
+ Object.assign(this, JSON.parse(JSON.stringify(_KubernetesComponentStatus)));
+ }
+}
diff --git a/app/kubernetes/component-status/rest.js b/app/kubernetes/component-status/rest.js
new file mode 100644
index 000000000..a286b584f
--- /dev/null
+++ b/app/kubernetes/component-status/rest.js
@@ -0,0 +1,24 @@
+angular.module('portainer.kubernetes').factory('KubernetesComponentStatus', [
+ '$resource',
+ 'API_ENDPOINT_ENDPOINTS',
+ 'EndpointProvider',
+ function KubernetesComponentStatusFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) {
+ 'use strict';
+ return function () {
+ const url = API_ENDPOINT_ENDPOINTS + '/:endpointId/kubernetes/api/v1' + '/componentstatuses/:id';
+ return $resource(
+ url,
+ {
+ endpointId: EndpointProvider.endpointID,
+ },
+ {
+ get: {
+ method: 'GET',
+ timeout: 15000,
+ ignoreLoadingBar: true,
+ },
+ }
+ );
+ };
+ },
+]);
diff --git a/app/kubernetes/component-status/service.js b/app/kubernetes/component-status/service.js
new file mode 100644
index 000000000..1b5d4efe2
--- /dev/null
+++ b/app/kubernetes/component-status/service.js
@@ -0,0 +1,34 @@
+import angular from 'angular';
+import PortainerError from 'Portainer/error';
+import _ from 'lodash-es';
+import { KubernetesComponentStatusConverter } from './converter';
+
+class KubernetesComponentStatusService {
+ /* @ngInject */
+ constructor($async, KubernetesComponentStatus) {
+ this.$async = $async;
+ this.KubernetesComponentStatus = KubernetesComponentStatus;
+
+ this.getAsync = this.getAsync.bind(this);
+ }
+
+ /**
+ * GET
+ */
+ async getAsync() {
+ try {
+ const data = await this.KubernetesComponentStatus().get().$promise;
+ const res = _.map(data.items, (item) => KubernetesComponentStatusConverter.apiToModel(item));
+ return res;
+ } catch (err) {
+ throw new PortainerError('Unable to retrieve cluster status', err);
+ }
+ }
+
+ get() {
+ return this.$async(this.getAsync);
+ }
+}
+
+export default KubernetesComponentStatusService;
+angular.module('portainer.kubernetes').service('KubernetesComponentStatusService', KubernetesComponentStatusService);
diff --git a/app/kubernetes/views/cluster/cluster.html b/app/kubernetes/views/cluster/cluster.html
index eeb43f9da..60bc353ff 100644
--- a/app/kubernetes/views/cluster/cluster.html
+++ b/app/kubernetes/views/cluster/cluster.html
@@ -5,11 +5,11 @@
Component | +Status | +Error | +
+ {{ cs.ComponentName }} + | ++ healthy + unhealthy + | ++ {{ cs.ErrorMessage !== '' ? cs.ErrorMessage : '-' }} + | +