Skip to content

Commit f732f16

Browse files
#RI-3572 - add check renamed command function
1 parent 84ba9b9 commit f732f16

File tree

2 files changed

+59
-25
lines changed

2 files changed

+59
-25
lines changed

redisinsight/api/src/modules/recommendation/providers/recommendation.provider.spec.ts

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -562,59 +562,59 @@ describe('RecommendationProvider', () => {
562562
.calledWith(jasmine.objectContaining({ name: 'FT._LIST' }))
563563
.mockResolvedValue(mockFTListResponse_1);
564564

565-
const redisServerRecommendation = await service
565+
const redisSearchRecommendation = await service
566566
.determineRediSearchRecommendation(nodeClient, [mockJSONKey]);
567-
expect(redisServerRecommendation).toEqual({ name: RECOMMENDATION_NAMES.REDIS_SEARCH });
567+
expect(redisSearchRecommendation).toEqual({ name: RECOMMENDATION_NAMES.REDIS_SEARCH });
568568
});
569569

570570
it('should return rediSearch recommendation when there is huge string key', async () => {
571571
when(nodeClient.sendCommand)
572572
.calledWith(jasmine.objectContaining({ name: 'FT._LIST' }))
573573
.mockResolvedValue(mockFTListResponse_1);
574574

575-
const redisServerRecommendation = await service
575+
const redisSearchRecommendation = await service
576576
.determineRediSearchRecommendation(nodeClient, [mockRediSearchStringKey_1]);
577-
expect(redisServerRecommendation).toEqual({ name: RECOMMENDATION_NAMES.REDIS_SEARCH });
577+
expect(redisSearchRecommendation).toEqual({ name: RECOMMENDATION_NAMES.REDIS_SEARCH });
578578
});
579579

580580
it('should not return rediSearch recommendation when there is small string key', async () => {
581581
when(nodeClient.sendCommand)
582582
.calledWith(jasmine.objectContaining({ name: 'FT._LIST' }))
583583
.mockResolvedValue(mockFTListResponse_1);
584584

585-
const redisServerRecommendation = await service
585+
const redisSearchRecommendation = await service
586586
.determineRediSearchRecommendation(nodeClient, [mockRediSearchStringKey_2]);
587-
expect(redisServerRecommendation).toEqual(null);
587+
expect(redisSearchRecommendation).toEqual(null);
588588
});
589589

590590
it('should not return rediSearch recommendation when there are no indexes', async () => {
591591
when(nodeClient.sendCommand)
592592
.calledWith(jasmine.objectContaining({ name: 'FT._LIST' }))
593593
.mockResolvedValue(mockFTListResponse_2);
594594

595-
const redisServerRecommendation = await service
595+
const redisSearchRecommendation = await service
596596
.determineRediSearchRecommendation(nodeClient, [mockJSONKey]);
597-
expect(redisServerRecommendation).toEqual(null);
597+
expect(redisSearchRecommendation).toEqual(null);
598598
});
599599

600600
it('should ignore errors when ft command execute with error', async () => {
601601
when(nodeClient.sendCommand)
602602
.calledWith(jasmine.objectContaining({ name: 'FT._LIST' }))
603603
.mockRejectedValue("some error");
604604

605-
const redisServerRecommendation = await service
605+
const redisSearchRecommendation = await service
606606
.determineRediSearchRecommendation(nodeClient, [mockJSONKey]);
607-
expect(redisServerRecommendation).toEqual({ name: RECOMMENDATION_NAMES.REDIS_SEARCH });
607+
expect(redisSearchRecommendation).toEqual({ name: RECOMMENDATION_NAMES.REDIS_SEARCH });
608608
});
609609

610610
it('should ignore errors when ft command execute with error', async () => {
611611
when(nodeClient.sendCommand)
612612
.calledWith(jasmine.objectContaining({ name: 'FT._LIST' }))
613613
.mockRejectedValue("some error");
614614

615-
const redisServerRecommendation = await service
615+
const redisSearchRecommendation = await service
616616
.determineRediSearchRecommendation(nodeClient, [mockRediSearchStringKey_2]);
617-
expect(redisServerRecommendation).toEqual(null);
617+
expect(redisSearchRecommendation).toEqual(null);
618618
});
619619
});
620620

@@ -624,19 +624,19 @@ describe('RecommendationProvider', () => {
624624
.calledWith(jasmine.objectContaining({ name: 'info' }))
625625
.mockResolvedValue(mockRedisServerResponse_1);
626626

627-
const redisServerRecommendation = await service
627+
const redisVersionRecommendation = await service
628628
.determineRedisVersionRecommendation(nodeClient);
629-
expect(redisServerRecommendation).toEqual(null);
629+
expect(redisVersionRecommendation).toEqual(null);
630630
});
631631

