def __parse_and_add_extension_settings(settings_node, name, ext_handler, depends_on_level, state=ExtensionState.Enabled): seq_no = getattrib(settings_node, "seqNo") if seq_no in (None, ""): raise ExtensionConfigError("SeqNo not specified for the Extension: {0}".format(name)) try: runtime_settings = json.loads(gettext(settings_node)) except ValueError as error: logger.error("Invalid extension settings: {0}", ustr(error)) # Incase of invalid/no settings, add the name and seqNo of the Extension and treat it as an extension with # no settings since we were able to successfully parse those data properly. Without this, we wont report # anything for that sequence number and CRP would eventually have to timeout rather than fail fast. ext_handler.properties.extensions.append( Extension(name=name, sequenceNumber=seq_no, state=state, dependencyLevel=depends_on_level)) return for plugin_settings_list in runtime_settings["runtimeSettings"]: handler_settings = plugin_settings_list["handlerSettings"] ext = Extension() # There is no "extension name" for single Handler Settings. Use HandlerName for those ext.name = name ext.state = state ext.sequenceNumber = seq_no ext.publicSettings = handler_settings.get("publicSettings") ext.protectedSettings = handler_settings.get("protectedSettings") ext.dependencyLevel = depends_on_level thumbprint = handler_settings.get("protectedSettingsCertThumbprint") ext.certificateThumbprint = thumbprint ext_handler.properties.extensions.append(ext)
def assert_extension_sequence_number( self, # pylint: disable=too-many-arguments patch_get_largest_seq, patch_add_event, goal_state_sequence_number, disk_sequence_number, expected_sequence_number): ext = Extension() ext.sequenceNumber = goal_state_sequence_number patch_get_largest_seq.return_value = disk_sequence_number ext_handler_props = ExtHandlerProperties() ext_handler_props.version = "1.2.3" ext_handler = ExtHandler(name='foo') ext_handler.properties = ext_handler_props instance = ExtHandlerInstance(ext_handler=ext_handler, protocol=None) seq, path = instance.get_status_file_path(ext) try: gs_seq_int = int(goal_state_sequence_number) gs_int = True except ValueError: gs_int = False if gs_int and gs_seq_int != disk_sequence_number: self.assertEqual(1, patch_add_event.call_count) args, kw_args = patch_add_event.call_args # pylint: disable=unused-variable self.assertEqual('SequenceNumberMismatch', kw_args['op']) self.assertEqual(False, kw_args['is_success']) self.assertEqual( 'Goal state: {0}, disk: {1}'.format(gs_seq_int, disk_sequence_number), kw_args['message']) else: self.assertEqual(0, patch_add_event.call_count) self.assertEqual(expected_sequence_number, seq) if seq > -1: self.assertTrue( path.endswith('/foo-1.2.3/status/{0}.status'.format( expected_sequence_number))) else: self.assertIsNone(path)
def assert_extension_sequence_number(self, patch_get_largest_seq=None, goal_state_sequence_number=None, disk_sequence_number=None, expected_sequence_number=None): ext = Extension() ext.sequenceNumber = goal_state_sequence_number patch_get_largest_seq.return_value = disk_sequence_number ext_handler_props = ExtHandlerProperties() ext_handler_props.version = "1.2.3" ext_handler = ExtHandler(name='foo') ext_handler.properties = ext_handler_props instance = ExtHandlerInstance(ext_handler=ext_handler, protocol=None) seq, path = instance.get_status_file_path(ext) self.assertEqual(expected_sequence_number, seq) if seq > -1: self.assertTrue(path.endswith('/foo-1.2.3/status/{0}.status'.format(expected_sequence_number))) else: self.assertIsNone(path)
def assert_extension_sequence_number(self, patch_get_largest_seq, patch_add_event, goal_state_sequence_number, disk_sequence_number, expected_sequence_number): ext = Extension() ext.sequenceNumber = goal_state_sequence_number patch_get_largest_seq.return_value = disk_sequence_number ext_handler_props = ExtHandlerProperties() ext_handler_props.version = "1.2.3" ext_handler = ExtHandler(name='foo') ext_handler.properties = ext_handler_props instance = ExtHandlerInstance(ext_handler=ext_handler, protocol=None) seq, path = instance.get_status_file_path(ext) try: gs_seq_int = int(goal_state_sequence_number) gs_int = True except ValueError: gs_int = False if gs_int and gs_seq_int != disk_sequence_number: self.assertEqual(1, patch_add_event.call_count) args, kw_args = patch_add_event.call_args self.assertEqual('SequenceNumberMismatch', kw_args['op']) self.assertEqual(False, kw_args['is_success']) self.assertEqual('Goal state: {0}, disk: {1}' .format(gs_seq_int, disk_sequence_number), kw_args['message']) else: self.assertEqual(0, patch_add_event.call_count) self.assertEqual(expected_sequence_number, seq) if seq > -1: self.assertTrue(path.endswith('/foo-1.2.3/status/{0}.status'.format(expected_sequence_number))) else: self.assertIsNone(path)
def _parse_plugin_settings(ext_handler, plugin_settings): if plugin_settings is None: return name = ext_handler.name version = ext_handler.properties.version to_lower = lambda str_to_change: str_to_change.lower( ) if str_to_change is not None else None ext_handler_plugin_settings = [ x for x in plugin_settings if to_lower(getattrib(x, "name")) == to_lower(name) ] if not ext_handler_plugin_settings: return settings = [ x for x in ext_handler_plugin_settings if getattrib(x, "version") == version ] if len(settings) != len(ext_handler_plugin_settings): msg = "ExtHandler PluginSettings Version Mismatch! Expected PluginSettings version: {0} for Handler: " \ "{1} but found versions: ({2})".format(version, name, ', '.join( set([getattrib(x, "version") for x in ext_handler_plugin_settings]))) add_event(AGENT_NAME, op=WALAEventOperation.PluginSettingsVersionMismatch, message=msg, log_event=False, is_success=False) if not settings: # If there is no corresponding settings for the specific extension handler, we will not process it at all, # this is an unexpected error as we always expect both versions to be in sync. logger.error(msg) return logger.warn(msg) runtime_settings = None runtime_settings_node = find(settings[0], "RuntimeSettings") seqNo = getattrib(runtime_settings_node, "seqNo") # pylint: disable=C0103 runtime_settings_str = gettext(runtime_settings_node) try: runtime_settings = json.loads(runtime_settings_str) except ValueError as e: # pylint: disable=W0612,C0103 logger.error("Invalid extension settings") return depends_on_level = 0 depends_on_node = find(settings[0], "DependsOn") if depends_on_node != None: # pylint: disable=C0121 try: depends_on_level = int( getattrib(depends_on_node, "dependencyLevel")) except (ValueError, TypeError): logger.warn( "Could not parse dependencyLevel for handler {0}. Setting it to 0" .format(name)) depends_on_level = 0 for plugin_settings_list in runtime_settings["runtimeSettings"]: handler_settings = plugin_settings_list["handlerSettings"] ext = Extension() # There is no "extension name" in wire protocol. # Put ext.name = ext_handler.name ext.sequenceNumber = seqNo ext.publicSettings = handler_settings.get("publicSettings") ext.protectedSettings = handler_settings.get("protectedSettings") ext.dependencyLevel = depends_on_level thumbprint = handler_settings.get( "protectedSettingsCertThumbprint") ext.certificateThumbprint = thumbprint ext_handler.properties.extensions.append(ext)