You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
6.1 KiB
166 lines
6.1 KiB
#!/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 os |
|
import sys |
|
|
|
import keystoneclient.exceptions as kc_exception |
|
from keystoneclient.v3 import client |
|
from oslo_config import cfg |
|
from oslo_log import log as logging |
|
|
|
from heat.common.i18n import _ |
|
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') |
|
PROJECT_NAME = os.environ.get('OS_PROJECT_NAME') |
|
USER_DOMAIN_NAME = os.environ.get('OS_USER_DOMAIN_NAME') |
|
PROJECT_DOMAIN_NAME = os.environ.get('OS_PROJECT_DOMAIN_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.')), |
|
|
|
] |
|
|
|
# Setup logging before registering additional options |
|
logging.register_options(cfg.CONF) |
|
extra_log_level_defaults = ['urllib3.connectionpool=WARNING'] |
|
logging.set_defaults( |
|
logging_context_format_string="%(levelname)s (%(module)s:" |
|
"%(lineno)d) %(message)s", |
|
default_log_levels=(logging.get_default_log_levels() + |
|
extra_log_level_defaults)) |
|
logging.setup(cfg.CONF, 'heat-keystone-setup-domain', |
|
version.version_info.version_string()) |
|
|
|
# Register additional options |
|
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' |
|
|
|
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(): |
|
client_kwargs = { |
|
'debug': DEBUG, |
|
'username': USERNAME, |
|
'password': PASSWORD, |
|
'auth_url': AUTH_URL, |
|
'endpoint': AUTH_URL, |
|
'project_name': PROJECT_NAME, |
|
'user_domain_name': USER_DOMAIN_NAME, |
|
'project_domain_name': PROJECT_DOMAIN_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, |
|
domain=heat_domain)[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()
|
|
|