#!/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, 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()