diff --git a/modules/puppet-fm/PKG_INFO b/modules/puppet-fm/PKG_INFO new file mode 100644 index 000000000..285a5ae04 --- /dev/null +++ b/modules/puppet-fm/PKG_INFO @@ -0,0 +1,2 @@ +Name: puppet-fm +Version: 1.0.0 diff --git a/modules/puppet-fm/centos/build_srpm.data b/modules/puppet-fm/centos/build_srpm.data new file mode 100644 index 000000000..29c4710a7 --- /dev/null +++ b/modules/puppet-fm/centos/build_srpm.data @@ -0,0 +1,3 @@ +SRC_DIR="src" +COPY_LIST="$SRC_DIR/LICENSE" +TIS_PATCH_VER=1 diff --git a/modules/puppet-fm/centos/puppet-fm.spec b/modules/puppet-fm/centos/puppet-fm.spec new file mode 100644 index 000000000..47322e77a --- /dev/null +++ b/modules/puppet-fm/centos/puppet-fm.spec @@ -0,0 +1,34 @@ +%global module_dir fm + +Name: puppet-%{module_dir} +Version: 1.0.0 +Release: %{tis_patch_ver}%{?_tis_dist} +Summary: Puppet FM module +License: Apache-2.0 +Packager: Wind River <info@windriver.com> + +URL: unknown + +Source0: %{name}-%{version}.tar.gz +Source1: LICENSE + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +A puppet module for Fault Management + +%prep +%autosetup -c %{module_dir} + +# +# The src for this puppet module needs to be staged to puppet/modules +# +%install +install -d -m 0755 %{buildroot}%{_datadir}/puppet/modules/%{module_dir} +cp -R %{name}-%{version}/%{module_dir} %{buildroot}%{_datadir}/puppet/modules + +%files +%license %{name}-%{version}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} diff --git a/modules/puppet-fm/src/LICENSE b/modules/puppet-fm/src/LICENSE new file mode 100644 index 000000000..8d968b6cb --- /dev/null +++ b/modules/puppet-fm/src/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/modules/puppet-fm/src/fm/lib/puppet/provider/fm_api_paste_ini/ini_setting.rb b/modules/puppet-fm/src/fm/lib/puppet/provider/fm_api_paste_ini/ini_setting.rb new file mode 100644 index 000000000..7fd50aeb3 --- /dev/null +++ b/modules/puppet-fm/src/fm/lib/puppet/provider/fm_api_paste_ini/ini_setting.rb @@ -0,0 +1,27 @@ +Puppet::Type.type(:fm_api_paste_ini).provide( + :ini_setting, + :parent => Puppet::Type.type(:ini_setting).provider(:ruby) +) do + + def section + resource[:name].split('/', 2).first + end + + def setting + resource[:name].split('/', 2).last + end + + def separator + '=' + end + + def self.file_path + '/etc/fm/api-paste.ini' + end + + # this needs to be removed. This has been replaced with the class method + def file_path + self.class.file_path + end + +end diff --git a/modules/puppet-fm/src/fm/lib/puppet/provider/fm_config/ini_setting.rb b/modules/puppet-fm/src/fm/lib/puppet/provider/fm_config/ini_setting.rb new file mode 100644 index 000000000..f00b4851d --- /dev/null +++ b/modules/puppet-fm/src/fm/lib/puppet/provider/fm_config/ini_setting.rb @@ -0,0 +1,10 @@ +Puppet::Type.type(:fm_config).provide( + :ini_setting, + :parent => Puppet::Type.type(:openstack_config).provider(:ini_setting) +) do + + def self.file_path + '/etc/fm/fm.conf' + end + +end diff --git a/modules/puppet-fm/src/fm/lib/puppet/type/fm_api_paste_ini.rb b/modules/puppet-fm/src/fm/lib/puppet/type/fm_api_paste_ini.rb new file mode 100644 index 000000000..0df981e0c --- /dev/null +++ b/modules/puppet-fm/src/fm/lib/puppet/type/fm_api_paste_ini.rb @@ -0,0 +1,43 @@ +Puppet::Type.newtype(:fm_api_paste_ini) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/fm/api_paste.ini' + newvalues(/\S+\/\S+/) + end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + + newvalues(:true, :false) + + defaultto false + end +end + diff --git a/modules/puppet-fm/src/fm/lib/puppet/type/fm_config.rb b/modules/puppet-fm/src/fm/lib/puppet/type/fm_config.rb new file mode 100644 index 000000000..e4ad3a832 --- /dev/null +++ b/modules/puppet-fm/src/fm/lib/puppet/type/fm_config.rb @@ -0,0 +1,51 @@ +Puppet::Type.newtype(:fm_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from fm.conf' + newvalues(/\S+\/\S+/) + end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + newvalues(/^[\S ]*$/) + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + newvalues(:true, :false) + defaultto false + end + + newparam(:ensure_absent_val) do + desc 'A value that is specified as the value property will behave as if ensure => absent was specified' + defaultto('<SERVICE DEFAULT>') + end + + autorequire(:package) do + 'fm-rest-api' + end + +end diff --git a/modules/puppet-fm/src/fm/manifests/api.pp b/modules/puppet-fm/src/fm/manifests/api.pp new file mode 100644 index 000000000..f5dcacf81 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/api.pp @@ -0,0 +1,109 @@ +# Installs & configure the fm api service +# +# == Parameters +# +# [*enabled*] +# (optional) Should the service be enabled. +# Defaults to true +# +# [*manage_service*] +# (optional) Whether the service should be managed by Puppet. +# Defaults to true. +# +# [*host*] +# (optional) The fm api bind address. +# Defaults to 0.0.0.0 +# +# [*port*] +# (optional) The fm api port. +# Defaults to 18002 +# +# [*package_ensure*] +# (optional) ensure state for package. +# Defaults to 'present' +# +# [*service_name*] +# (optional) Name of the service that will be providing the +# server functionality of fm-api. +# +# [*sync_db*] +# (optional) Run gnocchi-upgrade db sync on api nodes after installing the package. +# Defaults to false +# +# [*auth_strategy*] +# (optional) Type of authentication to be used. +# Defaults to 'keystone' +# +# [*enable_proxy_headers_parsing*] +# (Optional) Enable paste middleware to handle SSL requests through +# HTTPProxyToWSGI middleware. +# Defaults to $::os_service_default. +# +# [*paste_config*] +# (Optional) Configuration file for WSGI definition of API +# Defaults to $::os_service_default. +# +class fm::api ( + $manage_service = true, + $enabled = true, + $package_ensure = 'present', + $host = '0.0.0.0', + $port = '18002', + $workers = 1, + $service_name = $::fm::params::api_service, + $sync_db = false, + $auth_strategy = 'keystone', + $enable_proxy_headers_parsing = $::os_service_default, + $paste_config = '/etc/fm/api-paste.ini', +) inherits fm::params { + + + include ::fm::deps + include ::fm::params + + if $auth_strategy == 'keystone' { + include ::fm::keystone::authtoken + } + + package { 'fm-api': + ensure => $package_ensure, + name => $::fm::params::api_package, + tag => 'fm-package', + } + + if $manage_service { + if $enabled { + $service_ensure = 'running' + } else { + $service_ensure = 'stopped' + } + } + + if $sync_db { + include ::fm::db::sync + } + + if $service_name == $::fm::params::api_service { + service { 'fm-api': + ensure => $service_ensure, + name => $::fm::params::api_service, + enable => $enabled, + hasstatus => true, + hasrestart => true, + tag => 'fm-service', + } + } else { + fail("Invalid service_name. fm-api for running as a standalone service") + } + + fm_config { + 'api/bind_host': value => $host; + 'api/bind_port': value => $port; + 'api/api_workers': value => $workers; + 'api/api_paste_config': value => $paste_config; + } + + oslo::middleware { 'fm_config': + enable_proxy_headers_parsing => $enable_proxy_headers_parsing, + } +} diff --git a/modules/puppet-fm/src/fm/manifests/client.pp b/modules/puppet-fm/src/fm/manifests/client.pp new file mode 100644 index 000000000..1267012be --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/client.pp @@ -0,0 +1,22 @@ +# +# Installs the fm python client. +# +# == parameters +# [*ensure*] +# (optional) Ensure state of the package. +# Defaults to 'present'. +# +class fm::client ( + $ensure = 'present' +) { + + include ::fm::deps + include ::fm::params + + package { 'fmclient': + ensure => $ensure, + name => $::fm::params::client_package, + tag => 'fmclient', + } +} + diff --git a/modules/puppet-fm/src/fm/manifests/db.pp b/modules/puppet-fm/src/fm/manifests/db.pp new file mode 100644 index 000000000..f82d7c1df --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/db.pp @@ -0,0 +1,78 @@ +# == Class: fm::db +# +# Configure the fm database +# +# === Parameters +# +# [*database_db_max_retries*] +# (optional) Maximum retries in case of connection error or deadlock error +# before error is raised. Set to -1 to specify an infinite retry count. +# Defaults to $::os_service_default +# +# [*database_connection*] +# Url used to connect to database. +# (Optional) Defaults to "sqlite:////var/lib/fm/fm.sqlite". +# +# [*database_idle_timeout*] +# Timeout when db connections should be reaped. +# (Optional) Defaults to $::os_service_default. +# +# [*database_min_pool_size*] +# Minimum number of SQL connections to keep open in a pool. +# (Optional) Defaults to $::os_service_default. +# +# [*database_max_pool_size*] +# Maximum number of SQL connections to keep open in a pool. +# (Optional) Defaults to $::os_service_default. +# +# [*database_max_retries*] +# Maximum number of database connection retries during startup. +# Setting -1 implies an infinite retry count. +# (Optional) Defaults to $::os_service_default. +# +# [*database_retry_interval*] +# Interval between retries of opening a database connection. +# (Optional) Defaults to $::os_service_default. +# +# [*database_max_overflow*] +# If set, use this value for max_overflow with sqlalchemy. +# (Optional) Defaults to $::os_service_default. +# +class fm::db ( + $database_db_max_retries = $::os_service_default, + $database_connection = 'sqlite:////var/lib/fm/fm.sqlite', + $database_idle_timeout = $::os_service_default, + $database_min_pool_size = $::os_service_default, + $database_max_pool_size = $::os_service_default, + $database_max_retries = $::os_service_default, + $database_retry_interval = $::os_service_default, + $database_max_overflow = $::os_service_default, +) { + + include ::fm::deps + + $database_connection_real = pick($::fm::database_connection, $database_connection) + $database_idle_timeout_real = pick($::fm::database_idle_timeout, $database_idle_timeout) + $database_min_pool_size_real = pick($::fm::database_min_pool_size, $database_min_pool_size) + $database_max_pool_size_real = pick($::fm::database_max_pool_size, $database_max_pool_size) + $database_max_retries_real = pick($::fm::database_max_retries, $database_max_retries) + $database_retry_interval_real = pick($::fm::database_retry_interval, $database_retry_interval) + $database_max_overflow_real = pick($::fm::database_max_overflow, $database_max_overflow) + + oslo::db { 'fm_config': + db_max_retries => $database_db_max_retries, + connection => $database_connection_real, + idle_timeout => $database_idle_timeout_real, + min_pool_size => $database_min_pool_size_real, + max_pool_size => $database_max_pool_size_real, + max_retries => $database_max_retries_real, + retry_interval => $database_retry_interval_real, + max_overflow => $database_max_overflow_real, + } + + # set up the connection string for FM Manager + $sql_connection = regsubst($database_connection_real,'^postgresql+psycopg2:','postgresql:') + fm_config { + 'DEFAULT/sql_connection': value => $sql_connection; + } +} diff --git a/modules/puppet-fm/src/fm/manifests/db/mysql.pp b/modules/puppet-fm/src/fm/manifests/db/mysql.pp new file mode 100644 index 000000000..cbe034975 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/db/mysql.pp @@ -0,0 +1,75 @@ +# The fm::db::mysql class implements mysql backend for fm +# +# This class can be used to create tables, users and grant +# privileges for a mysql fm database. +# +# == parameters +# +# [*password*] +# (Mandatory) Password to connect to the database. +# Defaults to 'false'. +# +# [*dbname*] +# (Optional) Name of the database. +# Defaults to 'fm'. +# +# [*user*] +# (Optional) User to connect to the database. +# Defaults to 'fm'. +# +# [*host*] +# (Optional) The default source host user is allowed to connect from. +# Defaults to '127.0.0.1' +# +# [*allowed_hosts*] +# (Optional) Other hosts the user is allowed to connect from. +# Defaults to 'undef'. +# +# [*charset*] +# (Optional) The database charset. +# Defaults to 'utf8' +# +# [*collate*] +# (Optional) The database collate. +# Only used with mysql modules >= 2.2. +# Defaults to 'utf8_general_ci' +# +# == Dependencies +# Class['mysql::server'] +# +# == Examples +# +# == Authors +# +# == Copyright +# +class fm::db::mysql( + $password, + $dbname = 'fm', + $user = 'fm', + $host = '127.0.0.1', + $charset = 'utf8', + $collate = 'utf8_general_ci', + $allowed_hosts = undef +) { + + #include ::fm::deps + + validate_string($password) + + ::openstacklib::db::mysql { 'fm': + user => $user, + password_hash => mysql_password($password), + dbname => $dbname, + host => $host, + charset => $charset, + collate => $collate, + allowed_hosts => $allowed_hosts, + } + + Anchor['fm::db::begin'] + ~> Class['fm::db::mysql'] + ~> Anchor['fm::db::end'] + +} + diff --git a/modules/puppet-fm/src/fm/manifests/db/postgresql.pp b/modules/puppet-fm/src/fm/manifests/db/postgresql.pp new file mode 100644 index 000000000..26c272620 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/db/postgresql.pp @@ -0,0 +1,57 @@ +# == Class: fm::db::postgresql +# +# Class that configures postgresql for fm +# Requires the Puppetlabs postgresql module. +# +# === Parameters +# +# [*password*] +# (Required) Password to connect to the database. +# +# [*dbname*] +# (Optional) Name of the database. +# Defaults to 'fm'. +# +# [*user*] +# (Optional) User to connect to the database. +# Defaults to 'fm'. +# +# [*encoding*] +# (Optional) The charset to use for the database. +# Default to undef. +# +# [*privileges*] +# (Optional) Privileges given to the database user. +# Default to 'ALL' +# +# == Dependencies +# +# == Examples +# +# == Authors +# +# == Copyright +# +class fm::db::postgresql( + $password, + $dbname = 'fm', + $user = 'fm', + $encoding = undef, + $privileges = 'ALL', +) { + + include ::fm::deps + + ::openstacklib::db::postgresql { 'fm': + password_hash => postgresql_password($user, $password), + dbname => $dbname, + user => $user, + encoding => $encoding, + privileges => $privileges, + } + + Anchor['fm::db::begin'] + ~> Class['fm::db::postgresql'] + ~> Anchor['fm::db::end'] + +} diff --git a/modules/puppet-fm/src/fm/manifests/db/sync.pp b/modules/puppet-fm/src/fm/manifests/db/sync.pp new file mode 100644 index 000000000..e2fdbcd4b --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/db/sync.pp @@ -0,0 +1,30 @@ +# +# Class to execute "fm-dbsync" +# +# [*user*] +# (optional) User to run dbsync command. +# Defaults to 'fm' +# +class fm::db::sync ( + $user = 'fm', +){ + + include ::fm::deps + + exec { 'fm-db-sync': + command => 'fm-dbsync --config-file /etc/fm/fm.conf', + path => '/usr/bin', + refreshonly => true, + user => $user, + try_sleep => 5, + tries => 10, + logoutput => on_failure, + subscribe => [ + Anchor['fm::install::end'], + Anchor['fm::config::end'], + Anchor['fm::dbsync::begin'] + ], + notify => Anchor['fm::dbsync::end'], + } + +} diff --git a/modules/puppet-fm/src/fm/manifests/deps.pp b/modules/puppet-fm/src/fm/manifests/deps.pp new file mode 100644 index 000000000..ea7af7f13 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/deps.pp @@ -0,0 +1,40 @@ +# == Class: fm::deps +# +# FM anchors and dependency management +# +class fm::deps { + # Setup anchors for install, config and service phases of the module. These + # anchors allow external modules to hook the begin and end of any of these + # phases. Package or service management can also be replaced by ensuring the + # package is absent or turning off service management and having the + # replacement depend on the appropriate anchors. When applicable, end tags + # should be notified so that subscribers can determine if installation, + # config or service state changed and act on that if needed. + anchor { 'fm::install::begin': } + -> Package<| tag == 'fm-package'|> + ~> anchor { 'fm::install::end': } + -> anchor { 'fm::config::begin': } + -> Fm_config<||> + ~> anchor { 'fm::config::end': } + -> anchor { 'fm::db::begin': } + -> anchor { 'fm::db::end': } + ~> anchor { 'fm::dbsync::begin': } + -> anchor { 'fm::dbsync::end': } + ~> anchor { 'fm::service::begin': } + ~> Service<| tag == 'fm-service' |> + ~> anchor { 'fm::service::end': } + + # api paste ini config should occur in the config block also. + Anchor['fm::config::begin'] + -> Fm_api_paste_ini<||> + ~> Anchor['fm::config::end'] + + # all db settings should be applied and all packages should be installed + # before dbsync starts + Oslo::Db<||> -> Anchor['fm::dbsync::begin'] + + # Installation or config changes will always restart services. + Anchor['fm::install::end'] ~> Anchor['fm::service::begin'] + Anchor['fm::config::end'] ~> Anchor['fm::service::begin'] +} + diff --git a/modules/puppet-fm/src/fm/manifests/init.pp b/modules/puppet-fm/src/fm/manifests/init.pp new file mode 100644 index 000000000..b2958c933 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/init.pp @@ -0,0 +1,116 @@ +# == Class: fm +# +# Full description of class fm here. +# +# === Parameters +# +# [*package_ensure*] +# (optional) The state of fm packages +# Defaults to 'present' +# +# [*log_dir*] +# (optional) Directory where logs should be stored. +# If set to boolean false or the $::os_service_default, it will not log to +# any directory. +# Defaults to undef. +# +# [*debug*] +# (optional) Set log output to debug output. +# Defaults to undef +# +# [*use_syslog*] +# (optional) Use syslog for logging +# Defaults to undef +# +# [*use_stderr*] +# (optional) Use stderr for logging +# Defaults to undef +# +# [*log_facility*] +# (optional) Syslog facility to receive log lines. +# Defaults to undef +# +# [*database_connection*] +# (optional) Connection url for the fm database. +# Defaults to undef. +# +# [*database_max_retries*] +# (optional) Maximum database connection retries during startup. +# Defaults to undef. +# +# [*database_idle_timeout*] +# (optional) Timeout before idle database connections are reaped. +# Defaults to undef. +# +# [*database_retry_interval*] +# (optional) Interval between retries of opening a database connection. +# Defaults to undef. +# +# [*database_min_pool_size*] +# (optional) Minimum number of SQL connections to keep open in a pool. +# Defaults to undef. +# +# [*database_max_pool_size*] +# (optional) Maximum number of SQL connections to keep open in a pool. +# Defaults to undef. +# +# [*database_max_overflow*] +# (optional) If set, use this value for max_overflow with sqlalchemy. +# Defaults to: undef. +# +class fm ( + $package_ensure = 'present', + $debug = undef, + $use_syslog = undef, + $use_stderr = undef, + $log_facility = undef, + $log_dir = undef, + $database_connection = undef, + $database_idle_timeout = undef, + $database_min_pool_size = undef, + $database_max_pool_size = undef, + $database_max_retries = undef, + $database_retry_interval = undef, + $database_max_overflow = undef, + $event_log_max_size = 4000, + $system_name = undef, + $region_name = undef, + $trap_destinations = undef, + $sysinv_catalog_info = undef, +) inherits fm::params { + + include ::fm::deps + include ::fm::logging + + # set up the connection string for FM Manager, remove psycopg2 if it exists + $sql_connection = regsubst($database_connection,'^postgresql+psycopg2:','postgresql:') + fm_config { + 'DEFAULT/sql_connection': value => $sql_connection, secret => true; + 'DEFAULT/event_log_max_size': value => $event_log_max_size; + 'DEFAULT/system_name': value => $system_name; + 'DEFAULT/region_name': value => $region_name; + 'DEFAULT/trap_destinations': value => $trap_destinations; + } + + # Automatically add psycopg2 driver to postgresql (only does this if it is missing) + $real_connection = regsubst($database_connection,'^postgresql:','postgresql+psycopg2:') + fm_config { + 'database/connection': value => $real_connection, secret => true; + 'database/idle_timeout': value => $database_idle_timeout; + 'database/max_pool_size': value => $database_max_pool_size; + 'database/max_overflow': value => $database_max_overflow; + } + + fm_config { + 'sysinv/catalog_info': value => $sysinv_catalog_info; + 'sysinv/os_region_name': value => $region_name; + } + + fm_api_paste_ini { + 'pipeline:fm-api/pipeline': value => 'request_id authtoken api_v1'; + 'filter:request_id/paste.filter_factory': value => 'oslo_middleware:RequestId.factory'; + 'filter:authtoken/acl_public_routes': value => '/, /v1'; + 'filter:authtoken/paste.filter_factory': value => 'fm.api.middleware.auth_token:AuthTokenMiddleware.factory'; + 'app:api_v1/paste.app_factory': value => 'fm.api.app:app_factory'; + } +} diff --git a/modules/puppet-fm/src/fm/manifests/keystone/auth.pp b/modules/puppet-fm/src/fm/manifests/keystone/auth.pp new file mode 100644 index 000000000..ddbf31970 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/keystone/auth.pp @@ -0,0 +1,87 @@ +# == Class: fm::keystone::auth +# +# Configures fault management user, service and endpoint in Keystone. +# +# === Parameters +# +# [*password*] +# (required) Password for fm user. +# +# [*auth_name*] +# Username for fm service. Defaults to 'fm'. +# +# [*email*] +# Email for fm user. Defaults to 'fm@localhost'. +# +# [*tenant*] +# Tenant for fm user. Defaults to 'services'. +# +# [*configure_endpoint*] +# Should fm endpoint be configured? Defaults to 'true'. +# +# [*configure_user*] +# (Optional) Should the service user be configured? +# Defaults to 'true'. +# +# [*configure_user_role*] +# (Optional) Should the admin role be configured for the service user? +# Defaults to 'true'. +# +# [*service_type*] +# Type of service. Defaults to 'faultmanagement'. +# +# [*region*] +# Region for endpoint. Defaults to 'RegionOne'. +# +# [*service_name*] +# (optional) Name of the service. +# Defaults to 'fm'. +# +# [*public_url*] +# (optional) The endpoint's public url. (Defaults to 'http://127.0.0.1:18002') +# This url should *not* contain any trailing '/'. +# +# [*admin_url*] +# (optional) The endpoint's admin url. (Defaults to 'http://127.0.0.1:18002') +# This url should *not* contain any trailing '/'. +# +# [*internal_url*] +# (optional) The endpoint's internal url. (Defaults to 'http://127.0.0.1:18002') +# This url should *not* contain any trailing '/'. +# +class fm::keystone::auth ( + $password, + $auth_name = 'fm', + $email = 'fm@localhost', + $tenant = 'services', + $configure_endpoint = true, + $configure_user = true, + $configure_user_role = true, + $service_name = 'fm', + $service_type = 'faultmanagement', + $region = 'RegionOne', + $public_url = 'http://127.0.0.1:18002', + $internal_url = 'http://127.0.0.1:18002', + $admin_url = 'http://127.0.0.1:18002', +) { + + include ::fm::deps + + keystone::resource::service_identity { 'fm': + configure_user => $configure_user, + configure_user_role => $configure_user_role, + configure_endpoint => $configure_endpoint, + service_name => $service_name, + service_type => $service_type, + service_description => 'Fault Management Service', + region => $region, + auth_name => $auth_name, + password => $password, + email => $email, + tenant => $tenant, + public_url => $public_url, + internal_url => $internal_url, + admin_url => $admin_url, + } + +} diff --git a/modules/puppet-fm/src/fm/manifests/keystone/authtoken.pp b/modules/puppet-fm/src/fm/manifests/keystone/authtoken.pp new file mode 100644 index 000000000..2b2755249 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/keystone/authtoken.pp @@ -0,0 +1,243 @@ +# class: fm::keystone::authtoken +# +# Configure the keystone_authtoken section in the configuration file +# +# === Parameters +# +# [*username*] +# (Optional) The name of the service user +# Defaults to 'fm' +# +# [*password*] +# (Optional) Password to create for the service user +# Defaults to $::os_service_default +# +# [*auth_url*] +# (Optional) The URL to use for authentication. +# Defaults to 'http://localhost:35357' +# +# [*project_name*] +# (Optional) Service project name +# Defaults to 'services' +# +# [*user_domain_name*] +# (Optional) Name of domain for $username +# Defaults to 'Default' +# +# [*project_domain_name*] +# (Optional) Name of domain for $project_name +# Defaults to 'Default' +# +# [*insecure*] +# (Optional) If true, explicitly allow TLS without checking server cert +# against any certificate authorities. WARNING: not recommended. Use with +# caution. +# Defaults to $::os_service_default +# +# [*auth_section*] +# (Optional) Config Section from which to load plugin specific options +# Defaults to $::os_service_default. +# +# [*auth_type*] +# (Optional) Authentication type to load +# Defaults to 'password' +# +# [*auth_uri*] +# (Optional) Complete public Identity API endpoint. +# Defaults to 'http://localhost:5000' +# +# [*auth_version*] +# (Optional) API version of the admin Identity API endpoint. +# Defaults to $::os_service_default. +# +# [*cache*] +# (Optional) Env key for the swift cache. +# Defaults to $::os_service_default. +# +# [*cafile*] +# (Optional) A PEM encoded Certificate Authority to use when verifying HTTPs +# connections. +# Defaults to $::os_service_default. +# +# [*certfile*] +# (Optional) Required if identity server requires client certificate +# Defaults to $::os_service_default. +# +# [*check_revocations_for_cached*] +# (Optional) If true, the revocation list will be checked for cached tokens. +# This requires that PKI tokens are configured on the identity server. +# boolean value. +# Defaults to $::os_service_default. +# +# [*delay_auth_decision*] +# (Optional) Do not handle authorization requests within the middleware, but +# delegate the authorization decision to downstream WSGI components. Boolean +# value +# Defaults to $::os_service_default. +# +# [*enforce_token_bind*] +# (Optional) Used to control the use and type of token binding. Can be set +# to: "disabled" to not check token binding. "permissive" (default) to +# validate binding information if the bind type is of a form known to the +# server and ignore it if not. "strict" like "permissive" but if the bind +# type is unknown the token will be rejected. "required" any form of token +# binding is needed to be allowed. Finally the name of a binding method that +# must be present in tokens. String value. +# Defaults to $::os_service_default. +# +# [*hash_algorithms*] +# (Optional) Hash algorithms to use for hashing PKI tokens. This may be a +# single algorithm or multiple. The algorithms are those supported by Python +# standard hashlib.new(). The hashes will be tried in the order given, so put +# the preferred one first for performance. The result of the first hash will +# be stored in the cache. This will typically be set to multiple values only +# while migrating from a less secure algorithm to a more secure one. Once all +# the old tokens are expired this option should be set to a single value for +# better performance. List value. +# Defaults to $::os_service_default. +# +# [*http_connect_timeout*] +# (Optional) Request timeout value for communicating with Identity API +# server. +# Defaults to $::os_service_default. +# +# [*http_request_max_retries*] +# (Optional) How many times are we trying to reconnect when communicating +# with Identity API Server. Integer value +# Defaults to $::os_service_default. +# +# [*include_service_catalog*] +# (Optional) Indicate whether to set the X-Service-Catalog header. If False, +# middleware will not ask for service catalog on token validation and will +# not set the X-Service-Catalog header. Boolean value. +# Defaults to $::os_service_default. +# +# [*keyfile*] +# (Optional) Required if identity server requires client certificate +# Defaults to $::os_service_default. +# +# [*memcache_pool_conn_get_timeout*] +# (Optional) Number of seconds that an operation will wait to get a memcached +# client connection from the pool. Integer value +# Defaults to $::os_service_default. +# +# [*memcache_pool_dead_retry*] +# (Optional) Number of seconds memcached server is considered dead before it +# is tried again. Integer value +# Defaults to $::os_service_default. +# +# [*memcache_pool_maxsize*] +# (Optional) Maximum total number of open connections to every memcached +# server. Integer value +# Defaults to $::os_service_default. +# +# [*memcache_pool_socket_timeout*] +# (Optional) Number of seconds a connection to memcached is held unused in +# the pool before it is closed. Integer value +# Defaults to $::os_service_default. +# +# [*memcache_pool_unused_timeout*] +# (Optional) Number of seconds a connection to memcached is held unused in +# the pool before it is closed. Integer value +# Defaults to $::os_service_default. +# +# [*memcache_secret_key*] +# (Optional, mandatory if memcache_security_strategy is defined) This string +# is used for key derivation. +# Defaults to $::os_service_default. +# +# [*memcache_security_strategy*] +# (Optional) If defined, indicate whether token data should be authenticated +# or authenticated and encrypted. If MAC, token data is authenticated (with +# HMAC) in the cache. If ENCRYPT, token data is encrypted and authenticated in the +# cache. If the value is not one of these options or empty, auth_token will +# raise an exception on initialization. +# Defaults to $::os_service_default. +# +# [*memcache_use_advanced_pool*] +# (Optional) Use the advanced (eventlet safe) memcached client pool. The +# advanced pool will only work under python 2.x Boolean value +# Defaults to $::os_service_default. +# +# [*memcached_servers*] +# (Optional) Optionally specify a list of memcached server(s) to use for +# caching. If left undefined, tokens will instead be cached in-process. +# Defaults to $::os_service_default. +# +# [*manage_memcache_package*] +# (Optional) Whether to install the python-memcache package. +# Defaults to false. +# +# [*region_name*] +# (Optional) The region in which the identity server can be found. +# Defaults to $::os_service_default. +# +# [*revocation_cache_time*] +# (Optional) Determines the frequency at which the list of revoked tokens is +# retrieved from the Identity service (in seconds). A high number of +# revocation events combined with a low cache duration may significantly +# reduce performance. Only valid for PKI tokens. Integer value +# Defaults to $::os_service_default. +# +# [*token_cache_time*] +# (Optional) In order to prevent excessive effort spent validating tokens, +# the middleware caches previously-seen tokens for a configurable duration +# (in seconds). Set to -1 to disable caching completely. Integer value +# Defaults to $::os_service_default. +# +class fm::keystone::authtoken( + $username = 'fm', + $password = $::os_service_default, + $auth_url = 'http://localhost:35357', + $project_name = 'services', + $user_domain_name = 'Default', + $project_domain_name = 'Default', + $insecure = $::os_service_default, + $auth_section = $::os_service_default, + $auth_type = 'password', + $auth_uri = 'http://localhost:5000', + $auth_version = $::os_service_default, + $cache = $::os_service_default, + $cafile = $::os_service_default, + $certfile = $::os_service_default, + $check_revocations_for_cached = $::os_service_default, + $delay_auth_decision = $::os_service_default, + $enforce_token_bind = $::os_service_default, + $hash_algorithms = $::os_service_default, + $http_connect_timeout = $::os_service_default, + $http_request_max_retries = $::os_service_default, + $include_service_catalog = $::os_service_default, + $keyfile = $::os_service_default, + $memcache_pool_conn_get_timeout = $::os_service_default, + $memcache_pool_dead_retry = $::os_service_default, + $memcache_pool_maxsize = $::os_service_default, + $memcache_pool_socket_timeout = $::os_service_default, + $memcache_pool_unused_timeout = $::os_service_default, + $memcache_secret_key = $::os_service_default, + $memcache_security_strategy = $::os_service_default, + $memcache_use_advanced_pool = $::os_service_default, + $memcached_servers = $::os_service_default, + $manage_memcache_package = false, + $region_name = $::os_service_default, + $revocation_cache_time = $::os_service_default, + $token_cache_time = $::os_service_default, +) { + + include ::fm::deps + + if is_service_default($password) { + fail('Please set password for FM service user') + } + + keystone::resource::authtoken { 'fm_config': + username => $username, + password => $password, + project_name => $project_name, + auth_url => $auth_url, + auth_uri => $auth_uri, + auth_type => $auth_type, + user_domain_name => $user_domain_name, + project_domain_name => $project_domain_name, + region_name => $region_name, + } +} diff --git a/modules/puppet-fm/src/fm/manifests/logging.pp b/modules/puppet-fm/src/fm/manifests/logging.pp new file mode 100644 index 000000000..62a2f4a33 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/logging.pp @@ -0,0 +1,134 @@ +# Class fm::logging +# +# fm logging configuration +# +# == parameters +# +# [*debug*] +# (Optional) Should the daemons log debug messages +# Defaults to $::os_service_default +# +# [*use_syslog*] +# (Optional) Use syslog for logging. +# Defaults to $::os_service_default +# +# [*use_stderr*] +# (optional) Use stderr for logging +# Defaults to $::os_service_default +# +# [*log_facility*] +# (Optional) Syslog facility to receive log lines. +# Defaults to $::os_service_default +# +# [*log_dir*] +# (optional) Directory where logs should be stored. +# If set to boolean false or the $::os_service_default, it will not log to +# any directory. +# Defaults to '/var/log/fm'. +# +# [*logging_context_format_string*] +# (optional) Format string to use for log messages with context. +# Defaults to $::os_service_default +# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\ +# [%(request_id)s %(user_identity)s] %(instance)s%(message)s' +# +# [*logging_default_format_string*] +# (optional) Format string to use for log messages without context. +# Defaults to $::os_service_default +# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\ +# [-] %(instance)s%(message)s' +# +# [*logging_debug_format_suffix*] +# (optional) Formatted data to append to log format when level is DEBUG. +# Defaults to $::os_service_default +# Example: '%(funcName)s %(pathname)s:%(lineno)d' +# +# [*logging_exception_prefix*] +# (optional) Prefix each line of exception output with this format. +# Defaults to $::os_service_default +# Example: '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s' +# +# [*log_config_append*] +# The name of an additional logging configuration file. +# Defaults to $::os_service_default +# See https://docs.python.org/2/howto/logging.html +# +# [*default_log_levels*] +# (optional) Hash of logger (keys) and level (values) pairs. +# Defaults to $::os_service_default +# Example: +# { 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN', +# 'sqlalchemy' => 'WARN', 'suds' => 'INFO', 'iso8601' => 'WARN', +# 'requests.packages.urllib3.connectionpool' => 'WARN' } +# +# [*publish_errors*] +# (optional) Publish error events (boolean value). +# Defaults to $::os_service_default +# +# [*fatal_deprecations*] +# (optional) Make deprecations fatal (boolean value) +# Defaults to $::os_service_default +# +# [*instance_format*] +# (optional) If an instance is passed with the log message, format it +# like this (string value). +# Defaults to $::os_service_default +# Example: '[instance: %(uuid)s] ' +# +# [*instance_uuid_format*] +# (optional) If an instance UUID is passed with the log message, format +# it like this (string value). +# Defaults to $::os_service_default +# Example: instance_uuid_format='[instance: %(uuid)s] ' +# +# [*log_date_format*] +# (optional) Format string for %%(asctime)s in log records. +# Defaults to $::os_service_default +# Example: 'Y-%m-%d %H:%M:%S' +# +class fm::logging( + $use_syslog = $::os_service_default, + $use_stderr = $::os_service_default, + $log_facility = $::os_service_default, + $log_dir = '/var/log/fm', + $debug = $::os_service_default, + $logging_context_format_string = $::os_service_default, + $logging_default_format_string = $::os_service_default, + $logging_debug_format_suffix = $::os_service_default, + $logging_exception_prefix = $::os_service_default, + $log_config_append = $::os_service_default, + $default_log_levels = $::os_service_default, + $publish_errors = $::os_service_default, + $fatal_deprecations = $::os_service_default, + $instance_format = $::os_service_default, + $instance_uuid_format = $::os_service_default, + $log_date_format = $::os_service_default, +) { + + include ::fm::deps + + $use_syslog_real = pick($::fm::use_syslog,$use_syslog) + $use_stderr_real = pick($::fm::use_stderr,$use_stderr) + $log_facility_real = pick($::fm::log_facility,$log_facility) + $log_dir_real = pick($::fm::log_dir,$log_dir) + $debug_real = pick($::fm::debug,$debug) + + oslo::log { 'fm_config': + debug => $debug_real, + use_syslog => $use_syslog_real, + use_stderr => $use_stderr_real, + log_dir => $log_dir_real, + syslog_log_facility => $log_facility_real, + logging_context_format_string => $logging_context_format_string, + logging_default_format_string => $logging_default_format_string, + logging_debug_format_suffix => $logging_debug_format_suffix, + logging_exception_prefix => $logging_exception_prefix, + log_config_append => $log_config_append, + default_log_levels => $default_log_levels, + publish_errors => $publish_errors, + fatal_deprecations => $fatal_deprecations, + log_date_format => $log_date_format, + instance_format => $instance_format, + instance_uuid_format => $instance_uuid_format, + } +} diff --git a/modules/puppet-fm/src/fm/manifests/params.pp b/modules/puppet-fm/src/fm/manifests/params.pp new file mode 100644 index 000000000..d96ec2821 --- /dev/null +++ b/modules/puppet-fm/src/fm/manifests/params.pp @@ -0,0 +1,20 @@ +class fm::params { + + case $::osfamily { + 'RedHat': { + $client_package = 'python-fmclient' + $api_package = 'fm-rest-api' + $api_service = 'fm-api' + } + 'Debian': { + $client_package = 'python-fmclient' + $api_package = 'fm-rest-api' + $api_service = 'fm-api' + } + default: { + fail("Unsupported osfamily: ${::osfamily} operatingsystem") + } + + } # Case $::osfamily + +} diff --git a/modules/puppet-nfv/src/nfv/manifests/nfvi.pp b/modules/puppet-nfv/src/nfv/manifests/nfvi.pp index 96315c70f..c99ccae43 100644 --- a/modules/puppet-nfv/src/nfv/manifests/nfvi.pp +++ b/modules/puppet-nfv/src/nfv/manifests/nfvi.pp @@ -52,6 +52,10 @@ class nfv::nfvi ( $patching_service_name = 'patching', $patching_service_type = 'patching', $patching_endpoint_type = 'admin', + $fm_region_name = 'RegionOne', + $fm_service_name = 'fm', + $fm_service_type = 'faultmanagement', + $fm_endpoint_type = 'admin', $rabbit_host = '127.0.0.1', $rabbit_port = 5672, $rabbit_userid = 'guest', @@ -133,6 +137,11 @@ class nfv::nfvi ( 'patching/service_type': value => $patching_service_type; 'patching/endpoint_type': value => $patching_endpoint_type; + 'fm/region_name': value => $fm_region_name; + 'fm/service_name': value => $fm_service_name; + 'fm/service_type': value => $fm_service_type; + 'fm/endpoint_type': value => $fm_endpoint_type; + /* AMQP */ 'amqp/host': value => $rabbit_host; 'amqp/port': value => $rabbit_port; diff --git a/puppet-manifests/centos/puppet-manifests.spec b/puppet-manifests/centos/puppet-manifests.spec index d3f690476..7717aa38d 100644 --- a/puppet-manifests/centos/puppet-manifests.spec +++ b/puppet-manifests/centos/puppet-manifests.spec @@ -21,6 +21,7 @@ Requires: puppet-patching Requires: puppet-sysinv Requires: puppet-sshd Requires: puppet-smapi +Requires: puppet-fm # Openstack puppet modules Requires: puppet-aodh diff --git a/puppet-manifests/src/hieradata/controller.yaml b/puppet-manifests/src/hieradata/controller.yaml index c06f32f37..e54cd853c 100644 --- a/puppet-manifests/src/hieradata/controller.yaml +++ b/puppet-manifests/src/hieradata/controller.yaml @@ -524,3 +524,13 @@ dcorch::debug: false dcmanager::use_syslog: true dcmanager::log_facility: 'local2' dcmanager::debug: false + +#FM +fm::use_syslog: true +fm::log_facility: 'local2' +fm::api::enable_proxy_headers_parsing: true +fm::db::sync::user: 'root' +fm::database_idle_timeout: 60 +fm::database_max_overflow: 20 +fm::database_max_pool_size: 1 + diff --git a/puppet-manifests/src/manifests/controller.pp b/puppet-manifests/src/manifests/controller.pp index 89e733c41..ec0bfe1df 100644 --- a/puppet-manifests/src/manifests/controller.pp +++ b/puppet-manifests/src/manifests/controller.pp @@ -62,6 +62,9 @@ include ::platform::influxdb include ::platform::influxdb::logrotate include ::platform::collectd +include ::platform::fm +include ::platform::fm::api + include ::openstack::client include ::openstack::keystone include ::openstack::keystone::api diff --git a/puppet-manifests/src/modules/openstack/manifests/keystone.pp b/puppet-manifests/src/modules/openstack/manifests/keystone.pp index 500e29b14..e2c4d3b13 100644 --- a/puppet-manifests/src/modules/openstack/manifests/keystone.pp +++ b/puppet-manifests/src/modules/openstack/manifests/keystone.pp @@ -325,6 +325,7 @@ class openstack::keystone::endpoint::runtime { include ::sysinv::keystone::auth include ::patching::keystone::auth include ::nfv::keystone::auth + include ::fm::keystone::auth include ::openstack::aodh::params if $::openstack::aodh::params::service_enabled { diff --git a/puppet-manifests/src/modules/platform/manifests/fm.pp b/puppet-manifests/src/modules/platform/manifests/fm.pp new file mode 100644 index 000000000..75052d476 --- /dev/null +++ b/puppet-manifests/src/modules/platform/manifests/fm.pp @@ -0,0 +1,101 @@ +class platform::fm::params ( + $api_port = 18002, + $api_host = undef, + $region_name = undef, + $system_name = undef, + $service_create = false, + $service_enabled = true, + $trap_destinations = [], + $sysinv_catalog_info = 'platform:sysinv:internalURL', +) { } + + +class platform::fm::config + inherits ::platform::fm::params { + + $trap_dest_str = join($trap_destinations,',') + class { '::fm': + region_name => $region_name, + system_name => $system_name, + trap_destinations => $trap_dest_str, + sysinv_catalog_info => $sysinv_catalog_info, + } +} + +class platform::fm + inherits ::platform::fm::params { + + include ::fm::client + include ::fm::keystone::authtoken + include ::platform::fm::config + + include ::platform::params + if $::platform::params::init_database { + include ::fm::db::postgresql + } +} + +class platform::fm::firewall + inherits ::platform::fm::params { + + platform::firewall::rule { 'fm-api': + service_name => 'fm', + ports => $api_port, + } +} + +class platform::fm::haproxy + inherits ::platform::fm::params { + + include ::platform::haproxy::params + + platform::haproxy::proxy { 'fm-api-internal': + server_name => 's-fm-api-internal', + public_ip_address => $::platform::haproxy::params::private_ip_address, + public_port => $api_port, + private_ip_address => $api_host, + private_port => $api_port, + public_api => false, + } + + platform::haproxy::proxy { 'fm-api-public': + server_name => 's-fm-api-public', + public_port => $api_port, + private_port => $api_port, + } +} + +class platform::fm::api + inherits ::platform::fm::params { + + include ::platform::params + + if $service_enabled { + if ($::platform::fm::service_create and + $::platform::params::init_keystone) { + include ::fm::keystone::auth + } + + include ::platform::params + + class { '::fm::api': + host => $api_host, + workers => $::platform::params::eng_workers, + sync_db => $::platform::params::init_database, + } + + include ::platform::fm::firewall + include ::platform::fm::haproxy + } +} + +class platform::fm::runtime { + + require ::platform::fm::config + + exec { 'notify-fm-mgr': + command => "/usr/bin/pkill -HUP fmManager", + onlyif => "pgrep fmManager" + } +} + diff --git a/puppet-manifests/src/modules/platform/manifests/haproxy.pp b/puppet-manifests/src/modules/platform/manifests/haproxy.pp index 0430a566c..7191f800c 100644 --- a/puppet-manifests/src/modules/platform/manifests/haproxy.pp +++ b/puppet-manifests/src/modules/platform/manifests/haproxy.pp @@ -19,6 +19,7 @@ define platform::haproxy::proxy ( $client_timeout = undef, $x_forwarded_proto = true, $enable_https = undef, + $public_api = true, ) { include ::platform::haproxy::params @@ -29,7 +30,7 @@ define platform::haproxy::proxy ( } if $x_forwarded_proto { - if $https_enabled { + if $https_enabled and $public_api { $ssl_option = 'ssl crt /etc/ssl/private/server-cert.pem' $proto = 'X-Forwarded-Proto:\ https' # The value of max-age matches lighttpd.conf, and should be @@ -135,6 +136,7 @@ class platform::haproxy::runtime { include ::platform::sysinv::haproxy include ::platform::nfv::haproxy include ::platform::ceph::haproxy + include ::platform::fm::haproxy if $::platform::params::distributed_cloud_role =='systemcontroller' { include ::platform::dcmanager::haproxy include ::platform::dcorch::haproxy diff --git a/puppet-manifests/src/modules/platform/manifests/postgresql.pp b/puppet-manifests/src/modules/platform/manifests/postgresql.pp index e283c117f..60a0d9e79 100644 --- a/puppet-manifests/src/modules/platform/manifests/postgresql.pp +++ b/puppet-manifests/src/modules/platform/manifests/postgresql.pp @@ -211,6 +211,7 @@ class platform::postgresql::upgrade include ::sysinv::db::postgresql include ::keystone::db::postgresql include ::ironic::db::postgresql + include ::fm::db::postgresql } diff --git a/puppet-manifests/src/modules/platform/manifests/sysinv.pp b/puppet-manifests/src/modules/platform/manifests/sysinv.pp index c50b3f0f8..0b2afef96 100644 --- a/puppet-manifests/src/modules/platform/manifests/sysinv.pp +++ b/puppet-manifests/src/modules/platform/manifests/sysinv.pp @@ -60,12 +60,6 @@ class platform::sysinv 'sysinv %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s'; } - $sysinv_db_connection = $::sysinv::database_connection - file { "/etc/fm.conf": - ensure => 'present', - content => template('platform/fm.conf.erb'), - } - if str2bool($::is_initial_config_primary) { $software_version = $::platform::params::software_version diff --git a/puppet-manifests/src/modules/platform/templates/fm.conf.erb b/puppet-manifests/src/modules/platform/templates/fm.conf.erb deleted file mode 100644 index f6f418da4..000000000 --- a/puppet-manifests/src/modules/platform/templates/fm.conf.erb +++ /dev/null @@ -1,9 +0,0 @@ -################################################### -# -# fm.conf -# -# The configuration file for the fmManager process. -# -################################################### -event_log_max_size=4000 -sql_connection=<%= @sysinv_db_connection %> diff --git a/puppet-manifests/src/modules/platform/templates/fm.snmp.conf.erb b/puppet-manifests/src/modules/platform/templates/fm.snmp.conf.erb new file mode 100644 index 000000000..6822b9aff --- /dev/null +++ b/puppet-manifests/src/modules/platform/templates/fm.snmp.conf.erb @@ -0,0 +1,6 @@ +[snmp] +<%- @trap_destinations.each do |destination| -%> +trap2sink=<%= destination %> +<%- end -%> + +