Add SRIOV PF and VF listing to API
This commit is contained in:
		| @@ -2719,6 +2719,134 @@ class API_Network_ACL_Element(Resource): | ||||
| api.add_resource(API_Network_ACL_Element, '/network/<vni>/acl/<description>') | ||||
|  | ||||
|  | ||||
| ########################################################## | ||||
| # Client API - SR-IOV | ||||
| ########################################################## | ||||
|  | ||||
| # /sriov | ||||
| class API_SRIOV_Root(Resource): | ||||
|     @Authenticator | ||||
|     def get(self): | ||||
|         pass | ||||
|  | ||||
|  | ||||
| api.add_resource(API_SRIOV_Root, '/sriov') | ||||
|  | ||||
|  | ||||
| # /sriov/pf | ||||
| class API_SRIOV_PF_Root(Resource): | ||||
|     @RequestParser([ | ||||
|         {'name': 'node', 'required': True, 'helptext': "A valid node must be specified."}, | ||||
|     ]) | ||||
|     @Authenticator | ||||
|     def get(self, reqargs): | ||||
|         """ | ||||
|         Return a list of SR-IOV PFs on a given node | ||||
|         --- | ||||
|         tags: | ||||
|           - network / sriov | ||||
|         responses: | ||||
|           200: | ||||
|             description: OK | ||||
|             schema: | ||||
|               type: object | ||||
|               id: sriov_pf | ||||
|               properties: | ||||
|                 phy: | ||||
|                   type: string | ||||
|                   description: The name of the SR-IOV PF device | ||||
|                 mtu: | ||||
|                   type: string | ||||
|                   description: The MTU of the SR-IOV PF device | ||||
|                 vfs: | ||||
|                   type: list | ||||
|                   items: | ||||
|                     type: string | ||||
|                     description: The PHY name of a VF of this PF | ||||
|         """ | ||||
|         return api_helper.sriov_pf_list(reqargs.get('node')) | ||||
|  | ||||
|  | ||||
| api.add_resource(API_SRIOV_PF_Root, '/sriov/pf') | ||||
|  | ||||
|  | ||||
| # /sriov/vf | ||||
| class API_SRIOV_VF_Root(Resource): | ||||
|     @RequestParser([ | ||||
|         {'name': 'node', 'required': True, 'helptext': "A valid node must be specified."}, | ||||
|         {'name': 'pf', 'required': False, 'helptext': "A PF parent may be specified."}, | ||||
|     ]) | ||||
|     @Authenticator | ||||
|     def get(self, reqargs): | ||||
|         """ | ||||
|         Return a list of SR-IOV VFs on a given node, optionally limited to those in the specified PF | ||||
|         --- | ||||
|         tags: | ||||
|           - network / sriov | ||||
|         responses: | ||||
|           200: | ||||
|             description: OK | ||||
|             schema: | ||||
|               type: object | ||||
|               id: sriov_vf | ||||
|               properties: | ||||
|                 phy: | ||||
|                   type: string | ||||
|                   description: The name of the SR-IOV VF device | ||||
|                 pf: | ||||
|                   type: string | ||||
|                   description: The name of the SR-IOV PF parent of this VF device | ||||
|                 mtu: | ||||
|                   type: integer | ||||
|                   description: The current MTU of the VF device | ||||
|                 mac: | ||||
|                   type: string | ||||
|                   description: The current MAC address of the VF device | ||||
|                 config: | ||||
|                   type: object | ||||
|                   id: sriov_vf_config | ||||
|                   properties: | ||||
|                     vlan_id: | ||||
|                       type: string | ||||
|                       description: The tagged vLAN ID of the SR-IOV VF device | ||||
|                     vlan_qos: | ||||
|                       type: string | ||||
|                       description: The QOS group of the tagged vLAN | ||||
|                     tx_rate_min: | ||||
|                       type: string | ||||
|                       description: The minimum TX rate of the SR-IOV VF device | ||||
|                     tx_rate_max: | ||||
|                       type: string | ||||
|                       description: The maximum TX rate of the SR-IOV VF device | ||||
|                     spoof_check: | ||||
|                       type: boolean | ||||
|                       description: Whether device spoof checking is enabled or disabled | ||||
|                     link_state: | ||||
|                       type: string | ||||
|                       description: The current SR-IOV VF link state (either enabled, disabled, or auto) | ||||
|                     trust: | ||||
|                       type: boolean | ||||
|                       description: Whether guest device trust is enabled or disabled | ||||
|                     query_rss: | ||||
|                       type: boolean | ||||
|                       description: Whether VF RSS querying is enabled or disabled | ||||
|                 usage: | ||||
|                   type: object | ||||
|                   id: sriov_vf_usage | ||||
|                   properties: | ||||
|                     used: | ||||
|                       type: boolean | ||||
|                       description: Whether the SR-IOV VF is currently used by a VM or not | ||||
|                     domain: | ||||
|                       type: boolean | ||||
|                       description: The UUID of the domain the SR-IOV VF is currently used by | ||||
|         """ | ||||
|         return api_helper.sriov_vf_list(reqargs.get('node'), reqargs.get('pf', None)) | ||||
|  | ||||
|  | ||||
| api.add_resource(API_SRIOV_VF_Root, '/sriov/vf') | ||||
|  | ||||
|  | ||||
| ########################################################## | ||||
| # Client API - Storage | ||||
| ########################################################## | ||||
|   | ||||
| @@ -978,6 +978,62 @@ def net_acl_remove(zkhandler, network, description): | ||||
|     return output, retcode | ||||
|  | ||||
|  | ||||
| # | ||||
| # SR-IOV functions | ||||
| # | ||||
| @ZKConnection(config) | ||||
| def sriov_pf_list(zkhandler, node): | ||||
|     """ | ||||
|     List all PFs on a given node. | ||||
|     """ | ||||
|     retflag, retdata = pvc_network.get_list_sriov_pf(zkhandler, node) | ||||
|  | ||||
|     if retflag: | ||||
|         if retdata: | ||||
|             retcode = 200 | ||||
|         else: | ||||
|             retcode = 404 | ||||
|             retdata = { | ||||
|                 'message': 'PF not found.' | ||||
|             } | ||||
|     else: | ||||
|         retcode = 400 | ||||
|         retdata = { | ||||
|             'message': retdata | ||||
|         } | ||||
|  | ||||
|     return retdata, retcode | ||||
|  | ||||
|  | ||||
| @ZKConnection(config) | ||||
| def sriov_vf_list(zkhandler, node, pf=None): | ||||
|     """ | ||||
|     List all VFs on a given node, optionally limited to PF. | ||||
|     """ | ||||
|     retflag, retdata = pvc_network.get_list_sriov_vf(zkhandler, node, pf) | ||||
|  | ||||
|     if retflag: | ||||
|         retcode = 200 | ||||
|     else: | ||||
|         retcode = 400 | ||||
|  | ||||
|     if retflag: | ||||
|         if retdata: | ||||
|             retcode = 200 | ||||
|         else: | ||||
|             retcode = 404 | ||||
|             retdata = { | ||||
|                 'message': 'VF not found.' | ||||
|             } | ||||
|     else: | ||||
|         retcode = 400 | ||||
|         retdata = { | ||||
|             'message': retdata | ||||
|         } | ||||
|  | ||||
|     return retdata, retcode | ||||
|  | ||||
|  | ||||
| # | ||||
| # Ceph functions | ||||
| # | ||||
|   | ||||
| @@ -629,3 +629,114 @@ def get_list_acl(zkhandler, network, limit, direction, is_fuzzy=True): | ||||
|             acl_list.append(acl) | ||||
|  | ||||
|     return True, acl_list | ||||
|  | ||||
|  | ||||
| # | ||||
| # SR-IOV functions | ||||
| # | ||||
| # These are separate since they don't work like other network types | ||||
| # | ||||
| def getSRIOVPFInformation(zkhandler, node, pf): | ||||
|     mtu = zkhandler.read(('node.sriov.pf', node, 'sriov_pf.mtu', pf)) | ||||
|  | ||||
|     retcode, vf_list = get_list_sriov_vf(zkhandler, node, pf) | ||||
|     if retcode: | ||||
|         vfs = [vf['phy'] for vf in vf_list if vf['pf'] == pf] | ||||
|     else: | ||||
|         vfs = [] | ||||
|  | ||||
|     # Construct a data structure to represent the data | ||||
|     pf_information = { | ||||
|         'phy': pf, | ||||
|         'mtu': mtu, | ||||
|         'vfs': vfs, | ||||
|     } | ||||
|     return pf_information | ||||
|  | ||||
|  | ||||
| def get_info_sriov_pf(zkhandler, node, pf): | ||||
|     pf_information = getSRIOVPFInformation(zkhandler, node, pf) | ||||
|     if not pf_information: | ||||
|         return False, 'ERROR: Could not get information about SR-IOV PF "{}" on node "{}"'.format(pf, node) | ||||
|  | ||||
|     return True, pf_information | ||||
|  | ||||
|  | ||||
| def get_list_sriov_pf(zkhandler, node): | ||||
|     pf_list = list() | ||||
|     pf_phy_list = zkhandler.children(('node.sriov.pf', node)) | ||||
|     for phy in pf_phy_list: | ||||
|         retcode, pf_information = get_info_sriov_pf(zkhandler, node, phy) | ||||
|         if retcode: | ||||
|             pf_list.append(pf_information) | ||||
|  | ||||
|     return True, pf_list | ||||
|  | ||||
|  | ||||
| def getSRIOVVFInformation(zkhandler, node, vf): | ||||
|     pf = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.pf', vf)) | ||||
|     mtu = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.mtu', vf)) | ||||
|     mac = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.mac', vf)) | ||||
|     vlan_id = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.vlan_id', vf)) | ||||
|     vlan_qos = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.vlan_qos', vf)) | ||||
|     tx_rate_min = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.tx_rate_min', vf)) | ||||
|     tx_rate_max = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.tx_rate_max', vf)) | ||||
|     spoof_check = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.spoof_check', vf)) | ||||
|     link_state = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.link_state', vf)) | ||||
|     trust = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.trust', vf)) | ||||
|     query_rss = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.query_rss', vf)) | ||||
|     used = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.used', vf)) | ||||
|     used_by_domain = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.used_by', vf)) | ||||
|  | ||||
|     vf_information = { | ||||
|         'phy': vf, | ||||
|         'pf': pf, | ||||
|         'mtu': mtu, | ||||
|         'mac': mac, | ||||
|         'config': { | ||||
|             'vlan_id': vlan_id, | ||||
|             'vlan_qos': vlan_qos, | ||||
|             'tx_rate_min': tx_rate_min, | ||||
|             'tx_rate_max': tx_rate_max, | ||||
|             'spoof_check': spoof_check, | ||||
|             'link_state': link_state, | ||||
|             'trust': trust, | ||||
|             'query_rss': query_rss, | ||||
|         }, | ||||
|         'usage': { | ||||
|             'used': used, | ||||
|             'domain': used_by_domain, | ||||
|         } | ||||
|     } | ||||
|     return vf_information | ||||
|  | ||||
|  | ||||
| def get_info_sriov_vf(zkhandler, node, vf): | ||||
|     vf_information = getSRIOVVFInformation(zkhandler, node, vf) | ||||
|     if not vf_information: | ||||
|         return False, 'ERROR: Could not get information about SR-IOV VF "{}" on node "{}"'.format(vf, node) | ||||
|  | ||||
|     return True, vf_information | ||||
|  | ||||
|  | ||||
| def get_list_sriov_vf(zkhandler, node, pf=None): | ||||
|     vf_list = list() | ||||
|     vf_phy_list = sorted(zkhandler.children(('node.sriov.vf', node))) | ||||
|     for phy in vf_phy_list: | ||||
|         retcode, vf_information = get_info_sriov_vf(zkhandler, node, phy) | ||||
|         if retcode: | ||||
|             if pf is not None: | ||||
|                 if vf_information['pf'] == pf: | ||||
|                     vf_list.append(vf_information) | ||||
|             else: | ||||
|                 vf_list.append(vf_information) | ||||
|  | ||||
|     return True, vf_list | ||||
|  | ||||
|  | ||||
| def set_sriov_vf_config(zkhandler, node, vf, vlan_id=None, vlan_qos=None, tx_rate_min=None, tx_rate_max=None, spoof_check=None, link_state=None, trust=None, query_rss=None): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| def set_sriov_vf_vm(zkhandler, node, vf, vm_name, vm_macaddr): | ||||
|     pass | ||||
|   | ||||
		Reference in New Issue
	
	Block a user