diff --git a/manifests/api.pp b/manifests/api.pp index 50a132a1..3508d921 100644 --- a/manifests/api.pp +++ b/manifests/api.pp @@ -35,13 +35,9 @@ class octavia::api ( $sync_db = false, ) inherits octavia::params { + include ::octavia::deps include ::octavia::policy - Octavia_config<||> ~> Service['octavia-api'] - Class['octavia::policy'] ~> Service['octavia-api'] - - Package['octavia-api'] -> Service['octavia-api'] - Package['octavia-api'] -> Class['octavia::policy'] package { 'octavia-api': ensure => $package_ensure, name => $::octavia::params::api_package_name, @@ -66,7 +62,6 @@ class octavia::api ( enable => $enabled, hasstatus => true, hasrestart => true, - require => Class['octavia::db'], tag => ['octavia-service', 'octavia-db-sync-service'], } diff --git a/manifests/config.pp b/manifests/config.pp index fe569303..f74b9ddc 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -24,6 +24,8 @@ class octavia::config ( $octavia_config = {}, ) { + include ::octavia::deps + validate_hash($octavia_config) create_resources('octavia_config', $octavia_config) diff --git a/manifests/db.pp b/manifests/db.pp index 9fb010d0..fb18e1a1 100644 --- a/manifests/db.pp +++ b/manifests/db.pp @@ -49,6 +49,8 @@ class octavia::db ( $database_db_max_retries = $::os_service_default, ) { + include ::octavia::deps + validate_re($database_connection, '^(sqlite|mysql(\+pymysql)?|postgresql):\/\/(\S+:\S+@\S+\/\S+)?') diff --git a/manifests/db/mysql.pp b/manifests/db/mysql.pp index 7f5d5b9b..a09f2839 100644 --- a/manifests/db/mysql.pp +++ b/manifests/db/mysql.pp @@ -53,6 +53,8 @@ class octavia::db::mysql( $allowed_hosts = undef ) { + include ::octavia::deps + validate_string($password) ::openstacklib::db::mysql { 'octavia': @@ -65,5 +67,8 @@ class octavia::db::mysql( allowed_hosts => $allowed_hosts, } - ::Openstacklib::Db::Mysql['octavia'] ~> Exec<| title == 'octavia-manage db_sync' |> + Anchor['octavia::db::begin'] + ~> Class['octavia::db::mysql'] + ~> Anchor['octavia::db::end'] + } diff --git a/manifests/db/postgresql.pp b/manifests/db/postgresql.pp index 59142b27..0919a483 100644 --- a/manifests/db/postgresql.pp +++ b/manifests/db/postgresql.pp @@ -40,7 +40,7 @@ class octavia::db::postgresql( $privileges = 'ALL', ) { - Class['octavia::db::postgresql'] -> Service<| title == 'octavia' |> + include ::octavia::deps ::openstacklib::db::postgresql { 'octavia': password_hash => postgresql_password($user, $password), @@ -50,6 +50,8 @@ class octavia::db::postgresql( privileges => $privileges, } - ::Openstacklib::Db::Postgresql['octavia'] ~> Exec<| title == 'octavia-manage db_sync' |> + Anchor['octavia::db::begin'] + ~> Class['octavia::db::postgresql'] + ~> Anchor['octavia::db::end'] } diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp index e2b8fbd9..fa26c88d 100644 --- a/manifests/db/sync.pp +++ b/manifests/db/sync.pp @@ -11,6 +11,9 @@ class octavia::db::sync( $extra_params = undef, ) { + + include ::octavia::deps + exec { 'octavia-db-sync': command => "octavia-db-manage upgrade head ${extra_params}", path => '/usr/bin', @@ -18,8 +21,12 @@ class octavia::db::sync( refreshonly => true, try_sleep => 5, tries => 10, - subscribe => [Package['octavia'], Octavia_config['database/connection']], + subscribe => [ + Anchor['octavia::install::end'], + Anchor['octavia::config::end'], + Anchor['octavia::dbsync::begin'] + ], + notify => Anchor['octavia::dbsync::end'], } - Exec['octavia-db-sync'] ~> Service<| tag == 'octavia-db-sync-service' |> } diff --git a/manifests/deps.pp b/manifests/deps.pp new file mode 100644 index 00000000..428d424c --- /dev/null +++ b/manifests/deps.pp @@ -0,0 +1,35 @@ +# == Class: octavia::deps +# +# Octavia anchors and dependency management +# +class octavia::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 { 'octavia::install::begin': } + -> Package<| tag == 'octavia-package'|> + ~> anchor { 'octavia::install::end': } + -> anchor { 'octavia::config::begin': } + -> Octavia_config<||> + ~> anchor { 'octavia::config::end': } + -> anchor { 'octavia::db::begin': } + -> anchor { 'octavia::db::end': } + ~> anchor { 'octavia::dbsync::begin': } + -> anchor { 'octavia::dbsync::end': } + ~> anchor { 'octavia::service::begin': } + ~> Service<| tag == 'octavia-service' |> + ~> anchor { 'octavia::service::end': } + + # policy config should occur in the config block also. + Anchor['octavia::config::begin'] + -> Openstacklib::Policy::Base<||> + ~> Anchor['octavia::config::end'] + + # Installation or config changes will always restart services. + Anchor['octavia::install::end'] ~> Anchor['octavia::service::begin'] + Anchor['octavia::config::end'] ~> Anchor['octavia::service::begin'] +} diff --git a/manifests/health_manager.pp b/manifests/health_manager.pp index 43099a75..dd2559e0 100644 --- a/manifests/health_manager.pp +++ b/manifests/health_manager.pp @@ -21,19 +21,18 @@ # (optional) Driver to use for synchronizing octavia and lbaas databases. # Defaults to $::os_service_default # - class octavia::health_manager ( $heartbeat_key, - $manage_service = true, - $enabled = true, - $package_ensure = 'present', - $event_streamer_driver = $::os_service_default, + $manage_service = true, + $enabled = true, + $package_ensure = 'present', + $event_streamer_driver = $::os_service_default, ) inherits octavia::params { + include ::octavia::deps + validate_string($heartbeat_key) - Octavia_config<||> ~> Service['octavia-health-manager'] - Package['octavia-health-manager'] -> Service['octavia-health-manager'] package { 'octavia-health-manager': ensure => $package_ensure, name => $::octavia::params::health_manager_package_name, diff --git a/manifests/housekeeping.pp b/manifests/housekeeping.pp index 1a06c383..758fecf8 100644 --- a/manifests/housekeeping.pp +++ b/manifests/housekeeping.pp @@ -45,7 +45,7 @@ # [*cert_rotate_threads*] # (optional) Number of threads performing amphora certificate rotation. # Defaults to $::os_service_default - +# class octavia::housekeeping ( $manage_service = true, $enabled = true, @@ -60,8 +60,8 @@ class octavia::housekeeping ( $cert_rotate_threads = $::os_service_default, ) inherits octavia::params { - Octavia_config<||> ~> Service['octavia-housekeeping'] - Package['octavia-housekeeping'] -> Service['octavia-housekeeping'] + include ::octavia::deps + package { 'octavia-housekeeping': ensure => $package_ensure, name => $::octavia::params::housekeeping_package_name, diff --git a/manifests/init.pp b/manifests/init.pp index 3611e8f8..6f901a6b 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -203,6 +203,7 @@ class octavia ( $purge_config = false, ) inherits octavia::params { + include ::octavia::deps include ::octavia::logging include ::octavia::db diff --git a/manifests/keystone/auth.pp b/manifests/keystone/auth.pp index 801db80b..be0874fb 100644 --- a/manifests/keystone/auth.pp +++ b/manifests/keystone/auth.pp @@ -64,6 +64,8 @@ class octavia::keystone::auth ( $internal_url = 'http://127.0.0.1:9876', ) { + include ::octavia::deps + keystone::resource::service_identity { 'octavia': configure_user => $configure_user, configure_user_role => $configure_user_role, diff --git a/manifests/keystone/authtoken.pp b/manifests/keystone/authtoken.pp index 8dd01f7d..93776bbc 100644 --- a/manifests/keystone/authtoken.pp +++ b/manifests/keystone/authtoken.pp @@ -222,6 +222,8 @@ class octavia::keystone::authtoken( $token_cache_time = $::os_service_default, ) { + include ::octavia::deps + keystone::resource::authtoken { 'octavia_config': username => $username, password => $password, diff --git a/manifests/logging.pp b/manifests/logging.pp index 9b14cad3..5ac1d69e 100644 --- a/manifests/logging.pp +++ b/manifests/logging.pp @@ -113,6 +113,8 @@ class octavia::logging( $log_date_format = $::os_service_default, ) { + include ::octavia::deps + oslo::log { 'octavia_config': debug => $debug, use_syslog => $use_syslog, diff --git a/manifests/policy.pp b/manifests/policy.pp index 81cc7ba5..2cf47c9b 100644 --- a/manifests/policy.pp +++ b/manifests/policy.pp @@ -28,6 +28,8 @@ class octavia::policy ( $policy_path = '/etc/octavia/policy.json', ) { + include ::octavia::deps + validate_hash($policies) Openstacklib::Policy::Base { diff --git a/manifests/worker.pp b/manifests/worker.pp index d2af4564..5fd32e16 100644 --- a/manifests/worker.pp +++ b/manifests/worker.pp @@ -47,7 +47,6 @@ # Possible options are documented in puppet-nova nova_flavor type. # Defaults to {}. # - class octavia::worker ( $manage_service = true, $enabled = true, @@ -60,7 +59,9 @@ class octavia::worker ( $nova_flavor_config = {}, ) inherits octavia::params { -validate_hash($nova_flavor_config) + include ::octavia::deps + + validate_hash($nova_flavor_config) if ! is_service_default($loadbalancer_topology) and ! ($loadbalancer_topology in ['SINGLE', 'ACTIVE_STANDBY']) { fail('load balancer topology must be one of SINGLE or ACTIVE_STANDBY') @@ -88,8 +89,6 @@ validate_hash($nova_flavor_config) } } - Octavia_config<||> ~> Service['octavia-worker'] - Package['octavia-worker'] -> Service['octavia-worker'] package { 'octavia-worker': ensure => $package_ensure, name => $::octavia::params::worker_package_name, diff --git a/releasenotes/notes/external_install_mgmt_hook-1e652961711571a3.yaml b/releasenotes/notes/external_install_mgmt_hook-1e652961711571a3.yaml new file mode 100644 index 00000000..eeb3c9b5 --- /dev/null +++ b/releasenotes/notes/external_install_mgmt_hook-1e652961711571a3.yaml @@ -0,0 +1,10 @@ +--- +prelude: > + Add hooks for external install & svc management. +features: + - This adds defined anchor points for external modules to + hook into the software install, config and service dependency + chain. This allows external modules to manage software + installation (virtualenv, containers, etc) and service management + (pacemaker) without needing rely on resources that may change or + be renamed. diff --git a/spec/classes/octavia_api_spec.rb b/spec/classes/octavia_api_spec.rb index 93ebcae5..daaa6474 100644 --- a/spec/classes/octavia_api_spec.rb +++ b/spec/classes/octavia_api_spec.rb @@ -18,6 +18,7 @@ describe 'octavia::api' do shared_examples_for 'octavia-api' do + it { is_expected.to contain_class('octavia::deps') } it { is_expected.to contain_class('octavia::params') } it { is_expected.to contain_class('octavia::policy') } @@ -47,10 +48,11 @@ describe 'octavia::api' do :enable => params[:enabled], :hasstatus => true, :hasrestart => true, - :require => 'Class[Octavia::Db]', :tag => ['octavia-service', 'octavia-db-sync-service'], ) end + it { is_expected.to contain_service('octavia-api').that_subscribes_to('Anchor[octavia::service::begin]')} + it { is_expected.to contain_service('octavia-api').that_notifies('Anchor[octavia::service::end]')} end end diff --git a/spec/classes/octavia_init_spec.rb b/spec/classes/octavia_init_spec.rb index ec58f682..c6524eee 100644 --- a/spec/classes/octavia_init_spec.rb +++ b/spec/classes/octavia_init_spec.rb @@ -9,6 +9,10 @@ describe 'octavia' do { :purge_config => false } end + it 'contains the deps class' do + is_expected.to contain_class('octavia::deps') + end + it 'contains the logging class' do is_expected.to contain_class('octavia::logging') end