Exemplo n.º 1
0
        public async Task TestCascadedOwnership_BlankObjectAndGroupOwnerShouldReturnRootLevel()
        {
            await using var context = JosekiTestsDb.CreateUniqueContext();

            const string rootLevelId   = "/subscriptions/0000-000-000-0000";
            const string groupLevelId  = "/subscriptions/0000-000-000-0000/resource_group/das-rg";
            const string objectLevelId = "/subscriptions/0000-000-000-0000/resource_group/das-rg/VirtualNetwork/das-vn";

            context.Ownership.AddRange(new OwnershipEntity[]
            {
                new OwnershipEntity
                {
                    ComponentId = rootLevelId,
                    Owner       = "*****@*****.**",
                },
                new OwnershipEntity
                {
                    ComponentId = groupLevelId,
                    Owner       = string.Empty,
                },
                new OwnershipEntity
                {
                    ComponentId = objectLevelId,
                    Owner       = string.Empty,
                },
            });
            await context.SaveChangesAsync();

            var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions()));

            var owner = await ownershipCache.GetOwner(objectLevelId);

            owner.Should().Be("*****@*****.**");
        }
Exemplo n.º 2
0
        public async Task ExtractOwnershipFromK8sAudit()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();

            var cache     = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions()));
            var processor = new ExtractOwnershipProcessor(context, cache);

            context.Ownership.Count().Should().Be(0, "ownership list should be empty");

            var auditMetaPath = Path.Combine("audits", "samples", "k8s_audit.json");

            var audit = new Audit
            {
                MetadataKube = new MetadataKube
                {
                    Id      = 1,
                    AuditId = string.Empty,
                    Date    = DateTime.Now,
                    JSON    = File.ReadAllText(auditMetaPath),
                },
            };

            await processor.Process(audit, CancellationToken.None);

            var list = context.Ownership.ToList();

            context.Ownership.Count().Should().Be(2, "ownership list should have 2 items");
        }
Exemplo n.º 3
0
        public async Task ExtractOwnershipFromAzskAudit()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();

            context.Ownership.Count().Should().Be(0, "ownership list should be empty");

            var cache         = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions()));
            var processor     = new ExtractOwnershipProcessor(context, cache);
            var auditMetaPath = Path.Combine("audits", "samples", "azsk_audit.json");

            var audit = new Audit
            {
                MetadataAzure = new MetadataAzure
                {
                    Id      = 1,
                    AuditId = string.Empty,
                    Date    = DateTime.Now,
                    JSON    = File.ReadAllText(auditMetaPath),
                },
            };

            await processor.Process(audit, CancellationToken.None);

            var list = context.Ownership.ToList();

            context.Ownership.Count().Should().Be(17, "ownership list should have 17 items");

            foreach (var expectedComponentId in azskAuditComponentIds)
            {
                var item = context.Ownership.FirstOrDefault(x => x.ComponentId == expectedComponentId);
                item.Should().NotBe(null, expectedComponentId);
            }
        }
        public async Task ProcessAuditHappyPath()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();
            var parser      = new ConfigurationParser("config.sample.yaml");
            var checksCache = new ChecksCache(parser, context, new MemoryCache(new MemoryCacheOptions()));

            var blobsMock = new Mock <IBlobStorageProcessor>(MockBehavior.Strict);
            var dbMock    = new Mock <IJosekiDatabase>();
            var queueMock = new Mock <IQueue>();

            var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions()));
            var postProcessor  = new Mock <ExtractOwnershipProcessor>(context, ownershipCache);
            var processor      = new PolarisAuditProcessor(blobsMock.Object, dbMock.Object, checksCache, queueMock.Object, postProcessor.Object);

            var container = new ScannerContainer(Path.Combine("audits", "samples", "polaris"))
            {
                Metadata = new ScannerMetadata
                {
                    Type = ScannerType.Polaris,
                    Id   = Guid.NewGuid().ToString(),
                },
            };
            var audit = new AuditBlob {
                Name = "meta.json", ParentContainer = container
            };

            blobsMock
            .Setup(i => i.GetUnprocessedAudits(container))
            .ReturnsAsync(new[] { audit })
            .Verifiable();
            blobsMock
            .Setup(i => i.DownloadFile($"{container.Name}/{audit.Name}"))
            .ReturnsAsync(File.OpenRead($"{container.Name}/{audit.Name}"))
            .Verifiable();
            blobsMock
            .Setup(i => i.DownloadFile($"{container.Name}/audit.json"))
            .ReturnsAsync(File.OpenRead($"{container.Name}/audit.json"))
            .Verifiable();
            blobsMock
            .Setup(i => i.DownloadFile($"{container.Name}/k8s-meta.json"))
            .ReturnsAsync(File.OpenRead($"{container.Name}/k8s-meta.json"))
            .Verifiable();
            blobsMock
            .Setup(i => i.MarkAsProcessed(audit))
            .Returns(Task.CompletedTask)
            .Verifiable();

            // Act & Assert
            await processor.Process(container, CancellationToken.None);

            blobsMock.Verify();

            dbMock.Verify(i => i.GetNotExpiredImageScans(It.Is <string[]>(tags => tags.Length == UniqueImageTagCount)));
            dbMock.Verify(i => i.SaveInProgressImageScan(It.IsAny <ImageScanResultWithCVEs>()), Times.Exactly(UniqueImageTagCount));
            queueMock.Verify(i => i.EnqueueImageScanRequest(It.IsAny <ImageScanResultWithCVEs>()), Times.Exactly(UniqueImageTagCount));

            dbMock.Verify(i => i.SaveAuditResult(It.Is <Audit>(a => VerifyHappyPathAudit(a, container))));
        }
