diff --git a/app/kubernetes/converters/application.js b/app/kubernetes/converters/application.js index 0e0cd9dd5..d88feda09 100644 --- a/app/kubernetes/converters/application.js +++ b/app/kubernetes/converters/application.js @@ -56,6 +56,7 @@ class KubernetesApplicationConverter { const containers = data.spec.template ? _.without(_.concat(data.spec.template.spec.containers, data.spec.template.spec.initContainers), undefined) : data.spec.containers; res.Id = data.metadata.uid; res.Name = data.metadata.name; + res.Metadata = data.metadata; if (data.metadata.labels) { const { labels } = data.metadata; diff --git a/app/kubernetes/helpers/application/index.js b/app/kubernetes/helpers/application/index.js index d34529841..82fcd09ee 100644 --- a/app/kubernetes/helpers/application/index.js +++ b/app/kubernetes/helpers/application/index.js @@ -449,8 +449,8 @@ class KubernetesApplicationHelper { // filter out all the applications that are managed by helm // to identify the helm managed applications, we need to check if the applications pod labels include // `app.kubernetes.io/instance` and `app.kubernetes.io/managed-by` = `helm` - const helmManagedApps = applications.filter((app) => - app.Pods.flatMap((pod) => pod.Labels).some((label) => label && label[PodKubernetesInstanceLabel] && label[PodManagedByLabel] === 'Helm') + const helmManagedApps = applications.filter( + (app) => app.Metadata.labels && app.Metadata.labels[PodKubernetesInstanceLabel] && app.Metadata.labels[PodManagedByLabel] === 'Helm' ); // groups the helm managed applications by helm release name @@ -467,15 +467,12 @@ class KubernetesApplicationHelper { const namespacedHelmReleases = {}; helmManagedApps.forEach((app) => { const namespace = app.ResourcePool; - const labels = app.Pods.filter((p) => p.Labels).map((p) => p.Labels[PodKubernetesInstanceLabel]); - const uniqueLabels = [...new Set(labels)]; - uniqueLabels.forEach((instanceStr) => { - if (namespacedHelmReleases[namespace]) { - namespacedHelmReleases[namespace][instanceStr] = [...(namespacedHelmReleases[namespace][instanceStr] || []), app]; - } else { - namespacedHelmReleases[namespace] = { [instanceStr]: [app] }; - } - }); + const instanceLabel = app.Metadata.labels[PodKubernetesInstanceLabel]; + if (namespacedHelmReleases[namespace]) { + namespacedHelmReleases[namespace][instanceLabel] = [...(namespacedHelmReleases[namespace][instanceLabel] || []), app]; + } else { + namespacedHelmReleases[namespace] = { [instanceLabel]: [app] }; + } }); // `helmAppsEntriesList` object structure: @@ -511,5 +508,25 @@ class KubernetesApplicationHelper { return helmAppsList; } + + /** + * Get nested applications - + * @param {KubernetesApplication[]} applications Application list + * @returns {Object} { helmApplications: [app1, app2, ...], nonHelmApplications: [app3, app4, ...] } + */ + static getNestedApplications(applications) { + const helmApplications = KubernetesApplicationHelper.getHelmApplications(applications); + + // filter out helm managed applications + const helmAppNames = [...new Set(helmApplications.map((hma) => hma.Name))]; // distinct helm app names + const nonHelmApplications = applications.filter((app) => { + if (app.Metadata.labels) { + return !helmAppNames.includes(app.Metadata.labels[PodKubernetesInstanceLabel]); + } + return true; + }); + + return { helmApplications, nonHelmApplications }; + } } export default KubernetesApplicationHelper; diff --git a/app/kubernetes/models/application/models/index.js b/app/kubernetes/models/application/models/index.js index dff8b9112..0f280399e 100644 --- a/app/kubernetes/models/application/models/index.js +++ b/app/kubernetes/models/application/models/index.js @@ -16,6 +16,7 @@ const _KubernetesApplication = Object.freeze({ CreationDate: 0, Pods: [], Containers: [], + Metadata: {}, Limits: {}, ServiceType: '', ServiceId: '', diff --git a/app/kubernetes/views/applications/applicationsController.js b/app/kubernetes/views/applications/applicationsController.js index 53be7360c..36f91fc4f 100644 --- a/app/kubernetes/views/applications/applicationsController.js +++ b/app/kubernetes/views/applications/applicationsController.js @@ -1,7 +1,7 @@ import angular from 'angular'; import _ from 'lodash-es'; import KubernetesStackHelper from 'Kubernetes/helpers/stackHelper'; -import KubernetesApplicationHelper, { PodKubernetesInstanceLabel } from 'Kubernetes/helpers/application'; +import KubernetesApplicationHelper from 'Kubernetes/helpers/application'; import KubernetesConfigurationHelper from 'Kubernetes/helpers/configurationHelper'; import { KubernetesApplicationTypes } from 'Kubernetes/models/application/models'; @@ -109,18 +109,9 @@ class KubernetesApplicationsController { try { const [applications, configurations] = await Promise.all([this.KubernetesApplicationService.get(), this.KubernetesConfigurationService.get()]); const configuredApplications = KubernetesConfigurationHelper.getApplicationConfigurations(applications, configurations); - const helmApplications = KubernetesApplicationHelper.getHelmApplications(configuredApplications); + const { helmApplications, nonHelmApplications } = KubernetesApplicationHelper.getNestedApplications(configuredApplications); - // filter out multi-chart helm managed applications - const helmAppNames = [...new Set(helmApplications.map((hma) => hma.Name))]; // distinct helm app names - const nonHelmApps = configuredApplications.filter( - (app) => - !app.Pods.flatMap((pod) => pod.Labels) // flatten pod labels - .filter((label) => label) // filter out empty labels - .some((label) => helmAppNames.includes(label[PodKubernetesInstanceLabel])) // check if label key is in helmAppNames - ); - - this.state.applications = [...nonHelmApps, ...helmApplications]; + this.state.applications = [...helmApplications, ...nonHelmApplications]; this.state.stacks = KubernetesStackHelper.stacksFromApplications(applications); this.state.ports = KubernetesApplicationHelper.portMappingsFromApplications(applications); } catch (err) {