def decode_option_ps1(self, data, path=None): lines = data.split('\n') # TODO?: refactor below so that it won't break when parameter order of source is different than expected/not sourced from this encoder setting_line = list( filter( lambda l: l.startswith( 'Set-WebConfigurationProperty -Filter "{}" -PSPath "{}" -Name "{}" -Value ' .format( self.filter, path if path else self.default_path, self.name_override if self.name_override else self.name)), lines)) if len(setting_line) > 1: raise SettingRuntimeException( "Found more than one value for registry setting {} in the provided powershel text:\n{}", q(self.name), data) if len(setting_line) < 1: value = self.system_default # If web config settings are not adjusted, the system default value is in effect so long as the site exists else: value = setting_line[0].split()[-1] try: return self.get_value_encoder().decode(value) except ValueError as e: raise SettingRuntimeException( 'Invalid value to decode for setting {}. ' 'Error: {}. Arg: {}'.format(q(self.name), str(e), value))
def validate_data(self, data): if not isinstance(data, list): raise SettingRuntimeException( 'Expected list on input for RangeSetting. ' 'Got {} instead.'.format(q(type(data).__name__))) opts = self.filter_data(data) if len(opts) > 1: raise SettingRuntimeException( 'Received multiple values for setting {}, only one value is allowed ' 'on decode'.format(q(self.name))) if not opts and self.default is None: raise SettingRuntimeException( 'No value found to decode for setting {} and no ' 'default value was configured.'.format(q(self.name))) return opts
def validate_data(self, data): decoded_values = { setting.name: setting.decode_option(data) for setting in self.settings } if sum(decoded_values.values()) > 1: raise SettingRuntimeException( 'There is more than 1 active GC in the input data for setting GCType.' ) if not any(decoded_values.values()) and self.default is None: raise SettingRuntimeException( 'No value found to decode for setting GCType and no ' 'default value was configured.'.format(q(self.name))) return decoded_values
def validate_value(self, value): if value not in self.values: raise SettingRuntimeException( 'Provided value {} for encode is not ' 'one of the available ones: {}.'.format( q(value), ', '.join(self.values))) value = self.values.index(value) value = super().validate_value(value) return value
def decode_option(self, data): if isinstance(data, dict): return self.decode_option_json(data) elif isinstance(data, str): return self.decode_option_ps1(data) else: raise SettingRuntimeException( 'Unrecognized data type passed on decode_option in dotnet encoder setting: {}. ' 'Supported: "dict (loaded json)", "str (powershell script)"'. format(q(data.__class__.__name__)))
def decode_option_json(self, data, path=None): """ Decodes dict of primitive values back into single primitive value. :param data: dict of setting values for the given path and filter of the current setting class :param path: path string from parent WebConfigSetting config_list :return: Single primitive value """ if path is None: path = self.default_path wc = data.get("WebConfig") # NOTE: because json structure is used during adjust as validation, it is built to be more fail-deadly # as these failures would indicate the describe data is misformatted. When describe.ps1 is up to date, webconfig values will always # be present in describe json even if they haven't been adjusted yet if not wc: raise SettingRuntimeException( "WebConfig dict for path:setting {}:{} was not found in describe data" .format(path, self.name)) if not isinstance(wc, dict): raise SettingRuntimeException( 'Describe WebConfig data {} must have its value be a dict. ' 'It is currently {}.'.format(q(self.name), wc.__class__.__name__)) if len(wc) < 0: raise SettingRuntimeException( "WebConfig dict for path:setting {}:{} was found but had no key values" .format(path, self.name)) name_locator = self.name_override if self.name_override else self.name try: value = wc[path][self.filter][name_locator] except KeyError: raise SettingRuntimeException( "Unable to located value of setting in path '{}' under filter '{}' by name(_override) '{}'" " within the describe data provided".format( path, self.filter, name_locator)) try: return self.get_value_encoder().decode(value) except ValueError as e: raise SettingRuntimeException( 'Invalid value to decode for setting {}. ' 'Error: {}. Arg: {}'.format(q(self.name), str(e), value))
def decode_option(self, data): if not isinstance(data, dict): raise SettingRuntimeException( 'Unrecognized data type passed on decode_option in nameval encoder setting type: {}. ' 'Supported: "dict (parsed multiline file)"'.format( q(data.__class__.__name__))) value = data.get(self.name) if value is None: return self.config['default'] return value
def decode_option_json(self, data): """ Decodes describe data dict back into single primitive value of the current setting. :param data: dict of describe data :return: Single primitive value """ # NOTE: because json structure is used during adjust as validation, it is built to be more fail-deadly # as these failures would indicate an out of date describe.ps1 reg = data.get(self.path, None) if not reg: raise SettingRuntimeException( "Registry path {} for setting {} was not found in describe data" .format(self.path, self.name)) # NOTE: Until registry options are set, getting the registry path will return no keys but each of the settings does have a system default value # which will be considered to be in effect in cases where the path in data has no keys value = reg.get(self.name, self.system_default) try: return self.get_value_encoder().decode(value) except ValueError as e: raise SettingRuntimeException( 'Invalid value to decode for setting {}. ' 'Error: {}. Arg: {}'.format(q(self.name), str(e), value))
def decode_option(self, data): """ Decodes list of primitive values back into single primitive value. :param data: List of multiple primitive values :return: Single primitive value """ opts = self.validate_data(data) if opts: opt = opts[0] value = self.get_format_match(opt).groups()[0] try: return self.get_value_encoder().decode(value) except ValueError as e: raise SettingRuntimeException( 'Invalid value to decode for setting {}. ' 'Error: {}. Arg: {}'.format(q(self.name), str(e), opt)) return self.default
def validate_value(self, value): if value not in self.config['values']: raise SettingRuntimeException( 'Value provided for setting {} was not contained in configured values. ' 'Value: {}.'.format(q(self.name), q(value)))