Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support multi ingestion keys #5105

Merged
merged 15 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"lucide-react": "0.379.0",
"mini-css-extract-plugin": "2.4.5",
"papaparse": "5.4.1",
"rc-tween-one": "3.0.6",
YounixM marked this conversation as resolved.
Show resolved Hide resolved
"react": "18.2.0",
"react-addons-update": "15.6.3",
"react-beautiful-dnd": "13.1.1",
Expand Down
3 changes: 3 additions & 0 deletions frontend/public/locales/en-GB/ingestionKeys.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"delete_confirm_message": "Are you sure you want to delete {{keyName}}? Deleting an ingestion key is irreversible and cannot be undone."
}
4 changes: 4 additions & 0 deletions frontend/public/locales/en/ingestionKeys.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"delete_confirm_message": "Are you sure you want to delete {{keyName}}? Deleting an ingestion key is irreversible and cannot be undone.",
"delete_limit_confirm_message": "Are you sure you want to delete {{limit_name}} limit for ingestion key {{keyName}}?"
}
2 changes: 1 addition & 1 deletion frontend/src/api/ErrorResponseHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function ErrorResponseHandler(error: AxiosError): ErrorResponse {
return {
statusCode,
payload: null,
error: data.errorType,
error: data.errorType || data.type,
message: null,
};
}
Expand Down
29 changes: 29 additions & 0 deletions frontend/src/api/IngestionKeys/createIngestionKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { GatewayApiV1Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
CreateIngestionKeyProps,
IngestionKeyProps,
} from 'types/api/ingestionKeys/types';

const createIngestionKey = async (
props: CreateIngestionKeyProps,
): Promise<SuccessResponse<IngestionKeyProps> | ErrorResponse> => {
try {
const response = await GatewayApiV1Instance.post('/workspaces/me/keys', {
...props,
});

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
YounixM marked this conversation as resolved.
Show resolved Hide resolved
}
};

