Esempio n. 1
0
        public override async Task DoRequestAsync(IndexRequest request)
        {
            try
            {
                RegistryCredentials credentials = null;

                // if the request was submitted by a user, it must have auth info included
                if (!string.IsNullOrEmpty(request.Authorization))
                {
                    var authResult = authDecoder.AuthenticateAsync(request.Authorization).Result;
                    if (authResult.Succeeded)
                    {
                        credentials = authResult.Principal.ToRegistryCredentials();
                    }
                }
                // if the request came via an event sink, there is no auth provided, and we need to have a default user configured
                else
                {
                    credentials = config.GetCatalogCredentials() ?? throw new ArgumentException("The indexing request had no included authorization, and no default catalog user is configured.");
                }

                if (credentials == null)
                {
                    logger.LogWarning("Authorization failed for the work item. A token may have expired since it was first submitted.");
                }
                else
                {
                    await authHandler.LoginAsync(credentials);

                    var client = clientFactory.GetClient(authHandler);

                    // if deep indexing is configured, ignore target paths
                    if (config.DeepIndexing)
                    {
                        request.TargetPaths = new string[0];
                    }

                    var imageSet = await client.GetImageSetAsync(request.TargetRepo, request.TargetDigest);

                    if ((imageSet?.Images?.Count() ?? 0) != 1)
                    {
                        throw new Exception($"Couldn't find a valid image for {request.TargetRepo}:{request.TargetDigest}");
                    }
                    var image = imageSet.Images.First();

                    using (var @lock = await cacheFactory.Get <object>().TakeLockAsync($"idx:{image.Digest}", TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)))
                    {
                        if (!indexStore.IndexExists(image.Digest, request.TargetPaths.ToArray()))
                        {
                            logger.LogInformation($"Starting index for {request.TargetRepo}:{request.TargetDigest}");
                            var indexes = client.GetIndexes(request.TargetRepo, image, request.TargetPaths.ToArray());
                            indexStore.SetIndex(indexes, image.Digest, request.TargetPaths.ToArray());
                            logger.LogInformation($"Completed indexing {indexes.Max(i => i.Depth)} layer(s) from {request.TargetRepo}:{request.TargetDigest} {(request.TargetPaths.Count() == 0 ? "" : $"({string.Join(", ", request.TargetPaths)})")}");
                        }
                        else
                        {
                            logger.LogInformation($"Index already exists for {request.TargetRepo}:{request.TargetDigest}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"Processing failed for work item\n {Newtonsoft.Json.JsonConvert.SerializeObject(request)}");
            }
        }
Esempio n. 2
0
        public override async Task DoRequestAsync(ScanRequest request)
        {
            try
            {
                RegistryCredentials credentials = null;

                // if the request was submitted by a user, it must have auth info included
                if (!string.IsNullOrEmpty(request.Authorization))
                {
                    var authResult = authDecoder.AuthenticateAsync(request.Authorization).Result;
                    if (authResult.Succeeded)
                    {
                        credentials = authResult.Principal.ToRegistryCredentials();
                    }
                }
                // if the request came via an event sink, there is no auth provided, and we need to have a default user configured
                else
                {
                    credentials = config.GetCatalogCredentials() ?? throw new ArgumentException("The indexing request had no included authorization, and no default catalog user is configured.");
                }

                if (credentials == null)
                {
                    logger.LogError("Authorization failed for the work item. A token may have expired since it was first submitted.");
                }
                else
                {
                    await authHandler.LoginAsync(credentials);

                    var scope = authHandler.RepoPullScope(request.TargetRepo);
                    if (await authHandler.AuthorizeAsync(scope))
                    {
                        var proxyAuth = authHandler.TokensRequired ? $"Bearer {(await authHandler.GetAuthorizationAsync(scope)).Parameter}" : string.Empty;
                        var client    = clientFactory.GetClient(authHandler);

                        var imageSet = await client.GetImageSetAsync(request.TargetRepo, request.TargetDigest);

                        if ((imageSet?.Images?.Count() ?? 0) != 1)
                        {
                            throw new Exception($"Couldn't find a valid image for {request.TargetRepo}:{request.TargetDigest}");
                        }

                        var scanResult = scanner.GetScan(imageSet.Images.First());
                        if (scanResult == null)
                        {
                            if (request.Submitted)
                            {
                                // we've already submitted this one to the scanner, just sleep on it for a few seconds
                                Thread.Sleep(2000);
                            }
                            else
                            {
                                var host = authHandler.GetRegistryHost();
                                scanner.RequestScan(request.TargetRepo, imageSet.Images.First(), host, proxyAuth);
                                logger.LogInformation($"Submitted {request.TargetRepo}:{request.TargetDigest} to {scanner.GetType().Name} for analysis.");
                                request.Submitted = true;
                            }
                            queue.Push(request);
                        }
                        else
                        {
                            logger.LogInformation($"Got latest {scanner.GetType().Name} scan for {request.TargetRepo}:{request.TargetDigest}");
                        }
                    }
                    else
                    {
                        logger.LogError($"Failed to get pull authorization for {request.TargetRepo}");
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"Processing failed for work item\n {Newtonsoft.Json.JsonConvert.SerializeObject(request)}");
            }
        }