Skip to content

Commit 74fb2eb

Browse files
authored
Merge pull request #1459 from RedisInsight/release/2.14.0
Release 2.14.0
2 parents 35f734d + 2aced2d commit 74fb2eb

File tree

697 files changed

+23261
-12115
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

697 files changed

+23261
-12115
lines changed

.circleci/config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ aliases:
9191
- oss-clu # OSS Cluster
9292
- oss-clu-tls # OSS Cluster with TLS enabled
9393
- oss-sent # OSS Sentinel
94+
- oss-sent-tls-auth # OSS Sentinel with TLS auth
9495
- re-st # Redis Enterprise with Standalone inside
9596
- re-clu # Redis Enterprise with Cluster inside
9697
- re-crdt # Redis Enterprise with active-active database inside
@@ -99,6 +100,7 @@ aliases:
99100
- oss-st-6-tls-auth # OSS Standalone v6 with TLS auth required
100101
- oss-clu-tls # OSS Cluster with TLS enabled
101102
- re-crdt # Redis Enterprise with active-active database inside
103+
- oss-sent-tls-auth # OSS Sentinel with TLS auth
102104
guides-filter: &guidesFilter
103105
filters:
104106
branches:

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ renderer.prod.js.map
4646
redisinsight/ui/style.css
4747
redisinsight/ui/style.css.map
4848
redisinsight/ui/dist
49+
redisinsight/api/commands
50+
redisinsight/api/guides
51+
redisinsight/api/tutorials
52+
redisinsight/api/content
4953
dist
5054
distWeb
5155
dll

redisinsight/api/config/default.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export default {
155155
|| 'https://raw.githubusercontent.com/RediSearch/RediSearch/master/commands.json',
156156
},
157157
{
158-
name: 'redijson',
158+
name: 'redisjson',
159159
url: process.env.COMMANDS_REDIJSON_URL
160160
|| 'https://raw.githubusercontent.com/RedisJSON/RedisJSON/master/commands.json',
161161
},

redisinsight/api/config/ormconfig.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
2-
import { AgreementsEntity } from 'src/modules/core/models/agreements.entity';
3-
import { CaCertificateEntity } from 'src/modules/core/models/ca-certificate.entity';
4-
import { ClientCertificateEntity } from 'src/modules/core/models/client-certificate.entity';
5-
import { DatabaseInstanceEntity } from 'src/modules/core/models/database-instance.entity';
6-
import { ServerEntity } from 'src/modules/core/models/server.entity';
7-
import { SettingsEntity } from 'src/modules/core/models/settings.entity';
2+
import { ServerEntity } from 'src/modules/server/entities/server.entity';
83
import { CommandExecutionEntity } from 'src/modules/workbench/entities/command-execution.entity';
94
import { PluginStateEntity } from 'src/modules/workbench/entities/plugin-state.entity';
105
import { NotificationEntity } from 'src/modules/notification/entities/notification.entity';
116
import { DatabaseAnalysisEntity } from 'src/modules/database-analysis/entities/database-analysis.entity';
127
import { DataSource } from 'typeorm';
8+
import { AgreementsEntity } from 'src/modules/settings/entities/agreements.entity';
9+
import { SettingsEntity } from 'src/modules/settings/entities/settings.entity';
10+
import { CaCertificateEntity } from 'src/modules/certificate/entities/ca-certificate.entity';
11+
import { ClientCertificateEntity } from 'src/modules/certificate/entities/client-certificate.entity';
12+
import { DatabaseEntity } from 'src/modules/database/entities/database.entity';
1313
import migrations from '../migration';
1414
import * as config from '../src/utils/config';
1515

