diff --git a/.gitmodules b/.gitmodules index 1537cb216..695d0b0ea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -82,3 +82,6 @@ [submodule "packstack/puppet/modules/mongodb"] path = packstack/puppet/modules/mongodb url = https://github.com/puppetlabs/puppetlabs-mongodb.git +[submodule "packstack/puppet/modules/heat"] + path = packstack/puppet/modules/heat + url = https://github.com/packstack/puppet-heat.git diff --git a/packstack/plugins/heat_750.py b/packstack/plugins/heat_750.py new file mode 100644 index 000000000..269f71017 --- /dev/null +++ b/packstack/plugins/heat_750.py @@ -0,0 +1,202 @@ +""" +Installs and configures heat +""" + +import uuid +import logging +import os + +from packstack.installer import utils +from packstack.installer import validators + +from packstack.modules.ospluginutils import (getManifestTemplate, + manifestfiles, + appendManifestFile) + +controller = None + +# Plugin name +PLUGIN_NAME = "OS-HEAT" +PLUGIN_NAME_COLORED = utils.color_text(PLUGIN_NAME, 'blue') + +logging.debug("plugin %s loaded", __name__) + + +def initConfig(controllerObject): + global controller + controller = controllerObject + logging.debug("Adding OpenStack Heat configuration") + parameters = [ + {"CMD_OPTION" : "heat-host", + "USAGE" : ('The IP address of the server on which ' + 'to install Heat service'), + "PROMPT" : 'Enter the IP address of the Heat service', + "OPTION_LIST" : [], + "VALIDATORS" : [validators.validate_ssh], + "DEFAULT_VALUE" : utils.get_localhost_ip(), + "MASK_INPUT" : False, + "LOOSE_VALIDATION": True, + "CONF_NAME" : "CONFIG_HEAT_HOST", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, + + {"CMD_OPTION" : "heat-mysql-password", + "USAGE" : 'The password used by Heat user to authenticate against MySQL', + "PROMPT" : "Enter the password for the Heat MySQL user", + "OPTION_LIST" : [], + "VALIDATORS" : [validators.validate_not_empty], + "DEFAULT_VALUE" : uuid.uuid4().hex[:16], + "MASK_INPUT" : True, + "LOOSE_VALIDATION": False, + "CONF_NAME" : "CONFIG_HEAT_DB_PW", + "USE_DEFAULT" : True, + "NEED_CONFIRM" : True, + "CONDITION" : False }, + + {"CMD_OPTION" : "heat-ks-passwd", + "USAGE" : "The password to use for the Heat to authenticate with Keystone", + "PROMPT" : "Enter the password for the Heat Keystone access", + "OPTION_LIST" : [], + "VALIDATORS" : [validators.validate_not_empty], + "DEFAULT_VALUE" : uuid.uuid4().hex[:16], + "MASK_INPUT" : True, + "LOOSE_VALIDATION": False, + "CONF_NAME" : "CONFIG_HEAT_KS_PW", + "USE_DEFAULT" : True, + "NEED_CONFIRM" : True, + "CONDITION" : False }, + + {"CMD_OPTION" : "os-heat-cloudwatch-install", + "USAGE" : ("Set to 'y' if you would like Packstack to " + "install Heat CloudWatch API"), + "PROMPT" : "Should Packstack install Heat CloudWatch API", + "OPTION_LIST" : ["y", "n"], + "VALIDATORS" : [validators.validate_options], + "DEFAULT_VALUE" : "n", + "MASK_INPUT" : False, + "LOOSE_VALIDATION": False, + "CONF_NAME" : "CONFIG_HEAT_CLOUDWATCH_INSTALL", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, + + {"CMD_OPTION" : "os-heat-cfn-install", + "USAGE" : ("Set to 'y' if you would like Packstack to " + "install Heat CloudFormation API"), + "PROMPT" : "Should Packstack install Heat CloudFormation API", + "OPTION_LIST" : ["y", "n"], + "VALIDATORS" : [validators.validate_options], + "DEFAULT_VALUE" : "n", + "MASK_INPUT" : False, + "LOOSE_VALIDATION": False, + "CONF_NAME" : "CONFIG_HEAT_CFN_INSTALL", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, + ] + group = {"GROUP_NAME" : "Heat", + "DESCRIPTION" : "Heat Config parameters", + "PRE_CONDITION" : "CONFIG_HEAT_INSTALL", + "PRE_CONDITION_MATCH" : "y", + "POST_CONDITION" : False, + "POST_CONDITION_MATCH": True} + controller.addGroup(group, parameters) + + parameters = [ + {"CMD_OPTION" : "heat-api-cloudwatch-host", + "USAGE" : ('The IP address of the server on which ' + 'to install Heat CloudWatch API service'), + "PROMPT" : ('Enter the IP address of the Heat CloudWatch API ' + 'server'), + "OPTION_LIST" : [], + "VALIDATORS" : [validators.validate_ssh], + "DEFAULT_VALUE" : utils.get_localhost_ip(), + "MASK_INPUT" : False, + "LOOSE_VALIDATION": True, + "CONF_NAME" : "CONFIG_HEAT_CLOUDWATCH_HOST", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, + ] + group = {"GROUP_NAME" : "Heat CloudWatch API", + "DESCRIPTION" : "Heat CloudWatch API config parameters", + "PRE_CONDITION" : "CONFIG_HEAT_CLOUDWATCH_INSTALL", + "PRE_CONDITION_MATCH" : "y", + "POST_CONDITION" : False, + "POST_CONDITION_MATCH": True} + controller.addGroup(group, parameters) + + parameters = [ + {"CMD_OPTION" : "heat-api-cfn-host", + "USAGE" : ('The IP address of the server on which ' + 'to install Heat CloudFormation API service'), + "PROMPT" : ('Enter the IP address of the Heat CloudFormation ' + 'API server'), + "OPTION_LIST" : [], + "VALIDATORS" : [validators.validate_ssh], + "DEFAULT_VALUE" : utils.get_localhost_ip(), + "MASK_INPUT" : False, + "LOOSE_VALIDATION": True, + "CONF_NAME" : "CONFIG_HEAT_CFN_HOST", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, + ] + group = {"GROUP_NAME" : "Heat CloudFormation API", + "DESCRIPTION" : "Heat CloudFormation API config parameters", + "PRE_CONDITION" : "CONFIG_HEAT_CFN_INSTALL", + "PRE_CONDITION_MATCH" : "y", + "POST_CONDITION" : False, + "POST_CONDITION_MATCH": True} + controller.addGroup(group, parameters) + + +def initSequences(controller): + if controller.CONF['CONFIG_HEAT_INSTALL'] != 'y': + return + steps = [{'title': 'Adding Heat manifest entries', + 'functions': [create_manifest]}, + {'title': 'Adding Heat Keystone manifest entries', + 'functions':[create_keystone_manifest]}] + + if controller.CONF.get('CONFIG_HEAT_CLOUDWATCH_INSTALL', 'n') == 'y': + steps.append({'title': 'Adding Heat CloudWatch API manifest entries', + 'functions': [create_cloudwatch_manifest]}) + if controller.CONF.get('CONFIG_HEAT_CFN_INSTALL', 'n') == 'y': + steps.append({'title': 'Adding Heat CloudFormation API manifest entries', + 'functions': [create_cfn_manifest]}) + controller.addSequence("Installing Heat", [], [], steps) + + +def create_manifest(config): + if config['CONFIG_HEAT_CLOUDWATCH_INSTALL'] == 'y': + config['CONFIG_HEAT_WATCH_HOST'] = config['CONFIG_HEAT_CLOUDWATCH_HOST'] + else: + config['CONFIG_HEAT_WATCH_HOST'] = config['CONFIG_HEAT_HOST'] + if config['CONFIG_HEAT_CFN_INSTALL'] == 'y': + config['CONFIG_HEAT_METADATA_HOST'] = config['CONFIG_HEAT_CFN_HOST'] + else: + config['CONFIG_HEAT_METADATA_HOST'] = config['CONFIG_HEAT_HOST'] + + manifestfile = "%s_heat.pp" % controller.CONF['CONFIG_HEAT_HOST'] + manifestdata = getManifestTemplate("heat.pp") + appendManifestFile(manifestfile, manifestdata) + + +def create_keystone_manifest(config): + manifestfile = "%s_keystone.pp" % controller.CONF['CONFIG_KEYSTONE_HOST'] + manifestdata = getManifestTemplate("keystone_heat.pp") + appendManifestFile(manifestfile, manifestdata) + + +def create_cloudwatch_manifest(config): + manifestfile = "%s_heatcw.pp" % controller.CONF['CONFIG_HEAT_CLOUDWATCH_HOST'] + manifestdata = getManifestTemplate("heat_cloudwatch.pp") + appendManifestFile(manifestfile, manifestdata, marker='heat') + + +def create_cfn_manifest(config): + manifestfile = "%s_heatcnf.pp" % controller.CONF['CONFIG_HEAT_CFN_HOST'] + manifestdata = getManifestTemplate("heat_cfn.pp") + appendManifestFile(manifestfile, manifestdata, marker='heat') diff --git a/packstack/plugins/mysql_001.py b/packstack/plugins/mysql_001.py index 7527746f8..c903a176a 100644 --- a/packstack/plugins/mysql_001.py +++ b/packstack/plugins/mysql_001.py @@ -103,7 +103,7 @@ def createmanifest(config): manifestdata.append(getManifestTemplate(template)) append_for("keystone", suffix) - for mod in ['nova', 'cinder', 'glance', 'neutron']: + for mod in ['nova', 'cinder', 'glance', 'neutron', 'heat']: if config['CONFIG_%s_INSTALL' % mod.upper()] == 'y': append_for(mod, suffix) diff --git a/packstack/plugins/prescript_000.py b/packstack/plugins/prescript_000.py index 406a2a636..4bee99578 100644 --- a/packstack/plugins/prescript_000.py +++ b/packstack/plugins/prescript_000.py @@ -119,6 +119,18 @@ def initConfig(controllerObject): "USE_DEFAULT" : False, "NEED_CONFIRM" : False, "CONDITION" : False }, + {"CMD_OPTION" : "os-heat-install", + "USAGE" : "Set to 'y' if you would like Packstack to install Heat", + "PROMPT" : "Should Packstack install Heat", + "OPTION_LIST" : ["y", "n"], + "VALIDATORS" : [validators.validate_options], + "DEFAULT_VALUE" : "n", + "MASK_INPUT" : False, + "LOOSE_VALIDATION": False, + "CONF_NAME" : "CONFIG_HEAT_INSTALL", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, {"CMD_OPTION" : "os-client-install", "USAGE" : "Set to 'y' if you would like Packstack to install the OpenStack Client packages. An admin \"rc\" file will also be installed", "PROMPT" : "Should Packstack install OpenStack client tools", diff --git a/packstack/plugins/puppet_950.py b/packstack/plugins/puppet_950.py index a7627c8ce..dfb3bb443 100644 --- a/packstack/plugins/puppet_950.py +++ b/packstack/plugins/puppet_950.py @@ -77,7 +77,7 @@ def installdeps(config): def copyPuppetModules(config): os_modules = ' '.join(('apache', 'ceilometer', 'cinder', 'concat', 'create_resources', 'firewall', 'glance', - 'horizon', 'inifile', 'keystone', + 'heat', 'horizon', 'inifile', 'keystone', 'memcached', 'mongodb', 'mysql', 'neutron', 'nova', 'openstack', 'packstack', 'qpid', 'rsync', 'ssh', 'stdlib', 'swift', 'sysctl', diff --git a/packstack/puppet/modules/heat b/packstack/puppet/modules/heat new file mode 160000 index 000000000..84d623b0d --- /dev/null +++ b/packstack/puppet/modules/heat @@ -0,0 +1 @@ +Subproject commit 84d623b0d38bcb136b7ba0948d3fd066dac4c637 diff --git a/packstack/puppet/templates/heat.pp b/packstack/puppet/templates/heat.pp new file mode 100644 index 000000000..f9c82b365 --- /dev/null +++ b/packstack/puppet/templates/heat.pp @@ -0,0 +1,23 @@ + +class { 'heat': + keystone_host => '%(CONFIG_KEYSTONE_HOST)s', + keystone_password => '%(CONFIG_HEAT_KS_PW)s', + auth_uri => 'http://%(CONFIG_KEYSTONE_HOST)s:35357/v2.0', + rpc_backend => 'heat.openstack.common.rpc.impl_qpid', + qpid_hostname => '%(CONFIG_QPID_HOST)s', + verbose => true, + debug => true +} + +class {"heat::db": + sql_connection => "mysql://heat:%(CONFIG_HEAT_DB_PW)s@%(CONFIG_MYSQL_HOST)s/heat" +} + +class { 'heat::api': +} + +class { 'heat::engine': + heat_metadata_server_url => 'http://%(CONFIG_HEAT_METADATA_HOST)s:8000', + heat_waitcondition_server_url => 'http://%(CONFIG_HEAT_METADATA_HOST)s:8000/v1/waitcondition', + heat_watch_server_url => 'http://%(CONFIG_HEAT_WATCH_HOST)s:8003', +} diff --git a/packstack/puppet/templates/heat_cfn.pp b/packstack/puppet/templates/heat_cfn.pp new file mode 100644 index 000000000..c4afe0066 --- /dev/null +++ b/packstack/puppet/templates/heat_cfn.pp @@ -0,0 +1,18 @@ + +class { 'heat': + keystone_host => '%(CONFIG_KEYSTONE_HOST)s', + keystone_password => '%(CONFIG_HEAT_KS_PW)s', + auth_uri => 'http://%(CONFIG_KEYSTONE_HOST)s:35357/v2.0', + rpc_backend => 'heat.openstack.common.rpc.impl_qpid', + qpid_hostname => '%(CONFIG_QPID_HOST)s', + verbose => true, + debug => true +} + +class {"heat::db": + sql_connection => "mysql://heat:%(CONFIG_HEAT_DB_PW)s@%(CONFIG_MYSQL_HOST)s/heat" +} + +class { 'heat::api_cfn': +} + diff --git a/packstack/puppet/templates/heat_cloudwatch.pp b/packstack/puppet/templates/heat_cloudwatch.pp new file mode 100644 index 000000000..8ea6ceec5 --- /dev/null +++ b/packstack/puppet/templates/heat_cloudwatch.pp @@ -0,0 +1,17 @@ + +class { 'heat': + keystone_host => '%(CONFIG_KEYSTONE_HOST)s', + keystone_password => '%(CONFIG_HEAT_KS_PW)s', + auth_uri => 'http://%(CONFIG_KEYSTONE_HOST)s:35357/v2.0', + rpc_backend => 'heat.openstack.common.rpc.impl_qpid', + qpid_hostname => '%(CONFIG_QPID_HOST)s', + verbose => true, + debug => true +} + +class {"heat::db": + sql_connection => "mysql://heat:%(CONFIG_HEAT_DB_PW)s@%(CONFIG_MYSQL_HOST)s/heat" +} + +class { 'heat::api_cloudwatch': +} diff --git a/packstack/puppet/templates/keystone_heat.pp b/packstack/puppet/templates/keystone_heat.pp new file mode 100644 index 000000000..4d012a307 --- /dev/null +++ b/packstack/puppet/templates/keystone_heat.pp @@ -0,0 +1,20 @@ + +if '%(CONFIG_HEAT_CFN_INSTALL)s' == 'y' { + class {"heat::keystone::auth": + password => "%(CONFIG_HEAT_KS_PW)s", + heat_public_address => "%(CONFIG_HEAT_HOST)s", + heat_admin_address => "%(CONFIG_HEAT_HOST)s", + heat_internal_address => "%(CONFIG_HEAT_HOST)s", + cfn_public_address => "%(CONFIG_HEAT_HOST)s", + cfn_admin_address => "%(CONFIG_HEAT_HOST)s", + cfn_internal_address => "%(CONFIG_HEAT_HOST)s", + } +} else { + class {"heat::keystone::auth": + password => "%(CONFIG_HEAT_KS_PW)s", + heat_public_address => "%(CONFIG_HEAT_HOST)s", + heat_admin_address => "%(CONFIG_HEAT_HOST)s", + heat_internal_address => "%(CONFIG_HEAT_HOST)s", + cfn_auth_name => undef, + } +} diff --git a/packstack/puppet/templates/mysql_heat_install.pp b/packstack/puppet/templates/mysql_heat_install.pp new file mode 100644 index 000000000..dce040627 --- /dev/null +++ b/packstack/puppet/templates/mysql_heat_install.pp @@ -0,0 +1,4 @@ +class {"heat::db::mysql": + password => "%(CONFIG_HEAT_DB_PW)s", + allowed_hosts => "%%", +} diff --git a/packstack/puppet/templates/mysql_heat_noinstall.pp b/packstack/puppet/templates/mysql_heat_noinstall.pp new file mode 100644 index 000000000..c40b09818 --- /dev/null +++ b/packstack/puppet/templates/mysql_heat_noinstall.pp @@ -0,0 +1,27 @@ + +remote_database { 'heat': + ensure => 'present', + charset => 'latin1', + db_host => '%(CONFIG_MYSQL_HOST)s', + db_user => '%(CONFIG_MYSQL_USER)s', + db_password => '%(CONFIG_MYSQL_PW)s', + provider => 'mysql', +} + +remote_database_user { 'heat@%%': + password_hash => mysql_password('%(CONFIG_HEAT_DB_PW)s'), + db_host => '%(CONFIG_MYSQL_HOST)s', + db_user => '%(CONFIG_MYSQL_USER)s', + db_password => '%(CONFIG_MYSQL_PW)s', + provider => 'mysql', + require => Remote_database['heat'], +} + +remote_database_grant { 'heat@%%/heat': + privileges => "all", + db_host => '%(CONFIG_MYSQL_HOST)s', + db_user => '%(CONFIG_MYSQL_USER)s', + db_password => '%(CONFIG_MYSQL_PW)s', + provider => 'mysql', + require => Remote_database_user['heat@%%'], +}