diff --git a/packstack/installer/output_messages.py b/packstack/installer/output_messages.py index 295d6fdde..3a31e61f5 100644 --- a/packstack/installer/output_messages.py +++ b/packstack/installer/output_messages.py @@ -67,6 +67,17 @@ WARN_NM_ENABLED = ("Warning: NetworkManager is active on %s. OpenStack " "networking currently does not work on systems that have " "the Network Manager service enabled.") +WARN_IPA_INSTALLED = ("Warning: In order to join domain IPA hosts have their " + "DNS resolver set to CONFIG_IPA_HOST!") +WARN_IPA_CONTROLLER_SWIFT = ("Warning: FreeIPA was set up on controller node! " + "We had to switch swift_proxy port to 8081 and this " + "port isn't labeled properly so unless you set SElinux to " + "permissive mode, swift proxy won't work.") +WARN_IPA_CONTROLLER_HORIZON = ("Warning: FreeIPA was set up on controller node! " + "We couldn't set dashboard configuration from puppet-horizon. " + "Any Horizon SSL configuration will be ignored, dashboard will" + "be accessible from http and https with certificates " + "provided by ipa mod_nss configuration.") ERR_PING = "Error: the provided hostname is unreachable" ERR_SSH = "Error: could not connect to the ssh server: %s" diff --git a/packstack/modules/ospluginutils.py b/packstack/modules/ospluginutils.py index 63cffe054..46dd11060 100644 --- a/packstack/modules/ospluginutils.py +++ b/packstack/modules/ospluginutils.py @@ -106,6 +106,60 @@ def createFirewallResources(hiera_key, default_value='{}'): return "create_resources(packstack::firewall, %s)\n\n" % hiera_function +def createIpaHostResources(hiera_key, default_value='{}'): + hiera_function = "hiera('%s', %s)" % (hiera_key, default_value) + return "create_resources(ipa::hostadd, %s)\n\n" % hiera_function + + +def createIpaClientResources(hiera_key, default_value='{}'): + hiera_function = "hiera('%s', %s)" % (hiera_key, default_value) + return "create_resources(packstack::ipa_client, %s)\n\n" % hiera_function + + +def createIpaServiceResources(hiera_key, default_value='{}'): + hiera_function = "hiera('%s', %s)" % (hiera_key, default_value) + return "create_resources(ipa::serviceadd, %s)\n\n" % hiera_function + + +def createIpaCertmongerResources(hiera_key, default_value='{}'): + hiera_function = "hiera('%s', %s)" % (hiera_key, default_value) + return ("create_resources(certmonger::request_ipa_cert, %s)\n\n" + % hiera_function) + + +def generateIpaServiceManifests(config, ipa_host, ipa_service, ssl_key_file, + ssl_cert_file): + ipa_hosts = config['IPA_HOSTS_DICT'] + ipa_hostname = ipa_hosts.get(ipa_host) + ipa_server_service = dict() + key = "freeipa_service_%s_%s" % (ipa_host, ipa_service) + config_name = "FREEIPA_SERVICE_%s_%s" % (ipa_host, ipa_service) + ipa_server_service.setdefault(key, {}) + ipa_server_service[key]['name'] = ("%s/%s.packstack@PACKSTACK" + % (ipa_service, ipa_hostname)) + config[config_name] = ipa_server_service + manifestfile = "%s_ipa.pp" % config['CONFIG_IPA_HOST'] + manifestdata = createIpaServiceResources(config_name) + appendManifestFile(manifestfile, manifestdata) + + ipa_client_cert = dict() + key = "freeipa_cert_%s_%s" % (ipa_host, ipa_service) + config_name = "FREEIPA_CERTIFICATE_%s_%s" % (ipa_host, ipa_service) + ipa_client_cert.setdefault(key, {}) + ipa_client_cert[key]['name'] = ("openssl-%s/%s.packstack@PACKSTACK" + % (ipa_service, ipa_hostname)) + ipa_client_cert[key]['seclib'] = 'openssl' + ipa_client_cert[key]['principal'] = ("%s/%s.packstack@PACKSTACK" + % (ipa_service, ipa_hostname)) + ipa_client_cert[key]['key'] = ssl_key_file + ipa_client_cert[key]['cert'] = ssl_cert_file + ipa_client_cert[key]['hostname'] = "%s.packstack" % ipa_hostname + config[config_name] = ipa_client_cert + manifestfile = "%s_ipa_crts.pp" % ipa_host + manifestdata = createIpaCertmongerResources(config_name) + appendManifestFile(manifestfile, manifestdata, 'ipa-crts') + + def gethostlist(CONF): hosts = [] for key, value in CONF.items(): diff --git a/packstack/plugins/amqp_002.py b/packstack/plugins/amqp_003.py similarity index 87% rename from packstack/plugins/amqp_002.py rename to packstack/plugins/amqp_003.py index f89e89fce..377af2fb2 100644 --- a/packstack/plugins/amqp_002.py +++ b/packstack/plugins/amqp_003.py @@ -24,6 +24,7 @@ from packstack.modules.ospluginutils import appendManifestFile from packstack.modules.ospluginutils import createFirewallResources from packstack.modules.ospluginutils import getManifestTemplate +from packstack.modules.ospluginutils import generateIpaServiceManifests # ------------- AMQP Packstack Plugin Initialization -------------- @@ -156,6 +157,21 @@ def initConfig(controller): "NEED_CONFIRM": False, "CONDITION": False}, + {"CMD_OPTION": "amqp-ssl-cacert-file", + "USAGE": ("The filename of the CAcertificate that the AMQP service " + "is going to use for verification"), + "PROMPT": ("Enter the filename of the SSL CAcertificate for the AMQP" + " service"), + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty], + "DEFAULT_VALUE": "/etc/pki/tls/certs/amqp_selfcert.pem", + "MASK_INPUT": False, + "LOOSE_VALIDATION": True, + "CONF_NAME": "CONFIG_AMQP_SSL_CACERT_FILE", + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + {"CMD_OPTION": "amqp-ssl-key-file", "USAGE": ("The filename of the private key that the AMQP service " "is going to use"), @@ -245,13 +261,22 @@ def create_manifest(config, messages): config['CONFIG_AMQP_PROTOCOL'] = 'ssl' config['CONFIG_AMQP_CLIENTS_PORT'] = "5671" if config['CONFIG_AMQP_SSL_SELF_SIGNED'] == 'y': - server.append( - "openssl req -batch -new -x509 -nodes -keyout %s " - "-out %s -days 1095" - % (config['CONFIG_AMQP_SSL_KEY_FILE'], - config['CONFIG_AMQP_SSL_CERT_FILE']) - ) - server.execute() + if config['CONFIG_IPA_INSTALL'] != 'y': + server.append( + "openssl req -batch -new -x509 -nodes -keyout %s " + "-out %s -days 1095" + % (config['CONFIG_AMQP_SSL_KEY_FILE'], + config['CONFIG_AMQP_SSL_CERT_FILE']) + ) + server.execute() + else: + config['CONFIG_AMQP_SSL_CACERT_FILE'] = '/etc/ipa/ca.crt' + ipa_host = config['CONFIG_AMQP_HOST'] + ipa_service = 'AMQP' + ssl_key_file = config['CONFIG_AMQP_SSL_KEY_FILE'] + ssl_cert_file = config['CONFIG_AMQP_SSL_CERT_FILE'] + generateIpaServiceManifests(config, ipa_host, ipa_service, + ssl_key_file, ssl_cert_file) else: # Set default values config['CONFIG_AMQP_CLIENTS_PORT'] = "5672" diff --git a/packstack/plugins/ceilometer_800.py b/packstack/plugins/ceilometer_800.py index c27161b3e..0d0a6e2b2 100644 --- a/packstack/plugins/ceilometer_800.py +++ b/packstack/plugins/ceilometer_800.py @@ -26,6 +26,7 @@ from packstack.modules.ospluginutils import appendManifestFile from packstack.modules.ospluginutils import createFirewallResources from packstack.modules.ospluginutils import getManifestTemplate +from packstack.modules.ospluginutils import generateIpaServiceManifests # ------------- Ceilometer Packstack Plugin Initialization -------------- @@ -275,6 +276,16 @@ def create_manifest(config, messages): sentinel_fallbacks = '' config['CONFIG_REDIS_SENTINEL_FALLBACKS'] = sentinel_fallbacks + if (config['CONFIG_IPA_INSTALL'] == 'y' and + config['CONFIG_AMQP_ENABLE_SSL'] and + config['CONFIG_AMQP_SSL_SELF_SIGNED'] == 'y'): + ipa_host = config['CONFIG_CONTROLLER_HOST'] + ssl_key_file = '/etc/pki/tls/private/ssl_amqp_ceilometer.key' + ssl_cert_file = '/etc/pki/tls/certs/ssl_amqp_ceilometer.crt' + ipa_service = 'ceilometer' + generateIpaServiceManifests(config, ipa_host, ipa_service, + ssl_key_file, ssl_cert_file) + fw_details = dict() key = "ceilometer_api" fw_details.setdefault(key, {}) diff --git a/packstack/plugins/cinder_250.py b/packstack/plugins/cinder_250.py index 368bc4946..ea67275b8 100644 --- a/packstack/plugins/cinder_250.py +++ b/packstack/plugins/cinder_250.py @@ -30,6 +30,7 @@ from packstack.modules.ospluginutils import appendManifestFile from packstack.modules.ospluginutils import createFirewallResources from packstack.modules.ospluginutils import getManifestTemplate +from packstack.modules.ospluginutils import generateIpaServiceManifests # ------------------ Cinder Packstack Plugin initialization ------------------ @@ -729,6 +730,16 @@ def create_manifest(config, messages): if config['CONFIG_UNSUPPORTED'] != 'y': config['CONFIG_STORAGE_HOST'] = config['CONFIG_CONTROLLER_HOST'] + if (config['CONFIG_IPA_INSTALL'] == 'y' and + config['CONFIG_AMQP_ENABLE_SSL'] and + config['CONFIG_AMQP_SSL_SELF_SIGNED'] == 'y'): + ipa_host = config['CONFIG_STORAGE_HOST'] + ssl_key_file = '/etc/pki/tls/private/ssl_amqp_cinder.key' + ssl_cert_file = '/etc/pki/tls/certs/ssl_amqp_cinder.crt' + ipa_service = 'cinder' + generateIpaServiceManifests(config, ipa_host, ipa_service, + ssl_key_file, ssl_cert_file) + manifestdata = getManifestTemplate(get_mq(config, "cinder")) manifestfile = "%s_cinder.pp" % config['CONFIG_STORAGE_HOST'] manifestdata += getManifestTemplate("cinder") diff --git a/packstack/plugins/dashboard_500.py b/packstack/plugins/dashboard_500.py index 3e87af391..0fedec033 100644 --- a/packstack/plugins/dashboard_500.py +++ b/packstack/plugins/dashboard_500.py @@ -25,6 +25,7 @@ from packstack.modules.ospluginutils import appendManifestFile from packstack.modules.ospluginutils import getManifestTemplate +from packstack.modules.ospluginutils import generateIpaServiceManifests # ------------- Horizon Packstack Plugin Initialization -------------- @@ -129,7 +130,6 @@ def initSequences(controller): def create_manifest(config, messages): config["CONFIG_HORIZON_SECRET_KEY"] = uuid.uuid4().hex horizon_host = config['CONFIG_CONTROLLER_HOST'] - manifestfile = "%s_horizon.pp" % horizon_host proto = "http" config["CONFIG_HORIZON_PORT"] = 80 @@ -141,6 +141,9 @@ def create_manifest(config, messages): # Are we using the users cert/key files if config["CONFIG_SSL_CERT"]: + if config['CONFIG_IPA_HOST'] == config['CONFIG_CONTROLLER_HOST']: + raise RuntimeError("FreeIPA on same host as controller won't " + " work with user provided certificates.") ssl_cert = config["CONFIG_SSL_CERT"] ssl_key = config["CONFIG_SSL_KEY"] ssl_chain = config["CONFIG_SSL_CACHAIN"] @@ -163,11 +166,20 @@ def create_manifest(config, messages): host_resources.append((ssl_key, 'ssl_ps_server.key')) host_resources.append((ssl_chain, 'ssl_ps_chain.crt')) else: - messages.append( - "%sNOTE%s : A certificate was generated to be used for ssl, " - "You should change the ssl certificate configured in " - "/etc/httpd/conf.d/ssl.conf on %s to use a CA signed cert." - % (utils.COLORS['red'], utils.COLORS['nocolor'], horizon_host)) + if config['CONFIG_IPA_INSTALL'] == 'y': + ipa_host = config['CONFIG_CONTROLLER_HOST'] + ssl_key_file = '/etc/pki/tls/private/ssl_ps_server.key' + ssl_cert_file = '/etc/pki/tls/certs/ssl_ps_server.crt' + ipa_service = 'HTTP' + generateIpaServiceManifests(config, ipa_host, ipa_service, + ssl_key_file, ssl_cert_file) + else: + messages.append( + "%sNOTE%s : A certificate was generated to be used for " + "ssl, You should change the ssl certificate configured " + "in /etc/httpd/conf.d/ssl.conf on %s to use a CA signed " + "cert." % (utils.COLORS['red'], utils.COLORS['nocolor'], + horizon_host)) else: config["CONFIG_HORIZON_SSL"] = False @@ -180,6 +192,7 @@ def create_manifest(config, messages): if config["CONFIG_NEUTRON_FWAAS"] == 'y': config["CONFIG_HORIZON_NEUTRON_FW"] = True + manifestfile = "%s_horizon.pp" % horizon_host manifestdata = getManifestTemplate("horizon") appendManifestFile(manifestfile, manifestdata) diff --git a/packstack/plugins/freeipa_002.py b/packstack/plugins/freeipa_002.py new file mode 100644 index 000000000..94a7f0607 --- /dev/null +++ b/packstack/plugins/freeipa_002.py @@ -0,0 +1,210 @@ +# -*- coding: utf-8 -*- +# 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. + +""" +Installs and configures freeipa +""" + +from packstack.installer import validators +from packstack.installer import processors +from packstack.installer import utils +from packstack.installer import output_messages + +from packstack.modules.common import filtered_hosts +from packstack.modules.ospluginutils import getManifestTemplate +from packstack.modules.ospluginutils import appendManifestFile +from packstack.modules.ospluginutils import createFirewallResources +from packstack.modules.ospluginutils import createIpaHostResources +from packstack.modules.ospluginutils import createIpaClientResources + + +PLUGIN_NAME = "IPA" +PLUGIN_NAME_COLORED = utils.color_text(PLUGIN_NAME, 'blue') + + +def initConfig(controller): + conf_params = { + "IPA": [ + {"CMD_OPTION": "ipa-host", + "USAGE": ("The IP address of the server on which to install " + "the IPA service. It's stronly discouraged to " + "install IPA on controller node!"), + "PROMPT": "Enter the IP address of the IPA server", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_ssh], + "DEFAULT_VALUE": utils.get_localhost_ip(), + "MASK_INPUT": False, + "LOOSE_VALIDATION": True, + "CONF_NAME": "CONFIG_IPA_HOST", + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "ipa-dm-password", + "USAGE": "Password for IPA domain manager", + "PROMPT": "Enter the password for IPA domain manager", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty], + "PROCESSORS": [processors.process_password], + "DEFAULT_VALUE": "PW_PLACEHOLDER", + "MASK_INPUT": True, + "LOOSE_VALIDATION": True, + "CONF_NAME": "CONFIG_IPA_DM_PASSWORD", + "USE_DEFAULT": False, + "NEED_CONFIRM": True, + "CONDITION": False}, + + {"CMD_OPTION": "ipa-admin-password", + "USAGE": "Password for IPA admin user", + "PROMPT": "Enter the password for IPA admin user", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty], + "PROCESSORS": [processors.process_password], + "DEFAULT_VALUE": "PW_PLACEHOLDER", + "MASK_INPUT": True, + "LOOSE_VALIDATION": True, + "CONF_NAME": "CONFIG_IPA_ADMIN_PASSWORD", + "USE_DEFAULT": False, + "NEED_CONFIRM": True, + "CONDITION": False}, + ] + } + conf_groups = [ + {"GROUP_NAME": "IPA", + "DESCRIPTION": "IPA Config parameters", + "PRE_CONDITION": "CONFIG_IPA_INSTALL", + "PRE_CONDITION_MATCH": "y", + "POST_CONDITION": False, + "POST_CONDITION_MATCH": True}, + ] + for group in conf_groups: + params = conf_params[group["GROUP_NAME"]] + controller.addGroup(group, params) + + +def initSequences(controller): + config = controller.CONF + if config['CONFIG_IPA_INSTALL'] != 'y': + return + + ipa_hosts = dict() + for host in filtered_hosts(config, exclude=False): + server = utils.ScriptRunner(host) + server.append('hostname -s | head -n1') + retcode, hostname = server.execute() + if hostname != 'localhost': + server.append('hostname "$(hostname -s).packstack"') + server.execute() + ipa_hosts[host] = str(hostname).strip() + else: + raise RuntimeError("localhost is not a valid hostname") + if len(ipa_hosts.values()) != len(set(ipa_hosts.values())): + raise RuntimeError("Duplicate hostnames set on hosts") + # there is no other way to sneak ipa_hosts to other plugins than to put + # it into config :( + config['IPA_HOSTS_DICT'] = ipa_hosts + + ipasteps = [ + {'title': 'Adding IPA manifest entries', + 'functions': [create_manifest]} + ] + controller.addSequence("Installing IPA", [], [], ipasteps) + + +# -------------------------- step functions -------------------------- + +def create_manifest(config, messages): + # Yeah, ipa is demo and for development, sane user shouldn't use it + # we need to make sure he notices that. + msg = output_messages.WARN_IPA_INSTALLED + messages.append(utils.color_text(msg, 'yellow')) + + ipa_hosts = config['IPA_HOSTS_DICT'] + + if config['CONFIG_IPA_HOST'] == config['CONFIG_CONTROLLER_HOST']: + msg = output_messages.WARN_IPA_CONTROLLER_HORIZON + messages.append(utils.color_text(msg, 'yellow')) + + ipa_host = ipa_hosts.get(config['CONFIG_IPA_HOST']) + config['CONFIG_IPA_SERVER_HOSTNAME'] = ipa_host + + manifestfile = "%s_ipa.pp" % config['CONFIG_IPA_HOST'] + manifestdata = getManifestTemplate('ipa_server.pp') + + for ipaddress, hostname in ipa_hosts.items(): + if ipaddress != config['CONFIG_IPA_HOST']: + ipa_client_details = dict() + key = "freeipa_host_%s" % hostname + config_name = "FREEIPA_HOST_%s" % hostname + ipa_client_details.setdefault(key, {}) + ipa_client_details[key]['name'] = "%s.packstack" % hostname + ipa_client_details[key]['otp'] = "%s.packstack" % hostname + config[config_name] = ipa_client_details + manifestdata += createIpaHostResources(config_name) + + # All hosts should be able to talk to ipa + for host in filtered_hosts(config, exclude=False): + fw_details = dict() + ports = ['80', '443', '389', '636', '88', '464', '53'] + key = "freeipa_tcp_%s" % host + config_name = "FIREWALL_FREEIPA_TCP_RULES_%s" % host + fw_details.setdefault(key, {}) + fw_details[key]['service_name'] = "ipa_tcp" + fw_details[key]['ports'] = ports + fw_details[key]['chain'] = "INPUT" + fw_details[key]['proto'] = 'tcp' + fw_details[key]['host'] = "%s" % host + config[config_name] = fw_details + manifestdata += createFirewallResources(config_name) + + fw_details = dict() + key = "freeipa_udp_%s" % host + config_name = "FIREWALL_FREEIPA_UDP_RULES_%s" % host + fw_details.setdefault(key, {}) + fw_details[key]['service_name'] = "ipa_udp" + fw_details[key]['ports'] = ['88', '464', '53', '123'] + fw_details[key]['chain'] = "INPUT" + fw_details[key]['proto'] = 'udp' + fw_details[key]['host'] = "%s" % host + config[config_name] = fw_details + manifestdata += createFirewallResources(config_name) + + appendManifestFile(manifestfile, manifestdata, 'ipa-server') + + for ipaddress, hostname in ipa_hosts.items(): + if ipaddress != config['CONFIG_IPA_HOST']: + admin_install = False + else: + admin_install = True + manifestfile = "%s_ipa_client.pp" % ipaddress + ipa_client_details = dict() + key = "freeipa_client_%s" % hostname + config_name = "FREEIPA_CLIENT_%s" % hostname + ipa_server_hostname = config['CONFIG_IPA_SERVER_HOSTNAME'] + config['IPA_ADMIN_INSTALL'] = admin_install + ipa_client_details.setdefault(key, {}) + ipa_client_details[key]['ipa_hostname'] = hostname + ipa_client_details[key]['ipa_domain'] = 'packstack' + ipa_client_details[key]['ipa_host_ip'] = ipaddress + ipa_client_details[key]['ipa_server_hostname'] = ipa_server_hostname + ipa_client_details[key]['ipa_server_ip'] = config['CONFIG_IPA_HOST'] + ipa_client_details[key]['ipa_admin_install'] = admin_install + config[config_name] = ipa_client_details + manifestdata = createIpaClientResources(config_name) + appendManifestFile(manifestfile, manifestdata, 'ipa-client') + + for ipaddress, hostname in ipa_hosts.items(): + manifestfile = "%s_ipa_crts.pp" % ipaddress + manifestdata = getManifestTemplate('ipa_certmonger.pp') + appendManifestFile(manifestfile, manifestdata, 'ipa-crts') diff --git a/packstack/plugins/glance_200.py b/packstack/plugins/glance_200.py index 88b0a9a3a..4bb20093a 100644 --- a/packstack/plugins/glance_200.py +++ b/packstack/plugins/glance_200.py @@ -24,6 +24,7 @@ from packstack.modules.ospluginutils import appendManifestFile from packstack.modules.ospluginutils import createFirewallResources from packstack.modules.ospluginutils import getManifestTemplate +from packstack.modules.ospluginutils import generateIpaServiceManifests # ------------- Glance Packstack Plugin Initialization -------------- @@ -128,6 +129,16 @@ def create_manifest(config, messages): if config['CONFIG_UNSUPPORTED'] != 'y': config['CONFIG_STORAGE_HOST'] = config['CONFIG_CONTROLLER_HOST'] + if (config['CONFIG_IPA_INSTALL'] == 'y' and + config['CONFIG_AMQP_ENABLE_SSL'] and + config['CONFIG_AMQP_SSL_SELF_SIGNED'] == 'y'): + ipa_host = config['CONFIG_STORAGE_HOST'] + ssl_key_file = '/etc/pki/tls/private/ssl_amqp_glance.key' + ssl_cert_file = '/etc/pki/tls/certs/ssl_amqp_glance.crt' + ipa_service = 'glance' + generateIpaServiceManifests(config, ipa_host, ipa_service, + ssl_key_file, ssl_cert_file) + manifestfile = "%s_glance.pp" % config['CONFIG_STORAGE_HOST'] manifestdata = getManifestTemplate("glance") if config['CONFIG_CEILOMETER_INSTALL'] == 'y': diff --git a/packstack/plugins/heat_650.py b/packstack/plugins/heat_650.py index 03bfd4eff..be392f6a0 100644 --- a/packstack/plugins/heat_650.py +++ b/packstack/plugins/heat_650.py @@ -26,6 +26,7 @@ from packstack.modules.ospluginutils import appendManifestFile from packstack.modules.ospluginutils import createFirewallResources from packstack.modules.ospluginutils import getManifestTemplate +from packstack.modules.ospluginutils import generateIpaServiceManifests # ------------- Heat Packstack Plugin Initialization -------------- @@ -185,6 +186,16 @@ def create_manifest(config, messages): manifestdata += getManifestTemplate("heat") manifestdata += getManifestTemplate("keystone_heat") + if (config['CONFIG_IPA_INSTALL'] == 'y' and + config['CONFIG_AMQP_ENABLE_SSL'] and + config['CONFIG_AMQP_SSL_SELF_SIGNED'] == 'y'): + ipa_host = config['CONFIG_CONTROLLER_HOST'] + ssl_key_file = '/etc/pki/tls/private/ssl_amqp_heat.key' + ssl_cert_file = '/etc/pki/tls/certs/ssl_amqp_heat.crt' + ipa_service = 'heat' + generateIpaServiceManifests(config, ipa_host, ipa_service, + ssl_key_file, ssl_cert_file) + fw_details = dict() key = "heat" fw_details.setdefault(key, {}) diff --git a/packstack/plugins/neutron_350.py b/packstack/plugins/neutron_350.py index 0c597fd0e..23a6697bf 100644 --- a/packstack/plugins/neutron_350.py +++ b/packstack/plugins/neutron_350.py @@ -27,6 +27,7 @@ from packstack.modules.ospluginutils import appendManifestFile from packstack.modules.ospluginutils import createFirewallResources from packstack.modules.ospluginutils import getManifestTemplate +from packstack.modules.ospluginutils import generateIpaServiceManifests # ------------- Neutron Packstack Plugin Initialization -------------- @@ -575,6 +576,16 @@ def create_manifests(config, messages): plugin_manifest = 'neutron_ml2_plugin' for host in q_hosts: + if (config['CONFIG_IPA_INSTALL'] == 'y' and + config['CONFIG_AMQP_ENABLE_SSL'] and + config['CONFIG_AMQP_SSL_SELF_SIGNED'] == 'y'): + ipa_host = host + ssl_key_file = '/etc/pki/tls/private/ssl_amqp_neutron.key' + ssl_cert_file = '/etc/pki/tls/certs/ssl_amqp_neutron.crt' + ipa_service = 'neutron' + generateIpaServiceManifests(config, ipa_host, ipa_service, + ssl_key_file, ssl_cert_file) + manifest_file = "%s_neutron.pp" % (host,) manifest_data = getManifestTemplate("neutron") manifest_data += getManifestTemplate(get_mq(config, "neutron")) diff --git a/packstack/plugins/nova_300.py b/packstack/plugins/nova_300.py index 1c13cf129..8fbd081ba 100644 --- a/packstack/plugins/nova_300.py +++ b/packstack/plugins/nova_300.py @@ -32,6 +32,7 @@ from packstack.modules.ospluginutils import getManifestTemplate from packstack.modules.ospluginutils import manifestfiles from packstack.modules.ospluginutils import NovaConfig +from packstack.modules.ospluginutils import generateIpaServiceManifests # ------------- Nova Packstack Plugin Initialization -------------- @@ -699,6 +700,19 @@ def create_common_manifest(config, messages): data += getManifestTemplate("nova_common_nopw") appendManifestFile(os.path.split(manifestfile)[1], data) + ipa_nova_hosts = compute_hosts + ipa_nova_hosts |= set([config.get('CONFIG_CONTROLLER_HOST')]) + for host in ipa_nova_hosts: + if (config['CONFIG_IPA_INSTALL'] == 'y' and + config['CONFIG_AMQP_ENABLE_SSL'] and + config['CONFIG_AMQP_SSL_SELF_SIGNED'] == 'y'): + ipa_host = host + ssl_key_file = '/etc/pki/tls/private/ssl_amqp_nova.key' + ssl_cert_file = '/etc/pki/tls/certs/ssl_amqp_nova.crt' + ipa_service = 'nova' + generateIpaServiceManifests(config, ipa_host, ipa_service, + ssl_key_file, ssl_cert_file) + def create_neutron_manifest(config, messages): if config['CONFIG_NEUTRON_INSTALL'] != "y": diff --git a/packstack/plugins/prescript_000.py b/packstack/plugins/prescript_000.py index c00586ce1..798a0b8b3 100644 --- a/packstack/plugins/prescript_000.py +++ b/packstack/plugins/prescript_000.py @@ -102,6 +102,23 @@ def initConfig(controller): "CONDITION": False, "DEPRECATES": ['CONFIG_MYSQL_INSTALL']}, + {"CMD_OPTION": "ipa-install", + "USAGE": ( + "Set to 'y' if you would like Packstack to install and " + "integrate Openstack with FreeIPA. NOTE: This is unsupported " + "option." + ), + "PROMPT": "Should Packstack deploy and integrate with FreeIPA", + "OPTION_LIST": ["y", "n"], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": "n", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": "CONFIG_IPA_INSTALL", + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + {"CMD_OPTION": "os-glance-install", "USAGE": ( "Set to 'y' if you would like Packstack to install " diff --git a/packstack/plugins/puppet_950.py b/packstack/plugins/puppet_950.py index 982172b3f..907856bd0 100644 --- a/packstack/plugins/puppet_950.py +++ b/packstack/plugins/puppet_950.py @@ -187,12 +187,12 @@ def install_deps(config, messages): def copy_puppet_modules(config, messages): os_modules = ' '.join(('apache', 'ceilometer', 'certmonger', 'cinder', 'concat', 'firewall', 'glance', 'heat', 'horizon', - 'inifile', 'ironic', 'keystone', 'memcached', - 'mongodb', 'mysql', 'neutron', 'nova', 'nssdb', - 'openstack', 'packstack', 'qpid', 'rabbitmq', - 'redis', 'remote', 'rsync', 'sahara', 'ssh', - 'stdlib', 'swift', 'sysctl', 'tempest', 'trove', - 'vcsrepo', 'vlan', 'vswitch', 'xinetd', + 'inifile', 'ipa', 'ironic', 'keystone', + 'memcached', 'mongodb', 'mysql', 'neutron', 'nova', + 'nssdb', 'openstack', 'packstack', 'qpid', + 'rabbitmq', 'redis', 'remote', 'rsync', 'sahara', + 'ssh', 'stdlib', 'swift', 'sysctl', 'tempest', + 'trove', 'vcsrepo', 'vlan', 'vswitch', 'xinetd', 'openstacklib')) # write puppet manifest to disk diff --git a/packstack/plugins/swift_600.py b/packstack/plugins/swift_600.py index 160e2a479..7634faf04 100644 --- a/packstack/plugins/swift_600.py +++ b/packstack/plugins/swift_600.py @@ -25,6 +25,7 @@ from packstack.installer import processors from packstack.installer.exceptions import ParamValidationError from packstack.installer import utils +from packstack.installer import output_messages from packstack.installer.utils import split_hosts from packstack.modules.ospluginutils import appendManifestFile @@ -155,9 +156,19 @@ def initConfig(controller): def initSequences(controller): - if controller.CONF['CONFIG_SWIFT_INSTALL'] != 'y': + config = controller.CONF + if config['CONFIG_SWIFT_INSTALL'] != 'y': return + # If FreeIPA is installed on same host as swift ipa services collide + # on swift proxy port. This is unsupported setup but we still try to + # make it work. + if (config['CONFIG_IPA_INSTALL'] == 'y' and + config['CONFIG_IPA_HOST'] == config['CONFIG_CONTROLLER_HOST']): + config['CONFIG_SWIFT_PROXY_PORT'] = '8081' + else: + config['CONFIG_SWIFT_PROXY_PORT'] = '8080' + steps = [ {'title': 'Adding Swift Keystone manifest entries', 'functions': [create_keystone_manifest]}, @@ -305,7 +316,7 @@ def create_proxy_manifest(config, messages): fw_details[key]['host'] = "ALL" fw_details[key]['service_name'] = "swift proxy" fw_details[key]['chain'] = "INPUT" - fw_details[key]['ports'] = ['8080'] + fw_details[key]['ports'] = "%s" % config['CONFIG_SWIFT_PROXY_PORT'] fw_details[key]['proto'] = "tcp" config['FIREWALL_SWIFT_PROXY_RULES'] = fw_details @@ -356,6 +367,11 @@ def create_storage_manifest(config, messages): def create_common_manifest(config, messages): + if (config['CONFIG_IPA_INSTALL'] == 'y' and + config['CONFIG_IPA_HOST'] == config['CONFIG_CONTROLLER_HOST']): + msg = output_messages.WARN_IPA_CONTROLLER_SWIFT + messages.append(utils.color_text(msg, 'yellow')) + for manifestfile, marker in manifestfiles.getFiles(): if manifestfile.endswith("_swift.pp"): data = getManifestTemplate("swift_common") diff --git a/packstack/puppet/modules/packstack/manifests/ipa_client.pp b/packstack/puppet/modules/packstack/manifests/ipa_client.pp new file mode 100644 index 000000000..b4fb2fe08 --- /dev/null +++ b/packstack/puppet/modules/packstack/manifests/ipa_client.pp @@ -0,0 +1,115 @@ +# == Define: packstack::ipa_client +# +# Full description of defined resource type packstack::ipa_client here +# +# === Parameters +# +# [*ipa_hostname*] +# +# [*ipa_domain*] +# +# [*ipa_server_hostname*] +# +# [*ipa_host_ip*] +# +# [*ipa_server_ip*] +# +# [*ipa_admin_install*] +# +# === Examples +# +# Provide some examples on how to use this type: +# +# packstack::ipa_client { 'namevar': +# basedir => '/tmp/src', +# } +# +# === Authors +# +# Lukas Bezdicka +# +# === Copyright +# +# Copyright 2014 Red Hat, Inc. +# +define packstack::ipa_client ( + $ipa_hostname, + $ipa_domain, + $ipa_server_hostname, + $ipa_host_ip, + $ipa_server_ip, + $ipa_admin_install = true +) { + + $realm = upcase("${ipa_domain}") + + class { 'ipa': + client => true, + domain => $ipa_domain, + realm => $realm, + ipaservers => ["${ipa_server_hostname}.${ipa_domain}"], + desc => "${ipa_hostname}", + clntpkg => $::operatingsystem ? { + 'Fedora' => 'freeipa-client', + default => 'ipa-client', + }, + otp => "${ipa_hostname}.packstack", + } + + ipa::clientinstall { "$::fqdn": + domain => $ipa_domain, + masterfqdn => "${ipa_server_hostname}.${ipa_domain}", + realm => $realm, + otp => "${ipa_hostname}.packstack", + mkhomedir => false, + fixedprimary => true, + } + + # FIXME: hack around race condition in ::ipa + exec { 'sssd-sleep': + command => '/bin/sleep 5s', + subscribe => Ipa::Clientinstall[$::fqdn], + notify => Service['sssd'], + } + + file { '/etc/hostname': + content => "${::fqdn}", + } + + if !($ipa_admin_install) { + + $configured_interface = inline_template("<%= scope.lookupvar('::interfaces').split(',').reject { |int| ( scope.lookupvar('::ipaddress_' + int) != @ipa_host_ip ) }[0] -%>") + + # Ugly hack, we need clients to talk to DNS provided by IPA + service { 'network': + ensure => 'running', + before => Class["ipa"], + } + + file { '/etc/dhcp/dhclient.conf': + ensure => 'present', + } + + file_line { 'dhcp-force-ipa-dns': + path => '/etc/dhcp/dhclient.conf', + match => 'prepend domain-name-servers .*;', + line => "prepend domain-name-servers ${ipa_server_ip},;", + notify => Service['network'], + require => File['/etc/dhcp/dhclient.conf'], + } + + file_line { "ifcfg-PEERDNS-no-${configured_interface}": + path => "/etc/sysconfig/network-scripts/ifcfg-${configured_interface}", + match => '^PEERDNS=.*', + line => 'PEERDNS="no"', + notify => Service['network'], + } + + file_line { "ifcfg-DNS1-no-${configured_interface}": + path => "/etc/sysconfig/network-scripts/ifcfg-${configured_interface}", + match => '^DNS1=.*', + line => "DNS1=${ipa_server_ip}", + notify => Service['network'], + } + } +} diff --git a/packstack/puppet/templates/ceilometer_rabbitmq.pp b/packstack/puppet/templates/ceilometer_rabbitmq.pp index 4aeda329f..c4adf8269 100644 --- a/packstack/puppet/templates/ceilometer_rabbitmq.pp +++ b/packstack/puppet/templates/ceilometer_rabbitmq.pp @@ -1,10 +1,44 @@ -class { 'ceilometer': - metering_secret => hiera('CONFIG_CEILOMETER_SECRET'), - verbose => true, - debug => hiera('CONFIG_DEBUG_MODE'), - rabbit_host => hiera('CONFIG_AMQP_HOST'), - rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), - rabbit_use_ssl => hiera('CONFIG_AMQP_ENABLE_SSL'), - rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), - rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), +$ipa_install = hiera('CONFIG_IPA_INSTALL') +$amqp_enable_ssl = hiera('CONFIG_AMQP_ENABLE_SSL') +$amqp_ssl_self_signed = hiera('CONFIG_AMQP_SSL_SELF_SIGNED','n') + +if ($ipa_install == 'y' and + $amqp_enable_ssl and + $amqp_ssl_self_signed == 'y') { + $kombu_ssl_ca_certs = '/etc/ipa/ca.crt' + $kombu_ssl_keyfile = '/etc/pki/tls/private/ssl_amqp_ceilometer.key' + $kombu_ssl_certfile = '/etc/pki/tls/certs/ssl_amqp_ceilometer.crt' + + $files_to_set_owner = [ $kombu_ssl_keyfile, $kombu_ssl_certfile ] + file { $files_to_set_owner: + owner => 'ceilometer', + group => 'ceilometer', + require => Package['openstack-ceilometer-common'], + } + File[$files_to_set_owner] ~> Service<||> + + class { 'ceilometer': + metering_secret => hiera('CONFIG_CEILOMETER_SECRET'), + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + kombu_ssl_ca_certs => $kombu_ssl_ca_certs, + kombu_ssl_keyfile => $kombu_ssl_keyfile, + kombu_ssl_certfile => $kombu_ssl_certfile, + } +} else { + class { 'ceilometer': + metering_secret => hiera('CONFIG_CEILOMETER_SECRET'), + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + } } diff --git a/packstack/puppet/templates/cinder_rabbitmq.pp b/packstack/puppet/templates/cinder_rabbitmq.pp index 685f75db4..dfbd9afe4 100644 --- a/packstack/puppet/templates/cinder_rabbitmq.pp +++ b/packstack/puppet/templates/cinder_rabbitmq.pp @@ -1,13 +1,46 @@ $cinder_rab_cfg_cinder_db_pw = hiera('CONFIG_CINDER_DB_PW') $cinder_rab_cfg_mariadb_host = hiera('CONFIG_MARIADB_HOST') +$ipa_install = hiera('CONFIG_IPA_INSTALL') +$amqp_enable_ssl = hiera('CONFIG_AMQP_ENABLE_SSL') +$amqp_ssl_self_signed = hiera('CONFIG_AMQP_SSL_SELF_SIGNED','n') -class {'cinder': - rabbit_host => hiera('CONFIG_AMQP_HOST'), - rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), - rabbit_use_ssl => hiera('CONFIG_AMQP_ENABLE_SSL'), - rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), - rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), - database_connection => "mysql://cinder:${cinder_rab_cfg_cinder_db_pw}@${cinder_rab_cfg_mariadb_host}/cinder", - verbose => true, - debug => hiera('CONFIG_DEBUG_MODE'), +if ($ipa_install == 'y' and + $amqp_enable_ssl and + $amqp_ssl_self_signed == 'y') { + $kombu_ssl_ca_certs = '/etc/ipa/ca.crt' + $kombu_ssl_keyfile = '/etc/pki/tls/private/ssl_amqp_cinder.key' + $kombu_ssl_certfile = '/etc/pki/tls/certs/ssl_amqp_cinder.crt' + + $files_to_set_owner = [ $kombu_ssl_keyfile, $kombu_ssl_certfile ] + file { $files_to_set_owner: + owner => 'cinder', + group => 'cinder', + require => Class['cinder'], + notify => Service['cinder-api'], + } + + class {'cinder': + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + rabbit_use_ssl => $amqp_enable_ssl, + database_connection => "mysql://cinder:${cinder_rab_cfg_cinder_db_pw}@${cinder_rab_cfg_mariadb_host}/cinder", + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + kombu_ssl_ca_certs => $kombu_ssl_ca_certs, + kombu_ssl_keyfile => $kombu_ssl_keyfile, + kombu_ssl_certfile => $kombu_ssl_certfile, + } +} else { + class {'cinder': + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + database_connection => "mysql://cinder:${cinder_rab_cfg_cinder_db_pw}@${cinder_rab_cfg_mariadb_host}/cinder", + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + } } diff --git a/packstack/puppet/templates/glance_ceilometer_rabbitmq.pp b/packstack/puppet/templates/glance_ceilometer_rabbitmq.pp index 0d3eb1c2a..3272071d5 100644 --- a/packstack/puppet/templates/glance_ceilometer_rabbitmq.pp +++ b/packstack/puppet/templates/glance_ceilometer_rabbitmq.pp @@ -1,9 +1,42 @@ +$ipa_install = hiera('CONFIG_IPA_INSTALL') +$amqp_enable_ssl = hiera('CONFIG_AMQP_ENABLE_SSL') +$amqp_ssl_self_signed = hiera('CONFIG_AMQP_SSL_SELF_SIGNED','n') -class { 'glance::notify::rabbitmq': - rabbit_host => hiera('CONFIG_AMQP_HOST'), - rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), - rabbit_use_ssl => hiera('CONFIG_AMQP_ENABLE_SSL'), - rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), - rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), -} +if ($ipa_install == 'y' and + $amqp_enable_ssl and + $amqp_ssl_self_signed == 'y') { + + $kombu_ssl_ca_certs = '/etc/ipa/ca.crt' + $kombu_ssl_keyfile = '/etc/pki/tls/private/ssl_amqp_glance.key' + $kombu_ssl_certfile = '/etc/pki/tls/certs/ssl_amqp_glance.crt' + + $files_to_set_owner = [ $kombu_ssl_keyfile, $kombu_ssl_certfile ] + file { $files_to_set_owner: + owner => 'glance', + group => 'glance', + require => Class['glance::notify::rabbitmq'], + notify => Service['glance-api'], + } + + class { 'glance::notify::rabbitmq': + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + kombu_ssl_ca_certs => $kombu_ssl_ca_certs, + kombu_ssl_keyfile => $kombu_ssl_keyfile, + kombu_ssl_certfile => $kombu_ssl_certfile, + } +} else { + + class { 'glance::notify::rabbitmq': + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + } + +} diff --git a/packstack/puppet/templates/heat_rabbitmq.pp b/packstack/puppet/templates/heat_rabbitmq.pp index 0d1bc0201..dad303979 100644 --- a/packstack/puppet/templates/heat_rabbitmq.pp +++ b/packstack/puppet/templates/heat_rabbitmq.pp @@ -2,18 +2,57 @@ $heat_rabbitmq_cfg_heat_db_pw = hiera('CONFIG_HEAT_DB_PW') $heat_rabbitmq_cfg_mariadb_host = hiera('CONFIG_MARIADB_HOST') -class { 'heat': - keystone_host => $heat_rabbitmq_cfg_ctrl_host, - keystone_password => hiera('CONFIG_HEAT_KS_PW'), - auth_uri => "http://${heat_rabbitmq_cfg_ctrl_host}:35357/v2.0", - keystone_ec2_uri => "http://${heat_rabbitmq_cfg_ctrl_host}:35357/v2.0", - rpc_backend => 'heat.openstack.common.rpc.impl_kombu', - rabbit_host => hiera('CONFIG_AMQP_HOST'), - rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), - rabbit_use_ssl => hiera('CONFIG_AMQP_ENABLE_SSL'), - rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), - rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), - verbose => true, - debug => hiera('CONFIG_DEBUG_MODE'), - database_connection => "mysql://heat:${heat_rabbitmq_cfg_heat_db_pw}@${heat_rabbitmq_cfg_mariadb_host}/heat", +$ipa_install = hiera('CONFIG_IPA_INSTALL') +$amqp_enable_ssl = hiera('CONFIG_AMQP_ENABLE_SSL') +$amqp_ssl_self_signed = hiera('CONFIG_AMQP_SSL_SELF_SIGNED','n') + +if ($ipa_install == 'y' and + $amqp_enable_ssl and + $amqp_ssl_self_signed == 'y') { + $kombu_ssl_ca_certs = '/etc/ipa/ca.crt' + $kombu_ssl_keyfile = '/etc/pki/tls/private/ssl_amqp_heat.key' + $kombu_ssl_certfile = '/etc/pki/tls/certs/ssl_amqp_heat.crt' + + $files_to_set_owner = [ $kombu_ssl_keyfile, $kombu_ssl_certfile ] + file { $files_to_set_owner: + owner => 'heat', + group => 'heat', + require => Package['openstack-heat-common'], + } + File[$files_to_set_owner] ~> Service<||> + + class { 'heat': + keystone_host => $heat_rabbitmq_cfg_ctrl_host, + keystone_password => hiera('CONFIG_HEAT_KS_PW'), + auth_uri => "http://${heat_rabbitmq_cfg_ctrl_host}:35357/v2.0", + keystone_ec2_uri => "http://${heat_rabbitmq_cfg_ctrl_host}:35357/v2.0", + rpc_backend => 'heat.openstack.common.rpc.impl_kombu', + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + database_connection => "mysql://heat:${heat_rabbitmq_cfg_heat_db_pw}@${heat_rabbitmq_cfg_mariadb_host}/heat", + kombu_ssl_ca_certs => $kombu_ssl_ca_certs, + kombu_ssl_keyfile => $kombu_ssl_keyfile, + kombu_ssl_certfile => $kombu_ssl_certfile, + } +} else { + class { 'heat': + keystone_host => $heat_rabbitmq_cfg_ctrl_host, + keystone_password => hiera('CONFIG_HEAT_KS_PW'), + auth_uri => "http://${heat_rabbitmq_cfg_ctrl_host}:35357/v2.0", + keystone_ec2_uri => "http://${heat_rabbitmq_cfg_ctrl_host}:35357/v2.0", + rpc_backend => 'heat.openstack.common.rpc.impl_kombu', + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + database_connection => "mysql://heat:${heat_rabbitmq_cfg_heat_db_pw}@${heat_rabbitmq_cfg_mariadb_host}/heat", + } } diff --git a/packstack/puppet/templates/horizon.pp b/packstack/puppet/templates/horizon.pp index dffe895b7..a925dad6b 100644 --- a/packstack/puppet/templates/horizon.pp +++ b/packstack/puppet/templates/horizon.pp @@ -14,6 +14,69 @@ false => 'False', } +$controller_host = hiera('CONFIG_CONTROLLER_HOST') +$ipa_install = hiera('CONFIG_IPA_INSTALL') +$ipa_host = hiera('CONFIG_IPA_HOST',undef) + +$is_horizon_ssl = hiera('CONFIG_HORIZON_SSL') + +if $is_horizon_ssl == true { + $horizon_cert = '/etc/pki/tls/certs/ssl_ps_server.crt' + $horizon_key = '/etc/pki/tls/private/ssl_ps_server.key' + + if $ipa_install { + $horizon_ca = '/etc/ipa/ca.crt' + } else { + $horizon_ca = '/etc/pki/tls/certs/ssl_ps_chain.crt' + + file {'/etc/pki/tls/certs/ps_generate_ssl_certs.ssh': + ensure => present, + content => template('packstack/ssl/generate_ssl_certs.sh.erb'), + mode => '0755', + } + + exec {'/etc/pki/tls/certs/ps_generate_ssl_certs.ssh': + require => File['/etc/pki/tls/certs/ps_generate_ssl_certs.ssh'], + notify => Service['httpd'], + before => Class['horizon'], + } -> + exec { 'nova-novncproxy-restart': + # TODO: FIXME: this definetly does not belong to horizon.pp + # ps_generate_ssl_certs.ssh is generating ssl certs for nova-novncproxy + # so openstack-nova-novncproxy should be restarted. + path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'], + command => 'systemctl restart openstack-nova-novncproxy.service', + logoutput => 'on_failure', + } + } + + $files_to_set_owner = [ $horizon_cert, $horizon_key ] + file { $files_to_set_owner: + owner => 'apache', + group => 'apache', + require => Package['httpd'], + notify => Service['httpd'], + } + + apache::listen { '443': } + +} + +if ($ipa_install and ($ipa_host == $controller_host)) { + $configure_apache = false + $conf_template = '/etc/httpd/conf/httpd.conf' +} else { + $configure_apache = true + $conf_template = undef +} + +class{ 'apache': + purge_configs => false, + default_mods => true, + default_confd_files => true, + conf_template => $conf_template, +} + class {'horizon': secret_key => hiera('CONFIG_HORIZON_SECRET_KEY'), keystone_url => "http://${keystone_host}:5000/v2.0", @@ -25,47 +88,15 @@ django_debug => $is_django_debug, file_upload_temp_dir => '/var/tmp', listen_ssl => hiera('CONFIG_HORIZON_SSL'), - horizon_cert => '/etc/pki/tls/certs/ssl_ps_server.crt', - horizon_key => '/etc/pki/tls/private/ssl_ps_server.key', - horizon_ca => '/etc/pki/tls/certs/ssl_ps_chain.crt', + horizon_cert => $horizon_cert, + horizon_key => $horizon_key, + horizon_ca => $horizon_ca, neutron_options => { 'enable_lb' => hiera('CONFIG_HORIZON_NEUTRON_LB'), 'enable_firewall' => hiera('CONFIG_HORIZON_NEUTRON_FW'), }, -} - -$is_horizon_ssl = hiera('CONFIG_HORIZON_SSL') - -if $is_horizon_ssl == true { - file {'/etc/pki/tls/certs/ps_generate_ssl_certs.ssh': - ensure => present, - content => template('packstack/ssl/generate_ssl_certs.sh.erb'), - mode => '0755', - } - - exec {'/etc/pki/tls/certs/ps_generate_ssl_certs.ssh': - require => File['/etc/pki/tls/certs/ps_generate_ssl_certs.ssh'], - notify => Service['httpd'], - before => Class['horizon'], - } -> - exec { 'nova-novncproxy-restart': - # ps_generate_ssl_certs.ssh is generating ssl certs for nova-novncproxy - # so openstack-nova-novncproxy should be restarted. - path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'], - command => 'systemctl restart openstack-nova-novncproxy.service', - logoutput => 'on_failure', - } - - apache::listen { '443': } - - # little bit of hatred as we'll have to patch upstream puppet-horizon - file_line {'horizon_ssl_wsgi_fix': - path => '/etc/httpd/conf.d/15-horizon_ssl_vhost.conf', - match => 'WSGIProcessGroup.*', - line => ' WSGIProcessGroup horizon-ssl', - require => File['15-horizon_ssl_vhost.conf'], - notify => Service['httpd'], - } + configure_apache => $configure_apache, + notify => Service['httpd'], } class { 'memcached': } diff --git a/packstack/puppet/templates/ipa_certmonger.pp b/packstack/puppet/templates/ipa_certmonger.pp new file mode 100644 index 000000000..d79ad2706 --- /dev/null +++ b/packstack/puppet/templates/ipa_certmonger.pp @@ -0,0 +1 @@ +include certmonger::server diff --git a/packstack/puppet/templates/ipa_server.pp b/packstack/puppet/templates/ipa_server.pp new file mode 100644 index 000000000..15c50f71a --- /dev/null +++ b/packstack/puppet/templates/ipa_server.pp @@ -0,0 +1,21 @@ +$ipa_server_ip = hiera('CONFIG_IPA_HOST') + +file_line { 'hosts-record': + path => '/etc/hosts', + match => "${ipa_server_ip} ${::fqdn} ${::hostname}.*", + line => "${ipa_server_ip} ${::fqdn} ${::hostname}", + before => Class['ipa'], +} + +class { 'ipa': + master => true, + domain => 'packstack', + realm => 'PACKSTACK', + dspw => hiera('CONFIG_IPA_DM_PASSWORD'), + adminpw => hiera('CONFIG_IPA_ADMIN_PASSWORD'), + svrpkg => $::operatingsystem ? { + 'Fedora' => 'freeipa-server', + default => 'ipa-server', + }, + dns => true, +} diff --git a/packstack/puppet/templates/keystone.pp b/packstack/puppet/templates/keystone.pp index f9d932ec2..edfe02b4d 100644 --- a/packstack/puppet/templates/keystone.pp +++ b/packstack/puppet/templates/keystone.pp @@ -7,6 +7,17 @@ $keystone_api_version_str = hiera('CONFIG_KEYSTONE_API_VERSION') $keystone_url = "http://${keystone_endpoint_cfg_ctrl_host}:5000/${keystone_api_version_str}" $keystone_admin_url = "http://${keystone_endpoint_cfg_ctrl_host}:35357/${keystone_api_version_str}" +$controller_host = hiera('CONFIG_CONTROLLER_HOST') +$ipa_install = hiera('CONFIG_IPA_INSTALL') +$ipa_host = hiera('CONFIG_IPA_HOST',undef) + +if ($ipa_install and ($ipa_host == $controller_host)) { + $configure_apache = false + $conf_template = '/etc/httpd/conf/httpd.conf' +} else { + $configure_apache = true + $conf_template = undef +} class { 'keystone': admin_token => hiera('CONFIG_KEYSTONE_ADMIN_TOKEN'), @@ -21,8 +32,19 @@ if $keystone_service_name == 'httpd' { include packstack::apache_common - class { 'keystone::wsgi::apache': - ssl => $keystone_use_ssl, + class{ 'apache': + purge_configs => false, + default_mods => true, + default_confd_files => true, + conf_template => $conf_template, + } + + if $configure_apache { + class { 'keystone::wsgi::apache': + ssl => $keystone_use_ssl, + } + } else { + info ("TODO: FIXME: BROOOOKEEEEEN") } } diff --git a/packstack/puppet/templates/keystone_swift.pp b/packstack/puppet/templates/keystone_swift.pp index f07db840c..406c1b70e 100644 --- a/packstack/puppet/templates/keystone_swift.pp +++ b/packstack/puppet/templates/keystone_swift.pp @@ -2,4 +2,5 @@ public_address => hiera('CONFIG_CONTROLLER_HOST'), region => hiera('CONFIG_KEYSTONE_REGION'), password => hiera('CONFIG_SWIFT_KS_PW'), + port => hiera('CONFIG_SWIFT_PROXY_PORT'), } diff --git a/packstack/puppet/templates/nagios_server.pp b/packstack/puppet/templates/nagios_server.pp index c9c39e342..6c55085fd 100644 --- a/packstack/puppet/templates/nagios_server.pp +++ b/packstack/puppet/templates/nagios_server.pp @@ -13,6 +13,13 @@ before => Class['nagios_configs'] } +class{ 'apache': + purge_configs => false, + default_mods => true, + default_confd_files => true, + conf_template => '/etc/httpd/conf/httpd.conf', +} + class nagios_configs(){ file { ['/etc/nagios/nagios_command.cfg', '/etc/nagios/nagios_host.cfg']: ensure => 'present', @@ -75,10 +82,6 @@ include concat::setup -class { 'apache': - purge_configs => false, -} - class { 'apache::mod::php': } service { ['nagios']: diff --git a/packstack/puppet/templates/neutron_rabbitmq.pp b/packstack/puppet/templates/neutron_rabbitmq.pp index d53f43bf7..4beb7d385 100644 --- a/packstack/puppet/templates/neutron_rabbitmq.pp +++ b/packstack/puppet/templates/neutron_rabbitmq.pp @@ -1,13 +1,49 @@ +$ipa_install = hiera('CONFIG_IPA_INSTALL') +$amqp_enable_ssl = hiera('CONFIG_AMQP_ENABLE_SSL') +$amqp_ssl_self_signed = hiera('CONFIG_AMQP_SSL_SELF_SIGNED','n') -class { 'neutron': - rabbit_host => hiera('CONFIG_AMQP_HOST'), - rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), - rabbit_use_ssl => hiera('CONFIG_AMQP_ENABLE_SSL'), - rabbit_user => hiera('CONFIG_AMQP_AUTH_USER'), - rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), - core_plugin => hiera('CONFIG_NEUTRON_CORE_PLUGIN'), - allow_overlapping_ips => true, - service_plugins => hiera_array('SERVICE_PLUGINS'), - verbose => true, - debug => hiera('CONFIG_DEBUG_MODE'), +if ($ipa_install == 'y' and + $amqp_enable_ssl and + $amqp_ssl_self_signed == 'y') { + $kombu_ssl_ca_certs = '/etc/ipa/ca.crt' + $kombu_ssl_keyfile = '/etc/pki/tls/private/ssl_amqp_neutron.key' + $kombu_ssl_certfile = '/etc/pki/tls/certs/ssl_amqp_neutron.crt' + + $files_to_set_owner = [ $kombu_ssl_keyfile, $kombu_ssl_certfile ] + file { $files_to_set_owner: + owner => 'neutron', + group => 'neutron', + require => Class['neutron'], + } + + File[$files_to_set_owner] ~> Service <||> + + class { 'neutron': + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_user => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + core_plugin => hiera('CONFIG_NEUTRON_CORE_PLUGIN'), + allow_overlapping_ips => true, + service_plugins => hiera_array('SERVICE_PLUGINS'), + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + kombu_ssl_ca_certs => $kombu_ssl_ca_certs, + kombu_ssl_keyfile => $kombu_ssl_keyfile, + kombu_ssl_certfile => $kombu_ssl_certfile, + } +} else { + class { 'neutron': + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_user => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + core_plugin => hiera('CONFIG_NEUTRON_CORE_PLUGIN'), + allow_overlapping_ips => true, + service_plugins => hiera_array('SERVICE_PLUGINS'), + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + } } diff --git a/packstack/puppet/templates/nova_common_rabbitmq.pp b/packstack/puppet/templates/nova_common_rabbitmq.pp index 307658b83..336268bc5 100644 --- a/packstack/puppet/templates/nova_common_rabbitmq.pp +++ b/packstack/puppet/templates/nova_common_rabbitmq.pp @@ -9,16 +9,52 @@ } $nova_common_rabbitmq_cfg_storage_host = hiera('CONFIG_STORAGE_HOST') +$ipa_install = hiera('CONFIG_IPA_INSTALL') +$amqp_enable_ssl = hiera('CONFIG_AMQP_ENABLE_SSL') +$amqp_ssl_self_signed = hiera('CONFIG_AMQP_SSL_SELF_SIGNED','n') -class { 'nova': - glance_api_servers => "${nova_common_rabbitmq_cfg_storage_host}:9292", - rabbit_host => hiera('CONFIG_AMQP_HOST'), - rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), - rabbit_use_ssl => hiera('CONFIG_AMQP_ENABLE_SSL'), - rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), - rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), - verbose => true, - debug => hiera('CONFIG_DEBUG_MODE'), - nova_public_key => $public_key, - nova_private_key => $private_key, +if ($ipa_install == 'y' and + $amqp_enable_ssl and + $amqp_ssl_self_signed == 'y') { + $kombu_ssl_ca_certs = '/etc/ipa/ca.crt' + $kombu_ssl_keyfile = '/etc/pki/tls/private/ssl_amqp_nova.key' + $kombu_ssl_certfile = '/etc/pki/tls/certs/ssl_amqp_nova.crt' + + $files_to_set_owner = [ $kombu_ssl_keyfile, $kombu_ssl_certfile ] + file { $files_to_set_owner: + owner => 'nova', + group => 'nova', + require => Package['nova-common'], + } + + File[$files_to_set_owner] ~> Service <||> + + class { 'nova': + glance_api_servers => "${nova_common_rabbitmq_cfg_storage_host}:9292", + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + nova_public_key => $public_key, + nova_private_key => $private_key, + kombu_ssl_ca_certs => $kombu_ssl_ca_certs, + kombu_ssl_keyfile => $kombu_ssl_keyfile, + kombu_ssl_certfile => $kombu_ssl_certfile, + } +} else { + class { 'nova': + glance_api_servers => "${nova_common_rabbitmq_cfg_storage_host}:9292", + rabbit_host => hiera('CONFIG_AMQP_HOST'), + rabbit_port => hiera('CONFIG_AMQP_CLIENTS_PORT'), + rabbit_use_ssl => $amqp_enable_ssl, + rabbit_userid => hiera('CONFIG_AMQP_AUTH_USER'), + rabbit_password => hiera('CONFIG_AMQP_AUTH_PASSWORD'), + verbose => true, + debug => hiera('CONFIG_DEBUG_MODE'), + nova_public_key => $public_key, + nova_private_key => $private_key, + } } diff --git a/packstack/puppet/templates/prescript.pp b/packstack/puppet/templates/prescript.pp index 33dcf7852..e03c30b09 100644 --- a/packstack/puppet/templates/prescript.pp +++ b/packstack/puppet/templates/prescript.pp @@ -1,9 +1,5 @@ include firewall -if $::ipaddress == hiera('CONFIG_CONTROLLER_HOST') { - include ::apache -} - # We don't have openstack-selinux package for Fedora if $::operatingsystem != 'Fedora' { package{ 'openstack-selinux': diff --git a/packstack/puppet/templates/swift_proxy.pp b/packstack/puppet/templates/swift_proxy.pp index 4b3b7b4bf..f1a453639 100644 --- a/packstack/puppet/templates/swift_proxy.pp +++ b/packstack/puppet/templates/swift_proxy.pp @@ -5,6 +5,7 @@ class { 'swift::proxy': proxy_local_net_ip => hiera('CONFIG_CONTROLLER_HOST'), + port => hiera('CONFIG_SWIFT_PROXY_PORT'), pipeline => [ 'catch_errors', 'bulk',