export default createIngestionKey;
26 changes: 26 additions & 0 deletions frontend/src/api/IngestionKeys/deleteIngestionKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { GatewayApiV1Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { AllIngestionKeyProps } from 'types/api/ingestionKeys/types';

const deleteIngestionKey = async (
id: string,
): Promise<SuccessResponse<AllIngestionKeyProps> | ErrorResponse> => {
try {
const response = await GatewayApiV1Instance.delete(
`/workspaces/me/keys/${id}`,
);

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};

export default deleteIngestionKey;
21 changes: 21 additions & 0 deletions frontend/src/api/IngestionKeys/getAllIngestionKeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { GatewayApiV1Instance } from 'api';
import { AxiosResponse } from 'axios';
import {
AllIngestionKeyProps,
GetIngestionKeyProps,
} from 'types/api/ingestionKeys/types';

export const getAllIngestionKeys = (
props: GetIngestionKeyProps,
): Promise<AxiosResponse<AllIngestionKeyProps>> => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { search, per_page, page } = props;

const BASE_URL = '/workspaces/me/keys';
const URL_QUERY_PARAMS =
search && search.length > 0
? `/search?name=${search}&page=1&per_page=100`
: `?page=${page}&per_page=${per_page}`;

return GatewayApiV1Instance.get(`${BASE_URL}${URL_QUERY_PARAMS}`);
};
65 changes: 65 additions & 0 deletions frontend/src/api/IngestionKeys/limits/createLimitsForKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* eslint-disable @typescript-eslint/no-throw-literal */
import { GatewayApiV1Instance } from 'api';
import axios from 'axios';
import {
AddLimitProps,
LimitSuccessProps,
} from 'types/api/ingestionKeys/limits/types';

interface SuccessResponse<T> {
statusCode: number;
error: null;
message: string;
payload: T;
}

interface ErrorResponse {
statusCode: number;
error: string;
message: string;
payload: null;
}

const createLimitForIngestionKey = async (
props: AddLimitProps,
): Promise<SuccessResponse<LimitSuccessProps> | ErrorResponse> => {
try {
const response = await GatewayApiV1Instance.post(
`/workspaces/me/keys/${props.keyID}/limits`,
{
...props,
},
);

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
if (axios.isAxiosError(error)) {
// Axios error
const errResponse: ErrorResponse = {
statusCode: error.response?.status || 500,
error: error.response?.data?.error,
message: error.response?.data?.status || 'An error occurred',
payload: null,
};

throw errResponse;
} else {
// Non-Axios error
const errResponse: ErrorResponse = {
statusCode: 500,
error: 'Unknown error',
message: 'An unknown error occurred',
payload: null,
};

throw errResponse;
}
}
};

export default createLimitForIngestionKey;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { GatewayApiV1Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { AllIngestionKeyProps } from 'types/api/ingestionKeys/types';

const deleteLimitsForIngestionKey = async (
id: string,
): Promise<SuccessResponse<AllIngestionKeyProps> | ErrorResponse> => {
try {
const response = await GatewayApiV1Instance.delete(
`/workspaces/me/limits/${id}`,
);

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};

export default deleteLimitsForIngestionKey;
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* eslint-disable @typescript-eslint/no-throw-literal */
import { GatewayApiV1Instance } from 'api';
import axios from 'axios';
import {
LimitSuccessProps,
UpdateLimitProps,
} from 'types/api/ingestionKeys/limits/types';

interface SuccessResponse<T> {
statusCode: number;
error: null;
message: string;
payload: T;
}

interface ErrorResponse {
statusCode: number;
error: string;
message: string;
payload: null;
}

const updateLimitForIngestionKey = async (
props: UpdateLimitProps,
): Promise<SuccessResponse<LimitSuccessProps> | ErrorResponse> => {
try {
const response = await GatewayApiV1Instance.patch(
`/workspaces/me/limits/${props.limitID}`,
{
config: props.config,
},
);

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
if (axios.isAxiosError(error)) {
// Axios error
const errResponse: ErrorResponse = {
statusCode: error.response?.status || 500,
error: error.response?.data?.error,
message: error.response?.data?.status || 'An error occurred',
payload: null,
};

throw errResponse;
} else {
// Non-Axios error
const errResponse: ErrorResponse = {
statusCode: 500,
error: 'Unknown error',
message: 'An unknown error occurred',
payload: null,
};

throw errResponse;
}
}
};

export default updateLimitForIngestionKey;
32 changes: 32 additions & 0 deletions frontend/src/api/IngestionKeys/updateIngestionKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { GatewayApiV1Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
IngestionKeysPayloadProps,
UpdateIngestionKeyProps,
} from 'types/api/ingestionKeys/types';

const updateIngestionKey = async (
props: UpdateIngestionKeyProps,
): Promise<SuccessResponse<IngestionKeysPayloadProps> | ErrorResponse> => {
try {
const response = await GatewayApiV1Instance.patch(
`/workspaces/me/keys/${props.id}`,
{
...props.data,
},
);

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};

export default updateIngestionKey;
1 change: 1 addition & 0 deletions frontend/src/api/apiV1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const apiV1 = '/api/v1/';
export const apiV2 = '/api/v2/';
export const apiV3 = '/api/v3/';
export const apiV4 = '/api/v4/';
export const gatewayApiV1 = '/api/gateway/v1';
export const apiAlertManager = '/api/alertmanager';

export default apiV1;
21 changes: 20 additions & 1 deletion frontend/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import { ENVIRONMENT } from 'constants/env';
import { LOCALSTORAGE } from 'constants/localStorage';
import store from 'store';

import apiV1, { apiAlertManager, apiV2, apiV3, apiV4 } from './apiV1';
import apiV1, {
apiAlertManager,
apiV2,
apiV3,
apiV4,
gatewayApiV1,
} from './apiV1';
import { Logout } from './utils';

const interceptorsResponse = (
Expand Down Expand Up @@ -134,6 +140,19 @@ ApiV4Instance.interceptors.response.use(
ApiV4Instance.interceptors.request.use(interceptorsRequestResponse);
//

// gateway Api V1
export const GatewayApiV1Instance = axios.create({
baseURL: `${ENVIRONMENT.baseURL}${gatewayApiV1}`,
});

GatewayApiV1Instance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,
);

GatewayApiV1Instance.interceptors.request.use(interceptorsRequestResponse);
//

AxiosAlertManagerInstance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,
Expand Down
38 changes: 38 additions & 0 deletions frontend/src/components/Tags/Tags.styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.tags-container {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;

.tags {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}

.ant-form-item {
margin-bottom: 0;
}

.ant-tag {
margin-right: 0;
background: var(--bg-vanilla-100);
}
}

.add-tag-container {
display: flex;
align-items: center;
gap: 4px;

.ant-form-item {
margin-bottom: 0;
}

.confirm-cancel-actions {
display: flex;
align-items: center;
gap: 2px;
}
}
Loading
Loading