Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/N21-1285-launch-tool-on-board' i…
Browse files Browse the repository at this point in the history
…nto N21-1285-launch-tool-on-board
  • Loading branch information
MarvinOehlerkingCap committed Nov 2, 2023
2 parents 8cee1ce + fb2f632 commit 92b839b
Show file tree
Hide file tree
Showing 24 changed files with 422 additions and 53 deletions.
28 changes: 28 additions & 0 deletions ansible/roles/schulcloud-server-core/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,48 @@
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: deployment.yml.j2

- name: Ingress
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: ingress.yml.j2
apply: yes

- name: FileStorageDeployment
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: api-files-deployment.yml.j2

- name: FileStorageDeployment
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: api-files-deployment.yml.j2

- name: File Storage Ingress
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: api-files-ingress.yml.j2
apply: yes

- name: FwuLearningContentsDeployment
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: api-fwu-deployment.yml.j2
when: FEATURE_FWU_CONTENT_ENABLED is defined and FEATURE_FWU_CONTENT_ENABLED|bool

- name: Fwu Learning Contents Ingress
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: api-fwu-ingress.yml.j2
apply: yes
when: FEATURE_FWU_CONTENT_ENABLED is defined and FEATURE_FWU_CONTENT_ENABLED|bool

- name: Delete Files CronJob
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ NAMESPACE }}-api-files-ingress
namespace: {{ NAMESPACE }}
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "{{ TLS_ENABELD|default("false") }}"
nginx.ingress.kubernetes.io/proxy-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m"
nginx.org/client-max-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m"
# The following properties added with BC-3606.
# The header size of the request is too big. For e.g. state and the permanent growing jwt.
# Nginx throws away the Location header, resulting in the 502 Bad Gateway.
nginx.ingress.kubernetes.io/client-header-buffer-size: 100k
nginx.ingress.kubernetes.io/http2-max-header-size: 96k
nginx.ingress.kubernetes.io/large-client-header-buffers: 4 100k
nginx.ingress.kubernetes.io/proxy-buffer-size: 96k
{% if CLUSTER_ISSUER is defined %}
cert-manager.io/cluster-issuer: {{ CLUSTER_ISSUER }}
{% endif %}

spec:
ingressClassName: nginx
{% if CLUSTER_ISSUER is defined or (TLS_ENABELD is defined and TLS_ENABELD|bool) %}
tls:
- hosts:
- {{ DOMAIN }}
{% if CLUSTER_ISSUER is defined %}
secretName: {{ DOMAIN }}-tls
{% endif %}
{% endif %}
rules:
- host: {{ DOMAIN }}
http:
paths:
- path: /api/v3/file/
backend:
service:
name: api-files-svc
port:
number: {{ PORT_FILE_SERVICE }}
pathType: Prefix
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ NAMESPACE }}-api-fwu-ingress
namespace: {{ NAMESPACE }}
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "{{ TLS_ENABELD|default("false") }}"
nginx.ingress.kubernetes.io/proxy-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m"
nginx.org/client-max-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m"
# The following properties added with BC-3606.
# The header size of the request is too big. For e.g. state and the permanent growing jwt.
# Nginx throws away the Location header, resulting in the 502 Bad Gateway.
nginx.ingress.kubernetes.io/client-header-buffer-size: 100k
nginx.ingress.kubernetes.io/http2-max-header-size: 96k
nginx.ingress.kubernetes.io/large-client-header-buffers: 4 100k
nginx.ingress.kubernetes.io/proxy-buffer-size: 96k
{% if CLUSTER_ISSUER is defined %}
cert-manager.io/cluster-issuer: {{ CLUSTER_ISSUER }}
{% endif %}

