/// <summary>
        /// Executes logic to determine which projects are candidates for querying for scan results
        /// since the last run.
        /// </summary>
        /// <remarks>
        /// Each run will have a list of projects currently in the system.  There may be new projects
        /// since the last run that have never been checked for scans.  Some projects may have been
        /// deleted since the last run and need not be checked.
        /// </remarks>
        /// <returns>An instance of <see cref="ScanResolver"/> that will assist with
        /// picking scans that need to be used in the transformation.</returns>
        public ScanResolver Resolve(Dictionary <String, Action <ScanDescriptor, Transformer> > productAction)
        {
            if (_res == null && !_disallowAdd)
            {
                _disallowAdd = true;
                _targets     = new Dictionary <int, ProjectDescriptorExt>();
                int newProjects = 0;

                foreach (int pid in _newProjects.Keys)
                {
                    // Look for the project in the previous projects.  If it exists, use that record to make
                    // the project a target for scan pulling.
                    if (_previousTargets.ContainsKey(pid))
                    {
                        // Make a new descriptor so that if there is a new preset/name/team/etc
                        // it gets updated based on data pulled from the web service.
                        _targets.Add(pid, new ProjectDescriptorExt(_newProjects[pid],
                                                                   _previousTargets[pid]));
                        _previousTargets.Remove(pid);
                    }
                    else
                    {
                        // If the project was never seen before, it is a new project and a target for pulling scans.
                        _targets.Add(pid, ProjectDescriptorExt.newDetail(_newProjects[pid]));
                        newProjects++;
                    }
                }

                // scanTargets now contains the projects that were added via addProject.  If they were checked before,
                // the last check date is in the record.  If not, the last check date is the epoch.

                // _previousProjects now has projects that have likely been deleted, so throw some INFO in the log
                // that these aren't going to be scanned.
                _log.InfoFormat("{0} projects are targets for check for new scans. Since last scan: {1} projects removed, {2} new projects.",
                                _targets.Keys.Count, _previousTargets.Keys.Count, newProjects);

                foreach (int pid in _previousTargets.Keys)
                {
                    _log.InfoFormat("No longer tracking state for project {0}:[{1}] Team [{2}]",
                                    pid, _previousTargets[pid].ProjectName, _previousTargets[pid].TeamName);
                }

                _res = new ScanResolver(this, productAction);
            }

            return(_res);
        }
예제 #2
0
        private Transformer(CxRestContext ctx, CancellationToken token,
                            String previousStatePath)
        {
            RestContext = ctx;
            CancelToken = token;

            Policies = null;

            _log.Debug("Retrieving policies, if available.");

            // Policies may not have data if M&O is not installed.
            try
            {
                Policies = new ProjectPolicyIndex(CxMnoPolicies.GetAllPolicies(ctx, token));
            }
            catch (Exception ex)
            {
                _log.Warn("Policy data is not available.", ex);
            }


            // Populate the data resolver with teams and presets
            DataResolver dr = new DataResolver();

            _log.Debug("Retrieving presets.");

            var presetEnum = CxPresets.GetPresets(RestContext, CancelToken);

            foreach (var preset in presetEnum)
            {
                dr.addPreset(preset.PresetId, preset.PresetName);
            }

            _log.Debug("Retrieving teams.");

            var teamEnum = CxTeams.GetTeams(RestContext, CancelToken);

            foreach (var team in teamEnum)
            {
                dr.addTeam(team.TeamId, team.TeamName);
            }

            _log.Debug("Resolving projects.");

            // Now populate the project resolver with the projects
            ProjectResolver pr = dr.Resolve(previousStatePath);

            var projects = CxProjects.GetProjects(RestContext, CancelToken);

            foreach (var p in projects)
            {
                String combinedPolicyNames = String.Empty;

                if (Policies != null)
                {
                    try
                    {
                        IEnumerable <int> projectPolicyList = CxMnoPolicies.GetPolicyIdsForProject
                                                                  (ctx, token, p.ProjectId);

                        Policies.CorrelateProjectToPolicies(p.ProjectId, projectPolicyList);
                        combinedPolicyNames = GetFlatPolicyNames(Policies, projectPolicyList);
                    }
                    catch (Exception ex)
                    {
                        _log.Warn($"Unable to correlate policies to project {p.ProjectId}: {p.ProjectName}. " +
                                  $"Policy statistics will be unavalable.", ex);
                    }
                }

                var cfDict = new SortedDictionary <String, String>();
                p.CustomFields.ForEach((cf) => cfDict.Add(cf.FieldName, cf.FieldValue));

                pr.AddProject(p.TeamId, p.PresetId, p.ProjectId, p.ProjectName, combinedPolicyNames, cfDict);
            }

            // Resolve projects to get the scan resolver.
            ScanResolver sr = pr.Resolve(_mapActions);

            try
            {
                _log.Debug("Retrieving SAST scans.");

                var sastScans = CxSastScans.GetScans(RestContext, CancelToken, CxSastScans.ScanStatus.Finished);

                foreach (var sastScan in sastScans)
                {
                    _log.Debug($"SAST scan record: {sastScan}");

                    sr.AddScan(sastScan.ProjectId, sastScan.ScanType, SAST_PRODUCT_STRING,
                               sastScan.ScanId, sastScan.FinishTime);

                    SastScanCache.Add(sastScan.ScanId, sastScan);
                }


                _log.Debug("Retrieving OSA scans.");

                foreach (var p in projects)
                {
                    var scaScans = CxOsaScans.GetScans(ctx, token, p.ProjectId);
                    foreach (var scaScan in scaScans)
                    {
                        _log.Debug($"OSA scan record: {scaScan}");

                        sr.AddScan(scaScan.ProjectId, "Composition", SCA_PRODUCT_STRING, scaScan.ScanId,
                                   scaScan.FinishTime);
                        ScaScanCache.Add(scaScan.ScanId, scaScan);
                    }
                }

                ScanDescriptors = sr.Resolve(CheckTime);
            }
            catch (AggregateException aex)
            {
                _log.Error($"Multiple errors caught resolving scans.");

                int count = 0;
                aex.Handle(
                    (ex) =>
                {
                    _log.Error($"Exception {++count}: ", ex);
                    return(true);
                });
            }
            catch (Exception ex)
            {
                _log.Error($"Error resolving scans, server may be unavailable.", ex);
            }
        }