Exemplo n.º 5
0
        public async Task EmptyComponentId_ShouldThrowException()
        {
            await using var context = JosekiTestsDb.CreateUniqueContext();
            var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions()));

            string emptyComponentId = string.Empty;

            var owner1 = await ownershipCache.GetOwner(emptyComponentId);

            owner1.Should().Be(string.Empty);
        }
Exemplo n.º 6
0
        public async Task InvalidComponentId_ShouldThrowException()
        {
            await using var context = JosekiTestsDb.CreateUniqueContext();
            var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions()));

            const string invalidId_missingSlashPrefix = "subscription/0000-000-000-0000/";

            var owner1 = await ownershipCache.GetOwner(invalidId_missingSlashPrefix);

            owner1.Should().Be(string.Empty);
        }
Exemplo n.º 7
0
        public async Task ProcessAuditHappyPath()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();
            var parser = new ConfigurationParser("config.sample.yaml");

            var checksCache = new ChecksCache(parser, context, new MemoryCache(new MemoryCacheOptions()));

            var blobsMock = new Mock <IBlobStorageProcessor>(MockBehavior.Strict);
            var dbMock    = new Mock <IJosekiDatabase>();

            var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions()));
            var postProcessor  = new Mock <ExtractOwnershipProcessor>(context, ownershipCache);
            var processor      = new AzskAuditProcessor(blobsMock.Object, dbMock.Object, checksCache, postProcessor.Object);

            var container = new ScannerContainer(Path.Combine("audits", "samples", "azsk"))
            {
                Metadata = new ScannerMetadata
                {
                    Type = ScannerType.Azsk,
                    Id   = Guid.NewGuid().ToString(),
                },
            };
            var audit = new AuditBlob {
                Name = "meta.json", ParentContainer = container
            };

            blobsMock
            .Setup(i => i.GetUnprocessedAudits(container))
            .ReturnsAsync(new[] { audit })
            .Verifiable();
            blobsMock
            .Setup(i => i.DownloadFile($"{container.Name}/{audit.Name}"))
            .ReturnsAsync(File.OpenRead($"{container.Name}/{audit.Name}"))
            .Verifiable();
            blobsMock
            .Setup(i => i.DownloadFile($"{container.Name}/resources.json"))
            .ReturnsAsync(File.OpenRead($"{container.Name}/resources.json"))
            .Verifiable();
            blobsMock
            .Setup(i => i.DownloadFile($"{container.Name}/subscription.json"))
            .ReturnsAsync(File.OpenRead($"{container.Name}/subscription.json"))
            .Verifiable();
            blobsMock
            .Setup(i => i.MarkAsProcessed(audit))
            .Returns(Task.CompletedTask)
            .Verifiable();

            // Act & Assert
            await processor.Process(container, CancellationToken.None);

            blobsMock.Verify();
            dbMock.Verify(i => i.SaveAuditResult(It.Is <Audit>(a => VerifyHappyPathAudit(a, container))));
        }
Exemplo n.º 8
0
        public async Task OwnershipCache_ShouldInvalidateOnCall()
        {
            await using var context = JosekiTestsDb.CreateUniqueContext();

            const string rootLevelId = "/subscriptions/0000-000-000-0000";

            var ownerEntry = new OwnershipEntity
            {
                ComponentId = rootLevelId,
                Owner       = "*****@*****.**",
            };

            context.Ownership.Add(ownerEntry);
            await context.SaveChangesAsync();

            var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions()));

            var owner1 = await ownershipCache.GetOwner(rootLevelId);

            owner1.Should().Be("*****@*****.**");

            // remove entry from db
            context.Ownership.Remove(ownerEntry);
            await context.SaveChangesAsync();

            // see that cache is in progress.
            var ownerAgain = await ownershipCache.GetOwner(rootLevelId);

            ownerAgain.Should().Be("*****@*****.**");

            // invalidate cache
            ownershipCache.Invalidate();

            var ownerNull = await ownershipCache.GetOwner(rootLevelId);

            ownerNull.Should().Be(string.Empty);
        }