@@ -24,7 +24,7 @@ const ormConfig = {
2424
AgreementsEntity,
2525
CaCertificateEntity,
2626
ClientCertificateEntity,
27-
DatabaseInstanceEntity,
27+
DatabaseEntity,
2828
ServerEntity,
2929
SettingsEntity,
3030
CommandExecutionEntity,

redisinsight/api/config/stack.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ export default {
44
server: {
55
excludeRoutes: [
66
'redis-enterprise/*',
7-
'instance/redis-enterprise-dbs',
8-
'instance/redis-cloud-dbs',
9-
'instance/sentinel-masters',
10-
{ path: 'instance', method: RequestMethod.POST },
11-
{ path: 'instance', method: RequestMethod.DELETE },
12-
{ path: 'instance/:id', method: RequestMethod.DELETE },
7+
'redis-sentinel/*',
8+
{ path: 'databases', method: RequestMethod.POST },
9+
{ path: 'databases', method: RequestMethod.DELETE },
10+
{ path: 'databases/:id', method: RequestMethod.DELETE },
1311
],
1412
},
1513
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { MigrationInterface, QueryRunner } from "typeorm";
2+
3+
export class workbenchExecutionTime1667368983699 implements MigrationInterface {
4+
name = 'workbenchExecutionTime1667368983699'
5+
6+
public async up(queryRunner: QueryRunner): Promise<void> {
7+
await queryRunner.query(`DROP INDEX "IDX_5cd90dd6def1fd7c521e53fb2c"`);
8+
await queryRunner.query(`CREATE TABLE "temporary_command_execution" ("id" varchar PRIMARY KEY NOT NULL, "databaseId" varchar NOT NULL, "command" text NOT NULL, "result" text NOT NULL, "role" varchar, "nodeOptions" varchar, "encryption" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "mode" varchar, "resultsMode" varchar, "summary" varchar, "executionTime" integer, CONSTRAINT "FK_ea8adfe9aceceb79212142206b8" FOREIGN KEY ("databaseId") REFERENCES "database_instance" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`);
9+
await queryRunner.query(`INSERT INTO "temporary_command_execution"("id", "databaseId", "command", "result", "role", "nodeOptions", "encryption", "createdAt", "mode", "resultsMode", "summary") SELECT "id", "databaseId", "command", "result", "role", "nodeOptions", "encryption", "createdAt", "mode", "resultsMode", "summary" FROM "command_execution"`);
10+
await queryRunner.query(`DROP TABLE "command_execution"`);
11+
await queryRunner.query(`ALTER TABLE "temporary_command_execution" RENAME TO "command_execution"`);
12+
await queryRunner.query(`CREATE INDEX "IDX_5cd90dd6def1fd7c521e53fb2c" ON "command_execution" ("createdAt") `);
13+
}
14+
15+
public async down(queryRunner: QueryRunner): Promise<void> {
16+
await queryRunner.query(`DROP INDEX "IDX_5cd90dd6def1fd7c521e53fb2c"`);
17+
await queryRunner.query(`ALTER TABLE "command_execution" RENAME TO "temporary_command_execution"`);
18+
await queryRunner.query(`CREATE TABLE "command_execution" ("id" varchar PRIMARY KEY NOT NULL, "databaseId" varchar NOT NULL, "command" text NOT NULL, "result" text NOT NULL, "role" varchar, "nodeOptions" varchar, "encryption" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "mode" varchar, "resultsMode" varchar, "summary" varchar, CONSTRAINT "FK_ea8adfe9aceceb79212142206b8" FOREIGN KEY ("databaseId") REFERENCES "database_instance" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`);
19+
await queryRunner.query(`INSERT INTO "command_execution"("id", "databaseId", "command", "result", "role", "nodeOptions", "encryption", "createdAt", "mode", "resultsMode", "summary") SELECT "id", "databaseId", "command", "result", "role", "nodeOptions", "encryption", "createdAt", "mode", "resultsMode", "summary" FROM "temporary_command_execution"`);
20+
await queryRunner.query(`DROP TABLE "temporary_command_execution"`);
21+
await queryRunner.query(`CREATE INDEX "IDX_5cd90dd6def1fd7c521e53fb2c" ON "command_execution" ("createdAt") `);
22+
}
23+
24+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { MigrationInterface, QueryRunner } from "typeorm";
2+
3+
export class database1667477693934 implements MigrationInterface {
4+
name = 'database1667477693934'
5+
6+
public async up(queryRunner: QueryRunner): Promise<void> {
7+
await queryRunner.query(`CREATE TABLE "temporary_database_instance" ("id" varchar PRIMARY KEY NOT NULL, "host" varchar NOT NULL, "port" integer NOT NULL, "name" varchar NOT NULL, "username" varchar, "password" varchar, "tls" boolean, "verifyServerCert" boolean, "lastConnection" datetime, "caCertId" varchar, "clientCertId" varchar, "connectionType" varchar NOT NULL DEFAULT ('STANDALONE'), "nodes" varchar DEFAULT ('[]'), "nameFromProvider" varchar, "sentinelMasterName" varchar, "sentinelMasterUsername" varchar, "sentinelMasterPassword" varchar, "provider" varchar DEFAULT ('UNKNOWN'), "modules" varchar NOT NULL DEFAULT ('[]'), "db" integer, "encryption" varchar, "tlsServername" varchar, CONSTRAINT "FK_d1bc747b5938e22b4b708d8e9a5" FOREIGN KEY ("caCertId") REFERENCES "ca_certificate" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, CONSTRAINT "FK_3b9b625266c00feb2d66a9f36e4" FOREIGN KEY ("clientCertId") REFERENCES "client_certificate" ("id") ON DELETE SET NULL ON UPDATE NO ACTION)`);
8+
await queryRunner.query(`INSERT INTO "temporary_database_instance"("id", "host", "port", "name", "username", "password", "tls", "verifyServerCert", "lastConnection", "caCertId", "clientCertId", "connectionType", "nodes", "nameFromProvider", "sentinelMasterName", "sentinelMasterUsername", "sentinelMasterPassword", "provider", "modules", "db", "encryption", "tlsServername") SELECT "id", "host", "port", "name", "username", "password", "tls", "verifyServerCert", "lastConnection", "caCertId", "clientCertId", "connectionType", "nodes", "nameFromProvider", "sentinelMasterName", "sentinelMasterUsername", "sentinelMasterPassword", "provider", "modules", "db", "encryption", "tlsServername" FROM "database_instance"`);
9+
await queryRunner.query(`DROP TABLE "database_instance"`);
10+
await queryRunner.query(`ALTER TABLE "temporary_database_instance" RENAME TO "database_instance"`);
11+
}
12+
13+
public async down(queryRunner: QueryRunner): Promise<void> {
14+
await queryRunner.query(`ALTER TABLE "database_instance" RENAME TO "temporary_database_instance"`);
15+
await queryRunner.query(`CREATE TABLE "database_instance" ("id" varchar PRIMARY KEY NOT NULL, "host" varchar NOT NULL, "port" integer NOT NULL, "name" varchar NOT NULL, "username" varchar, "password" varchar, "tls" boolean NOT NULL, "verifyServerCert" boolean NOT NULL, "lastConnection" datetime, "caCertId" varchar, "clientCertId" varchar, "connectionType" varchar NOT NULL DEFAULT ('STANDALONE'), "nodes" varchar, "nameFromProvider" varchar, "sentinelMasterName" varchar, "sentinelMasterUsername" varchar, "sentinelMasterPassword" varchar, "provider" varchar DEFAULT ('UNKNOWN'), "modules" varchar NOT NULL DEFAULT ('[]'), "db" integer, "encryption" varchar, "tlsServername" varchar, CONSTRAINT "FK_d1bc747b5938e22b4b708d8e9a5" FOREIGN KEY ("caCertId") REFERENCES "ca_certificate" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, CONSTRAINT "FK_3b9b625266c00feb2d66a9f36e4" FOREIGN KEY ("clientCertId") REFERENCES "client_certificate" ("id") ON DELETE SET NULL ON UPDATE NO ACTION)`);
16+
await queryRunner.query(`INSERT INTO "database_instance"("id", "host", "port", "name", "username", "password", "tls", "verifyServerCert", "lastConnection", "caCertId", "clientCertId", "connectionType", "nodes", "nameFromProvider", "sentinelMasterName", "sentinelMasterUsername", "sentinelMasterPassword", "provider", "modules", "db", "encryption", "tlsServername") SELECT "id", "host", "port", "name", "username", "password", "tls", "verifyServerCert", "lastConnection", "caCertId", "clientCertId", "connectionType", "nodes", "nameFromProvider", "sentinelMasterName", "sentinelMasterUsername", "sentinelMasterPassword", "provider", "modules", "db", "encryption", "tlsServername" FROM "temporary_database_instance"`);
17+
await queryRunner.query(`DROP TABLE "temporary_database_instance"`);
18+
}
19+
20+
}

redisinsight/api/migration/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import { workbenchMode1660664717573 } from './1660664717573-workbench-mode';
1919
import { workbenchGroupMode1663093411715 } from './1663093411715-workbench-group-mode';
2020
import { databaseAnalysis1664785208236 } from './1664785208236-database-analysis';
2121
import { databaseAnalysisExpirationGroups1664886479051 } from './1664886479051-database-analysis-expiration-groups';
22+
import { workbenchExecutionTime1667368983699 } from './1667368983699-workbench-execution-time';
23+
import { database1667477693934 } from './1667477693934-database';
2224

2325
export default [
2426
initialMigration1614164490968,
@@ -42,4 +44,6 @@ export default [
4244
workbenchGroupMode1663093411715,
4345
databaseAnalysis1664785208236,
4446
databaseAnalysisExpirationGroups1664886479051,
47+
workbenchExecutionTime1667368983699,
48+
database1667477693934,
4549
];
Lines changed: 76 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,76 @@
1-
import { IAgreement } from 'src/models';
2-
import {
3-
AgreementsEntity,
4-
IAgreementsJSON,
5-
} from 'src/modules/core/models/agreements.entity';
6-
import {
7-
ISettingsJSON,
8-
SettingsEntity,
9-
} from 'src/modules/core/models/settings.entity';
10-
11-
export const mockAppAgreement: IAgreement = {
12-
defaultValue: false,
13-
required: true,
14-
since: '1.0.0',
15-
disabled: false,
16-
displayInSetting: false,
17-
editable: false,
18-
title: 'License Terms',
19-
label: 'I have read and understood the License Terms',
20-
};
21-
22-
export const mockAgreementsJSON = {
23-
version: null,
24-
};
25-
26-
export const mockAgreementsEntity: AgreementsEntity = {
27-
id: 1,
28-
version: null,
29-
data: null,
30-
toJSON: (): IAgreementsJSON => mockAgreementsJSON,
31-
};
32-
33-
export const mockSettingsJSON: ISettingsJSON = {
34-
theme: null,
35-
scanThreshold: null,
36-
batchSize: null,
37-
};
38-
39-
export const mockSettingsEntity: SettingsEntity = {
40-
id: 1,
41-
data: null,
42-
toJSON: (): ISettingsJSON => mockSettingsJSON,
43-
};
1+
import { Settings } from 'src/modules/settings/models/settings';
2+
import { Agreements } from 'src/modules/settings/models/agreements';
3+
import { mockUserId } from 'src/__mocks__/user';
4+
import { GetAppSettingsResponse } from 'src/modules/settings/dto/settings.dto';
5+
import { AgreementsEntity } from 'src/modules/settings/entities/agreements.entity';
6+
import { SettingsEntity } from 'src/modules/settings/entities/settings.entity';
7+
8+
export const mockSettings = Object.assign(new Settings(), {
9+
id: mockUserId,
10+
data: {
11+
theme: 'DARK',
12+
scanThreshold: 500,
13+
batchSize: 10,
14+
},
15+
});
16+
17+
export const mockSettingsEntity = Object.assign(new SettingsEntity(), {
18+
id: mockSettings.id,
19+
data: JSON.stringify(mockSettings.data),
20+
});
21+
22+
export const mockAgreements = Object.assign(new Agreements(), {
23+
id: mockUserId,
24+
version: '1.0.0',
25+
data: {
26+
eula: true,
27+
analytics: true,
28+
encryption: true,
29+
notifications: true,
30+
},
31+
});
32+
33+
export const mockAgreementsEntity = Object.assign(new AgreementsEntity(), {
34+
id: mockAgreements.id,
35+
version: mockAgreements.version,
36+
data: JSON.stringify(mockAgreements.data),
37+
});
38+
39+
export const mockAppSettings = Object.assign(new GetAppSettingsResponse(), {
40+
...mockSettings.data,
41+
agreements: {
42+
version: mockAgreements.version,
43+
...mockAgreements.data,
44+
},
45+
});
46+
47+
export const mockAppSettingsWithoutPermissions = Object.assign(new GetAppSettingsResponse(), {
48+
...mockSettings.data,
49+
agreements: {
50+
version: mockAgreements.version,
51+
eula: false,
52+
analytics: false,
53+
encryption: false,
54+
notifications: false,
55+
},
56+
});
57+
58+
export const mockAppSettingsInitial = Object.assign(new GetAppSettingsResponse(), {
59+
agreements: null,
60+
});
61+
62+
export const mockAgreementsRepository = jest.fn(() => ({
63+
getOrCreate: jest.fn(),
64+
update: jest.fn(),
65+
}));
66+
67+
export const mockSettingsRepository = jest.fn(() => ({
68+
getOrCreate: jest.fn(),
69+
update: jest.fn(),
70+
}));
71+
72+
export const mockSettingsService = jest.fn(() => ({
73+
getAppSettings: jest.fn(),
74+
updateAppSettings: jest.fn(),
75+
getAgreementsSpec: jest.fn(),
76+
}));
Lines changed: 7 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
getTCPEndpoints,
3-
} from 'src/utils/auto-discovery-helper';
4-
5-
const winNetstat = ''
1+
export const mockWinNetstat = ''
62
+ 'Proto Local Address Foreign Address State PID\n'
73
+ 'TCP 0.0.0.0:5000 0.0.0.0:0 LISTENING 13728\n'
84
+ 'TCP 0.0.0.0:6379 0.0.0.0:0 LISTENING 13728\n'
@@ -15,7 +11,7 @@ const winNetstat = ''
1511
+ 'TCP [::]:5000 [::]:0 LISTENING 6056\n'
1612
+ 'TCP *:* LISTENING 6056';
1713

18-
const linuxNetstat = ''
14+
export const mockLinuxNetstat = ''
1915
+ 'Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \n'
2016
+ 'tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN - \n'
2117
+ 'tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN - \n'
@@ -30,7 +26,7 @@ const linuxNetstat = ''
3026
+ 'tcp6 0 0 ::1:6379 :::* LISTEN - \n';
3127

3228
/* eslint-disable max-len */
33-
const macNetstat = ''
29+
export const mockMacNetstat = ''
3430
+ 'Proto Recv-Q Send-Q Local Address Foreign Address (state) rhiwat shiwat pid epid state options\n'
3531
+ 'tcp4 0 0 10.55.1.235.5000 10.55.1.235.52217 FIN_WAIT_2 407280 146988 30555 0 0x2131 0x00000104\n'
3632
+ 'tcp4 0 0 10.55.1.235.6379 10.55.1.235.5001 CLOSE_WAIT 407682 146988 872 0 0x0122 0x00000008\n'
@@ -40,54 +36,7 @@ const macNetstat = ''
4036
+ 'tcp6 0 0 ::1.52167 ::1.5002 ESTABLISHED 406172 146808 31200 0 0x0102 0x00000008\n';
4137
/* eslint-enable max-len */
4238

43-
const getTCPEndpointsTests = [
44-
{
45-
name: 'win output',
46-
input: winNetstat.split('\n'),
47-
output: [
48-
{ host: 'localhost', port: 5000 },
49-
{ host: 'localhost', port: 6379 },
50-
{ host: 'localhost', port: 6380 },
51-
{ host: 'localhost', port: 135 },
52-
{ host: 'localhost', port: 445 },
53-
{ host: 'localhost', port: 808 },
54-
{ host: 'localhost', port: 2701 },
55-
],
56-
},
57-
{
58-
name: 'linux output',
59-
input: linuxNetstat.split('\n'),
60-
output: [
61-
{ host: 'localhost', port: 5000 },
62-
{ host: 'localhost', port: 6379 },
63-
{ host: 'localhost', port: 6380 },
64-
{ host: 'localhost', port: 28100 },
65-
{ host: 'localhost', port: 8100 },
66-
{ host: 'localhost', port: 8101 },
67-
{ host: 'localhost', port: 8102 },
68-
{ host: 'localhost', port: 8103 },
69-
{ host: 'localhost', port: 8200 },
70-
],
71-
},
72-
{
73-
name: 'mac output',
74-
input: macNetstat.split('\n'),
75-
output: [
76-
{ host: 'localhost', port: 5000 },
77-
{ host: 'localhost', port: 6379 },
78-
{ host: 'localhost', port: 6380 },
79-
{ host: 'localhost', port: 5002 },
80-
{ host: 'localhost', port: 52167 },
81-
],
82-
},
83-
];
84-
85-
describe('getTCP4Endpoints', () => {
86-
getTCPEndpointsTests.forEach((test) => {
87-
it(`Should return endpoints to test ${test.name}`, async () => {
88-
const result = getTCPEndpoints(test.input);
89-
90-
expect(result).toEqual(test.output);
91-
});
92-
});
93-
});
39+
export const mockAutodiscoveryEndpoint = {
40+
host: '127.0.0.1',
41+
port: 6379,
42+
};

0 commit comments

Comments
 (0)