11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4- use crate :: configure:: config_doc:: { ExecutionKind , Metadata , Resource , Parameter } ;
54use crate :: configure:: context:: { Context , ProcessMode } ;
6- use crate :: configure:: { config_doc:: RestartRequired , parameters:: Input } ;
5+ use crate :: configure:: { config_doc:: { ExecutionKind , Metadata , Parameter , Resource , RestartRequired , ValueOrCopy } , parameters:: Input } ;
76use crate :: discovery:: discovery_trait:: DiscoveryFilter ;
87use crate :: dscerror:: DscError ;
98use crate :: dscresources:: {
@@ -413,6 +412,10 @@ impl Configurator {
413412 result. metadata = Some (
414413 self . get_result_metadata ( Operation :: Get )
415414 ) ;
415+ self . process_output ( ) ?;
416+ if !self . context . outputs . is_empty ( ) {
417+ result. outputs = Some ( self . context . outputs . clone ( ) ) ;
418+ }
416419 Ok ( result)
417420 }
418421
@@ -584,6 +587,10 @@ impl Configurator {
584587 result. metadata = Some (
585588 self . get_result_metadata ( Operation :: Set )
586589 ) ;
590+ self . process_output ( ) ?;
591+ if !self . context . outputs . is_empty ( ) {
592+ result. outputs = Some ( self . context . outputs . clone ( ) ) ;
593+ }
587594 Ok ( result)
588595 }
589596
@@ -662,6 +669,10 @@ impl Configurator {
662669 result. metadata = Some (
663670 self . get_result_metadata ( Operation :: Test )
664671 ) ;
672+ self . process_output ( ) ?;
673+ if !self . context . outputs . is_empty ( ) {
674+ result. outputs = Some ( self . context . outputs . clone ( ) ) ;
675+ }
665676 Ok ( result)
666677 }
667678
@@ -724,6 +735,10 @@ impl Configurator {
724735 }
725736
726737 result. result = Some ( conf) ;
738+ self . process_output ( ) ?;
739+ if !self . context . outputs . is_empty ( ) {
740+ result. outputs = Some ( self . context . outputs . clone ( ) ) ;
741+ }
727742 Ok ( result)
728743 }
729744
@@ -738,6 +753,46 @@ impl Configurator {
738753 Ok ( false )
739754 }
740755
756+ pub fn process_output ( & mut self ) -> Result < ( ) , DscError > {
757+ if self . config . outputs . is_none ( ) || self . context . execution_type == ExecutionKind :: WhatIf {
758+ return Ok ( ( ) ) ;
759+ }
760+ if let Some ( outputs) = & self . config . outputs {
761+ for ( name, output) in outputs {
762+ if let Some ( condition) = & output. condition {
763+ let condition_result = self . statement_parser . parse_and_execute ( condition, & self . context ) ?;
764+ if condition_result != Value :: Bool ( true ) {
765+ info ! ( "{}" , t!( "configure.mod.skippingOutput" , name = name) ) ;
766+ continue ;
767+ }
768+ }
769+
770+ match & output. value_or_copy {
771+ ValueOrCopy :: Value ( value) => {
772+ let value_result = self . statement_parser . parse_and_execute ( & value, & self . context ) ?;
773+ if output. r#type == DataType :: SecureString || output. r#type == DataType :: SecureObject {
774+ warn ! ( "{}" , t!( "configure.mod.secureOutputSkipped" , name = name) ) ;
775+ continue ;
776+ }
777+ if value_result. is_string ( ) && output. r#type != DataType :: String ||
778+ value_result. is_i64 ( ) && output. r#type != DataType :: Int ||
779+ value_result. is_boolean ( ) && output. r#type != DataType :: Bool ||
780+ value_result. is_array ( ) && output. r#type != DataType :: Array ||
781+ value_result. is_object ( ) && output. r#type != DataType :: Object {
782+ return Err ( DscError :: Validation ( t ! ( "configure.mod.outputTypeNotMatch" , name = name, expected_type = output. r#type) . to_string ( ) ) ) ;
783+ }
784+ self . context . outputs . insert ( name. clone ( ) , value_result) ;
785+ } ,
786+ _ => {
787+ warn ! ( "{}" , t!( "configure.mod.copyNotSupported" , name = name) ) ;
788+ continue ;
789+ }
790+ }
791+ }
792+ }
793+ Ok ( ( ) )
794+ }
795+
741796 /// Set the mounted path for the configuration.
742797 ///
743798 /// # Arguments
@@ -779,7 +834,7 @@ impl Configurator {
779834 if let Some ( parameters_input) = parameters_input {
780835 trace ! ( "parameters_input: {parameters_input}" ) ;
781836 let input_parameters: HashMap < String , Value > = serde_json:: from_value :: < Input > ( parameters_input. clone ( ) ) ?. parameters ;
782-
837+
783838 for ( name, value) in input_parameters {
784839 if let Some ( constraint) = parameters. get ( & name) {
785840 debug ! ( "Validating parameter '{name}'" ) ;
@@ -818,7 +873,7 @@ impl Configurator {
818873
819874 while !unresolved_parameters. is_empty ( ) {
820875 let mut resolved_in_this_pass = Vec :: new ( ) ;
821-
876+
822877 for ( name, parameter) in & unresolved_parameters {
823878 debug ! ( "{}" , t!( "configure.mod.processingParameter" , name = name) ) ;
824879 if let Some ( default_value) = & parameter. default_value {
0 commit comments