spec:
ingressClassName: nginx
{% if CLUSTER_ISSUER is defined or (TLS_ENABELD is defined and TLS_ENABELD|bool) %}
tls:
- hosts:
- {{ DOMAIN }}
{% if CLUSTER_ISSUER is defined %}
secretName: {{ DOMAIN }}-tls
{% endif %}
{% endif %}
rules:
- host: {{ DOMAIN }}
http:
paths:
- path: /api/v3/fwu/
backend:
service:
name: api-fwu-svc
port:
number: {{ PORT_FWU_LEARNING_CONTENTS }}
pathType: Prefix
41 changes: 41 additions & 0 deletions ansible/roles/schulcloud-server-core/templates/ingress.yml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ NAMESPACE }}-api-ingress
namespace: {{ NAMESPACE }}
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "{{ TLS_ENABELD|default("false") }}"
nginx.ingress.kubernetes.io/proxy-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m"
nginx.org/client-max-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m"
# The following properties added with BC-3606.
# The header size of the request is too big. For e.g. state and the permanent growing jwt.
# Nginx throws away the Location header, resulting in the 502 Bad Gateway.
nginx.ingress.kubernetes.io/client-header-buffer-size: 100k
nginx.ingress.kubernetes.io/http2-max-header-size: 96k
nginx.ingress.kubernetes.io/large-client-header-buffers: 4 100k
nginx.ingress.kubernetes.io/proxy-buffer-size: 96k
{% if CLUSTER_ISSUER is defined %}
cert-manager.io/cluster-issuer: {{ CLUSTER_ISSUER }}
{% endif %}

spec:
ingressClassName: nginx
{% if CLUSTER_ISSUER is defined or (TLS_ENABELD is defined and TLS_ENABELD|bool) %}
tls:
- hosts:
- {{ DOMAIN }}
{% if CLUSTER_ISSUER is defined %}
secretName: {{ DOMAIN }}-tls
{% endif %}
{% endif %}
rules:
- host: {{ DOMAIN }}
http:
paths:
- path: /api/v3/
backend:
service:
name: api-svc
port:
number: {{ PORT_SERVER }}
pathType: Prefix
8 changes: 8 additions & 0 deletions ansible/roles/schulcloud-server-h5p/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,12 @@
namespace: "{{ NAMESPACE }}"
template: api-h5p-deployment.yml.j2
when: WITH_H5P_EDITOR is defined and WITH_H5P_EDITOR|bool

- name: H5p Editor Ingress
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: api-h5p-ingress.yml.j2
apply: yes
when: WITH_H5P_EDITOR is defined and WITH_H5P_EDITOR|bool

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ NAMESPACE }}-api-h5p-ingress
namespace: {{ NAMESPACE }}
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "{{ TLS_ENABELD|default("false") }}"
nginx.ingress.kubernetes.io/proxy-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m"
nginx.org/client-max-body-size: "{{ INGRESS_MAX_BODY_SIZE|default("2560") }}m"
# The following properties added with BC-3606.
# The header size of the request is too big. For e.g. state and the permanent growing jwt.
# Nginx throws away the Location header, resulting in the 502 Bad Gateway.
nginx.ingress.kubernetes.io/client-header-buffer-size: 100k
nginx.ingress.kubernetes.io/http2-max-header-size: 96k
nginx.ingress.kubernetes.io/large-client-header-buffers: 4 100k
nginx.ingress.kubernetes.io/proxy-buffer-size: 96k
{% if CLUSTER_ISSUER is defined %}
cert-manager.io/cluster-issuer: {{ CLUSTER_ISSUER }}
{% endif %}

spec:
ingressClassName: nginx
{% if CLUSTER_ISSUER is defined or (TLS_ENABELD is defined and TLS_ENABELD|bool) %}
tls:
- hosts:
- {{ DOMAIN }}
{% if CLUSTER_ISSUER is defined %}
secretName: {{ DOMAIN }}-tls
{% endif %}
{% endif %}
rules:
- host: {{ DOMAIN }}
http:
paths:
- path: /api/v3/h5p-editor/
backend:
service:
name: api-h5p-svc
port:
number: 4448
pathType: Prefix
104 changes: 100 additions & 4 deletions apps/server/src/core/error/filter/global-error.filter.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/* eslint-disable promise/valid-params */
import { NotFound } from '@feathersjs/errors';
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { ArgumentsHost, BadRequestException, HttpStatus } from '@nestjs/common';
import { ArgumentsHost, BadRequestException, HttpStatus, InternalServerErrorException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { BusinessError } from '@shared/common';
import { ErrorLogger, ErrorLogMessage, Loggable, LogMessage, ValidationErrorLogMessage } from '@src/core/logger';
import { Response } from 'express';
import util from 'util';
import { ErrorResponse } from '../dto';
import { ErrorLoggable } from '../loggable/error.loggable';
import { ErrorUtils } from '../utils';
import { GlobalErrorFilter } from './global-error.filter';

class SampleBusinessError extends BusinessError {
Expand Down Expand Up @@ -42,6 +43,24 @@ class SampleLoggableException extends BadRequestException implements Loggable {
}
}

class SampleLoggableExceptionWithCause extends InternalServerErrorException implements Loggable {
constructor(private readonly testValue: string, error?: unknown) {
super(ErrorUtils.createHttpExceptionOptions(error));
}

getLogMessage(): ErrorLogMessage {
const message: ErrorLogMessage = {
type: 'WITH_CAUSE',
stack: this.stack,
data: {
testValue: this.testValue,
},
};

return message;
}
}

describe('GlobalErrorFilter', () => {
let module: TestingModule;
let service: GlobalErrorFilter<any>;

Check warning on line 66 in apps/server/src/core/error/filter/global-error.filter.spec.ts

View workflow job for this annotation

GitHub Actions / nest_lint

Unexpected any. Specify a different type
Expand Down Expand Up @@ -304,24 +323,101 @@ describe('GlobalErrorFilter', () => {
).toBeCalledWith(expectedResponse);
});
});

