157 lines
5.6 KiB
Python
Executable File
157 lines
5.6 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# 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 logging
|
|
import os
|
|
import sys
|
|
|
|
import keystoneclient.exceptions as kc_exception
|
|
from keystoneclient.v3 import client
|
|
from oslo_config import cfg
|
|
|
|
from heat import version
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
DEBUG = False
|
|
USERNAME = os.environ.get('OS_USERNAME')
|
|
PASSWORD = os.environ.get('OS_PASSWORD')
|
|
AUTH_URL = os.environ.get('OS_AUTH_URL', '').replace('v2.0', 'v3')
|
|
TENANT_NAME = os.environ.get('OS_TENANT_NAME')
|
|
|
|
opts = [
|
|
cfg.StrOpt('stack-user-domain-name',
|
|
default="heat",
|
|
help="Name of domain to create for stack users."),
|
|
cfg.StrOpt('stack-domain-admin',
|
|
default="heat_stack_admin",
|
|
help="Keystone username with roles sufficient to manage users"
|
|
" and projects in the stack-user-domain"),
|
|
cfg.StrOpt('stack-domain-admin-password',
|
|
secret=True,
|
|
help="Password to set for stack-domain-admin"),
|
|
cfg.BoolOpt('insecure',
|
|
default=False,
|
|
help="If set, then the server's certificate will not "
|
|
"be verified."),
|
|
cfg.StrOpt('os-cacert',
|
|
help='Optional CA cert file to use in SSL connections.'),
|
|
cfg.StrOpt('os-cert',
|
|
help='Optional PEM-formatted certificate chain file.'),
|
|
cfg.StrOpt('os-key',
|
|
help='Optional PEM-formatted file that contains the '
|
|
'private key.'),
|
|
|
|
]
|
|
|
|
cfg.CONF.register_cli_opts(opts)
|
|
cfg.CONF(sys.argv[1:],
|
|
project='heat',
|
|
prog='heat-keystone-setup-domain',
|
|
version=version.version_info.version_string())
|
|
|
|
HEAT_DOMAIN_NAME = os.environ.get(
|
|
'HEAT_DOMAIN', cfg.CONF.stack_user_domain_name)
|
|
HEAT_DOMAIN_ADMIN = os.environ.get('HEAT_DOMAIN_ADMIN',
|
|
cfg.CONF.stack_domain_admin)
|
|
HEAT_DOMAIN_PASSWORD = os.environ.get('HEAT_DOMAIN_PASSWORD',
|
|
cfg.CONF.stack_domain_admin_password)
|
|
HEAT_DOMAIN_DESCRIPTION = 'Contains users and projects created by heat'
|
|
|
|
logger.debug("USERNAME=%s" % USERNAME)
|
|
logger.debug("AUTH_URL=%s" % AUTH_URL)
|
|
|
|
CACERT = os.environ.get('OS_CACERT', cfg.CONF.os_cacert)
|
|
CERT = os.environ.get('OS_CERT', cfg.CONF.os_cert)
|
|
KEY = os.environ.get('OS_KEY', cfg.CONF.os_key)
|
|
insecure = cfg.CONF.insecure
|
|
|
|
|
|
def main():
|
|
log_lvl = logging.DEBUG if DEBUG else logging.WARNING
|
|
logging.basicConfig(
|
|
format="%(levelname)s (%(module)s:%(lineno)d) %(message)s",
|
|
level=log_lvl)
|
|
logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING)
|
|
|
|
client_kwargs = {
|
|
'debug': DEBUG,
|
|
'username': USERNAME,
|
|
'password': PASSWORD,
|
|
'auth_url': AUTH_URL,
|
|
'endpoint': AUTH_URL,
|
|
'tenant_name': TENANT_NAME
|
|
}
|
|
|
|
if insecure:
|
|
client_kwargs['verify'] = False
|
|
else:
|
|
client_kwargs.update({
|
|
'cacert': CACERT,
|
|
'cert': CERT,
|
|
'key': KEY
|
|
})
|
|
|
|
c = client.Client(**client_kwargs)
|
|
c.authenticate()
|
|
|
|
# Create the heat domain
|
|
logger.info("Creating domain %s" % HEAT_DOMAIN_NAME)
|
|
try:
|
|
heat_domain = c.domains.create(name=HEAT_DOMAIN_NAME,
|
|
description=HEAT_DOMAIN_DESCRIPTION)
|
|
except kc_exception.Conflict:
|
|
logger.warning("Domain %s already exists" % HEAT_DOMAIN_NAME)
|
|
heat_domain = c.domains.list(name=HEAT_DOMAIN_NAME)[0]
|
|
if heat_domain.name != HEAT_DOMAIN_NAME:
|
|
logger.error("Unexpected filtered list response, please upgrade "
|
|
"keystoneclient to >= 0.5")
|
|
sys.exit(1)
|
|
except kc_exception.Forbidden:
|
|
logger.error("User '%s' is not authorized to perform this "
|
|
"operation, please try with other OS_USERNAME setting." %
|
|
USERNAME)
|
|
sys.exit(1)
|
|
|
|
# Create heat domain admin user
|
|
if not HEAT_DOMAIN_PASSWORD:
|
|
logger.error("Must export HEAT_DOMAIN_PASSWORD or use"
|
|
" --stack-domain-admin-password")
|
|
sys.exit(1)
|
|
|
|
try:
|
|
domain_admin = c.users.create(name=HEAT_DOMAIN_ADMIN,
|
|
password=HEAT_DOMAIN_PASSWORD,
|
|
domain=heat_domain,
|
|
description="Heat domain admin")
|
|
except kc_exception.Conflict:
|
|
logger.warning("User %s already exists" % HEAT_DOMAIN_ADMIN)
|
|
domain_admin = c.users.list(name=HEAT_DOMAIN_ADMIN)[0]
|
|
|
|
# Make the user a domain admin
|
|
roles_list = c.roles.list()
|
|
# FIXME(shardy): seems filtering roles by name currently doesn't work
|
|
admin_role = [r for r in roles_list
|
|
if r.name == 'admin'][0]
|
|
c.roles.grant(role=admin_role, user=domain_admin, domain=heat_domain)
|
|
|
|
print("\nPlease update your heat.conf with the following in [DEFAULT]\n")
|
|
print("stack_user_domain_id=%s" % heat_domain.id)
|
|
print("stack_domain_admin=%s" % HEAT_DOMAIN_ADMIN)
|
|
print("stack_domain_admin_password=%s" % HEAT_DOMAIN_PASSWORD)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|