Use OS command line parameters for credentials
In order to comply with OpenStack de-facto standards user's credentials must be supplied via appropriate --os parameters. Closes-bug: #1535417 Change-Id: Ifd186f0d703a840635f6f111c379338e93fde0a3
This commit is contained in:
@@ -48,12 +48,6 @@ class Action(object):
|
||||
"""Entry point for all actions subclasses
|
||||
"""
|
||||
APIClient.debug_mode(debug=params.debug)
|
||||
if getattr(params, 'user') and getattr(params, 'password'):
|
||||
APIClient.user = params.user
|
||||
APIClient.password = params.password
|
||||
# tenant is set by default to 'admin' in parser.add_argument
|
||||
APIClient.tenant = params.tenant
|
||||
APIClient.initialize_keystone_client()
|
||||
|
||||
self.serializer = Serializer.from_params(params)
|
||||
if self.flag_func_map is not None:
|
||||
|
||||
@@ -23,7 +23,9 @@ from fuelclient.cli.error import exceptions_decorator
|
||||
from fuelclient.cli.error import ParserException
|
||||
from fuelclient.cli.serializers import Serializer
|
||||
from fuelclient import consts
|
||||
from fuelclient import fuelclient_settings
|
||||
from fuelclient import profiler
|
||||
from fuelclient import utils
|
||||
|
||||
|
||||
class Parser(object):
|
||||
@@ -96,8 +98,8 @@ class Parser(object):
|
||||
self.generate_actions()
|
||||
self.add_version_args()
|
||||
self.add_debug_arg()
|
||||
self.add_keystone_credentials_args()
|
||||
self.add_serializers_args()
|
||||
utils.add_os_cli_parameters(self.parser)
|
||||
|
||||
def generate_actions(self):
|
||||
for action, action_object in actions.items():
|
||||
@@ -129,7 +131,12 @@ class Parser(object):
|
||||
if len(self.args) < 2:
|
||||
self.parser.print_help()
|
||||
sys.exit(0)
|
||||
|
||||
parsed_params = self.parser.parse_args(self.args[1:])
|
||||
|
||||
settings = fuelclient_settings.get_settings()
|
||||
settings.update_from_command_line_options(parsed_params)
|
||||
|
||||
if parsed_params.action not in actions:
|
||||
self.parser.print_help()
|
||||
sys.exit(0)
|
||||
@@ -169,32 +176,6 @@ class Parser(object):
|
||||
default=False
|
||||
)
|
||||
|
||||
def add_keystone_credentials_args(self):
|
||||
self.credential_flags.append('--user')
|
||||
self.credential_flags.append('--password')
|
||||
self.credential_flags.append('--tenant')
|
||||
self.parser.add_argument(
|
||||
"--user",
|
||||
dest="user",
|
||||
type=str,
|
||||
help="credentials for keystone authentication user",
|
||||
default=None
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--password",
|
||||
dest="password",
|
||||
type=str,
|
||||
help="credentials for keystone authentication password",
|
||||
default=None
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--tenant",
|
||||
dest="tenant",
|
||||
type=str,
|
||||
help="credentials for keystone authentication tenant",
|
||||
default="admin"
|
||||
)
|
||||
|
||||
def add_version_args(self):
|
||||
for args in (get_version_arg(), get_fuel_version_arg()):
|
||||
self.parser.add_argument(*args["args"], **args["params"])
|
||||
|
||||
@@ -44,9 +44,6 @@ class Client(object):
|
||||
self.keystone_base = urlparse.urljoin(self.root, "/keystone/v2.0")
|
||||
self.api_root = urlparse.urljoin(self.root, "/api/v1/")
|
||||
self.ostf_root = urlparse.urljoin(self.root, "/ostf/")
|
||||
self.user = conf.KEYSTONE_USER
|
||||
self.password = conf.KEYSTONE_PASS
|
||||
self.tenant = 'admin'
|
||||
self._keystone_client = None
|
||||
self._auth_required = None
|
||||
self._session = None
|
||||
@@ -122,17 +119,22 @@ class Client(object):
|
||||
return self._keystone_client
|
||||
|
||||
def update_own_password(self, new_pass):
|
||||
conf = fuelclient_settings.get_settings()
|
||||
|
||||
if self.auth_token:
|
||||
self.keystone_client.users.update_own_password(
|
||||
self.password, new_pass)
|
||||
self.keystone_client.users.update_own_password(conf.OS_PASSWORD,
|
||||
new_pass)
|
||||
|
||||
def initialize_keystone_client(self):
|
||||
conf = fuelclient_settings.get_settings()
|
||||
|
||||
if self.auth_required:
|
||||
self._keystone_client = auth_client.Client(
|
||||
username=self.user,
|
||||
password=self.password,
|
||||
auth_url=self.keystone_base,
|
||||
tenant_name=self.tenant)
|
||||
username=conf.OS_USERNAME,
|
||||
password=conf.OS_PASSWORD,
|
||||
tenant_name=conf.OS_TENANT_NAME)
|
||||
|
||||
self._keystone_client.session.auth = self._keystone_client
|
||||
self._keystone_client.authenticate()
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
# Connection settings
|
||||
SERVER_ADDRESS: "127.0.0.1"
|
||||
SERVER_PORT: "8000"
|
||||
KEYSTONE_USER:
|
||||
KEYSTONE_PASS:
|
||||
OS_USERNAME:
|
||||
OS_PASSWORD:
|
||||
# There's a need to provide default value for
|
||||
# tenant name until fuel-library is updated.
|
||||
# After that, it will be removed.
|
||||
OS_TENANT_NAME: "admin"
|
||||
HTTP_PROXY: null
|
||||
HTTP_TIMEOUT: 10
|
||||
|
||||
|
||||
@@ -27,10 +27,12 @@ from fuelclient.cli import error
|
||||
_SETTINGS = None
|
||||
|
||||
# Format: old parameter: new parameter or None
|
||||
DEPRECATION_TABLE = {'LISTEN_PORT': 'SERVER_PORT'}
|
||||
DEPRECATION_TABLE = {'LISTEN_PORT': 'SERVER_PORT',
|
||||
'KEYSTONE_USER': 'OS_USERNAME',
|
||||
'KEYSTONE_PASS': 'OS_PASSWORD'}
|
||||
|
||||
# Format: parameter: fallback parameter
|
||||
FALLBACK_TABLE = {'SERVER_PORT': 'LISTEN_PORT'}
|
||||
FALLBACK_TABLE = {DEPRECATION_TABLE[p]: p for p in DEPRECATION_TABLE}
|
||||
|
||||
|
||||
class FuelClientSettings(object):
|
||||
@@ -101,25 +103,40 @@ class FuelClientSettings(object):
|
||||
if k in os.environ:
|
||||
self.config[k] = os.environ[k]
|
||||
|
||||
def _check_deprecated(self):
|
||||
"""Looks for deprecated options and prints warnings if finds any."""
|
||||
def _print_deprecation_warning(self, old_option, new_option=None):
|
||||
"""Print deprecation warning for an option."""
|
||||
|
||||
dep_msg = ('DEPRECATION WARNING: {old} parameter was deprecated and '
|
||||
'will not be supported in the next version of '
|
||||
'python-fuelclient.{repl}')
|
||||
repl_msg = ' Please replace this parameter with {0}'
|
||||
deprecation_tpl = ('DEPRECATION WARNING: {} parameter was '
|
||||
'deprecated and will not be supported in the next '
|
||||
'version of python-fuelclient.')
|
||||
replace_tpl = ' Please replace this parameter with {}'
|
||||
|
||||
deprecation = deprecation_tpl.format(old_option)
|
||||
replace = '' if new_option is None else replace_tpl.format(new_option)
|
||||
|
||||
six.print_(deprecation, end='')
|
||||
six.print_(replace)
|
||||
|
||||
def _check_deprecated(self):
|
||||
"""Looks for deprecated options in user's configuration."""
|
||||
|
||||
dep_opts = [opt for opt in self.config if opt in DEPRECATION_TABLE]
|
||||
|
||||
for opt in dep_opts:
|
||||
replace = ''
|
||||
|
||||
if DEPRECATION_TABLE.get(opt) is not None:
|
||||
replace = repl_msg.format(DEPRECATION_TABLE.get(opt))
|
||||
new_opt = DEPRECATION_TABLE.get(opt)
|
||||
|
||||
msg = dep_msg.format(old=opt, repl=replace)
|
||||
# Clean up new option if it was not set by a user
|
||||
# Produce a warning, if both old and new options are set.
|
||||
if self.config.get(new_opt) is None:
|
||||
self.config.pop(new_opt, None)
|
||||
else:
|
||||
six.print_('WARNING: configuration contains both {old} and '
|
||||
'{new} options set. Since {old} was deprecated, '
|
||||
'only the value of {new} '
|
||||
'will be used.'.format(old=opt, new=new_opt))
|
||||
|
||||
six.print_(msg)
|
||||
self._print_deprecation_warning(opt, new_opt)
|
||||
|
||||
def populate_default_settings(self, source, destination):
|
||||
"""Puts default configuration file to a user's home directory."""
|
||||
@@ -137,6 +154,16 @@ class FuelClientSettings(object):
|
||||
'directory is writable')
|
||||
raise error.SettingsException(msg.format(dst_dir))
|
||||
|
||||
def update_from_command_line_options(self, options):
|
||||
"""Update parameters from valid command line options."""
|
||||
|
||||
for param in self.config:
|
||||
opt_name = param.lower()
|
||||
|
||||
value = getattr(options, opt_name, None)
|
||||
if value is not None:
|
||||
self.config[param] = value
|
||||
|
||||
def dump(self):
|
||||
return yaml.dump(self.config)
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ from cliff import app
|
||||
from cliff.commandmanager import CommandManager
|
||||
|
||||
from fuelclient.actions import fuel_version
|
||||
from fuelclient import fuelclient_settings
|
||||
from fuelclient import utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@@ -34,6 +36,7 @@ class FuelClient(app.App):
|
||||
|
||||
def build_option_parser(self, description, version, argparse_kwargs=None):
|
||||
"""Overrides default options for backwards compatibility."""
|
||||
|
||||
p_inst = super(FuelClient, self)
|
||||
parser = p_inst.build_option_parser(description=description,
|
||||
version=version,
|
||||
@@ -46,6 +49,8 @@ class FuelClient(app.App):
|
||||
"WARNING: deprecated since 7.0 release. "
|
||||
"Please use fuel-version command instead"))
|
||||
|
||||
utils.add_os_cli_parameters(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def configure_logging(self):
|
||||
@@ -65,6 +70,14 @@ class FuelClient(app.App):
|
||||
'urllib3.connectionpool'):
|
||||
logging.getLogger(logger_name).setLevel(logging.WARNING)
|
||||
|
||||
def run(self, argv):
|
||||
options, _ = self.parser.parse_known_args(argv)
|
||||
|
||||
settings = fuelclient_settings.get_settings()
|
||||
settings.update_from_command_line_options(options)
|
||||
|
||||
return super(FuelClient, self).run(argv)
|
||||
|
||||
|
||||
def main(argv=sys.argv[1:]):
|
||||
fuelclient_app = FuelClient(
|
||||
|
||||
@@ -75,16 +75,41 @@ class TestSettings(base.UnitTestCase):
|
||||
|
||||
@mock.patch('six.print_')
|
||||
def test_deprecated_option_produces_warning(self, m_print):
|
||||
expected_waring = ('DEPRECATION WARNING: LISTEN_PORT parameter was '
|
||||
'deprecated and will not be supported in the next '
|
||||
'version of python-fuelclient. Please replace this '
|
||||
'parameter with SERVER_PORT')
|
||||
expected_warings = [mock.call('DEPRECATION WARNING: LISTEN_PORT '
|
||||
'parameter was deprecated and will not '
|
||||
'be supported in the next version of '
|
||||
'python-fuelclient.', end=''),
|
||||
mock.call(' Please replace this '
|
||||
'parameter with SERVER_PORT')]
|
||||
|
||||
m = mock.mock_open(read_data='LISTEN_PORT: 9000')
|
||||
with mock.patch('fuelclient.fuelclient_settings.open', m):
|
||||
fuelclient_settings.get_settings()
|
||||
|
||||
m_print.assert_called_once_with(expected_waring)
|
||||
m_print.assert_has_calls(expected_warings, any_order=False)
|
||||
|
||||
@mock.patch('six.print_')
|
||||
def test_both_deprecated_and_new_options_produce_warning(self, m_print):
|
||||
expected_waring = ('WARNING: configuration contains both '
|
||||
'LISTEN_PORT and SERVER_PORT options set. Since '
|
||||
'LISTEN_PORT was deprecated, only the value of '
|
||||
'SERVER_PORT will be used.')
|
||||
|
||||
m = mock.mock_open(read_data='LISTEN_PORT: 9000\nSERVER_PORT: 9000')
|
||||
with mock.patch('fuelclient.fuelclient_settings.open', m):
|
||||
fuelclient_settings.get_settings()
|
||||
|
||||
m_print.assert_has_calls([mock.call(expected_waring)])
|
||||
|
||||
@mock.patch('six.print_')
|
||||
def test_set_deprecated_option_overwrites_unset_new_option(self, m_print):
|
||||
m = mock.mock_open(read_data='KEYSTONE_PASS: "admin"\n'
|
||||
'OS_PASSWORD:\n')
|
||||
with mock.patch('fuelclient.fuelclient_settings.open', m):
|
||||
settings = fuelclient_settings.get_settings()
|
||||
|
||||
self.assertEqual('admin', settings.OS_PASSWORD)
|
||||
self.assertNotIn('OS_PASSWORD', settings.config)
|
||||
|
||||
def test_fallback_to_deprecated_option(self):
|
||||
m = mock.mock_open(read_data='LISTEN_PORT: 9000')
|
||||
@@ -92,3 +117,26 @@ class TestSettings(base.UnitTestCase):
|
||||
settings = fuelclient_settings.get_settings()
|
||||
|
||||
self.assertEqual(9000, settings.LISTEN_PORT)
|
||||
|
||||
def test_update_from_cli_params(self):
|
||||
test_config_text = ('SERVER_ADDRESS: "127.0.0.1"\n'
|
||||
'SERVER_PORT: "8000"\n'
|
||||
'OS_USERNAME: "admin"\n'
|
||||
'OS_PASSWORD:\n'
|
||||
'OS_TENANT_NAME:\n')
|
||||
|
||||
test_parsed_args = mock.Mock(os_password='test_password',
|
||||
server_port="3000",
|
||||
os_username=None)
|
||||
del test_parsed_args.server_address
|
||||
del test_parsed_args.os_tenant_name
|
||||
|
||||
m = mock.mock_open(read_data=test_config_text)
|
||||
with mock.patch('fuelclient.fuelclient_settings.open', m):
|
||||
settings = fuelclient_settings.get_settings()
|
||||
|
||||
settings.update_from_command_line_options(test_parsed_args)
|
||||
|
||||
self.assertEqual('3000', settings.SERVER_PORT)
|
||||
self.assertEqual('test_password', settings.OS_PASSWORD)
|
||||
self.assertEqual('admin', settings.OS_USERNAME)
|
||||
|
||||
@@ -14,87 +14,92 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from mock import Mock
|
||||
from mock import patch
|
||||
from six.moves import urllib
|
||||
import fixtures
|
||||
import mock
|
||||
|
||||
from fuelclient import fuelclient_settings
|
||||
from fuelclient.tests.unit.v1 import base
|
||||
|
||||
|
||||
@mock.patch('keystoneclient.v2_0.client.Client',
|
||||
return_value=mock.Mock(auth_token=''))
|
||||
class TestAuthentication(base.UnitTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAuthentication, self).setUp()
|
||||
|
||||
self.auth_required_mock.return_value = True
|
||||
|
||||
def validate_credentials_response(self,
|
||||
args,
|
||||
username=None,
|
||||
password=None,
|
||||
tenant_name=None):
|
||||
conf = fuelclient_settings.get_settings()
|
||||
|
||||
self.assertEqual(args['username'], username)
|
||||
self.assertEqual(args['password'], password)
|
||||
self.assertEqual(args['tenant_name'], tenant_name)
|
||||
pr = urllib.parse.urlparse(args['auth_url'])
|
||||
self.assertEqual(conf.SERVER_ADDRESS, pr.hostname)
|
||||
self.assertEqual(int(conf.SERVER_PORT), int(pr.port))
|
||||
self.assertEqual('/keystone/v2.0', pr.path)
|
||||
|
||||
@patch('fuelclient.client.auth_client')
|
||||
def test_credentials(self, mkeystone_cli):
|
||||
self.m_request.get('/api/v1/nodes/', json={})
|
||||
|
||||
mkeystone_cli.return_value = Mock(auth_token='')
|
||||
self.execute(
|
||||
['fuel', '--user=a', '--password=b', 'node'])
|
||||
self.validate_credentials_response(
|
||||
mkeystone_cli.Client.call_args[1],
|
||||
self.useFixture(fixtures.MockPatchObject(fuelclient_settings,
|
||||
'_SETTINGS',
|
||||
None))
|
||||
|
||||
def validate_credentials_response(self, m_client, username=None,
|
||||
password=None, tenant_name=None):
|
||||
"""Checks whether keystone was called properly."""
|
||||
|
||||
conf = fuelclient_settings.get_settings()
|
||||
|
||||
expected_url = 'http://{}:{}{}'.format(conf.SERVER_ADDRESS,
|
||||
conf.SERVER_PORT,
|
||||
'/keystone/v2.0')
|
||||
m_client.__init__assert_called_once_with(auth_url=expected_url,
|
||||
username=username,
|
||||
password=password,
|
||||
tenant_name=tenant_name)
|
||||
|
||||
def test_credentials_settings(self, mkeystone_cli):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USERNAME'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PASSWORD'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_TENANT_NAME'))
|
||||
|
||||
conf = fuelclient_settings.get_settings()
|
||||
conf.config['OS_USERNAME'] = 'test_user'
|
||||
conf.config['OS_PASSWORD'] = 'test_password'
|
||||
conf.config['OS_TENANT_NAME'] = 'test_tenant_name'
|
||||
|
||||
self.execute(['fuel', 'node'])
|
||||
self.validate_credentials_response(mkeystone_cli,
|
||||
username='test_user',
|
||||
password='test_password',
|
||||
tenant_name='test_tenant_name')
|
||||
|
||||
def test_credentials_cli(self, mkeystone_cli):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USERNAME'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PASSWORD'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_TENANT_NAME'))
|
||||
|
||||
self.execute(['fuel', '--os-username=a', '--os-tenant-name=admin',
|
||||
'--os-password=b', 'node'])
|
||||
self.validate_credentials_response(mkeystone_cli,
|
||||
username='a',
|
||||
password='b',
|
||||
tenant_name='admin'
|
||||
)
|
||||
self.execute(
|
||||
['fuel', '--user=a', '--password', 'b', 'node'])
|
||||
self.validate_credentials_response(
|
||||
mkeystone_cli.Client.call_args[1],
|
||||
username='a',
|
||||
password='b',
|
||||
tenant_name='admin'
|
||||
)
|
||||
self.execute(
|
||||
['fuel', '--user=a', '--password=b', '--tenant=t', 'node'])
|
||||
self.validate_credentials_response(
|
||||
mkeystone_cli.Client.call_args[1],
|
||||
username='a',
|
||||
password='b',
|
||||
tenant_name='t'
|
||||
)
|
||||
self.execute(
|
||||
['fuel', '--user', 'a', '--password', 'b', '--tenant', 't',
|
||||
'node'])
|
||||
self.validate_credentials_response(
|
||||
mkeystone_cli.Client.call_args[1],
|
||||
username='a',
|
||||
password='b',
|
||||
tenant_name='t'
|
||||
)
|
||||
self.execute(
|
||||
['fuel', 'node', '--user=a', '--password=b', '--tenant=t'])
|
||||
self.validate_credentials_response(
|
||||
mkeystone_cli.Client.call_args[1],
|
||||
username='a',
|
||||
password='b',
|
||||
tenant_name='t'
|
||||
)
|
||||
self.execute(
|
||||
['fuel', 'node', '--user', 'a', '--password', 'b',
|
||||
'--tenant', 't'])
|
||||
self.validate_credentials_response(
|
||||
mkeystone_cli.Client.call_args[1],
|
||||
username='a',
|
||||
password='b',
|
||||
tenant_name='t'
|
||||
)
|
||||
tenant_name='admin')
|
||||
|
||||
def test_authentication_env_variables(self, mkeystone_cli):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USERNAME', 'name'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PASSWORD', 'pass'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_TENANT_NAME', 'ten'))
|
||||
|
||||
self.execute(['fuel', 'node'])
|
||||
self.validate_credentials_response(mkeystone_cli,
|
||||
username='name',
|
||||
password='pass',
|
||||
tenant_name='ten')
|
||||
|
||||
def test_credentials_override(self, mkeystone_cli):
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_USERNAME'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_PASSWORD', 'var_p'))
|
||||
self.useFixture(fixtures.EnvironmentVariable('OS_TENANT_NAME', 'va_t'))
|
||||
|
||||
conf = fuelclient_settings.get_settings()
|
||||
conf.config['OS_USERNAME'] = 'conf_user'
|
||||
conf.config['OS_PASSWORD'] = 'conf_password'
|
||||
conf.config['OS_TENANT_NAME'] = 'conf_tenant_name'
|
||||
|
||||
self.execute(['fuel', '--os-tenant-name=cli_tenant', 'node'])
|
||||
self.validate_credentials_response(mkeystone_cli,
|
||||
username='conf_user',
|
||||
password='var_p',
|
||||
tenant_name='cli_tenant')
|
||||
|
||||
@@ -108,3 +108,18 @@ class BaseCLITest(oslo_base.BaseTestCase):
|
||||
expected_data,
|
||||
mock.ANY,
|
||||
mock.ANY)
|
||||
|
||||
@mock.patch('fuelclient.fuelclient_settings.'
|
||||
'FuelClientSettings.update_from_command_line_options')
|
||||
def test_settings_override_called(self, m_update):
|
||||
cmd = ('--os-password tpass --os-username tname --os-tenant-name tten '
|
||||
'node list')
|
||||
|
||||
self.exec_command(cmd)
|
||||
|
||||
m_update.assert_called_once_with(mock.ANY)
|
||||
passed_settings = m_update.call_args[0][0]
|
||||
|
||||
self.assertEqual('tname', passed_settings.os_username)
|
||||
self.assertEqual('tpass', passed_settings.os_password)
|
||||
self.assertEqual('tten', passed_settings.os_tenant_name)
|
||||
|
||||
@@ -194,3 +194,22 @@ def safe_deserialize(loader):
|
||||
''.format(e.__class__.__name__,
|
||||
six.text_type(e)))
|
||||
return wrapper
|
||||
|
||||
|
||||
def add_os_cli_parameters(parser):
|
||||
parser.add_argument(
|
||||
'--os-auth-url', metavar='<auth-url>',
|
||||
help='Authentication URL, defaults to env[OS_AUTH_URL].')
|
||||
|
||||
parser.add_argument(
|
||||
'--os-tenant-name', metavar='<auth-tenant-name>',
|
||||
help='Authentication tenant name, defaults to '
|
||||
'env[OS_TENANT_NAME].')
|
||||
|
||||
parser.add_argument(
|
||||
'--os-username', metavar='<auth-username>',
|
||||
help='Authentication username, defaults to env[OS_USERNAME].')
|
||||
|
||||
parser.add_argument(
|
||||
'--os-password', metavar='<auth-password>',
|
||||
help='Authentication password, defaults to env[OS_PASSWORD].')
|
||||
|
||||
@@ -109,8 +109,9 @@ EOL
|
||||
# Connection settings
|
||||
SERVER_ADDRESS: "127.0.0.1"
|
||||
SERVER_PORT: "${NAILGUN_PORT}"
|
||||
KEYSTONE_USER: "admin"
|
||||
KEYSTONE_PASS: "admin"
|
||||
OS_USERNAME: "admin"
|
||||
OS_PASSWORD: "admin"
|
||||
OS_TENANT_NAME: "admin"
|
||||
EOL
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user