示例#1
0
 public Envelope(
     [JsonProperty("@type")] string typeAnnotation,
     [JsonProperty("instanceSetHistory")] ReportArchive instanceSetHistory)
     : this(instanceSetHistory)
 {
     if (typeAnnotation != TypeAnnotation)
     {
         throw new FormatException("Missing type annotation: " + TypeAnnotation);
     }
 }
示例#2
0
        public static async Task LoadLicenseAnnotationsAsync(
            ReportArchive annotatedSet,
            IComputeEngineAdapter computeEngineAdapter,
            CancellationToken cancellationToken)
        {
            foreach (var image in annotatedSet.History.Instances
                     .Where(i => i.Image != null)
                     .Select(i => i.Image)
                     .Distinct())
            {
                try
                {
                    Image imageInfo = await computeEngineAdapter
                                      .GetImageAsync(image, cancellationToken)
                                      .ConfigureAwait(false);

                    // Images can contain more than one license, and liceses like
                    // "/compute/v1/projects/compute-image-tools/global/licenses/virtual-disk-import"
                    // are not helpful here. So do some filtering.

                    var license = TryGetRelevantLicenseFromImage(imageInfo);
                    annotatedSet.AddLicenseAnnotation(
                        image,
                        license);

                    TraceSources.IapDesktop.TraceVerbose("License for {0} is {1}", image, license);
                }
                catch (ResourceNotFoundException) when(image.ProjectId == "windows-cloud")
                {
                    // That image might not exist anymore, but we know it's
                    // a Windows SPLA image.
                    annotatedSet.AddLicenseAnnotation(
                        image,
                        OperatingSystemTypes.Windows,
                        LicenseTypes.Spla);

                    TraceSources.IapDesktop.TraceVerbose(
                        "License for {0} could not be found, but must be Windows/SPLA", image);
                }
                catch (ResourceNotFoundException e)
                {
                    // Unknown or inaccessible image, skip.
                    TraceSources.IapDesktop.TraceWarning(
                        "License for {0} could not be found: {0}", image, e);
                }
                catch (ResourceAccessDeniedException e)
                {
                    // Unknown or inaccessible image, skip.
                    TraceSources.IapDesktop.TraceWarning(
                        "License for {0} could not be accessed: {0}", image, e);
                }
            }
        }
示例#3
0
 public Envelope(
     ReportArchive instanceSetHistory)
 {
     this.InstanceSetHistory = instanceSetHistory;
 }
示例#4
0
        public async Task <ReportArchive> BuildAsync(
            CancellationToken cancellationToken)
        {
            using (TraceSources.IapDesktop.TraceMethod().WithParameters(this.projectIds, sources))
            {
                this.PercentageDone = 5;
                this.BuildStatus    = "1. Analyzing current inventory...";

                //
                // (1) Take inventory of what's there currently (pretty fast).
                //
                foreach (var projectId in this.projectIds)
                {
                    //
                    // Load disks.
                    //
                    // NB. Instances.list returns the disks associated with each
                    // instance, but lacks the information about the source image.
                    // Therefore, we load disks first and then join the data.
                    //
                    var disks = await this.computeEngineAdapter.ListDisksAsync(
                        projectId,
                        cancellationToken).ConfigureAwait(false);

                    //
                    // Load instances.
                    //
                    var instances = await this.computeEngineAdapter.ListInstancesAsync(
                        projectId,
                        cancellationToken).ConfigureAwait(false);

                    this.builder.AddExistingInstances(
                        instances,
                        disks,
                        projectId);
                }

                //
                // (2) Try to use GCS exports for as many projects as we can (reasonably fast).
                //

                var pendingProjectIds = new HashSet <string>(this.projectIds);

                if (this.sources.HasFlag(AuditLogSources.StorageExport))
                {
                    this.PercentageDone = 10;
                    this.BuildStatus   += $"\n2. Loading Cloud Storage exports...";

                    foreach (var projectId in this.projectIds)
                    {
                        // NB. Listing sinks does not requir any more permissions than
                        // querying the API.

                        var auditLogExportBucket = await this.auditExportAdapter
                                                   .FindCloudStorageExportBucketForAuditLogsAsync(
                            projectId,
                            this.builder.StartDate,
                            cancellationToken)
                                                   .ConfigureAwait(false);

                        if (auditLogExportBucket != null)
                        {
                            TraceSources.IapDesktop.TraceVerbose(
                                "Found storage export buckets for {0}: {1}",
                                projectId,
                                auditLogExportBucket);

                            this.BuildStatus += $"\n    - {auditLogExportBucket}...";
                            await this.auditExportAdapter.ProcessInstanceEventsAsync(
                                auditLogExportBucket,
                                this.builder.StartDate,
                                this.builder.EndDate,
                                this,
                                cancellationToken)
                            .ConfigureAwait(false);

                            // Check this project off.
                            pendingProjectIds.Remove(projectId);
                        }
                    }
                }

                //
                // (3) Use API for remaining projects (very slow).
                //

                if (pendingProjectIds.Any() && this.sources.HasFlag(AuditLogSources.Api))
                {
                    this.PercentageDone = 30;
                    this.BuildStatus   += $"\n3. Querying Audit Log API...";

                    TraceSources.IapDesktop.TraceVerbose(
                        "Querying audit log API for remaining projects {0}",
                        string.Join(", ", pendingProjectIds));

                    await this.auditLogAdapter.ProcessInstanceEventsAsync(
                        pendingProjectIds,
                        null,      // all zones.
                        null,      // all instances.
                        this.builder.StartDate,
                        this,
                        cancellationToken)
                    .ConfigureAwait(false);
                }

                //
                // (4) Finish up.
                //

                this.PercentageDone = 90;
                this.BuildStatus   += "\n4. Finalizing report...";

                var archive = ReportArchive.FromInstanceSetHistory(this.builder.Build());

                await archive.LoadLicenseAnnotationsAsync(
                    this.computeEngineAdapter,
                    cancellationToken).ConfigureAwait(false);

                return(archive);
            }
        }