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>') | 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 | # Client API - Storage | ||||||
| ########################################################## | ########################################################## | ||||||
|   | |||||||
| @@ -978,6 +978,62 @@ def net_acl_remove(zkhandler, network, description): | |||||||
|     return output, retcode |     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 | # Ceph functions | ||||||
| # | # | ||||||
|   | |||||||
| @@ -629,3 +629,114 @@ def get_list_acl(zkhandler, network, limit, direction, is_fuzzy=True): | |||||||
|             acl_list.append(acl) |             acl_list.append(acl) | ||||||
|  |  | ||||||
|     return True, acl_list |     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