start moving integrations state to mobx

This commit is contained in:
nick-delirium 2024-09-16 17:51:25 +02:00
parent de35ef8822
commit 452fe62ebe
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
4 changed files with 606 additions and 0 deletions

View file

@ -0,0 +1,126 @@
import { makeAutoObservable } from 'mobx';
import { integrationsService } from 'App/services';
import {
Bugsnag,
Cloudwatch,
DatadogInt,
ElasticSearchInt,
GithubInt,
Integration,
IssueTracker,
JiraInt,
NewRelicInt,
RollbarInt,
SentryInt,
StackDriverInt,
SumoLogic,
} from './types/integrations';
class GenericIntegrationsStore {
list: any[] = [];
siteId: string | null = null;
constructor() {
makeAutoObservable(this);
}
setSiteId(siteId: string) {
this.siteId = siteId;
}
setList(list: any[]) {
this.list = list;
}
fetchIntegrations = async () => {
//client.get(`/${siteID}/integrations`)
// this.setList()
};
}
class NamedIntegrationStore<T extends Integration> {
instance: T | null = null;
list: T[] = [];
fetched: boolean = false;
issuesFetched: boolean = false;
constructor(
private readonly name: string,
private readonly NamedType: new (config: Record<string, any>) => T
) {
makeAutoObservable(this);
}
setInstance(instance: T) {
this.instance = instance;
}
setList(list: T[]) {
this.list = list;
}
setFetched(fetched: boolean) {
this.fetched = fetched;
}
setIssuesFetched(issuesFetched: boolean) {
this.issuesFetched = issuesFetched;
}
fetchIntegrations = async () => {
const { data } = await integrationsService.fetchList(this.name);
this.setList(
data.map((config: Record<string, any>) => new this.NamedType(config))
);
};
fetchIntegration = async (siteId: string) => {
const { data } = await integrationsService.fetchIntegration(
this.name,
siteId
);
this.setInstance(new this.NamedType(data));
};
saveIntegration(name: string, siteId: string) {
if (!this.instance) return;
const response = integrationsService.saveIntegration(
name,
siteId,
this.instance.toData()
);
return;
}
edit(data: T) {
this.setInstance(data);
}
deleteIntegration(siteId: string) {
if (!this.instance) return;
integrationsService.removeIntegration(this.name, siteId);
}
init(config: Record<string, any>) {
this.instance = new this.NamedType(config);
}
}
export class IntegrationsStore {
sentry = new NamedIntegrationStore('sentry', SentryInt);
datadog = new NamedIntegrationStore('datadog', DatadogInt);
stackdriver = new NamedIntegrationStore('stackdriver', StackDriverInt);
rollbar = new NamedIntegrationStore('rollbar', RollbarInt);
newrelic = new NamedIntegrationStore('newrelic', NewRelicInt);
bugsnag = new NamedIntegrationStore('bugsnag', Bugsnag);
cloudwatch = new NamedIntegrationStore('cloudwatch', Cloudwatch);
elasticsearch = new NamedIntegrationStore('elasticsearch', ElasticSearchInt);
sumologic = new NamedIntegrationStore('sumologic', SumoLogic);
jira = new NamedIntegrationStore('jira', JiraInt);
github = new NamedIntegrationStore('github', GithubInt);
issues = new NamedIntegrationStore('issues', IssueTracker);
integrations = new GenericIntegrationsStore();
// + slack
// + teams
}

View file

