Skip to content

Commit

Permalink
feat(linstor-manager): add methods to modify/destroy/list net interfaces
Browse files Browse the repository at this point in the history
Signed-off-by: Ronan Abhamon <[email protected]>
  • Loading branch information
Wescoeur committed Dec 19, 2023
1 parent 9a0fa9b commit 44f2ee3
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 22 deletions.
76 changes: 68 additions & 8 deletions drivers/linstor-manager
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,19 @@ def force_destroy_drbd_volume(minor):
if ret:
raise Exception('Failed to destroy volume: {}'.format(stderr))


def get_ip_addr_of_pif(session, pif_uuid):
pif_ref = session.xenapi.PIF.get_by_uuid(pif_uuid)
pif = session.xenapi.PIF.get_record(pif_ref)

if not pif['currently_attached']:
raise XenAPIPlugin.Failure('-1', ['PIF is not plugged'])

ip_addr = pif['IP'] if pif['primary_address_type'].lower() == 'ipv4' else pif['IPv6'].split('/')[0]
if ip_addr == '':
raise XenAPIPlugin.Failure('-1', ['PIF has no IP'])
return ip_addr

# ------------------------------------------------------------------------------


Expand Down Expand Up @@ -983,28 +996,72 @@ def create_node_interface(session, args):
name = args['name']
pif_uuid = args['pifUuid']

pif_ref = session.xenapi.PIF.get_by_uuid(pif_uuid)
pif = session.xenapi.PIF.get_record(pif_ref)
ip_addr = get_ip_addr_of_pif(session, pif_uuid)

if not pif['currently_attached']:
raise XenAPIPlugin.Failure('-1', ['PIF is not plugged'])
linstor = LinstorVolumeManager(
get_controller_uri(),
group_name,
logger=util.SMlog
)
try:
linstor.create_node_interface(hostname, name, ip_addr)
except Exception as e:
raise XenAPIPlugin.Failure('-1', [str(e)])
return str(True)

ip_addr = pif['IP'] if pif['primary_address_type'].lower() == 'ipv4' else pif['IPv6'].split('/')[0]
if ip_addr == '':
raise XenAPIPlugin.Failure('-1', ['PIF has no IP'])

def destroy_node_interface(session, args):
group_name = args['groupName']
hostname = args['hostname']
name = args['name']

linstor = LinstorVolumeManager(
get_controller_uri(),
group_name,
logger=util.SMlog
)
try:
linstor.create_node_interface(hostname, name, ip_addr)
linstor.destroy_node_interface(hostname, name)
except Exception as e:
raise XenAPIPlugin.Failure('-1', [str(e)])
return str(True)


def modify_node_interface(session, args):
group_name = args['groupName']
hostname = args['hostname']
name = args['name']
pif_uuid = args['pifUuid']

ip_addr = get_ip_addr_of_pif(session, pif_uuid)

linstor = LinstorVolumeManager(
get_controller_uri(),
group_name,
logger=util.SMlog
)
try:
linstor.modify_node_interface(hostname, name, ip_addr)
except Exception as e:
raise XenAPIPlugin.Failure('-1', [str(e)])
return str(True)


def list_node_interfaces(session, args):
group_name = args['groupName']
hostname = args['hostname']

linstor = LinstorVolumeManager(
get_controller_uri(),
group_name,
logger=util.SMlog
)
try:
return json.dumps(linstor.list_node_interfaces(hostname))
except Exception as e:
raise XenAPIPlugin.Failure('-1', [str(e)])


def set_node_preferred_interface(session, args):
group_name = args['groupName']
hostname = args['hostname']
Expand Down Expand Up @@ -1072,5 +1129,8 @@ if __name__ == '__main__':
'healthCheck': health_check,

'createNodeInterface': create_node_interface,
'destroyNodeInterface': destroy_node_interface,
'modifyNodeInterface': modify_node_interface,
'listNodeInterfaces': list_node_interfaces,
'setNodePreferredInterface': set_node_preferred_interface
})
98 changes: 84 additions & 14 deletions drivers/linstorvolumemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,6 @@ def get_volume_size(self, volume_uuid):
)
return size * 1024


