public static bool Validate(Package package, out List <string> warnings) { warnings = new List <string>(); var ovfEnv = package.OvfEnvelope; if (ovfEnv == null) { warnings.Add(Messages.VALIDATION_INVALID_OVF); return(false); } log.InfoFormat("Started validation of package {0}", package.Name); var validationFlags = (ValidationFlags)Properties.Settings.Default.RequiredValidations; if (validationFlags.HasFlag(ValidationFlags.Version)) { ValidateVersion(ovfEnv, ref warnings); } if (validationFlags.HasFlag(ValidationFlags.Schema)) { ValidateSchema(package.DescriptorXml, ref warnings); } var files = package.OvfEnvelope?.References?.File ?? new File_Type[0]; if (validationFlags.HasFlag(ValidationFlags.Files)) { foreach (File_Type file in files) { string ext = Path.GetExtension(file.href).ToLower(); if (ext == Package.MANIFEST_EXT || ext == Package.CERTIFICATE_EXT) { continue; } if (!package.HasFile(file.href)) { warnings.Add(string.Format(Messages.VALIDATION_FILE_NOT_FOUND, file.href)); log.Error($"Failed to find file {file.href} listed in the reference section."); return(false); } if (!KnownFileExtensions.Contains(ext)) { warnings.Add(string.Format(Messages.VALIDATION_FILE_UNSUPPORTED_EXTENSION, file.href)); } } } VirtualDiskDesc_Type[] disks = null; NetworkSection_TypeNetwork[] networks = null; foreach (var section in ovfEnv.Sections) { if (section is DiskSection_Type diskSection) { disks = diskSection.Disk; } else if (section is NetworkSection_Type netSection) { networks = netSection.Network; } } var systems = new Content_Type[0]; switch (ovfEnv.Item) { case VirtualSystemCollection_Type vsCol: systems = vsCol.Content; break; case VirtualSystem_Type _: systems = new [] { ovfEnv.Item }; break; default: log.Error($"OVF envelope item type {ovfEnv.Item.GetType()} is not recognized."); warnings.Add(string.Format(Messages.VALIDATION_INVALID_TYPE, ovfEnv.Item.GetType())); break; } var linkedFiles = new List <File_Type>(); foreach (var system in systems) { foreach (var section in system.Items) { if (!(section is VirtualHardwareSection_Type vhs)) { continue; } var hardwareType = vhs.System?.VirtualSystemType?.Value; if (hardwareType != null && !Properties.Settings.Default.knownVirtualSystemTypes.Contains(hardwareType)) { log.Warn($"Found unexpected virtual hardware type {hardwareType}."); warnings.Add(string.Format(Messages.VALIDATION_UNKNOWN_HARDWARE_TYPE, hardwareType)); } RASD_Type[] rasds = vhs.Item; foreach (RASD_Type rasd in rasds) { if ((rasd.ResourceType.Value == 17 || rasd.ResourceType.Value == 19 || rasd.ResourceType.Value == 20 || rasd.ResourceType.Value == 21) && validationFlags.HasFlag(ValidationFlags.Files)) { ValidateDisks(rasd, files, disks, ref linkedFiles, ref warnings); } if (rasd.ResourceType.Value == 3 && validationFlags.HasFlag(ValidationFlags.Cpu)) { ValidateCpu(rasd, ref warnings); } if (rasd.ResourceType.Value == 4 && validationFlags.HasFlag(ValidationFlags.Memory)) { ValidateMemory(rasd, ref warnings); } if (rasd.ResourceType.Value == 10 && validationFlags.HasFlag(ValidationFlags.Networks)) { ValidateNetworks(rasd, networks, ref warnings); } if (validationFlags.HasFlag(ValidationFlags.Capability)) { ValidateCapability(rasd, ref warnings); } } } } foreach (File_Type file in files) { if (!linkedFiles.Contains(file)) { log.WarnFormat("Disk linkage (file to RASD) does not exist for {0}", file.href); warnings.Add(string.Format(Messages.VALIDATION_FILE_INVALID_LINKAGE, file.href)); } } log.InfoFormat("Finished validation of package {0}", package.Name); return(true); }
private static bool ValidateDisks(Package package, VirtualDiskDesc_Type[] disks, RASD_Type[] rasds, ref List <string> warnings) { log.Info("Validating disks"); bool isValid = true; File_Type[] files = package.OvfEnvelope?.References?.File ?? new File_Type[0]; foreach (File_Type file in files) { string ext = Path.GetExtension(file.href).ToLower(); if (ext == Properties.Settings.Default.manifestFileExtension || ext == Properties.Settings.Default.certificateFileExtension) { continue; } if (package.HasFile(file.href)) { if (!Properties.Settings.Default.knownFileExtensions.ToLower().Contains(ext)) { warnings.Add(string.Format(Messages.VALIDATION_FILE_UNSUPPORTED_EXTENSION, file.href)); continue; } bool validlink = false; foreach (VirtualDiskDesc_Type disk in disks) { if (file.id == disk.fileRef) { foreach (RASD_Type rasd in rasds) { if (rasd.ResourceType.Value == 17 || rasd.ResourceType.Value == 19 || rasd.ResourceType.Value == 20 || rasd.ResourceType.Value == 21) { if (rasd.HostResource != null && rasd.HostResource.Length > 0) { if (rasd.HostResource[0].Value.Contains(disk.diskId)) { validlink = true; break; } } else if (disk.diskId == rasd.InstanceID.Value) { validlink = true; break; } } } } } if (!validlink) { log.WarnFormat("Disk linkage (file to RASD) does not exist for {0}", file.href); warnings.Add(string.Format(Messages.VALIDATION_FILE_INVALID_LINKAGE, file.href)); } } else { warnings.Add(string.Format(Messages.VALIDATION_FILE_NOT_FOUND, file.href)); log.Error($"Failed to find file {file.href} listed in the reference section."); isValid = false; } } return(isValid); }