@ -0,0 +1,444 @@
import { makeAutoObservable } from 'mobx';
import { validateURL } from 'App/validate';
export interface Integration {
validate(): boolean;
exists(): boolean;
toData(): Record<string, any>;
}
export class SentryInt implements Integration {
projectId: number;
organizationSlug: string = '';
projectSlug: string = '';
token: string = '';
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return Boolean(this.organizationSlug && this.projectSlug && this.token);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
organizationSlug: this.organizationSlug,
projectSlug: this.projectSlug,
token: this.token,
projectId: this.projectId,
};
}
}
export class DatadogInt implements Integration {
apiKey: string = '';
applicationKey: string = '';
projectId: number;
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return Boolean(this.apiKey && this.applicationKey);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
apiKey: this.apiKey,
applicationKey: this.applicationKey,
projectId: this.projectId,
};
}
}
export class StackDriverInt implements Integration {
projectId: number;
logName: string = '';
serviceAccountCredentials: string = '';
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return Boolean(
this.serviceAccountCredentials !== '' && this.logName !== ''
);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
logName: this.logName,
serviceAccountCredentials: this.serviceAccountCredentials,
projectId: this.projectId,
};
}
}
export class RollbarInt implements Integration {
projectId: number;
accessToken: string = '';
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return Boolean(this.accessToken);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
accessToken: this.accessToken,
projectId: this.projectId,
};
}
}
export class NewRelicInt implements Integration {
projectId: number;
applicationId: string = '';
xQueryKey: string = '';
region: boolean = true;
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return Boolean(this.applicationId && this.xQueryKey);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
applicationId: this.applicationId,
xQueryKey: this.xQueryKey,
region: this.region,
projectId: this.projectId,
};
}
}
export class Bugsnag implements Integration {
projectId: number;
authorizationToken: string = '';
bugsnagProjectId: string = '';
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return Boolean(
this.bugsnagProjectId !== '' && tokenRE.test(this.authorizationToken)
);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
authorizationToken: this.authorizationToken,
bugsnagProjectId: this.bugsnagProjectId,
projectId: this.projectId,
};
}
}
export class Cloudwatch implements Integration {
projectId: number;
awsAccessKeyId: string = '';
awsSecretAccessKey: string = '';
region: string = 'us-east-1';
logGroupName: string = '';
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return Boolean(
this.awsAccessKeyId !== '' &&
this.awsSecretAccessKey !== '' &&
this.logGroupName !== '' &&
this.region !== ''
);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
awsAccessKeyId: this.awsAccessKeyId,
awsSecretAccessKey: this.awsSecretAccessKey,
region: this.region,
logGroupName: this.logGroupName,
projectId: this.projectId,
};
}
}
export class ElasticSearchInt implements Integration {
projectId: number;
host: string = '';
apiKeyId: string = '';
apiKey: string = '';
indexes: string = '*log*';
port: number = 9200;
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
private validateKeys() {
return Boolean(
this.apiKeyId.length > API_KEY_ID_LENGTH &&
this.apiKey.length > API_KEY_LENGTH &&
validateURL(this.host)
);
}
validate() {
return (
this.host !== '' &&
this.apiKeyId !== '' &&
this.apiKey !== '' &&
this.indexes !== '' &&
!!this.port &&
this.validateKeys()
);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
host: this.host,
apiKeyId: this.apiKeyId,
apiKey: this.apiKey,
indexes: this.indexes,
port: this.port,
projectId: this.projectId,
};
}
}
export class SumoLogic implements Integration {
projectId: number;
accessId: string = '';
accessKey: string = '';
region: 'au';
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return Boolean(this.accessKey && this.accessId);
}
exists() {
return this.projectId >= 0;
}
toData() {
return {
accessId: this.accessId,
accessKey: this.accessKey,
region: this.region,
projectId: this.projectId,
};
}
}
export class JiraInt implements Integration {
projectId: number;
username: string = '';
token: string = '';
url: string = '';
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validateFetchProjects() {
return this.username !== '' && this.token !== '' && validateURL(this.url);
}
validate() {
return this.validateFetchProjects();
}
exists() {
return !!this.token;
}
toData() {
return {
username: this.username,
token: this.token,
url: this.url,
projectId: this.projectId,
};
}
}
export class GithubInt implements Integration {
projectId: number;
provider: string = 'github';
token: string = '';
constructor(config: any) {
Object.assign(this, {
...config,
projectId: config.projectId || -1,
});
}
validate() {
return this.token !== '';
}
exists() {
return !!this.token;
}
toData() {
return {
provider: this.provider,
token: this.token,
projectId: this.projectId,
};
}
}
export class IssueTracker implements Integration {
username: string = '';
token: string = '';
url: string = '';
provider = 'jira';
constructor(config: any) {
Object.assign(this, {
...config,
});
}
validateFetchProjects() {
return this.username !== '' && this.token !== '' && validateURL(this.url);
}
validate() {
return !!this.url;
}
exists() {
return !!this.token;
}
toData() {
return {
username: this.username,
token: this.token,
url: this.url,
provider: this.provider,
};
}
}
export const sumoRegionLabels = {
au: 'Asia Pacific (Sydney)',
ca: 'Canada (Central)',
de: 'EU (Frankfurt)',
eu: 'EU (Ireland)',
fed: 'US East (N. Virginia)',
in: 'Asia Pacific (Mumbai)',
jp: 'Asia Pacific (Tokyo)',
us1: 'US East (N. Virginia)',
us2: 'US West (Oregon)',
};
export const API_KEY_ID_LENGTH = 5;
export const API_KEY_LENGTH = 5;
export const SECRET_ACCESS_KEY_LENGTH = 40;
export const ACCESS_KEY_ID_LENGTH = 20;
export const tokenRE =
/^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/i;
export const awsRegionLabels = {
'us-east-1': 'US East (N. Virginia)',
'us-east-2': 'US East (Ohio)',
'us-west-1': 'US West (N. California)',
'us-west-2': 'US West (Oregon)',
'ap-east-1': 'Asia Pacific (Hong Kong)',
'ap-south-1': 'Asia Pacific (Mumbai)',
'ap-northeast-2': 'Asia Pacific (Seoul)',
'ap-southeast-1': 'Asia Pacific (Singapore)',
'ap-southeast-2': 'Asia Pacific (Sydney)',
'ap-northeast-1': 'Asia Pacific (Tokyo)',
'ca-central-1': 'Canada (Central)',
'eu-central-1': 'EU (Frankfurt)',
'eu-west-1': 'EU (Ireland)',
'eu-west-2': 'EU (London)',
'eu-west-3': 'EU (Paris)',
'eu-north-1': 'EU (Stockholm)',
'me-south-1': 'Middle East (Bahrain)',
'sa-east-1': 'South America (São Paulo)',
};

