public Envelope( [JsonProperty("@type")] string typeAnnotation, [JsonProperty("instanceSetHistory")] ReportArchive instanceSetHistory) : this(instanceSetHistory) { if (typeAnnotation != TypeAnnotation) { throw new FormatException("Missing type annotation: " + TypeAnnotation); } }
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); } } }
public Envelope( ReportArchive instanceSetHistory) { this.InstanceSetHistory = instanceSetHistory; }
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); } }