|
1 | 1 | // Copyright (c) Microsoft Corporation. |
2 | 2 | // Licensed under the MIT License. |
3 | 3 |
|
4 | | -use crate::discovery::{ |
5 | | - discovery_trait::{DiscoveryFilter, DiscoveryKind, ResourceDiscovery} |
6 | | -}; |
| 4 | +use crate::{discovery::discovery_trait::{DiscoveryFilter, DiscoveryKind, ResourceDiscovery}, parser::Statement}; |
7 | 5 | use crate::{locked_is_empty, locked_extend, locked_clone, locked_get}; |
| 6 | +use crate::configure::context::Context; |
8 | 7 | use crate::dscresources::dscresource::{Capability, DscResource, ImplementedAs}; |
9 | 8 | use crate::dscresources::resource_manifest::{import_manifest, validate_semver, Kind, ResourceManifest, SchemaKind}; |
10 | 9 | use crate::dscresources::command_resource::invoke_command; |
@@ -259,37 +258,39 @@ impl ResourceDiscovery for CommandDiscovery { |
259 | 258 | }, |
260 | 259 | }; |
261 | 260 |
|
262 | | - match resource { |
263 | | - ImportedManifest::Extension(extension) => { |
264 | | - if regex.is_match(&extension.type_name) { |
265 | | - trace!("{}", t!("discovery.commandDiscovery.extensionFound", extension = extension.type_name, version = extension.version)); |
266 | | - // we only keep newest version of the extension so compare the version and only keep the newest |
267 | | - if let Some(existing_extension) = extensions.get_mut(&extension.type_name) { |
268 | | - let Ok(existing_version) = Version::parse(&existing_extension.version) else { |
269 | | - return Err(DscError::Operation(t!("discovery.commandDiscovery.extensionInvalidVersion", extension = existing_extension.type_name, version = existing_extension.version).to_string())); |
270 | | - }; |
271 | | - let Ok(new_version) = Version::parse(&extension.version) else { |
272 | | - return Err(DscError::Operation(t!("discovery.commandDiscovery.extensionInvalidVersion", extension = extension.type_name, version = extension.version).to_string())); |
273 | | - }; |
274 | | - if new_version > existing_version { |
| 261 | + if let Some(resource) = resource { |
| 262 | + match resource { |
| 263 | + ImportedManifest::Extension(extension) => { |
| 264 | + if regex.is_match(&extension.type_name) { |
| 265 | + trace!("{}", t!("discovery.commandDiscovery.extensionFound", extension = extension.type_name, version = extension.version)); |
| 266 | + // we only keep newest version of the extension so compare the version and only keep the newest |
| 267 | + if let Some(existing_extension) = extensions.get_mut(&extension.type_name) { |
| 268 | + let Ok(existing_version) = Version::parse(&existing_extension.version) else { |
| 269 | + return Err(DscError::Operation(t!("discovery.commandDiscovery.extensionInvalidVersion", extension = existing_extension.type_name, version = existing_extension.version).to_string())); |
| 270 | + }; |
| 271 | + let Ok(new_version) = Version::parse(&extension.version) else { |
| 272 | + return Err(DscError::Operation(t!("discovery.commandDiscovery.extensionInvalidVersion", extension = extension.type_name, version = extension.version).to_string())); |
| 273 | + }; |
| 274 | + if new_version > existing_version { |
| 275 | + extensions.insert(extension.type_name.clone(), extension.clone()); |
| 276 | + } |
| 277 | + } else { |
275 | 278 | extensions.insert(extension.type_name.clone(), extension.clone()); |
276 | 279 | } |
277 | | - } else { |
278 | | - extensions.insert(extension.type_name.clone(), extension.clone()); |
279 | 280 | } |
280 | | - } |
281 | | - }, |
282 | | - ImportedManifest::Resource(resource) => { |
283 | | - if regex.is_match(&resource.type_name) { |
284 | | - if let Some(ref manifest) = resource.manifest { |
285 | | - let manifest = import_manifest(manifest.clone())?; |
286 | | - if manifest.kind == Some(Kind::Adapter) { |
287 | | - trace!("{}", t!("discovery.commandDiscovery.adapterFound", adapter = resource.type_name, version = resource.version)); |
288 | | - insert_resource(&mut adapters, &resource); |
| 281 | + }, |
| 282 | + ImportedManifest::Resource(resource) => { |
| 283 | + if regex.is_match(&resource.type_name) { |
| 284 | + if let Some(ref manifest) = resource.manifest { |
| 285 | + let manifest = import_manifest(manifest.clone())?; |
| 286 | + if manifest.kind == Some(Kind::Adapter) { |
| 287 | + trace!("{}", t!("discovery.commandDiscovery.adapterFound", adapter = resource.type_name, version = resource.version)); |
| 288 | + insert_resource(&mut adapters, &resource); |
| 289 | + } |
| 290 | + // also make sure to add adapters as a resource as well |
| 291 | + trace!("{}", t!("discovery.commandDiscovery.resourceFound", resource = resource.type_name, version = resource.version)); |
| 292 | + insert_resource(&mut resources, &resource); |
289 | 293 | } |
290 | | - // also make sure to add adapters as a resource as well |
291 | | - trace!("{}", t!("discovery.commandDiscovery.resourceFound", resource = resource.type_name, version = resource.version)); |
292 | | - insert_resource(&mut resources, &resource); |
293 | 294 | } |
294 | 295 | } |
295 | 296 | } |
@@ -606,35 +607,63 @@ fn insert_resource(resources: &mut BTreeMap<String, Vec<DscResource>>, resource: |
606 | 607 | /// # Errors |
607 | 608 | /// |
608 | 609 | /// * Returns a `DscError` if the manifest could not be loaded or parsed. |
609 | | -pub fn load_manifest(path: &Path) -> Result<ImportedManifest, DscError> { |
| 610 | +pub fn load_manifest(path: &Path) -> Result<Option<ImportedManifest>, DscError> { |
610 | 611 | let contents = fs::read_to_string(path)?; |
611 | 612 | if path.extension() == Some(OsStr::new("json")) { |
612 | 613 | if let Ok(manifest) = serde_json::from_str::<ExtensionManifest>(&contents) { |
| 614 | + if !evaluate_condition(manifest.condition.as_deref())? { |
| 615 | + debug!("{}", t!("discovery.commandDiscovery.conditionNotMet", path = path.to_string_lossy(), condition = manifest.condition.unwrap_or_default())); |
| 616 | + return Ok(None); |
| 617 | + } |
613 | 618 | let extension = load_extension_manifest(path, &manifest)?; |
614 | | - return Ok(ImportedManifest::Extension(extension)); |
| 619 | + return Ok(Some(ImportedManifest::Extension(extension))); |
615 | 620 | } |
616 | 621 | let manifest = match serde_json::from_str::<ResourceManifest>(&contents) { |
617 | 622 | Ok(manifest) => manifest, |
618 | 623 | Err(err) => { |
619 | 624 | return Err(DscError::Manifest(t!("discovery.commandDiscovery.invalidManifest", resource = path.to_string_lossy()).to_string(), err)); |
620 | 625 | } |
621 | 626 | }; |
| 627 | + if !evaluate_condition(manifest.condition.as_deref())? { |
| 628 | + debug!("{}", t!("discovery.commandDiscovery.conditionNotMet", path = path.to_string_lossy(), condition = manifest.condition.unwrap_or_default())); |
| 629 | + return Ok(None); |
| 630 | + } |
622 | 631 | let resource = load_resource_manifest(path, &manifest)?; |
623 | | - return Ok(ImportedManifest::Resource(resource)); |
| 632 | + return Ok(Some(ImportedManifest::Resource(resource))); |
624 | 633 | } |
625 | 634 |
|
626 | 635 | if let Ok(manifest) = serde_yaml::from_str::<ResourceManifest>(&contents) { |
| 636 | + if !evaluate_condition(manifest.condition.as_deref())? { |
| 637 | + debug!("{}", t!("discovery.commandDiscovery.conditionNotMet", path = path.to_string_lossy(), condition = manifest.condition.unwrap_or_default())); |
| 638 | + return Ok(None); |
| 639 | + } |
627 | 640 | let resource = load_resource_manifest(path, &manifest)?; |
628 | | - return Ok(ImportedManifest::Resource(resource)); |
| 641 | + return Ok(Some(ImportedManifest::Resource(resource))); |
629 | 642 | } |
630 | 643 | let manifest = match serde_yaml::from_str::<ExtensionManifest>(&contents) { |
631 | 644 | Ok(manifest) => manifest, |
632 | 645 | Err(err) => { |
633 | 646 | return Err(DscError::Validation(t!("discovery.commandDiscovery.invalidManifest", path = path.to_string_lossy(), err = err).to_string())); |
634 | 647 | } |
635 | 648 | }; |
| 649 | + if !evaluate_condition(manifest.condition.as_deref())? { |
| 650 | + debug!("{}", t!("discovery.commandDiscovery.conditionNotMet", path = path.to_string_lossy(), condition = manifest.condition.unwrap_or_default())); |
| 651 | + return Ok(None); |
| 652 | + } |
636 | 653 | let extension = load_extension_manifest(path, &manifest)?; |
637 | | - Ok(ImportedManifest::Extension(extension)) |
| 654 | + Ok(Some(ImportedManifest::Extension(extension))) |
| 655 | +} |
| 656 | + |
| 657 | +fn evaluate_condition(condition: Option<&str>) -> Result<bool, DscError> { |
| 658 | + if let Some(cond) = condition { |
| 659 | + let mut statement = Statement::new()?; |
| 660 | + let result = statement.parse_and_execute(cond, &Context::new())?; |
| 661 | + if let Some(bool_result) = result.as_bool() { |
| 662 | + return Ok(bool_result); |
| 663 | + } |
| 664 | + return Err(DscError::Validation(t!("discovery.commandDiscovery.conditionNotBoolean", condition = cond).to_string())); |
| 665 | + } |
| 666 | + Ok(true) |
638 | 667 | } |
639 | 668 |
|
640 | 669 | fn load_resource_manifest(path: &Path, manifest: &ResourceManifest) -> Result<DscResource, DscError> { |
|
0 commit comments