Add --nic attr to get-connector command
Added attribute permits usage of different network interfaces for getting connector. Change-Id: If08c7094b233ee440642f6e4651656f6332c9460
This commit is contained in:
@@ -37,6 +37,8 @@ ENFORCE_MULTIPATH_HELP_MESSAGE = (
|
||||
'If enforce_multipath=True is specified too, an exception is thrown when '
|
||||
'multipathd is not running. Otherwise, it falls back to multipath=False '
|
||||
'and only the first path shown up is used.')
|
||||
NETWORK_INTERFACE_HELP_MESSAGE = ('Use a specific network interface to '
|
||||
'determine IP address.')
|
||||
|
||||
|
||||
@utils.arg('--multipath',
|
||||
@@ -47,12 +49,17 @@ ENFORCE_MULTIPATH_HELP_MESSAGE = (
|
||||
metavar='<enforce_multipath>',
|
||||
default=False,
|
||||
help=ENFORCE_MULTIPATH_HELP_MESSAGE)
|
||||
@utils.arg('--nic',
|
||||
metavar='<nic>',
|
||||
default=None,
|
||||
help=NETWORK_INTERFACE_HELP_MESSAGE)
|
||||
@brick_utils.require_root
|
||||
def do_get_connector(client, args):
|
||||
"""Get the connection properties for all protocols."""
|
||||
brickclient = brick_client.Client(client)
|
||||
connector = brickclient.get_connector(args.multipath,
|
||||
args.enforce_multipath)
|
||||
args.enforce_multipath,
|
||||
args.nic)
|
||||
utils.print_dict(connector)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# Copyright 2011-2014 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
@@ -14,9 +13,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netifaces
|
||||
import os
|
||||
import socket
|
||||
|
||||
from brick_cinderclient_ext import exceptions as exc
|
||||
from cinderclient import exceptions
|
||||
from oslo_concurrency import processutils
|
||||
|
||||
@@ -32,6 +33,28 @@ def get_my_ip():
|
||||
return None
|
||||
|
||||
|
||||
def get_ip(nic_name=None):
|
||||
"""Getting ip address by network interface name.
|
||||
|
||||
:param nic_name: interface name
|
||||
:returns: ip address from interface or default ip
|
||||
"""
|
||||
# TODO(mdovgal): add ipv6 support
|
||||
if not nic_name:
|
||||
return get_my_ip()
|
||||
|
||||
existing_ifaces = netifaces.interfaces()
|
||||
if nic_name not in existing_ifaces:
|
||||
raise exc.NicNotFound(iface=nic_name)
|
||||
|
||||
# get necessary iface information
|
||||
iface = netifaces.ifaddresses(nic_name)
|
||||
try:
|
||||
return iface[netifaces.AF_INET][0]['addr']
|
||||
except KeyError:
|
||||
raise exc.IncorrectNic(iface=nic_name)
|
||||
|
||||
|
||||
def get_root_helper():
|
||||
# NOTE (e0ne): We don't use rootwrap now
|
||||
return 'sudo'
|
||||
|
||||
@@ -21,7 +21,17 @@ from brick_cinderclient_ext import volume_actions as actions
|
||||
|
||||
|
||||
class Client(object):
|
||||
version = '1.1.0'
|
||||
"""Python client for os-brick
|
||||
|
||||
Version history:
|
||||
|
||||
1.0.0 - Initial version
|
||||
1.1.0 - Query volume paths implementation
|
||||
1.2.0 - Add --nic attribute to get-connector
|
||||
|
||||
"""
|
||||
|
||||
version = '1.2.0'
|
||||
|
||||
def __init__(self, volumes_client=None):
|
||||
self.volumes_client = volumes_client
|
||||
@@ -45,10 +55,11 @@ class Client(object):
|
||||
device_scan_attempts=device_scan_attempts,
|
||||
*args, **kwargs)
|
||||
|
||||
def get_connector(self, multipath=False, enforce_multipath=False):
|
||||
def get_connector(self, multipath=False, enforce_multipath=False,
|
||||
nic=None):
|
||||
conn_prop = connector.get_connector_properties(
|
||||
brick_utils.get_root_helper(),
|
||||
brick_utils.get_my_ip(),
|
||||
brick_utils.get_ip(nic),
|
||||
multipath=multipath,
|
||||
enforce_multipath=(enforce_multipath),
|
||||
execute=processutils.execute)
|
||||
|
||||
41
brick_cinderclient_ext/exceptions.py
Normal file
41
brick_cinderclient_ext/exceptions.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# Copyright 2017 Mirantis.Inc
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
Exception definitions.
|
||||
"""
|
||||
from cinderclient._i18n import _
|
||||
|
||||
|
||||
class BrickInterfaceException(Exception):
|
||||
"""Base exception for brick-cinderclient."""
|
||||
message = _("An unknown exception occurred.")
|
||||
|
||||
def __init__(self, message=None, **kwargs):
|
||||
if message:
|
||||
self.message = message
|
||||
self.message = self.message % kwargs
|
||||
|
||||
def __str__(self):
|
||||
return self.message
|
||||
|
||||
|
||||
class NicNotFound(BrickInterfaceException):
|
||||
message = _("Could not find network interface %(iface)s.")
|
||||
|
||||
|
||||
class IncorrectNic(BrickInterfaceException):
|
||||
# TODO(mdovgal): change message after adding ipv6 support
|
||||
message = _("Network interface %(iface)s has not ipv4 address assigned.")
|
||||
60
brick_cinderclient_ext/tests/unit/test_brick_utils.py
Normal file
60
brick_cinderclient_ext/tests/unit/test_brick_utils.py
Normal file
@@ -0,0 +1,60 @@
|
||||
# Copyright 2017 Mirantis.Inc
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
import netifaces
|
||||
from oslotest import base
|
||||
|
||||
from brick_cinderclient_ext import brick_utils
|
||||
from brick_cinderclient_ext import exceptions as exc
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestBrickUtils(base.BaseTestCase):
|
||||
@mock.patch('netifaces.ifaddresses',
|
||||
return_value={netifaces.AF_INET: [{'addr': '127.0.0.1'}]})
|
||||
@mock.patch('netifaces.interfaces', return_value=['eth1'])
|
||||
@mock.patch('brick_cinderclient_ext.brick_utils.get_my_ip',
|
||||
return_value='1.0.0.0')
|
||||
@ddt.data((None, '1.0.0.0'),
|
||||
('eth1', '127.0.0.1'))
|
||||
@ddt.unpack
|
||||
def test_get_ip(self, nic, expected,
|
||||
_fake_my_ip, _fake_interfaces,
|
||||
_fake_ifaddresses):
|
||||
"""Test getting ip address using interface name.
|
||||
|
||||
Test cases:
|
||||
1. Getting address from existing interface;
|
||||
2. Getting default value when network-iface param is missing;
|
||||
"""
|
||||
self.assertEqual(expected, brick_utils.get_ip(nic))
|
||||
|
||||
@mock.patch('netifaces.interfaces', return_value=[])
|
||||
def test_get_ip_failed_interface(self, _fake_interfaces):
|
||||
"""Test getting ip from nonexistent interface."""
|
||||
nic = 'fake_nic'
|
||||
self.assertRaises(exc.NicNotFound, brick_utils.get_ip,
|
||||
nic)
|
||||
|
||||
@mock.patch('netifaces.ifaddresses', return_value={})
|
||||
@mock.patch('netifaces.interfaces', return_value=['without_addr'])
|
||||
def test_get_ip_non_addr_in_iface(self, _fake_interfaces,
|
||||
_fake_ifaddresses):
|
||||
"""Test getting ip using nic that doesn't have ipv4 address."""
|
||||
nic = 'without_addr'
|
||||
self.assertRaises(exc.IncorrectNic, brick_utils.get_ip, nic)
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Added attribute --nic to get-connector command.
|
||||
Reference in New Issue
Block a user