View file

@ -0,0 +1,33 @@
import BaseService from "./BaseService";
export default class IntegrationsService extends BaseService {
fetchList = async (name) => {
const r = await this.client.get(`/integrations/${name}`)
const data = await r.json()
return data
}
fetchIntegration = async (name: string, siteId: string) => {
const url = siteId && name !== 'github' && name !== 'jira' ? `/${siteId}/integrations/${name}` : `/integrations/${name}`
const r = await this.client.get(url)
const data = await r.json()
return data
}
saveIntegration = async (name: string, siteId: string, data: any) => {
const url = (siteId ? `/${siteId}` : '') + `/integrations/${name}`
const r = await this.client.post(url, data)
const res = await r.json()
return res
}
removeIntegration = async (name: string, siteId: string) => {
const url = (siteId ? `/${siteId}` : '') + `/integrations/${name}`
const r = await this.client.delete(url)
const res = await r.json()
return res
}

View file

@ -21,6 +21,7 @@ import SpotService from './spotService';
import LoginService from "./loginService";
import FilterService from "./FilterService";
import IssueReportsService from "./IssueReportsService";
import IntegrationsService from './IntegrationsService';
export const dashboardService = new DashboardService();
export const metricService = new MetricService();
@ -44,6 +45,7 @@ export const spotService = new SpotService();
export const loginService = new LoginService();
export const filterService = new FilterService();
export const issueReportsService = new IssueReportsService();
export const integrationsService = new IntegrationsService();
export const services = [
dashboardService,
@ -68,4 +70,5 @@ export const services = [
loginService,
filterService,
issueReportsService,
integrationsService,
];