Support keystone v3
Make all the various bits of OVB that interact with the host cloud able to use keystone v3 authentication. Note that my experience has been that a newer novaclient is needed on the bmc in order for this to work. The pre-built BMC image in the docs has been updated with a new enough novaclient.
This commit is contained in:
parent
43af75766c
commit
7e7ccea3dc
|
@ -36,7 +36,13 @@ export OS_USERNAME=$os_user
|
|||
export OS_TENANT_NAME=$os_tenant
|
||||
export OS_PASSWORD=$os_password
|
||||
export OS_AUTH_URL=$os_auth_url
|
||||
private_subnet=$(neutron net-show -f value -c subnets $private_net)
|
||||
export OS_PROJECT_NAME=$os_project
|
||||
export OS_USER_DOMAIN_ID=$os_user_domain
|
||||
export OS_PROJECT_DOMAIN_ID=$os_project_domain
|
||||
# At some point neutronclient started returning a python list repr from this
|
||||
# command instead of just the value. This sed will strip off the bits we
|
||||
# don't care about without messing up the output from older clients.
|
||||
private_subnet=$(neutron net-show -f value -c subnets $private_net | sed "s/\[u'\(.*\)'\]/\1/")
|
||||
default_gw=$(neutron subnet-show $private_subnet -f value -c gateway_ip)
|
||||
prefix_len=$(neutron subnet-show -f value -c cidr $private_subnet | awk -F / '{print $2}')
|
||||
|
||||
|
@ -76,6 +82,11 @@ do
|
|||
bm_instance=$(neutron port-show $bm_port -c device_id -f value)
|
||||
bmc_port="$bmc_prefix_$(($i-1))"
|
||||
bmc_ip=$(neutron port-show $bmc_port -c fixed_ips -f value | jq -r .ip_address)
|
||||
# Newer neutronclient requires explicit json output and a slightly
|
||||
# different jq query
|
||||
if [ -z "$bmc_ip" ]; then
|
||||
bmc_ip=$(neutron port-show $bmc_port -c fixed_ips -f json | jq -r .fixed_ips[0].ip_address)
|
||||
fi
|
||||
unit="openstack-bmc-$bm_port.service"
|
||||
|
||||
cat <<EOF >/usr/lib/systemd/system/$unit
|
||||
|
@ -85,7 +96,7 @@ Requires=config-bmc-ips.service
|
|||
After=config-bmc-ips.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/openstackbmc --os-user $os_user --os-password $os_password --os-tenant $os_tenant --os-auth-url $os_auth_url --instance $bm_instance --address $bmc_ip
|
||||
ExecStart=/usr/local/bin/openstackbmc --os-user $os_user --os-password $os_password --os-tenant "$os_tenant" --os-auth-url $os_auth_url --os-project "$os_project" --os-user-domain "$os_user_domain" --os-project-domain "$os_project_domain" --instance $bm_instance --address $bmc_ip
|
||||
Restart=always
|
||||
|
||||
User=root
|
||||
|
|
|
@ -94,24 +94,48 @@ def _get_clients():
|
|||
username = os.environ.get('OS_USERNAME')
|
||||
password = os.environ.get('OS_PASSWORD')
|
||||
tenant = os.environ.get('OS_TENANT_NAME')
|
||||
auth_url = os.environ.get('OS_AUTH_URL')
|
||||
if not username or not password or not tenant or not auth_url:
|
||||
print('Source an appropriate rc file first')
|
||||
sys.exit(1)
|
||||
auth_url = os.environ.get('OS_AUTH_URL', '')
|
||||
project = os.environ.get('OS_PROJECT_NAME')
|
||||
user_domain = os.environ.get('OS_USER_DOMAIN_ID')
|
||||
project_domain = os.environ.get('OS_PROJECT_DOMAIN_ID')
|
||||
|
||||
# novaclient 7+ is backwards-incompatible :-(
|
||||
if int(nc.__version__[0]) <= 6:
|
||||
nova = novaclient.Client(2, username, password, tenant, auth_url)
|
||||
if '/v3' not in auth_url:
|
||||
if not username or not password or not tenant or not auth_url:
|
||||
print('Source an appropriate rc file first')
|
||||
sys.exit(1)
|
||||
# novaclient 7+ is backwards-incompatible :-(
|
||||
if int(nc.__version__[0]) <= 6:
|
||||
nova = novaclient.Client(2, username, password, tenant, auth_url)
|
||||
else:
|
||||
nova = novaclient.Client(2, username, password,
|
||||
auth_url=auth_url,
|
||||
project_name=tenant)
|
||||
neutron = neutronclient.Client(
|
||||
username=username,
|
||||
password=password,
|
||||
tenant_name=tenant,
|
||||
auth_url=auth_url
|
||||
)
|
||||
else:
|
||||
if (not username or not password or not auth_url or not project or
|
||||
not user_domain or not project_domain):
|
||||
print('Source an appropriate rc file first')
|
||||
sys.exit(1)
|
||||
nova = novaclient.Client(2, username, password,
|
||||
auth_url=auth_url,
|
||||
project_name=tenant)
|
||||
neutron = neutronclient.Client(
|
||||
username=username,
|
||||
password=password,
|
||||
tenant_name=tenant,
|
||||
auth_url=auth_url
|
||||
)
|
||||
project_name=project,
|
||||
user_domain_name=user_domain,
|
||||
project_domain_name=project_domain)
|
||||
from keystoneauth1.identity import v3
|
||||
from keystoneauth1 import session
|
||||
auth = v3.Password(auth_url=auth_url,
|
||||
username=username,
|
||||
password=password,
|
||||
project_name=project,
|
||||
user_domain_name=user_domain,
|
||||
project_domain_name=project_domain)
|
||||
sess = session.Session(auth=auth)
|
||||
neutron = neutronclient.Client(session=sess)
|
||||
return nova, neutron
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import yaml
|
|||
from heatclient import client as heat_client
|
||||
from heatclient.common import template_utils
|
||||
from keystoneclient.v2_0 import client as keystone_client
|
||||
from keystoneclient.v3 import client as keystone_v3_client
|
||||
|
||||
def _parse_args():
|
||||
parser = argparse.ArgumentParser(description='Deploy an OVB environment')
|
||||
|
@ -143,24 +144,59 @@ def _get_heat_client():
|
|||
password = os.environ.get('OS_PASSWORD')
|
||||
tenant = os.environ.get('OS_TENANT_NAME')
|
||||
auth_url = os.environ.get('OS_AUTH_URL')
|
||||
if not username or not password or not tenant or not auth_url:
|
||||
print('Source an appropriate rc file first')
|
||||
sys.exit(1)
|
||||
project = os.environ.get('OS_PROJECT_NAME')
|
||||
user_domain = os.environ.get('OS_USER_DOMAIN_ID')
|
||||
project_domain = os.environ.get('OS_PROJECT_DOMAIN_ID')
|
||||
|
||||
# Get token for Heat to use
|
||||
kclient = keystone_client.Client(username=username, password=password,
|
||||
tenant_name=tenant, auth_url=auth_url)
|
||||
token_data = kclient.get_raw_token_from_identity_service(
|
||||
username=username,
|
||||
password=password,
|
||||
tenant_name=tenant,
|
||||
auth_url=auth_url)
|
||||
token_id = token_data['token']['id']
|
||||
if '/v3' not in auth_url:
|
||||
if not username or not password or not tenant or not auth_url:
|
||||
print('Source an appropriate rc file first')
|
||||
sys.exit(1)
|
||||
kclient = keystone_client.Client(username=username, password=password,
|
||||
tenant_name=tenant, auth_url=auth_url)
|
||||
token_data = kclient.get_raw_token_from_identity_service(
|
||||
username=username,
|
||||
password=password,
|
||||
tenant_name=tenant,
|
||||
auth_url=auth_url)
|
||||
token_id = token_data['token']['id']
|
||||
catalog_key = 'serviceCatalog'
|
||||
else:
|
||||
if (not username or not password or not auth_url or not project or
|
||||
not user_domain or not project_domain):
|
||||
print('Source an appropriate rc file first')
|
||||
sys.exit(1)
|
||||
from keystoneauth1.identity import v3
|
||||
from keystoneauth1 import session
|
||||
auth = v3.Password(auth_url=auth_url,
|
||||
username=username,
|
||||
password=password,
|
||||
project_name=project,
|
||||
user_domain_name=user_domain,
|
||||
project_domain_name=project_domain)
|
||||
sess = session.Session(auth=auth)
|
||||
kclient = keystone_v3_client.Client(session=sess)
|
||||
token_data = kclient.get_raw_token_from_identity_service(
|
||||
username=username,
|
||||
password=password,
|
||||
project_name=project,
|
||||
auth_url=auth_url,
|
||||
user_domain_name=user_domain,
|
||||
project_domain_name=project_domain)
|
||||
token_id = token_data['auth_token']
|
||||
catalog_key = 'catalog'
|
||||
|
||||
# Get Heat endpoint
|
||||
for endpoint in token_data['serviceCatalog']:
|
||||
for endpoint in token_data[catalog_key]:
|
||||
if endpoint['name'] == 'heat':
|
||||
# TODO: What if there's more than one endpoint?
|
||||
heat_endpoint = endpoint['endpoints'][0]['publicURL']
|
||||
try:
|
||||
# TODO: What if there's more than one endpoint?
|
||||
heat_endpoint = endpoint['endpoints'][0]['publicURL']
|
||||
except KeyError:
|
||||
# Keystone v3 endpoint data looks different
|
||||
heat_endpoint = [e for e in endpoint['endpoints']
|
||||
if e['interface'] == 'public'][0]['url']
|
||||
|
||||
return heat_client.Client('1', endpoint=heat_endpoint, token=token_id)
|
||||
|
||||
|
@ -179,10 +215,16 @@ def _create_auth_parameters():
|
|||
password = os.environ.get('OS_PASSWORD')
|
||||
tenant = os.environ.get('OS_TENANT_NAME')
|
||||
auth_url = os.environ.get('OS_AUTH_URL')
|
||||
project = os.environ.get('OS_PROJECT_NAME')
|
||||
user_domain = os.environ.get('OS_USER_DOMAIN_ID')
|
||||
project_domain = os.environ.get('OS_PROJECT_DOMAIN_ID')
|
||||
return {'os_user': username,
|
||||
'os_password': password,
|
||||
'os_tenant': tenant,
|
||||
'os_auth_url': auth_url,
|
||||
'os_project': project,
|
||||
'os_user_domain': user_domain,
|
||||
'os_project_domain': project_domain,
|
||||
}
|
||||
|
||||
def _deploy(stack_name, stack_template, env_path, poll):
|
||||
|
|
|
@ -35,16 +35,23 @@ import pyghmi.ipmi.bmc as bmc
|
|||
|
||||
class OpenStackBmc(bmc.Bmc):
|
||||
def __init__(self, authdata, port, address, instance, user, password, tenant,
|
||||
auth_url):
|
||||
auth_url, project, user_domain, project_domain):
|
||||
super(OpenStackBmc, self).__init__(authdata, port=port, address=address)
|
||||
# novaclient 7+ is backwards-incompatible :-(
|
||||
if int(nc.__version__[0]) <= 6:
|
||||
self.novaclient = novaclient.Client(2, user, password,
|
||||
tenant, auth_url)
|
||||
if not '/v3' in auth_url:
|
||||
# novaclient 7+ is backwards-incompatible :-(
|
||||
if int(nc.__version__[0]) <= 6:
|
||||
self.novaclient = novaclient.Client(2, user, password,
|
||||
tenant, auth_url)
|
||||
else:
|
||||
self.novaclient = novaclient.Client(2, user, password,
|
||||
auth_url=auth_url,
|
||||
project_name=tenant)
|
||||
else:
|
||||
self.novaclient = novaclient.Client(2, user, password,
|
||||
auth_url=auth_url,
|
||||
project_name=tenant)
|
||||
project_name=project,
|
||||
user_domain_name=user_domain,
|
||||
project_domain_name=project_domain)
|
||||
self.instance = None
|
||||
self.cached_status = None
|
||||
self.target_status = None
|
||||
|
@ -191,12 +198,28 @@ def main():
|
|||
help='The password for connecting to OpenStack')
|
||||
parser.add_argument('--os-tenant',
|
||||
dest='tenant',
|
||||
required=True,
|
||||
required=False,
|
||||
default='',
|
||||
help='The tenant for connecting to OpenStack')
|
||||
parser.add_argument('--os-auth-url',
|
||||
dest='auth_url',
|
||||
required=True,
|
||||
help='The OpenStack Keystone auth url')
|
||||
parser.add_argument('--os-project',
|
||||
dest='project',
|
||||
required=False,
|
||||
default='',
|
||||
help='The project for connecting to OpenStack')
|
||||
parser.add_argument('--os-user-domain',
|
||||
dest='user_domain',
|
||||
required=False,
|
||||
default='',
|
||||
help='The user domain for connecting to OpenStack')
|
||||
parser.add_argument('--os-project-domain',
|
||||
dest='project_domain',
|
||||
required=False,
|
||||
default='',
|
||||
help='The project domain for connecting to OpenStack')
|
||||
args = parser.parse_args()
|
||||
# Default to ipv6 format, but if we get an ipv4 address passed in use the
|
||||
# appropriate format for pyghmi to listen on it.
|
||||
|
@ -209,7 +232,10 @@ def main():
|
|||
user=args.user,
|
||||
password=args.password,
|
||||
tenant=args.tenant,
|
||||
auth_url=args.auth_url)
|
||||
auth_url=args.auth_url,
|
||||
project=args.project,
|
||||
user_domain=args.user_domain,
|
||||
project_domain=args.project_domain)
|
||||
mybmc.listen()
|
||||
|
||||
|
||||
|
|
|
@ -164,9 +164,7 @@ class TestBuildNodesJson(testtools.TestCase):
|
|||
mock.call('network', cloud='foo')]
|
||||
self.assertEqual(calls, mock_make_client.mock_calls)
|
||||
|
||||
@mock.patch('neutronclient.v2_0.client.Client')
|
||||
@mock.patch('novaclient.client.Client')
|
||||
def test_get_clients_env(self, mock_nova, mock_neutron):
|
||||
def _test_get_clients_env(self, mock_nova, mock_neutron):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USERNAME', 'admin'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PASSWORD', 'pw'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_TENANT_NAME',
|
||||
|
@ -180,11 +178,68 @@ class TestBuildNodesJson(testtools.TestCase):
|
|||
self.assertEqual(mock_nova_client, nova)
|
||||
self.assertEqual(mock_neutron_client, neutron)
|
||||
|
||||
@mock.patch('openstack_virtual_baremetal.build_nodes_json.nc.__version__',
|
||||
('6', '0', '0'))
|
||||
@mock.patch('neutronclient.v2_0.client.Client')
|
||||
@mock.patch('novaclient.client.Client')
|
||||
def test_get_clients_env_6(self, mock_nova, mock_neutron):
|
||||
self._test_get_clients_env(mock_nova, mock_neutron)
|
||||
|
||||
@mock.patch('openstack_virtual_baremetal.build_nodes_json.nc.__version__',
|
||||
('7', '0', '0'))
|
||||
@mock.patch('neutronclient.v2_0.client.Client')
|
||||
@mock.patch('novaclient.client.Client')
|
||||
def test_get_clients_env_7(self, mock_nova, mock_neutron):
|
||||
self._test_get_clients_env(mock_nova, mock_neutron)
|
||||
|
||||
@mock.patch('keystoneauth1.session.Session')
|
||||
@mock.patch('keystoneauth1.identity.v3.Password')
|
||||
@mock.patch('neutronclient.v2_0.client.Client')
|
||||
@mock.patch('novaclient.client.Client')
|
||||
def test_get_clients_env_v3(self, mock_nova, mock_neutron, mock_password,
|
||||
mock_session):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USERNAME', 'admin'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PASSWORD', 'pw'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PROJECT_NAME',
|
||||
'admin'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_AUTH_URL', 'auth/v3'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USER_DOMAIN_ID',
|
||||
'default'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PROJECT_DOMAIN_ID',
|
||||
'default'))
|
||||
mock_nova_client = mock.Mock()
|
||||
mock_nova.return_value = mock_nova_client
|
||||
mock_neutron_client = mock.Mock()
|
||||
mock_neutron.return_value = mock_neutron_client
|
||||
mock_auth = mock.Mock()
|
||||
mock_password.return_value = mock_auth
|
||||
mock_session_inst = mock.Mock()
|
||||
mock_session.return_value = mock_session_inst
|
||||
nova, neutron = build_nodes_json._get_clients()
|
||||
mock_password.assert_called_once_with(auth_url='auth/v3',
|
||||
username='admin',
|
||||
password='pw',
|
||||
project_name='admin',
|
||||
user_domain_name='default',
|
||||
project_domain_name='default'
|
||||
)
|
||||
mock_session.assert_called_once_with(auth=mock_auth)
|
||||
mock_neutron.assert_called_once_with(session=mock_session_inst)
|
||||
self.assertEqual(mock_nova_client, nova)
|
||||
self.assertEqual(mock_neutron_client, neutron)
|
||||
|
||||
@mock.patch('sys.exit')
|
||||
def test_get_clients_missing(self, mock_exit):
|
||||
build_nodes_json._get_clients()
|
||||
mock_exit.assert_called_once_with(1)
|
||||
|
||||
@mock.patch('sys.exit')
|
||||
def test_get_clients_missing_v3(self, mock_exit):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_AUTH_URL',
|
||||
'http://host/v3'))
|
||||
build_nodes_json._get_clients()
|
||||
mock_exit.assert_called_once_with(1)
|
||||
|
||||
def test_get_ports(self):
|
||||
neutron = mock.Mock()
|
||||
fake_ports = {'ports':
|
||||
|
|
|
@ -17,7 +17,9 @@ import io
|
|||
import unittest
|
||||
import yaml
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
import deploy
|
||||
|
||||
|
@ -58,7 +60,7 @@ class TestProcessArgs(unittest.TestCase):
|
|||
self.assertEqual('foo', name)
|
||||
self.assertEqual('templates/quintupleo.yaml', template)
|
||||
|
||||
def test_id_quintuple(self):
|
||||
def test_id_quintupleo(self):
|
||||
mock_args = mock.Mock()
|
||||
mock_args.id = 'foo'
|
||||
mock_args.quintupleo = False
|
||||
|
@ -368,5 +370,93 @@ class TestDeploy(unittest.TestCase):
|
|||
deploy._validate_env(args, 'foo.yaml')
|
||||
|
||||
|
||||
V2_TOKEN_DATA = {'token': {'id': 'fake_token'},
|
||||
'serviceCatalog': [{'name': 'nova'},
|
||||
{'name': 'heat',
|
||||
'endpoints': [
|
||||
{'publicURL': 'heat_endpoint'}
|
||||
]
|
||||
}
|
||||
]}
|
||||
V3_TOKEN_DATA = {'auth_token': 'fake_v3_token',
|
||||
'catalog': [{'name': 'nova'},
|
||||
{'name': 'heat',
|
||||
'endpoints': [
|
||||
{'interface': 'private'},
|
||||
{'interface': 'public',
|
||||
'url': 'heat_endpoint'}
|
||||
]
|
||||
}
|
||||
]}
|
||||
class TestGetHeatClient(testtools.TestCase):
|
||||
@mock.patch('os_client_config.make_client')
|
||||
def test_os_cloud(self, mock_make_client):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_CLOUD', 'foo'))
|
||||
deploy._get_heat_client()
|
||||
mock_make_client.assert_called_once_with('orchestration', cloud='foo')
|
||||
|
||||
@mock.patch('heatclient.client.Client')
|
||||
@mock.patch('keystoneclient.v2_0.client.Client')
|
||||
def test_keystone_v2(self, mock_ksc, mock_hc):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USERNAME', 'admin'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PASSWORD', 'pw'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_TENANT_NAME',
|
||||
'admin'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_AUTH_URL', 'auth'))
|
||||
mock_ks_client = mock.Mock()
|
||||
mock_ksc.return_value = mock_ks_client
|
||||
mock_ks_client.get_raw_token_from_identity_service.return_value = (
|
||||
V2_TOKEN_DATA)
|
||||
mock_token_value = 'fake_token'
|
||||
deploy._get_heat_client()
|
||||
mock_ksc.assert_called_once_with(username='admin', password='pw',
|
||||
tenant_name='admin', auth_url='auth')
|
||||
get_token = mock_ks_client.get_raw_token_from_identity_service
|
||||
get_token.assert_called_once_with(username='admin', password='pw',
|
||||
tenant_name='admin', auth_url='auth')
|
||||
mock_hc.assert_called_once_with('1', endpoint='heat_endpoint',
|
||||
token=mock_token_value)
|
||||
|
||||
@mock.patch('keystoneauth1.session.Session')
|
||||
@mock.patch('keystoneauth1.identity.v3.Password')
|
||||
@mock.patch('heatclient.client.Client')
|
||||
@mock.patch('keystoneclient.v3.client.Client')
|
||||
def test_keystone_v3(self, mock_ksc, mock_hc, mock_password, mock_session):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USERNAME', 'admin'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PASSWORD', 'pw'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_AUTH_URL', 'auth/v3'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PROJECT_NAME', 'admin'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USER_DOMAIN_ID',
|
||||
'default'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PROJECT_DOMAIN_ID',
|
||||
'default'))
|
||||
mock_auth = mock.Mock()
|
||||
mock_password.return_value = mock_auth
|
||||
mock_session_inst = mock.Mock()
|
||||
mock_session.return_value = mock_session_inst
|
||||
mock_ks_client = mock.Mock()
|
||||
mock_ksc.return_value = mock_ks_client
|
||||
mock_ks_client.get_raw_token_from_identity_service.return_value = (
|
||||
V3_TOKEN_DATA)
|
||||
mock_token_value = 'fake_v3_token'
|
||||
deploy._get_heat_client()
|
||||
mock_password.assert_called_once_with(auth_url='auth/v3',
|
||||
username='admin',
|
||||
password='pw',
|
||||
project_name='admin',
|
||||
user_domain_name='default',
|
||||
project_domain_name='default'
|
||||
)
|
||||
mock_session.assert_called_once_with(auth=mock_auth)
|
||||
get_token = mock_ks_client.get_raw_token_from_identity_service
|
||||
get_token.assert_called_once_with(username='admin', password='pw',
|
||||
project_name='admin',
|
||||
auth_url='auth/v3',
|
||||
user_domain_name='default',
|
||||
project_domain_name='default')
|
||||
mock_hc.assert_called_once_with('1', endpoint='heat_endpoint',
|
||||
token=mock_token_value)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -42,7 +42,10 @@ class TestOpenStackBmcInit(unittest.TestCase):
|
|||
user='admin',
|
||||
password='password',
|
||||
tenant='admin',
|
||||
auth_url='http://keystone:5000'
|
||||
auth_url='http://keystone:5000',
|
||||
project='',
|
||||
user_domain='',
|
||||
project_domain=''
|
||||
)
|
||||
if old_nova:
|
||||
mock_nova.assert_called_once_with(2, 'admin', 'password', 'admin',
|
||||
|
@ -60,16 +63,47 @@ class TestOpenStackBmcInit(unittest.TestCase):
|
|||
@mock.patch('openstack_virtual_baremetal.openstackbmc.nc.__version__',
|
||||
('6', '0', '0'))
|
||||
def test_init_6(self, mock_find_instance, mock_nova, mock_bmc_init,
|
||||
mock_log):
|
||||
mock_log):
|
||||
self._test_init(mock_find_instance, mock_nova, mock_bmc_init, mock_log)
|
||||
|
||||
@mock.patch('openstack_virtual_baremetal.openstackbmc.nc.__version__',
|
||||
('7', '0', '0'))
|
||||
def test_init_7(self, mock_find_instance, mock_nova, mock_bmc_init,
|
||||
mock_log):
|
||||
mock_log):
|
||||
self._test_init(mock_find_instance, mock_nova, mock_bmc_init, mock_log,
|
||||
old_nova=False)
|
||||
|
||||
def test_init_v3(self, mock_find_instance, mock_nova, mock_bmc_init,
|
||||
mock_log, old_nova=True):
|
||||
mock_client = mock.Mock()
|
||||
mock_server = mock.Mock()
|
||||
mock_server.name = 'foo-instance'
|
||||
mock_client.servers.get.return_value = mock_server
|
||||
mock_nova.return_value = mock_client
|
||||
mock_find_instance.return_value = 'abc-123'
|
||||
bmc = openstackbmc.OpenStackBmc(authdata={'admin': 'password'},
|
||||
port=623,
|
||||
address='::ffff:127.0.0.1',
|
||||
instance='foo',
|
||||
user='admin',
|
||||
password='password',
|
||||
tenant='',
|
||||
auth_url='http://keystone:5000/v3',
|
||||
project='admin',
|
||||
user_domain='default',
|
||||
project_domain='default'
|
||||
)
|
||||
mock_nova.assert_called_once_with(2, 'admin', 'password',
|
||||
auth_url='http://keystone:5000/v3',
|
||||
project_name='admin',
|
||||
user_domain_name='default',
|
||||
project_domain_name='default')
|
||||
mock_find_instance.assert_called_once_with('foo')
|
||||
self.assertEqual('abc-123', bmc.instance)
|
||||
mock_client.servers.get.assert_called_once_with('abc-123')
|
||||
mock_log.assert_called_once_with('Managing instance: %s UUID: %s' %
|
||||
('foo-instance', 'abc-123'))
|
||||
|
||||
@mock.patch('openstack_virtual_baremetal.openstackbmc.nc.__version__',
|
||||
('6', '0', '0'))
|
||||
@mock.patch('time.sleep')
|
||||
|
@ -88,7 +122,10 @@ class TestOpenStackBmcInit(unittest.TestCase):
|
|||
user='admin',
|
||||
password='password',
|
||||
tenant='admin',
|
||||
auth_url='http://keystone:5000'
|
||||
auth_url='http://keystone:5000',
|
||||
project='',
|
||||
user_domain='',
|
||||
project_domain=''
|
||||
)
|
||||
mock_nova.assert_called_once_with(2, 'admin', 'password', 'admin',
|
||||
'http://keystone:5000')
|
||||
|
@ -119,7 +156,10 @@ class TestOpenStackBmc(unittest.TestCase):
|
|||
user='admin',
|
||||
password='password',
|
||||
tenant='admin',
|
||||
auth_url='http://keystone:5000'
|
||||
auth_url='http://keystone:5000',
|
||||
project='',
|
||||
user_domain='',
|
||||
project_domain=''
|
||||
)
|
||||
self.bmc.novaclient = self.mock_client
|
||||
self.bmc.instance = 'abc-123'
|
||||
|
@ -321,7 +361,10 @@ class TestMain(unittest.TestCase):
|
|||
user='admin',
|
||||
password='password',
|
||||
tenant='admin',
|
||||
auth_url='http://host:5000/v2.0'
|
||||
auth_url='http://host:5000/v2.0',
|
||||
project='',
|
||||
user_domain='',
|
||||
project_domain=''
|
||||
)
|
||||
mock_instance.listen.assert_called_once_with()
|
||||
|
||||
|
@ -342,6 +385,9 @@ class TestMain(unittest.TestCase):
|
|||
user='admin',
|
||||
password='password',
|
||||
tenant='admin',
|
||||
auth_url='http://host:5000/v2.0'
|
||||
auth_url='http://host:5000/v2.0',
|
||||
project='',
|
||||
user_domain='',
|
||||
project_domain=''
|
||||
)
|
||||
mock_instance.listen.assert_called_once_with()
|
||||
|
|
|
@ -137,6 +137,27 @@ parameters:
|
|||
default: http://127.0.0.1:5000/v2.0
|
||||
description: The Keystone auth_url of the host cloud
|
||||
|
||||
os_project:
|
||||
type: string
|
||||
default: ''
|
||||
description: |
|
||||
The project for os_user. Required for Keystone v3, should be left
|
||||
blank for Keystone v2.
|
||||
|
||||
os_user_domain:
|
||||
type: string
|
||||
default: ''
|
||||
description: |
|
||||
The user domain for os_user. Required for Keystone v3, should be left
|
||||
blank for Keystone v2.
|
||||
|
||||
os_project_domain:
|
||||
type: string
|
||||
default: ''
|
||||
description: |
|
||||
The project domain for os_user. Required for Keystone v3, should be left
|
||||
blank for Keystone v2.
|
||||
|
||||
resources:
|
||||
provision_network:
|
||||
type: OS::Neutron::Net
|
||||
|
@ -209,6 +230,9 @@ resources:
|
|||
os_password: {get_param: os_password}
|
||||
os_tenant: {get_param: os_tenant}
|
||||
os_auth_url: {get_param: os_auth_url}
|
||||
os_project: {get_param: os_project}
|
||||
os_user_domain: {get_param: os_user_domain}
|
||||
os_project_domain: {get_param: os_project_domain}
|
||||
|
||||
outputs:
|
||||
undercloud_host_floating_ip:
|
||||
|
|
|
@ -87,6 +87,27 @@ parameters:
|
|||
default: http://127.0.0.1:5000/v2.0
|
||||
description: The Keystone auth_url of the host cloud
|
||||
|
||||
os_project:
|
||||
type: string
|
||||
default: ''
|
||||
description: |
|
||||
The project for os_user. Required for Keystone v3, should be left
|
||||
blank for Keystone v2.
|
||||
|
||||
os_user_domain:
|
||||
type: string
|
||||
default: ''
|
||||
description: |
|
||||
The user domain for os_user. Required for Keystone v3, should be left
|
||||
blank for Keystone v2.
|
||||
|
||||
os_project_domain:
|
||||
type: string
|
||||
default: ''
|
||||
description: |
|
||||
The project domain for os_user. Required for Keystone v3, should be left
|
||||
blank for Keystone v2.
|
||||
|
||||
default_sg:
|
||||
type: string
|
||||
default: all_sg
|
||||
|
@ -154,6 +175,9 @@ resources:
|
|||
$os_password: {get_param: os_password}
|
||||
$os_tenant: {get_param: os_tenant}
|
||||
$os_auth_url: {get_param: os_auth_url}
|
||||
$os_project: {get_param: os_project}
|
||||
$os_user_domain: {get_param: os_user_domain}
|
||||
$os_project_domain: {get_param: os_project_domain}
|
||||
$bm_node_count: {get_param: node_count}
|
||||
$bmc_prefix: {get_param: bmc_prefix}
|
||||
$bmc_utility: {get_attr: [bmc_port, fixed_ips, 0, ip_address]}
|
||||
|
|
Loading…
Reference in New Issue