1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

feat(k8s/application): add/edit placement preferences/constraints (#4210)

* feat(k8s/application): create application with placement preferences/constraints

* feat(k8s/application): edit application placement preferences/constraints
This commit is contained in:
xAt0mZ 2020-08-14 01:56:53 +02:00 committed by GitHub
parent 32bac9ffcc
commit 52bdcf2e2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 451 additions and 190 deletions

View file

@ -49,7 +49,7 @@ function _apiPortsToPublishedPorts(pList, pRefs) {
}
class KubernetesApplicationConverter {
static applicationCommon(res, data, service, ingresses) {
static applicationCommon(res, data, pods, service, ingresses) {
const containers = _.without(_.concat(data.spec.template.spec.containers, data.spec.template.spec.initContainers), undefined);
res.Id = data.metadata.uid;
res.Name = data.metadata.name;
@ -61,6 +61,7 @@ class KubernetesApplicationConverter {
res.Image = containers[0].image;
res.CreationDate = data.metadata.creationTimestamp;
res.Env = _.without(_.flatMap(_.map(containers, 'env')), undefined);
res.Pods = KubernetesApplicationHelper.associatePodsAndApplication(pods, data);
const limits = {
Cpu: 0,
@ -212,9 +213,9 @@ class KubernetesApplicationConverter {
);
}
static apiDeploymentToApplication(data, service, ingresses) {
static apiDeploymentToApplication(data, pods, service, ingresses) {
const res = new KubernetesApplication();
KubernetesApplicationConverter.applicationCommon(res, data, service, ingresses);
KubernetesApplicationConverter.applicationCommon(res, data, pods, service, ingresses);
res.ApplicationType = KubernetesApplicationTypes.DEPLOYMENT;
res.DeploymentType = KubernetesApplicationDeploymentTypes.REPLICATED;
res.DataAccessPolicy = KubernetesApplicationDataAccessPolicies.SHARED;
@ -223,9 +224,9 @@ class KubernetesApplicationConverter {
return res;
}
static apiDaemonSetToApplication(data, service, ingresses) {
static apiDaemonSetToApplication(data, pods, service, ingresses) {
const res = new KubernetesApplication();
KubernetesApplicationConverter.applicationCommon(res, data, service, ingresses);
KubernetesApplicationConverter.applicationCommon(res, data, pods, service, ingresses);
res.ApplicationType = KubernetesApplicationTypes.DAEMONSET;
res.DeploymentType = KubernetesApplicationDeploymentTypes.GLOBAL;
res.DataAccessPolicy = KubernetesApplicationDataAccessPolicies.SHARED;
@ -234,9 +235,9 @@ class KubernetesApplicationConverter {
return res;
}
static apiStatefulSetToapplication(data, service, ingresses) {
static apiStatefulSetToapplication(data, pods, service, ingresses) {
const res = new KubernetesApplication();
KubernetesApplicationConverter.applicationCommon(res, data, service, ingresses);
KubernetesApplicationConverter.applicationCommon(res, data, pods, service, ingresses);
res.ApplicationType = KubernetesApplicationTypes.STATEFULSET;
res.DeploymentType = KubernetesApplicationDeploymentTypes.REPLICATED;
res.DataAccessPolicy = KubernetesApplicationDataAccessPolicies.ISOLATED;
@ -246,7 +247,7 @@ class KubernetesApplicationConverter {
return res;
}
static applicationToFormValues(app, resourcePools, configurations, persistentVolumeClaims) {
static applicationToFormValues(app, resourcePools, configurations, persistentVolumeClaims, nodesLabels) {
const res = new KubernetesApplicationFormValues();
res.ApplicationType = app.ApplicationType;
res.ResourcePool = _.find(resourcePools, ['Namespace.Name', app.ResourcePool]);
@ -276,6 +277,8 @@ class KubernetesApplicationConverter {
} else {
res.PublishingType = KubernetesApplicationPublishingTypes.INTERNAL;
}
KubernetesApplicationHelper.generatePlacementsFormValuesFromAffinity(res, app.Pods[0].Affinity, nodesLabels);
return res;
}

View file

@ -30,6 +30,7 @@ class KubernetesDaemonSetConverter {
res.Env = KubernetesApplicationHelper.generateEnvFromEnvVariables(formValues.EnvironmentVariables);
KubernetesApplicationHelper.generateVolumesFromPersistentVolumClaims(res, volumeClaims);
KubernetesApplicationHelper.generateEnvOrVolumesFromConfigurations(res, formValues.Configurations);
KubernetesApplicationHelper.generateAffinityFromPlacements(res, formValues);
return res;
}
@ -51,6 +52,7 @@ class KubernetesDaemonSetConverter {
payload.spec.template.metadata.labels[KubernetesPortainerApplicationNameLabel] = daemonSet.ApplicationName;
payload.spec.template.spec.containers[0].name = daemonSet.Name;
payload.spec.template.spec.containers[0].image = daemonSet.Image;
payload.spec.template.spec.affinity = daemonSet.Affinity;
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.containers[0].env', daemonSet.Env);
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.containers[0].volumeMounts', daemonSet.VolumeMounts);
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.volumes', daemonSet.Volumes);

View file

@ -32,6 +32,7 @@ class KubernetesDeploymentConverter {
res.Containers = formValues.Containers;
KubernetesApplicationHelper.generateVolumesFromPersistentVolumClaims(res, volumeClaims);
KubernetesApplicationHelper.generateEnvOrVolumesFromConfigurations(res, formValues.Configurations);
KubernetesApplicationHelper.generateAffinityFromPlacements(res, formValues);
return res;
}
@ -53,6 +54,7 @@ class KubernetesDeploymentConverter {
payload.spec.template.metadata.labels[KubernetesPortainerApplicationNameLabel] = deployment.ApplicationName;
payload.spec.template.spec.containers[0].name = deployment.Name;
payload.spec.template.spec.containers[0].image = deployment.Image;
payload.spec.template.spec.affinity = deployment.Affinity;
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.containers[0].env', deployment.Env);
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.containers[0].volumeMounts', deployment.VolumeMounts);
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.volumes', deployment.Volumes);

View file

@ -33,6 +33,7 @@ class KubernetesStatefulSetConverter {
res.Env = KubernetesApplicationHelper.generateEnvFromEnvVariables(formValues.EnvironmentVariables);
KubernetesApplicationHelper.generateVolumesFromPersistentVolumClaims(res, volumeClaims);
KubernetesApplicationHelper.generateEnvOrVolumesFromConfigurations(res, formValues.Configurations);
KubernetesApplicationHelper.generateAffinityFromPlacements(res, formValues);
return res;
}
@ -56,6 +57,7 @@ class KubernetesStatefulSetConverter {
payload.spec.template.metadata.labels[KubernetesPortainerApplicationNameLabel] = statefulSet.ApplicationName;
payload.spec.template.spec.containers[0].name = statefulSet.Name;
payload.spec.template.spec.containers[0].image = statefulSet.Image;
payload.spec.template.spec.affinity = statefulSet.Affinity;
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.containers[0].env', statefulSet.Env);
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.containers[0].volumeMounts', statefulSet.VolumeMounts);
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.volumes', statefulSet.Volumes);