예제 #3
0
        private Transformer(CxRestContext ctx, CancellationToken token,
                            String previousStatePath)
        {
            RestContext = ctx;
            CancelToken = token;

            Policies = null;

            // Policies may not have data if M&O is not installed.
            try
            {
                Policies = new ProjectPolicyIndex(CxMnoPolicies.GetAllPolicies(ctx, token));
            }
            catch (Exception ex)
            {
                _log.Warn("Policy data is not available.", ex);
            }


            // Populate the data resolver with teams and presets
            DataResolver dr = new DataResolver();

            var presetEnum = CxPresets.GetPresets(RestContext, CancelToken);

            foreach (var preset in presetEnum)
            {
                dr.addPreset(preset.PresetId, preset.PresetName);
            }

            var teamEnum = CxTeams.GetTeams(RestContext, CancelToken);

            foreach (var team in teamEnum)
            {
                dr.addTeam(team.TeamId, team.TeamName);
            }

            // Now populate the project resolver with the projects
            ProjectResolver pr = dr.Resolve(previousStatePath);

            var projects = CxProjects.GetProjects(RestContext, CancelToken);

            foreach (var p in projects)
            {
                String combinedPolicyNames = String.Empty;

                if (Policies != null)
                {
                    try
                    {
                        IEnumerable <int> projectPolicyList = CxMnoPolicies.GetPolicyIdsForProject
                                                                  (ctx, token, p.ProjectId);

                        Policies.CorrelateProjectToPolicies(p.ProjectId, projectPolicyList);
                        combinedPolicyNames = GetFlatPolicyNames(Policies, projectPolicyList);
                    }
                    catch (Exception ex)
                    {
                        _log.Warn($"Unable to correlate policies to project {p.ProjectId}: {p.ProjectName}. " +
                                  $"Policy statistics will be unavalable.", ex);
                    }
                }

                pr.AddProject(p.TeamId, p.PresetId, p.ProjectId, p.ProjectName, combinedPolicyNames);
            }

            // Resolve projects to get the scan resolver.
            ScanResolver sr = pr.Resolve(_mapActions);

            try
            {
                var sastScans = CxSastScans.GetScans(RestContext, CancelToken, CxSastScans.ScanStatus.Finished);
                foreach (var sastScan in sastScans)
                {
                    sr.AddScan(sastScan.ProjectId, sastScan.ScanType, SAST_PRODUCT_STRING,
                               sastScan.ScanId, sastScan.FinishTime);

                    SastScanCache.Add(sastScan.ScanId, sastScan);
                }


                foreach (var p in projects)
                {
                    var scaScans = CxScaScans.GetScans(ctx, token, p.ProjectId);
                    foreach (var scaScan in scaScans)
                    {
                        sr.AddScan(scaScan.ProjectId, "Composition", SCA_PRODUCT_STRING, scaScan.ScanId,
                                   scaScan.FinishTime);
                        ScaScanCache.Add(scaScan.ScanId, scaScan);
                    }
                }

                ScanDescriptors = sr.Resolve(CheckTime);
            }
            catch (Exception ex)
            {
                _log.Error($"Error resolving scans, server may be unavailable.", ex);
            }
        }