def admin_operation(oi_handle, c_invocation_id, c_name, c_operation_id, c_params): ''' Callback for administrative operations ''' # Unmarshal parameters invocation_id = c_invocation_id name = saImm.unmarshalSaImmValue(c_name, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) operation_id = c_operation_id params = [] for param in saAis.unmarshalNullArray(c_params): param_name = param.paramName param_type = param.paramType param_buffer = param.paramBuffer value = saImm.unmarshalSaImmValue(param_buffer, param_type) parameter = AdminOperationParameter(param_name, param_type, value) params.append(parameter) # Invoke the operation result = implementer_instance.admin_operation(operation_id, name, params) # Report the result try: immoi.report_admin_operation_result(invocation_id, result) except SafException as err: print "ERROR: Failed to report that %s::%s returned %s (%s)" % \ (name, invocation_id, result, err.msg)
def attr_update(oi_handle, c_name, c_attr_names): ''' Callback for attribute update calls from IMM ''' # Unmarshall parameters name = saImm.unmarshalSaImmValue(c_name, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) attr_names = saAis.unmarshalNullArray(c_attr_names) # Get the class of the object class_name = immoi.get_class_name_for_dn(name) # Get the values from the user and report back attributes = {} for attr_name in attr_names: values = implementer_instance.on_runtime_values_get(name, class_name, attr_name) if values is None: return eSaAisErrorT.SA_AIS_ERR_UNAVAILABLE if not isinstance(values, list): values = [values] attributes[attr_name] = values # Report the updated values for the attributes try: immoi.update_rt_object(name, attributes) return eSaAisErrorT.SA_AIS_OK except SafException: return eSaAisErrorT.SA_AIS_ERR_FAILED_OPERATION
def unmarshal_len_array(c_array, length, value_type): """ Convert C array with a known length to a Python list Args: c_array (C array): Array in C length (int): Length of array value_type (str): Element type in array Returns: list: The list converted from c_array """ if not c_array: return [] ctype = c_array[0].__class__ if ctype is str or (PY3 and ctype is SaStringT): return unmarshalSaStringTArray(c_array) val_list = [] i = 0 for ptr in c_array: if i == length: break if not ptr: break val = unmarshalSaImmValue(ptr, value_type) val_list.append(val) i = i + 1 return val_list
def _ccb_delete_callback(self, oi_handle, ccb_id, c_name): """ Callback for object delete operation Args: oi_handle (SaImmOiHandleT): OI handle ccb_id (SaImmOiCcbIdT): CCB id c_name (SaNameT): Pointer to object name Returns: SaAisErrorT: Return code of the object delete callback """ # Unmarshal the parameters name = \ saImm.unmarshalSaImmValue(c_name, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) # Create a new CCB in the cache if needed if ccb_id not in list(self.ccbs.keys()): self.ccbs[ccb_id] = [] # Cache the operation self.ccbs[ccb_id].append({'type': 'DELETE', 'dn': name}) # Tell the implementer about the operation return self.on_delete_added(name)
def next(self): name = SaNameT() attributes = pointer(pointer(SaImmAttrValuesT_2())) try: immom.saImmOmSearchNext_2(self.search_handle, name, attributes) except SafException as err: if err.value == eSaAisErrorT.SA_AIS_ERR_NOT_EXIST: raise StopIteration else: raise err attribs = {} attr_list = unmarshalNullArray(attributes) for attr in attr_list: attr_range = range(attr.attrValuesNumber) attribs[attr.attrName] = [ attr.attrValueType, [ unmarshalSaImmValue(attr.attrValues[val], attr.attrValueType) for val in attr_range ] ] return ImmObject(name.value, attribs)
def get(self, object_name, attr_name_list=None, class_name=None): """ Obtain values of some attributes of the given object Args: object_name (str): Object name attr_name_list (list): List of attributes class_name (str): Class name Returns: SaAisErrorT: Return code of the corresponding IMM API call(s) ImmObject: Imm object """ imm_obj = None # Always request the SaImmAttrClassName attribute if needed if attr_name_list and not class_name \ and 'SaImmAttrClassName' not in attr_name_list \ and not attr_name_list == \ ['SA_IMM_SEARCH_GET_CONFIG_ATTR']: attr_name_list.append('SaImmAttrClassName') attr_names = [SaImmAttrNameT(attr) for attr in attr_name_list] \ if attr_name_list else None attributes = pointer(pointer(SaImmAttrValuesT_2())) rc = agent.saImmOmAccessorGet_2(self.accessor_handle, SaNameT(object_name), attr_names, attributes) if rc == eSaAisErrorT.SA_AIS_OK: attrs = {} attr_list = unmarshalNullArray(attributes) for attr in attr_list: attr_range = list(range(attr.attrValuesNumber)) attrs[attr.attrName] = [ attr.attrValueType, [ unmarshalSaImmValue(attr.attrValues[val], attr.attrValueType) for val in attr_range ] ] if 'SaImmAttrClassName' not in attrs and class_name: attrs['SaImmAttrClassName'] = class_name imm_obj = ImmObject(dn=object_name, attributes=attrs) if rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE: init_rc = self.init() # If the re-initialization of agent handle succeeds, we still need # to return BAD_HANDLE to the users, so that they would re-try the # failed operation. Otherwise, the true error code is returned # to the user to decide further actions. if init_rc != eSaAisErrorT.SA_AIS_OK: log_err("saImmOmAccessorGet_2 FAILED - %s" % eSaAisErrorT.whatis(rc)) rc = init_rc return rc, imm_obj
def _ccb_modify_callback(self, oi_handle, ccb_id, c_name, c_attr_modification): """ Callback for object modify operation Args: oi_handle (SaImmOiHandleT): OI handle ccb_id (SaImmOiCcbIdT): CCB id c_name (SaNameT): Pointer to object name c_attr_modification (SaImmAttrModificationT_2): Pointer to an array of pointers to descriptors of the modifications to perform Returns: SaAisErrorT: Return code of the object modify callback """ # Unmarshal the parameters name = \ saImm.unmarshalSaImmValue(c_name, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) attribute_modifications = [] implementer_objection = None for attr in unmarshalNullArray(c_attr_modification): attr_name = attr.modAttr.attrName attr_type = attr.modAttr.attrValueType mod_type = attr.modType attr_values = self.unmarshal_len_array( attr.modAttr.attrValues, attr.modAttr.attrValuesNumber, attr.modAttr.attrValueType) attribute_modifications.append({ 'attribute': attr_name, 'type': attr_type, 'modification': mod_type, 'values': attr_values }) # Tell the implementer about the modification result = self.on_modify_added(attr_name, mod_type, attr_values) if result != eSaAisErrorT.SA_AIS_OK: implementer_objection = result # Create a new CCB in the cache if needed if ccb_id not in list(self.ccbs.keys()): self.ccbs[ccb_id] = [] # Store the modifications in the cache self.ccbs[ccb_id].append({ 'type': 'MODIFY', 'dn': name, 'modification': attribute_modifications }) # Respond and say if this is accepted by the implementer if implementer_objection: return implementer_objection return eSaAisErrorT.SA_AIS_OK
def _ccb_create_callback(self, oi_handle, ccb_id, class_name, c_parent, c_attr_values): """ Callback for object create operation Args: oi_handle (SaImmOiHandleT): OI handle ccb_id (SaImmOiCcbIdT): CCB id class_name (SaImmClassNameT): Class name c_parent (SaNameT): Pointer to name of object's parent c_attr_values (SaImmAttrValuesT_2): Pointer to an array of pointers to attribute descriptors Returns: SaAisErrorT: Return code of the object create callback """ # Unmarshal parameters parent = saImm.unmarshalSaImmValue( c_parent, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) attributes = {} for attr in unmarshalNullArray(c_attr_values): attr_name = attr.attrName attr_type = attr.attrValueType nr_values = attr.attrValuesNumber attr_values = self.unmarshal_len_array(attr.attrValues, nr_values, attr_type) if attr_values: attributes[attr_name] = attr_values else: attributes[attr_name] = None # Fill in any missing attributes _, description = self.imm_om.get_class_description(class_name) for attribute in description: if attribute.attrName not in attributes: attributes[attribute.attrName] = None # Create a new CCB in the cache if needed if ccb_id not in list(self.ccbs.keys()): self.ccbs[ccb_id] = [] # Cache the create operation self.ccbs[ccb_id].append({ 'type': 'CREATE', 'parent': parent, 'className': class_name, 'attributes': attributes }) # Tell the implementer about the operation obj = self.create_non_existing_imm_object(class_name, parent, attributes) return self.on_create_added(class_name, parent, obj)
def _admin_operation_callback(self, oi_handle, c_invocation_id, c_name, c_operation_id, c_params): """ Callback for administrative operations Args: oi_handle (SaImmOiHandleT): OI handle c_invocation_id (SaInvocationT): Invocation id c_name (SaNameT): Pointer to object name c_operation_id (SaImmAdminOperationIdT): Operation id c_params (SaImmAdminOperationParamsT_2): Pointer to an array of pointers to parameter descriptors """ # Unmarshal parameters invocation_id = c_invocation_id name = \ saImm.unmarshalSaImmValue(c_name, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) operation_id = c_operation_id params = [] for param in unmarshalNullArray(c_params): param_name = param.paramName param_type = param.paramType param_buffer = param.paramBuffer value = saImm.unmarshalSaImmValue(param_buffer, param_type) parameter = AdminOperationParameter(param_name, param_type, value) params.append(parameter) # Invoke the operation result = self.admin_operation(operation_id, name, params) # Report the result try: self.report_admin_operation_result(invocation_id, result) except SafException as err: print("ERROR: Failed to report that %s::%s returned %s (%s)" % (name, invocation_id, result, err.msg))
def __init__(self, dn, attribs, numeric=False): self.dn = dn self.attribs = {} attrList = unmarshalNullArray(attribs) for attr in attrList: attrRange = range(attr.attrValuesNumber) self.attribs[attr.attrName] = [ saImm.eSaImmValueTypeT.whatis(attr.attrValueType), [ saImm.unmarshalSaImmValue(attr.attrValues[val], attr.attrValueType) for val in attrRange ] ] if not numeric: SafObject.resolveStates(self.attribs)
def modify_added(oi_handle, c_ccb_id, c_name, c_attr_modification): ''' Callback for object modify ''' # Unmarshal the parameters name = saImm.unmarshalSaImmValue(c_name, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) ccb_id = c_ccb_id attribute_modifications = [] implementer_objection = None for attr in saAis.unmarshalNullArray(c_attr_modification): attr_name = attr.modAttr.attrName attr_type = attr.modAttr.attrValueType mod_type = attr.modType attr_values = immoi.unmarshall_len_array(attr.modAttr.attrValues, attr.modAttr.attrValuesNumber, attr.modAttr.attrValueType) attribute_modifications.append({'attribute' : attr_name, 'type' : attr_type, 'modification' : mod_type, 'values' : attr_values}) # Tell the implementer about the modification result = implementer_instance.on_modify_added(attr_name, mod_type, attr_values) if result != eSaAisErrorT.SA_AIS_OK: implementer_objection = result # Create a new CCB in the cache if needed if not ccb_id in CCBS.keys(): CCBS[ccb_id] = [] # Store the modifications in the cache CCBS[ccb_id].append({'type' : 'MODIFY', 'dn' : name, 'modification' : attribute_modifications}) # Respond and say if this is accepted by the implementer if implementer_objection: return implementer_objection else: return eSaAisErrorT.SA_AIS_OK
def delete_added(oi_handle, ccb_id, c_name): ''' Callback for object delete ''' # Unmarshall the parameters name = saImm.unmarshalSaImmValue(c_name, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) # Create a new CCB in the cache if needed if not ccb_id in CCBS.keys(): CCBS[ccb_id] = [] # Cache the operation CCBS[ccb_id].append({'type' : 'DELETE', 'dn' : name}) # Tell the implementer about the operation return implementer_instance.on_delete_added(name)
def create_added(oi_handle, c_ccb_id, c_class_name, c_parent, c_attr_values): ''' Callback for object create ''' # Unmarshal parameters parent = saImm.unmarshalSaImmValue(c_parent, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) class_name = c_class_name ccb_id = c_ccb_id attributes = {} for attr in saAis.unmarshalNullArray(c_attr_values): attr_name = attr.attrName attr_type = attr.attrValueType nr_values = attr.attrValuesNumber attr_values = immoi.unmarshall_len_array(attr.attrValues, nr_values, attr_type) if len(attr_values) > 0: attributes[attr_name] = attr_values else: attributes[attr_name] = None # Fill in any missing attributes description = immom.class_description_get(class_name) for attribute in description: if not attribute.attrName in attributes: attributes[attribute.attrName] = None # Create a new CCB in the cache if needed if not ccb_id in CCBS.keys(): CCBS[ccb_id] = [] # Cache the create operation CCBS[ccb_id].append({'type' : 'CREATE', 'parent' : parent, 'className' : class_name, 'attributes' : attributes}) # Tell the implementer about the operation obj = immoi.create_non_existing_imm_object(class_name, parent, attributes) return implementer_instance.on_create_added(class_name, parent, obj)
def __next__(self): obj_name = SaNameT() attributes = pointer(pointer(SaImmAttrValuesT_2())) rc = agent.saImmOmSearchNext_2(self.search_handle, obj_name, attributes) if rc != eSaAisErrorT.SA_AIS_OK: if rc != eSaAisErrorT.SA_AIS_ERR_NOT_EXIST: log_err("saImmOmSearchNext_2 FAILED - %s" % eSaAisErrorT.whatis(rc)) raise StopIteration attrs = {} attr_list = unmarshalNullArray(attributes) for attr in attr_list: attr_range = list(range(attr.attrValuesNumber)) attrs[attr.attrName] = [attr.attrValueType, [unmarshalSaImmValue(attr.attrValues[val], attr.attrValueType) for val in attr_range]] return ImmObject(str(obj_name), attrs)
def next(self): name = SaNameT() attributes = pointer(pointer(SaImmAttrValuesT_2())) error = saImmOm.saImmOmSearchNext_2(self.search_handle, name, attributes) if error == eSaAisErrorT.SA_AIS_ERR_NOT_EXIST: raise StopIteration elif error != eSaAisErrorT.SA_AIS_OK: raise SafException(error) attribs = {} attr_list = unmarshalNullArray(attributes) for attr in attr_list: attr_range = range(attr.attrValuesNumber) attribs[attr.attrName] = [attr.attrValueType, [unmarshalSaImmValue( attr.attrValues[val], attr.attrValueType) for val in attr_range] ] return ImmObject(name.value, attribs)
def get(object_name, attr_name_list=None): ''' obtain values of some attributes of the specified object ''' attrib_names = [SaImmAttrNameT(a) for a in attr_name_list]\ if attr_name_list else None attributes = pointer(pointer(SaImmAttrValuesT_2())) one_sec_sleeps = 0 err = saImmOm.saImmOmAccessorGet_2(ACCESSOR_HANDLE, SaNameT(object_name), attrib_names, attributes) while err == eSaAisErrorT.SA_AIS_ERR_TRY_AGAIN: if one_sec_sleeps == TRYAGAIN_CNT: break time.sleep(1) one_sec_sleeps += 1 err = saImmOm.saImmOmAccessorGet_2(ACCESSOR_HANDLE, SaNameT(object_name), attrib_names, attributes) if err == eSaAisErrorT.SA_AIS_ERR_NOT_EXIST: return None if err != eSaAisErrorT.SA_AIS_OK: raise SafException(err, "saImmOmInitialize: %s" % eSaAisErrorT.whatis(err)) attribs = {} attr_list = unmarshalNullArray(attributes) for attr in attr_list: attr_range = range(attr.attrValuesNumber) attribs[attr.attrName] = [ attr.attrValueType, [unmarshalSaImmValue( attr.attrValues[val], attr.attrValueType) for val in attr_range] ] return ImmObject(object_name, attribs)
def get(object_name, attr_name_list=None, class_name=None): ''' obtain values of some attributes of the specified object ''' # Always request the SaImmAttrClassName attribute if needed if attr_name_list and \ not class_name and \ not 'SaImmAttrClassName' in attr_name_list and \ not attr_name_list == ['SA_IMM_SEARCH_GET_CONFIG_ATTR']: attr_name_list.append('SaImmAttrClassName') attrib_names = [SaImmAttrNameT(a) for a in attr_name_list]\ if attr_name_list else None attributes = pointer(pointer(SaImmAttrValuesT_2())) try: err = saImmOmAccessorGet_2(ACCESSOR_HANDLE, SaNameT(object_name), attrib_names, attributes) except SafException as err: if err.value == eSaAisErrorT.SA_AIS_ERR_NOT_EXIST: return None else: raise err attribs = {} attr_list = unmarshalNullArray(attributes) for attr in attr_list: attr_range = range(attr.attrValuesNumber) attribs[attr.attrName] = [ attr.attrValueType, [ unmarshalSaImmValue(attr.attrValues[val], attr.attrValueType) for val in attr_range ] ] if not 'SaImmAttrClassName' in attribs and class_name: attribs['SaImmAttrClassName'] = class_name return ImmObject(object_name, attribs)
def _attr_update_callback(self, oi_handle, c_name, c_attr_names): """ Callback for attribute update operation Args: oi_handle (SaImmOiHandleT): OI handle c_name (SaNameT): Pointer to object name c_attr_names (SaImmAttrNameT): Pointer to array of attribute names Returns: SaAisErrorT: Return code of the attribute update callback """ # Unmarshal parameters name = \ saImm.unmarshalSaImmValue(c_name, eSaImmValueTypeT.SA_IMM_ATTR_SANAMET) attr_names = unmarshalNullArray(c_attr_names) # Get the class of the object class_name = self.get_class_name_for_dn(dn=name) # Get the values from the user and report back attributes = {} for attr_name in attr_names: values = self.on_runtime_values_get(name, class_name, attr_name) if values is None: return eSaAisErrorT.SA_AIS_ERR_UNAVAILABLE if not isinstance(values, list): values = [values] attributes[attr_name] = values # Report the updated values for the attributes try: self.update_runtime_object(name, attributes) return eSaAisErrorT.SA_AIS_OK except SafException: return eSaAisErrorT.SA_AIS_ERR_FAILED_OPERATION
def unmarshall_len_array(c_array, length, value_type): ''' Convert c array with a known length to a Python list. ''' if not c_array: return [] ctype = c_array[0].__class__ if ctype is str: return unmarshalSaStringTArray(c_array) val_list = [] i = 0 for ptr in c_array: if i == length: break if not ptr: break val = unmarshalSaImmValue(ptr, value_type) val_list.append(val) i = i + 1 return val_list