describe('when error has a cause error', () => {
const setup = () => {
const causeError = new Error('Cause error');
const error = new SampleLoggableExceptionWithCause('test', causeError);
const expectedResponse = new ErrorResponse(
'SAMPLE_WITH_CAUSE',
'Sample With Cause',
'Sample Loggable Exception With Cause',
HttpStatus.INTERNAL_SERVER_ERROR
);

const argumentsHost = setupHttpArgumentsHost();

return { error, argumentsHost, expectedResponse };
};

it('should set response status appropriately', () => {
const { error, argumentsHost } = setup();

service.catch(error, argumentsHost);

expect(argumentsHost.switchToHttp().getResponse<Response>().status).toBeCalledWith(
HttpStatus.INTERNAL_SERVER_ERROR
);
});

it('should send appropriate error response', () => {
const { error, argumentsHost, expectedResponse } = setup();

service.catch(error, argumentsHost);

expect(
argumentsHost.switchToHttp().getResponse<Response>().status(HttpStatus.INTERNAL_SERVER_ERROR).json
).toBeCalledWith(expectedResponse);
});
});
});

describe('when context is rmq', () => {
describe('when error is unknown error', () => {
const setup = () => {
const argumentsHost = createMock<ArgumentsHost>();
argumentsHost.getType.mockReturnValueOnce('rmq');

const error = new Error();

return { error, argumentsHost };
};

it('should return an RpcMessage with the error', () => {
const { error, argumentsHost } = setup();

const result = service.catch(error, argumentsHost);

expect(result).toEqual({ message: undefined, error });
});
});

describe('when error is a LoggableError', () => {
const setup = () => {
const causeError = new Error('Cause error');
const error = new SampleLoggableExceptionWithCause('test', causeError);
const argumentsHost = createMock<ArgumentsHost>();
argumentsHost.getType.mockReturnValueOnce('rmq');

return { error, argumentsHost };
};

it('should return appropriate error', () => {
const { error, argumentsHost } = setup();

const result = service.catch(error, argumentsHost);

expect(result).toEqual({ message: undefined, error });
});
});
});

describe('when context is other than rmq and http', () => {
const setup = () => {
const argumentsHost = createMock<ArgumentsHost>();
argumentsHost.getType.mockReturnValueOnce('rmq');
argumentsHost.getType.mockReturnValueOnce('other');

const error = new Error();

return { error, argumentsHost };
};

it('should return an RpcMessage with the error', () => {
it('should return undefined', () => {
const { error, argumentsHost } = setup();

const result = service.catch(error, argumentsHost);

expect(result).toEqual({ message: undefined, error });
expect(result).toBeUndefined();
});
});
});
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/core/error/filter/global-error.filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export class GlobalErrorFilter<T extends IError | undefined> implements Exceptio

if (contextType === 'http') {
this.sendHttpResponse(error, host);
} else if (contextType === 'rmq') {
}

if (contextType === 'rmq') {
return { message: undefined, error };
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface CreateJwtPayload {
systemId?: string; // without this the user needs to change his PW during first login
support?: boolean;
// support UserId is missed see featherJS
isExternalUser: boolean;
}

export interface JwtPayload extends CreateJwtPayload {
Expand Down
Loading

0 comments on commit 92b839b

Please sign in to comment.