632632
it('should return redis version recommendation', async () => {
633633
when(nodeClient.sendCommand)
634634
.calledWith(jasmine.objectContaining({ name: 'info' }))
635635
.mockResolvedValueOnce(mockRedisServerResponse_2);
636636

637-
const redisServerRecommendation = await service
637+
const redisVersionRecommendation = await service
638638
.determineRedisVersionRecommendation(nodeClient);
639-
expect(redisServerRecommendation).toEqual({ name: RECOMMENDATION_NAMES.REDIS_VERSION });
639+
expect(redisVersionRecommendation).toEqual({ name: RECOMMENDATION_NAMES.REDIS_VERSION });
640640
});
641641

642642
it('should not return redis version recommendation when info command executed with error',
@@ -646,9 +646,23 @@ describe('RecommendationProvider', () => {
646646
.calledWith(jasmine.objectContaining({ name: 'info' }))
647647
.mockRejectedValue('some error');
648648

649-
const redisServerRecommendation = await service
649+
const redisVersionRecommendation = await service
650650
.determineRedisVersionRecommendation(nodeClient);
651-
expect(redisServerRecommendation).toEqual(null);
651+
expect(redisVersionRecommendation).toEqual(null);
652+
});
653+
});
654+
655+
describe('determineDangerousCommandsRecommendation', () => {
656+
it('should not return dangerous commands recommendation when "command" command executed with error',
657+
async () => {
658+
resetAllWhenMocks();
659+
when(nodeClient.sendCommand)
660+
.calledWith(jasmine.objectContaining({ name: 'command' }))
661+
.mockRejectedValue('some error');
662+
663+
const dangerousCommandsRecommendation = await service
664+
.determineDangerousCommandsRecommendation(nodeClient);
665+
expect(dangerousCommandsRecommendation).toEqual(null);
652666
});
653667
});
654668
});

redisinsight/api/src/modules/recommendation/providers/recommendation.provider.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable, Logger } from '@nestjs/common';
22
import { Redis, Cluster, Command } from 'ioredis';
3-
import { get, isNumber } from 'lodash';
3+
import { get, isNull, isNumber } from 'lodash';
44
import { isValid } from 'date-fns';
55
import * as semverCompare from 'node-version-compare';
66
import { convertRedisInfoReplyToObject, convertBulkStringsToObject } from 'src/utils';
@@ -440,13 +440,13 @@ export class RecommendationProvider {
440440
if (keys[processedKeysNumber].type !== RedisDataType.ZSet) {
441441
processedKeysNumber += 1;
442442
} else {
443-
let keyBySortedSetMember;
443+
let keyType: string;
444444
const sortedSetMember = await redisClient.sendCommand(
445445
new Command('zrange', [keys[processedKeysNumber].name, 0, 0], { replyEncoding: 'utf8' }),
446446
) as string[];
447447

448448
try {
449-
keyBySortedSetMember = await redisClient.sendCommand(
449+
keyType = await redisClient.sendCommand(
450450
new Command('type', [sortedSetMember[0]], { replyEncoding: 'utf8' }),
451451
) as string;
452452
} catch (err) {
@@ -461,12 +461,12 @@ export class RecommendationProvider {
461461
);
462462
}
463463

464-
keyBySortedSetMember = await node.sendCommand(
464+
keyType = await node.sendCommand(
465465
new Command('type', [sortedSetMember[0]], { replyEncoding: 'utf8' }),
466466
) as string;
467467
}
468468
}
469-
if (keyBySortedSetMember === RedisDataType.JSON || keyBySortedSetMember === RedisDataType.Hash) {
469+
if (keyType === RedisDataType.JSON || keyType === RedisDataType.Hash) {
470470
isJSONOrHash = true;
471471
}
472472
processedKeysNumber += 1;
@@ -517,8 +517,14 @@ export class RecommendationProvider {
517517
const commandName = command.split('|')[0];
518518
return !redisInsightCommands.includes(commandName);
519519
});
520-
const commands = filteredDangerousCommands.join('\r\n').toUpperCase();
521-
return filteredDangerousCommands
520+
521+
const activeDangerousCommands = await Promise.all(
522+
filteredDangerousCommands.map(async (command) => await this.checkCommandInfo(redisClient, command)),
523+
);
524+
const commands = activeDangerousCommands
525+
.filter((command) => !isNull(command))
526+
.join('\r\n').toUpperCase();
527+
return activeDangerousCommands.length
522528
? { name: RECOMMENDATION_NAMES.DANGEROUS_COMMANDS, params: { commands } }
523529
: null;
524530
} catch (err) {
@@ -540,6 +546,20 @@ export class RecommendationProvider {
540546
return false;
541547
}
542548

549+
private async checkCommandInfo(redisClient: Redis | Cluster, command: string): Promise<string> {
550+
try {
551+
const result = await redisClient.sendCommand(
552+
new Command('command', ['info', command]),
553+
);
554+
if (isNull(result[0])) {
555+
return null;
556+
}
557+
} catch (err) {
558+
return null;
559+
}
560+
return command;
561+
}
562+
543563
private checkTimestamp(value: string): boolean {
544564
try {
545565
if (!IS_NUMBER_REGEX.test(value) && isValid(new Date(value))) {

0 commit comments

Comments
 (0)