mirror of https://github.com/portainer/portainer
fix(kubernetes/pods): save note (#4675)
* feat(kubernetes/pods): introduce patch api * feat(k8s/pods): pod converter * feat(kubernetes/pods): introduce patch api * feat(k8s/pod): add annotations only if needed * fix(k8s/pod): replace class with factory functionpull/4730/head
parent
2b257d2785
commit
46ff8a01bc
|
@ -1,5 +1,16 @@
|
|||
import * as JsonPatch from 'fast-json-patch';
|
||||
import _ from 'lodash-es';
|
||||
import { KubernetesPod, KubernetesPodToleration, KubernetesPodAffinity, KubernetesPodContainer, KubernetesPodContainerTypes } from 'Kubernetes/pod/models';
|
||||
|
||||
import KubernetesCommonHelper from 'Kubernetes/helpers/commonHelper';
|
||||
import {
|
||||
KubernetesPortainerApplicationStackNameLabel,
|
||||
KubernetesPortainerApplicationNameLabel,
|
||||
KubernetesPortainerApplicationOwnerLabel,
|
||||
KubernetesPortainerApplicationNote,
|
||||
} from 'Kubernetes/models/application/models';
|
||||
|
||||
import { createPayloadFactory } from './payloads/create';
|
||||
import { KubernetesPod, KubernetesPodToleration, KubernetesPodAffinity, KubernetesPodContainer, KubernetesPodContainerTypes } from './models';
|
||||
|
||||
function computeStatus(statuses) {
|
||||
const containerStatuses = _.map(statuses, 'state');
|
||||
|
@ -104,4 +115,48 @@ export default class KubernetesPodConverter {
|
|||
res.Tolerations = computeTolerations(data.spec.tolerations);
|
||||
return res;
|
||||
}
|
||||
|
||||
static patchPayload(oldPod, newPod) {
|
||||
const oldPayload = createPayload(oldPod);
|
||||
const newPayload = createPayload(newPod);
|
||||
const payload = JsonPatch.compare(oldPayload, newPayload);
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
|
||||
function createPayload(pod) {
|
||||
const payload = createPayloadFactory();
|
||||
payload.metadata.name = pod.Name;
|
||||
payload.metadata.namespace = pod.Namespace;
|
||||
payload.metadata.labels[KubernetesPortainerApplicationStackNameLabel] = pod.StackName;
|
||||
payload.metadata.labels[KubernetesPortainerApplicationNameLabel] = pod.ApplicationName;
|
||||
payload.metadata.labels[KubernetesPortainerApplicationOwnerLabel] = pod.ApplicationOwner;
|
||||
if (pod.Note) {
|
||||
payload.metadata.annotations[KubernetesPortainerApplicationNote] = pod.Note;
|
||||
} else {
|
||||
payload.metadata.annotations = undefined;
|
||||
}
|
||||
|
||||
payload.spec.replicas = pod.ReplicaCount;
|
||||
payload.spec.selector.matchLabels.app = pod.Name;
|
||||
payload.spec.template.metadata.labels.app = pod.Name;
|
||||
payload.spec.template.metadata.labels[KubernetesPortainerApplicationNameLabel] = pod.ApplicationName;
|
||||
payload.spec.template.spec.containers[0].name = pod.Name;
|
||||
payload.spec.template.spec.containers[0].image = pod.Image;
|
||||
payload.spec.template.spec.affinity = pod.Affinity;
|
||||
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.containers[0].env', pod.Env);
|
||||
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.containers[0].volumeMounts', pod.VolumeMounts);
|
||||
KubernetesCommonHelper.assignOrDeleteIfEmpty(payload, 'spec.template.spec.volumes', pod.Volumes);
|
||||
if (pod.MemoryLimit) {
|
||||
payload.spec.template.spec.containers[0].resources.limits.memory = pod.MemoryLimit;
|
||||
payload.spec.template.spec.containers[0].resources.requests.memory = pod.MemoryLimit;
|
||||
}
|
||||
if (pod.CpuLimit) {
|
||||
payload.spec.template.spec.containers[0].resources.limits.cpu = pod.CpuLimit;
|
||||
payload.spec.template.spec.containers[0].resources.requests.cpu = pod.CpuLimit;
|
||||
}
|
||||
if (!pod.CpuLimit && !pod.MemoryLimit) {
|
||||
delete payload.spec.template.spec.containers[0].resources;
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import { KubernetesCommonMetadataPayload } from 'Kubernetes/models/common/payloads';
|
||||
|
||||
export function createPayloadFactory() {
|
||||
return {
|
||||
metadata: new KubernetesCommonMetadataPayload(),
|
||||
spec: {
|
||||
replicas: 0,
|
||||
selector: {
|
||||
matchLabels: {
|
||||
app: '',
|
||||
},
|
||||
},
|
||||
strategy: {
|
||||
type: 'RollingUpdate',
|
||||
rollingUpdate: {
|
||||
maxSurge: 0,
|
||||
maxUnavailable: '100%',
|
||||
},
|
||||
},
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: '',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
affinity: {},
|
||||
containers: [
|
||||
{
|
||||
name: '',
|
||||
image: '',
|
||||
env: [],
|
||||
resources: {
|
||||
limits: {},
|
||||
requests: {},
|
||||
},
|
||||
volumeMounts: [],
|
||||
},
|
||||
],
|
||||
volumes: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
|
@ -2,6 +2,7 @@ import angular from 'angular';
|
|||
import PortainerError from 'Portainer/error';
|
||||
|
||||
import { KubernetesCommonParams } from 'Kubernetes/models/common/params';
|
||||
import KubernetesPodConverter from './converter';
|
||||
|
||||
class KubernetesPodService {
|
||||
/* @ngInject */
|
||||
|
@ -13,6 +14,7 @@ class KubernetesPodService {
|
|||
this.getAllAsync = this.getAllAsync.bind(this);
|
||||
this.logsAsync = this.logsAsync.bind(this);
|
||||
this.deleteAsync = this.deleteAsync.bind(this);
|
||||
this.patchAsync = this.patchAsync.bind(this);
|
||||
}
|
||||
|
||||
async getAsync(namespace, name) {
|
||||
|
@ -74,6 +76,29 @@ class KubernetesPodService {
|
|||
return this.$async(this.logsAsync, namespace, podName, containerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* PATCH
|
||||
*/
|
||||
async patchAsync(oldPod, newPod) {
|
||||
try {
|
||||
const params = new KubernetesCommonParams();
|
||||
params.id = newPod.Name;
|
||||
const namespace = newPod.Namespace;
|
||||
const payload = KubernetesPodConverter.patchPayload(oldPod, newPod);
|
||||
if (!payload.length) {
|
||||
return;
|
||||
}
|
||||
const data = await this.KubernetesPods(namespace).patch(params, payload).$promise;
|
||||
return data;
|
||||
} catch (err) {
|
||||
throw new PortainerError('Unable to patch pod', err);
|
||||
}
|
||||
}
|
||||
|
||||
patch(oldPod, newPod) {
|
||||
return this.$async(this.patchAsync, oldPod, newPod);
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,12 @@ angular.module('portainer.kubernetes').factory('KubernetesPods', [
|
|||
create: { method: 'POST' },
|
||||
update: { method: 'PUT' },
|
||||
delete: { method: 'DELETE' },
|
||||
patch: {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json-patch+json',
|
||||
},
|
||||
},
|
||||
logs: {
|
||||
method: 'GET',
|
||||
params: { action: 'log' },
|
||||
|
|
Loading…
Reference in New Issue