def ldap_role_group_delete_all(handle): """ Delete all the ldap role groups Args: handle (ImcHandle) Returns: None Examples: ldap_role_group_delete_all(handle) """ api = 'ldap_role_group_delete_all' dn_to_group_dict = {} mos = [] groups = handle.query_classid('AaaLdapRoleGroup') for group in groups: if not group.name and not group.domain: continue group.admin_action = 'clear' mos.append(group) dn_to_group_dict[group.dn] = group.name ret = [] response = handle.set_mos(mos) if response: ret = process_conf_mos_response(response, api, False, "Delete LDAP groups failed", ldap_role_group_callback, dn_to_group_dict) if len(ret) != 0: error_msg = 'Delete LDAP groups failed:\n' for item in ret: object = item["Object"] error = item["Error"] error = sanitize_message(error) error_msg += object + ": " + error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) results = {} results["changed"] = True results["msg"] = "" results["msg_params"] = ret return results
def _process_response(response, api, callback, dn_to_vd_dict): ret = process_conf_mos_response(response, api, False, 'sd card config set m5', callback, dn_to_vd_dict) if len(ret) != 0: error_msg = 'cannot enable/disable virtual drive:\n' for item in ret: obj = item["Object"] error = item["Error"] error = sanitize_message(error) error_msg += "[virtual drive " + obj + "] " + error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) results = {} results["changed"] = True results["msg"] = "" results["msg_params"] = ret return results
def _process_response(response, api, error_msg, callback=None, *cbargs): callback_params = [] if callback is not None: callback_params = [callback] callback_params.extend(cbargs) ret = process_conf_mos_response(response, api, False, error_msg, *callback_params) error_msg += "\n" if len(ret) != 0: for item in ret: obj = item["Object"] error_msg += "%s: " % obj error = item["Error"] error = sanitize_message(error) error_msg += error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) return ret
def snmp_user_add_all(handle, users=None): """ Adds snmp user. Args: handle (ImcHandle) users (list): list of user dict keys: name (string): snmp username security_level (string): "authpriv", "authnopriv", "noauthnopriv" auth (string): "MD5", "SHA" auth_pwd (string): password for existing user privacy (string): "AES", "DES" privacy_pwd (string): privacy password for existing user example: [{'name': 'snmpuser', 'security_level': 'authpriv', 'auth': 'MD5', 'auth_pwd': 'password', 'privacy': 'AES', 'privacy_pwd': 'password'} ] Returns: list: List of CommSnmpUser Managed Object Raises: ImcOperationError is maximum number of users already configured Example: snmp_user_add_all( handle, users = [{'name': 'snmpuser', 'security_level': 'authpriv', 'auth': 'MD5', 'auth_pwd': 'password', 'privacy': 'AES', 'privacy_pwd': 'password']) """ from imcsdk.mometa.comm.CommSnmpUser import CommSnmpUser from imcsdk.mometa.comm.CommSnmpUser import CommSnmpUserConsts from imcsdk.mometa.comm.CommSnmp import CommSnmpConsts api = 'snmp_user_add_all' parent_mo = _get_mo(handle, dn=SNMP_DN) if parent_mo.admin_state != CommSnmpConsts.ADMIN_STATE_ENABLED: raise ImcOperationError(api, 'SNMP is not enabled.') dn_to_user_dict = {} mos = [] id = 0 for user in users: name = user.pop('name', None) security_level = user.pop('security_level', None) _validate_api_prop('name', name, api) _validate_api_prop('security_level', security_level, api) auth = user.pop('auth', None) auth_pwd = user.pop('auth_pwd', None) privacy = user.pop('privacy', None) privacy_pwd = user.pop('privacy_pwd', None) params = { 'name': name, 'security_level': security_level } if security_level == CommSnmpUserConsts.SECURITY_LEVEL_AUTHNOPRIV: #_validate_api_prop('auth', auth, api, True, ['MD5', 'SHA']) _validate_api_prop('auth_pwd', auth_pwd, api) params['auth'] = auth params['auth_pwd'] = auth_pwd elif security_level == CommSnmpUserConsts.SECURITY_LEVEL_AUTHPRIV: _validate_api_prop('auth', auth, api, True, ['MD5', 'SHA']) _validate_api_prop('auth_pwd', auth_pwd, api) _validate_api_prop('privacy', privacy, api, True, ['AES', 'DES']) _validate_api_prop('privacy_pwd', privacy_pwd, api) params['auth'] = auth params['auth_pwd'] = auth_pwd params['privacy'] = privacy params['privacy_pwd'] = privacy_pwd id += 1 mo = CommSnmpUser(parent_mo_or_dn=parent_mo, id=str(id)) mo.set_prop_multiple(**params) mos.append(mo) dn_to_user_dict[mo.dn] = mo.name response = handle.set_mos(mos) if response: ret = process_conf_mos_response(response, api, False, 'Create SNMP users failed', snmp_users_callback, dn_to_user_dict) if len(ret) != 0: error_msg = 'Create/Update SNMP users failed:\n' for item in ret: obj = item["Object"] error = item["Error"] error = sanitize_message(error) error_msg += "[User " + obj + "] " + error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) results = {} results["changed"] = True results["msg"] = "" results["msg_params"] = ret return results
def snmp_trap_add_all(handle, traps=None): """ Adds snmp trap. Args: handle (ImcHandle) traps (list): list of trap dict keys: hostname (string): ip address admin_state (string): enabled, disabled version (string): "v2c", "v3" notification_type (string): "informs", "traps" Required only for version "v2c" and "v3" user (string): send traps for a specific user port (int): port Returns: list: List of CommSnmpTrap Managed Object Example: snmp_trap_add_all(handle, traps=[{hostname: "10.10.10.10", port: "162", version:"v2c", notification_type:"informs"}] ) """ from imcsdk.mometa.comm.CommSnmp import CommSnmpConsts from imcsdk.mometa.comm.CommSnmpTrap import CommSnmpTrap from imcsdk.mometa.comm.CommSnmpTrap import CommSnmpTrapConsts api = 'snmp_trap_add_all' parent_mo = _get_mo(handle, dn=SNMP_DN) if parent_mo.admin_state != CommSnmpConsts.ADMIN_STATE_ENABLED: raise ImcOperationError(api, 'SNMP is not enabled.') dn_to_trap_dict = {} mos = [] id = 0 for trap in traps: hostname = trap.pop('hostname', None) _validate_api_prop('hostname', hostname, api) version = trap.pop('version', None) _validate_api_prop('version', version, api, True, [CommSnmpTrapConsts.VERSION_V1, CommSnmpTrapConsts.VERSION_V2C, CommSnmpTrapConsts.VERSION_V3]) notification_type = trap.pop('notification_type', None) _validate_api_prop('notification_type', notification_type, api, True, [CommSnmpTrapConsts.NOTIFICATION_TYPE_INFORMS, CommSnmpTrapConsts.NOTIFICATION_TYPE_TRAPS]) admin_state = trap.pop('admin_state', 'enabled') _validate_api_prop('admin_state', admin_state, api, True, [CommSnmpTrapConsts.ADMIN_STATE_ENABLED, CommSnmpTrapConsts.ADMIN_STATE_DISABLED]) user = trap.pop('user', None) port = trap.pop('port', None) if version == CommSnmpTrapConsts.VERSION_V2C and user: user = None if version == CommSnmpTrapConsts.VERSION_V3: notification_type = CommSnmpTrapConsts.NOTIFICATION_TYPE_TRAPS params = { 'hostname': hostname, 'version': version, 'notification_type': notification_type, 'admin_state': admin_state, 'port': str(port) if port else None, 'user': user } id += 1 mo = CommSnmpTrap(parent_mo_or_dn=parent_mo, id=str(id)) mo.set_prop_multiple(**params) mos.append(mo) dn_to_trap_dict[mo.dn] = mo.hostname response = handle.set_mos(mos) if response: ret = process_conf_mos_response(response, api, False, 'Create SNMP traps failed', snmp_traps_callback, dn_to_trap_dict) if len(ret) != 0: error_msg = 'Create/Update SNMP traps failed:\n' for item in ret: obj = item["Object"] error = item["Error"] error = sanitize_message(error) error_msg += "[Trap " + obj + "] " + error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) results = {} results["changed"] = True results["msg"] = "" results["msg_params"] = ret return results
def vmedia_mount_create_all(handle, mappings = None, server_id=1, timeout=60): """ This method will make one request to create all the vmedia mappings Args: handle (ImcHandle) mappings (list): list of mappings dict keys: volume_name (string): Name of the volume or identity of the image map (string): "cifs", "nfs", "www" mount_options (string): Options to be passed while mounting the image remote_share (string): URI of the image remote_file (string): name of the image username (string): username password (string): password server_id (int): Server Id to be specified for C3260 platforms Returns: List of CommVMediaMap object Examples: vmedia_mount_create_all( handle, mappings=[{volume_name: "A", map: "www" mount_options: "ro" remote_share: "http://10.10.10.20/test/" remote_file: "a.iso" username: "" password: ""}] ) """ api = 'vmedia_mount_create_all' mos = [] dn_to_vmedia_dict = {} for mapping in mappings: volume_name = mapping.get('volume_name') map = mapping.get('map') remote_share = mapping.get('remote_share') remote_file = mapping.get('remote_file') _validate_api_prop('volume_name', volume_name, api) _validate_api_prop('map',map, api) _validate_api_prop('remote_share', remote_share, api) _validate_api_prop('remote_file', remote_file,api) params = { 'map': map, 'remote_file': remote_file, 'remote_share': remote_share } if mapping.get('mount_options'): params['mount_options'] = mapping.get('mount_options') if map != CommVMediaMapConsts.MAP_NFS: mount_options = mapping.get('mount_options') #In CIMC, security context authentication protocol for CIFS Share, is always set to "ntlm" by default. #If authentication protocol is set to none, CIMC rejects the mapping and the deployment fails. #Hence, removing the security context from parameters mount_options if the authentication protocol is set to none. mount_options_array = mount_options.split(",") for option in mount_options_array: if "sec" in option and len(option.split("=")) >= 2 and option.split("=")[1] == "none": mount_options_array.remove(option) if len(mount_options_array) == 0: del params['mount_options'] else: new_mount_options = ','.join([str(element) for element in mount_options_array]) params['mount_options'] = new_mount_options if mapping.get('username'): params['username'] = mapping.get('username') if mapping.get('password'): params['password'] = mapping.get('password') mo = CommVMediaMap(parent_mo_or_dn=_get_vmedia_mo_dn(handle, server_id), volume_name=volume_name) mo.set_prop_multiple(**params) mos.append(mo) dn_to_vmedia_dict[mo.dn] = mo.volume_name response = handle.set_mos(mos) if response: ret = process_conf_mos_response(response, api, False, 'Create Virtual Media mapping failed',vmedia_mounts_callback, dn_to_vmedia_dict) if len(ret) != 0: error_msg = 'Create Virtual Media mapping failed:\n' for item in ret: obj = item["Object"] error = item["Error"] error = sanitize_message(error) error_msg += "[Virtual Media mapping " + obj + "] " + error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) mapping_error_msg = '' timeout_error_msg = '' for mo in mos: wait_time = 0 interval = 10 while wait_time < timeout: mapping_mo = handle.query_dn(mo.dn) if mapping_mo: existing_mapping_status = mapping_mo.mapping_status if existing_mapping_status.lower() == "ok": break elif re.match(r"error", existing_mapping_status.lower()): mapping_error_msg += "[Virtual Media mapping "+ mo.volume_name + "] " +existing_mapping_status + "\n" break time.sleep(interval) wait_time += interval if wait_time >= timeout: timeout_error_msg += "[Virtual Media mapping "+ mo.volume_name +"] \n" if len(mapping_error_msg) != 0: raise ImcOperationErrorDetail(api,"Create Virtual Media mapping failed: "+ mapping_error_msg,[]) if len(timeout_error_msg) != 0: raise ImcOperationErrorDetail(api,"Create Virtual Media mapping timed out: "+ timeout_error_msg,[]) results = {} results["changed"] = True results["msg"] = "" results["msg_params"] = ret return results
def local_users_update(handle, users=None): """ This method will create, modify or delete local users. It could also be a combination of these operations. Args: handle (ImcHandle) users (list): list of user dict keys: name (string): username priv (string): "admin", "user", "read-only" pwd (string): password account_status(string): "active", "inactive" change_password(boolean): flag used to change password example: [{'name':'dummy', 'pwd': '*****', 'priv': 'admin', 'change_password': true, 'account_status': 'active'}] Returns: boolean: flag that indicates if users were created, modified or deleted. It could also be a combination of these operations. Raises: IMCOperationError for various failure scenarios. A sample IMC Exception looks something like this: "Update Local Users failed, error: User:dum1 - [ErrorCode]: 2003[ErrorDescription]: Operation failed. Matching old password(s), please enter a different password.; Note: This error msg format is being used in Cisco Intersight to map error messages to respective users. Please excercise caution before changing it in the API. """ from imcsdk.mometa.aaa.AaaUser import AaaUser from imcsdk.imccoreutils import sanitize_message api = "Update Local Users" if users is None: users = [] if len(users) > MAX_USERS: raise ImcOperationError( api, "Number of users exceeded max allowed limit on IMC") update_users = False create_users = False endpoint_users = _get_local_users(handle) used_ids, delete_users = _delete_users(handle, users, endpoint_users) all_ids = range(2, MAX_USERS + 1) free_ids = list(set(all_ids) - set(used_ids)) create_mos = [] modify_mos = [] dn_to_user_dict = {} aaa_user_prefix = "sys/user-ext/user-" id = 0 for user in users: if 'name' not in user: raise ImcOperationError(api, "User Name is invalid") if 'pwd' not in user: raise ImcOperationError(api, "Password is invalid") if 'priv' not in user: raise ImcOperationError(api, "Privilege is invalid") if 'account_status' not in user: account_status = "active" else: account_status = user['account_status'] if 'change_password' not in user: change_password = False else: change_password = user['change_password'] name = user['name'] pwd = user['pwd'] priv = user['priv'] args = { "name": name, "pwd": pwd, "priv": priv, "account_status": account_status } # Existing users are not touched and hence we can safely check the # endpoint users list if there is found_user = None l = [x for x in endpoint_users if x.name == name] if len(l) != 0: found_user = l[0] if found_user: if not change_password: args.pop('pwd', None) if not found_user.check_prop_match(**args): update_users = True dn_to_user_dict[aaa_user_prefix + str(found_user.id)] = name found_user.set_prop_multiple(**args) modify_mos.append(found_user) continue if len(free_ids) == 0 or id >= len(free_ids): raise ImcOperationError( api, "Cannot configure more users than allowed limit on IMC") create_users = True free_id = free_ids[id] dn_to_user_dict[aaa_user_prefix + str(free_id)] = name mo = AaaUser(parent_mo_or_dn="sys/user-ext", id=str(free_id)) mo.set_prop_multiple(**args) create_mos.append(mo) id += 1 ret = [] mos = [] mos.extend(modify_mos) mos.extend(create_mos) response = handle.set_mos(mos) if response: ret = process_conf_mos_response(response, api, False, 'Create/Update local users failed', user_mos_callback, dn_to_user_dict) if len(ret) != 0: error_msg = 'Create/Update local users failed:\n' for item in ret: user = item["Object"] error = item["Error"] error = sanitize_message(error) error_msg += user + ": " + error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) results = {} # print(create_users, update_users, delete_users) results["changed"] = create_users or update_users or delete_users results["msg"] = "" results["msg_params"] = ret return results
def ldap_role_group_create_all(handle, groups=None): """ Creates an LDAP role groups. Note: This will overwrite the exisiting role groups. Args: handle (ImcHandle) groups (list of LDAP group dict) keys: domain (str): The LDAP server domain the group resides in. name (str): The name of the group in the LDAP server database. role (str): The role assigned to all users in this LDAP server group. ['read-only', 'user', 'admin'] example: [{'domain': 'abcd.pqrs.com', 'name': 'abcd', 'role': 'user'} ] Returns: List of AaaLdapRoleGroup object Examples: ldap_role_group_create_all(handle, groups= [ {'domain': 'abcd.pqrs.com', 'name': 'abcd', 'role': 'user'}]) """ api = 'ldap_role_group_create_all' dn_to_group_dict = {} domain_name_str_list = [] mos = [] id = 0 if len(groups) > 28: raise ImcOperationError(api, "Maximum allowed LDAP groups are 28.") for group in groups: domain = group.get('domain', None) name = group.get('name', None) role = group.get('role', 'read-only') domain = domain.strip() if domain else None name = name.strip() if name else None role = role.strip() if role else None _validate_api_prop('domain', domain, api) _validate_api_prop('name', name, api) _validate_api_prop('role', role, api, True, ['read-only', 'user', 'admin']) domain_name_str = domain + "_" + name if domain_name_str in domain_name_str_list: raise ImcOperationError( api, "LDAP Role Group with domain:%s name:%s already exists." % ( domain, name)) domain_name_str_list.append(domain_name_str) params = { 'domain': domain, 'name': name, 'role': role } id += 1 mo = AaaLdapRoleGroup(parent_mo_or_dn=LDAP_DN, id=str(id)) mo.set_prop_multiple(**params) mos.append(mo) dn_to_group_dict[mo.dn] = mo.name ret = [] response = handle.set_mos(mos) if response: ret = process_conf_mos_response(response, api, False, "Create LDAP groups failed", ldap_role_group_callback, dn_to_group_dict) if len(ret) != 0: error_msg = 'Create LDAP groups failed:\n' for item in ret: object = item["Object"] error = item["Error"] error = sanitize_message(error) error_msg += object + ": " + error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) results = {} results["changed"] = True results["msg"] = "" results["msg_params"] = ret return results
def _apply_config_card_action_util(handle, mos_dict, vds): from imcsdk.mometa.storage.StorageFlexFlashVirtualDrive import \ StorageFlexFlashVirtualDriveConsts # slot = _choose_slot(mos_dict['flexflash_pds']) # Utility drive should always be created on: # "slot-2", if both cards present # slot in which card is present, if only one card present # error, if no cards present pds = mos_dict['flexflash_pds'] primary_slot = None available_slots = _get_available_slots(pds) available_slots_cnt = len(available_slots) if available_slots_cnt == 0: raise ImcOperationError("Cannot set virtual drive", "Cards are missing in both the slots") elif available_slots_cnt == 1: primary_slot = available_slots[0] elif available_slots_cnt == 2: primary_slot = Slot.SLOT_2 partition_name = None non_util_partition_name = None if 'USER' in vds and hasattr(vds['USER'], 'vd_name'): partition_name = vds['USER'].vd_name if 'OS' in vds and hasattr(vds['OS'], 'vd_name'): non_util_partition_name = vds['OS'].vd_name flexflash_controller_mode_util_set( handle, card_slot=primary_slot, partition_name=partition_name, non_util_partition_name=non_util_partition_name ) dn_to_vd_dict = {} api = "sd_card_virtual_drive_set" mos = [] controller_dn = mos_dict['flexflash_controller'].dn for vd_type, vd in vds.items(): if not vd.vd_enable: continue # skip OS if only one slot is available in utility mode in M4 if vd_type == "OS" and available_slots_cnt == 1: continue partition_id = vd_map_type_id_util_m4[vd.vd_type] mo = _set_admin_action_flash_vd( handle, partition_id, StorageFlexFlashVirtualDriveConsts.ADMIN_ACTION_ENABLE_VD, controller_dn ) mos.append(mo) dn_to_vd_dict[mo.dn] = vd.vd_type if len(mos) == 0: return response = handle.set_mos(mos) if response: ret = process_conf_mos_response(response, api, False, 'Configuring virtual drives failed', util_mode_cb, dn_to_vd_dict) if len(ret) != 0: error_msg = 'Configuring virtual drives failed:\n' for item in ret: obj = item["Object"] error = item["Error"] error = sanitize_message(error) error_msg += "[Virtual drive " + obj + "] " + error + "\n" raise ImcOperationErrorDetail(api, error_msg, ret) results = {} results["changed"] = True results["msg"] = "" results["msg_params"] = ret return results