def set_auto_promote_timeout(self, volume_uuid, timeout):
"""
Define the blocking time of open calls when a DRBD
Expand Down Expand Up @@ -1120,7 +1119,6 @@ def get_volume_openers(self, volume_uuid):
"""
return get_all_volume_openers(self.get_volume_name(volume_uuid), '0')


def get_volumes_with_name(self):
"""
Give a volume dictionnary that contains names actually owned.
Expand Down Expand Up @@ -1529,21 +1527,93 @@ def destroy_node(self, node_name):
'Failed to destroy node `{}`: {}'.format(node_name, error_str)
)

def create_node_interface(self, hostname, name, ip_addr):
result = self._linstor.netinterface_create(hostname, name, ip_addr)
if not linstor.Linstor.all_api_responses_no_error(result):
def create_node_interface(self, node_name, name, ip):
"""
Create a new node interface in the LINSTOR database.
:param str node_name: Node name of the interface to use.
:param str name: Interface to create.
:param str ip: IP of the interface.
"""
result = self._linstor.netinterface_create(node_name, name, ip)
errors = self._filter_errors(result)
if errors:
error_str = self._get_error_str(errors)
raise LinstorVolumeManagerError(
'Unable to create interface on `{}`: {}'.format(hostname, ', '.join(
[str(x) for x in result]))
)
'Failed to create node interface on `{}`: {}'.format(node_name, error_str)
)

def set_node_preferred_interface(self, hostname, name):
result = self._linstor.node_modify(hostname, property_dict={'PrefNic': name})
if not linstor.Linstor.all_api_responses_no_error(result):
def destroy_node_interface(self, node_name, name):
"""
Destroy a node interface in the LINSTOR database.
:param str node_name: Node name of the interface to remove.
:param str name: Interface to remove.
"""
result = self._linstor.netinterface_delete(node_name, name)
errors = self._filter_errors(result)
if errors:
error_str = self._get_error_str(errors)
raise LinstorVolumeManagerError(
'Unable to set preferred interface on `{}`: {}'.format(hostname, ', '.join(
[str(x) for x in result]))
)
'Failed to destroy node interface on `{}`: {}'.format(node_name, error_str)
)

def modify_node_interface(self, node_name, name, ip):
"""
Modify a node interface in the LINSTOR database. Create it if necessary.
:param str node_name: Node name of the interface to use.
:param str name: Interface to modify or create.
:param str ip: IP of the interface.
"""
result = self._linstor.netinterface_create(node_name, name, ip)
errors = self._filter_errors(result)
if not errors:
return

if self._check_errors(errors, [linstor.consts.FAIL_EXISTS_NET_IF]):
result = self._linstor.netinterface_modify(node_name, name, ip)
errors = self._filter_errors(result)
if not errors:
return

error_str = self._get_error_str(errors)
raise LinstorVolumeManagerError(
'Unable to modify interface on `{}`: {}'.format(node_name, error_str)
)

def list_node_interfaces(self, node_name):
"""
List all node interfaces.
:param str node_name: Node name to use to list interfaces.
:rtype: list
:
"""
result = self._linstor.net_interface_list(node_name)
if not result:
raise LinstorVolumeManagerError(
'Unable to list interfaces on `{}`: no list received'.format(node_name)
)

interfaces = {}
for interface in result:
interface = interface._rest_data
interfaces[interface['name']] = {
'address': interface['address'],
'active': interface['is_active']
}
return interfaces

def set_node_preferred_interface(self, node_name, name):
"""
Set the preferred interface to use on a node.
:param str node_name: Node name of the interface.
:param str name: Preferred interface to use.
"""
result = self._linstor.node_modify(node_name, property_dict={'PrefNic': name})
errors = self._filter_errors(result)
if errors:
error_str = self._get_error_str(errors)
raise LinstorVolumeManagerError(
'Failed to set preferred node interface on `{}`: {}'.format(node_name, error_str)
)

def get_nodes_info(self):
"""
Expand Down

0 comments on commit 44f2ee3

Please sign in to comment.