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

feat(kubernetes): add ingress details (#4013)

* feat(kubernetes): add ingress details

* fix(kubernetes): fix broken ingress generated links + ignore IP retrieval/display info on missing LB ingress ip

* refactor(kubernetes): each ingress rule in apps port mappings has now its own row

* feat(kubernetes): remove protocol column and concat it to container port

* feat(kubernetes): edit display of ingress rules in application details

* feat(kubernetes): minor UI update

Co-authored-by: Anthony Lapenna <lapenna.anthony@gmail.com>
This commit is contained in:
xAt0mZ 2020-07-14 22:45:19 +02:00 committed by GitHub
parent b09b1b1691
commit 1b3e2c8f69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 450 additions and 137 deletions

View file

@ -0,0 +1,19 @@
import * as _ from 'lodash-es';
import { KubernetesIngressRule } from './models';
export class KubernetesIngressConverter {
static apiToModel(data) {
const rules = _.flatMap(data.spec.rules, (rule) => {
return _.map(rule.http.paths, (path) => {
const ingRule = new KubernetesIngressRule();
ingRule.ServiceName = path.backend.serviceName;
ingRule.Host = rule.host;
ingRule.IP = data.status.loadBalancer.ingress ? data.status.loadBalancer.ingress[0].ip : undefined;
ingRule.Port = path.backend.servicePort;
ingRule.Path = path.path;
return ingRule;
});
});
return rules;
}
}

View file

@ -0,0 +1,7 @@
import * as _ from 'lodash-es';
export class KubernetesIngressHelper {
static findSBoundServiceIngressesRules(ingressRules, service) {
return _.filter(ingressRules, (r) => r.ServiceName === service.metadata.name);
}
}

View file

@ -0,0 +1,16 @@
/**
* KubernetesIngressRule Model
*/
const _KubernetesIngressRule = Object.freeze({
ServiceName: '',
Host: '',
IP: '',
Port: '',
Path: '',
});
export class KubernetesIngressRule {
constructor() {
Object.assign(this, JSON.parse(JSON.stringify(_KubernetesIngressRule)));
}
}

View file

@ -0,0 +1,50 @@
import { rawResponse } from 'Kubernetes/rest/response/transform';
angular.module('portainer.kubernetes').factory('KubernetesIngresses', [
'$resource',
'API_ENDPOINT_ENDPOINTS',
'EndpointProvider',
function KubernetesIngressesFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) {
'use strict';
return function (namespace) {
const url = API_ENDPOINT_ENDPOINTS + '/:endpointId/kubernetes/apis/networking.k8s.io/v1beta1' + (namespace ? '/namespaces/:namespace' : '') + '/ingresses/:id/:action';
return $resource(
url,
{
endpointId: EndpointProvider.endpointID,
namespace: namespace,
},
{
get: {
method: 'GET',
timeout: 15000,
ignoreLoadingBar: true,
},
getYaml: {
method: 'GET',
headers: {
Accept: 'application/yaml',
},
transformResponse: rawResponse,
ignoreLoadingBar: true,
},
create: { method: 'POST' },
update: { method: 'PUT' },
patch: {
method: 'PATCH',
headers: {
'Content-Type': 'application/json-patch+json',
},
},
rollback: {
method: 'PATCH',
headers: {
'Content-Type': 'application/json-patch+json',
},
},
delete: { method: 'DELETE' },
}
);
};
},
]);

View file

@ -0,0 +1,54 @@
import * as _ from 'lodash-es';
import angular from 'angular';
import PortainerError from 'Portainer/error';
import { KubernetesCommonParams } from 'Kubernetes/models/common/params';
import { KubernetesIngressConverter } from './converter';
class KubernetesIngressService {
/* @ngInject */
constructor($async, KubernetesIngresses) {
this.$async = $async;
this.KubernetesIngresses = KubernetesIngresses;
this.getAsync = this.getAsync.bind(this);
this.getAllAsync = this.getAllAsync.bind(this);
}
/**
* GET
*/
async getAsync(namespace, name) {
try {
const params = new KubernetesCommonParams();
params.id = name;
const [raw, yaml] = await Promise.all([this.KubernetesIngresses(namespace).get(params).$promise, this.KubernetesIngresses(namespace).getYaml(params).$promise]);
const res = {
Raw: KubernetesIngressConverter.apiToModel(raw),
Yaml: yaml.data,
};
return res;
} catch (err) {
throw new PortainerError('Unable to retrieve Ingress', err);
}
}
async getAllAsync(namespace) {
try {
const data = await this.KubernetesIngresses(namespace).get().$promise;
const res = _.reduce(data.items, (arr, item) => _.concat(arr, KubernetesIngressConverter.apiToModel(item)), []);
return res;
} catch (err) {
throw new PortainerError('Unable to retrieve Ingresses', err);
}
}
get(namespace, name) {
if (name) {
return this.$async(this.getAsync, namespace, name);
}
return this.$async(this.getAllAsync, namespace);
}
}
export default KubernetesIngressService;
angular.module('portainer.kubernetes').service('KubernetesIngressService', KubernetesIngressService);