Add keystone password change callback
Adding a callback to execute the puppet class 'platform::keystone::password::runtime' Test Plan: PASS: Verify the command 'openstack user password set' ran in openstack /var/log/sysinv.log PASS: Verify the password change trigger reaches the subcloud when the environment variable OS REGION NAME is changed to 'SystemController' PASS: Verify the patch apply using sw-patch and sw-manager patch-strategy commands after changing openstack (keystone) password Regression: PASS: Verify system patch install PASS: Verify feature logging PASS: Verify controllers, compute nodes after a force reboot PASS: Verify bm type ipmi, redfish and dynamic PASS: Verify push docker image to local registry PASS: Verify uploading charts via helm upload PASS: Verify host operations with custom kubectl app PASS: Verify isolated 2 peers to big pod (HT non-AIO) PASS: Verify system core dumps and crashes PASS: Verify system health pre session for pods, alarms, system apps PASS: Verify horizon host inventory display PASS: Verify lock unlock host PASS: Verify swact controller platform PASS: Verify pod to pod connection PASS: Verify pod to service connection PASS: Verify host to service connection Story: 2009194 Task: 43249 Signed-off-by: Alexandre Horst <alexandre.horst@windriver.com> Change-Id: I1a2d3ff0c99ca29f63db9ca0a3f0d78b59b8d819
This commit is contained in:
parent
d221cafce0
commit
a6740ee507
|
@ -2,6 +2,7 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
# Copyright (C) 2019 Intel Corporation
|
# Copyright (C) 2019 Intel Corporation
|
||||||
|
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
"""
|
"""
|
||||||
Sysinv Keystone notification listener.
|
Sysinv Keystone notification listener.
|
||||||
|
@ -9,7 +10,6 @@ Sysinv Keystone notification listener.
|
||||||
|
|
||||||
import keyring
|
import keyring
|
||||||
import oslo_messaging
|
import oslo_messaging
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@ from sysinv.db import api as dbapi
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
kube_app = None
|
callback_func = None
|
||||||
|
context = None
|
||||||
|
|
||||||
|
|
||||||
class NotificationEndpoint(object):
|
class NotificationEndpoint(object):
|
||||||
|
@ -38,8 +39,15 @@ class NotificationEndpoint(object):
|
||||||
|
|
||||||
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
||||||
"""Receives notification at info level."""
|
"""Receives notification at info level."""
|
||||||
global kube_app
|
global callback_func
|
||||||
kube_app.audit_local_registry_secrets()
|
global context
|
||||||
|
|
||||||
|
if payload['eventType'] == 'activity' and \
|
||||||
|
payload['action'] == 'updated.user' and \
|
||||||
|
payload['outcome'] == 'success' and \
|
||||||
|
payload['resource_info'] == context.user:
|
||||||
|
callback_func(context)
|
||||||
|
|
||||||
return oslo_messaging.NotificationResult.HANDLED
|
return oslo_messaging.NotificationResult.HANDLED
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,14 +65,19 @@ def get_transport_url():
|
||||||
|
|
||||||
auth_password = keyring.get_password('amqp', 'rabbit')
|
auth_password = keyring.get_password('amqp', 'rabbit')
|
||||||
|
|
||||||
transport_url = "rabbit://guest:%s@%s:5672" % (auth_password, address.address)
|
if utils.is_valid_ipv6(address.address):
|
||||||
|
address = "[%s]" % address
|
||||||
|
|
||||||
|
transport_url = "rabbit://guest:%s@%s:5672" % (auth_password, address)
|
||||||
return transport_url
|
return transport_url
|
||||||
|
|
||||||
|
|
||||||
def start_keystone_listener(app):
|
def start_keystone_listener(func, ctxt):
|
||||||
|
|
||||||
global kube_app
|
global callback_func
|
||||||
kube_app = app
|
global context
|
||||||
|
callback_func = func
|
||||||
|
context = ctxt
|
||||||
|
|
||||||
conf = cfg.ConfigOpts()
|
conf = cfg.ConfigOpts()
|
||||||
conf.transport_url = get_transport_url()
|
conf.transport_url = get_transport_url()
|
||||||
|
|
|
@ -957,7 +957,7 @@ class AppOperator(object):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
|
|
||||||
def audit_local_registry_secrets(self):
|
def audit_local_registry_secrets(self, context):
|
||||||
"""
|
"""
|
||||||
local registry uses admin's username&password for authentication.
|
local registry uses admin's username&password for authentication.
|
||||||
K8s stores the authentication info in secrets in order to access
|
K8s stores the authentication info in secrets in order to access
|
||||||
|
|
|
@ -258,7 +258,19 @@ class ConductorManager(service.PeriodicService):
|
||||||
|
|
||||||
# monitor keystone user update event to check whether admin password is
|
# monitor keystone user update event to check whether admin password is
|
||||||
# changed or not. If changed, then sync it to kubernetes's secret info.
|
# changed or not. If changed, then sync it to kubernetes's secret info.
|
||||||
greenthread.spawn(keystone_listener.start_keystone_listener, self._app)
|
|
||||||
|
admin_user = self._openstack.get_keystone_admin_user()
|
||||||
|
|
||||||
|
if admin_user:
|
||||||
|
admin_context = ctx.RequestContext(user=admin_user.id, tenant='admin', is_admin=True)
|
||||||
|
# The thread for kube_app auditing local registry secrets
|
||||||
|
greenthread.spawn(keystone_listener.start_keystone_listener,
|
||||||
|
self._app.audit_local_registry_secrets, admin_context)
|
||||||
|
|
||||||
|
# The thread for updating keystone admin password in config files
|
||||||
|
greenthread.spawn(keystone_listener.start_keystone_listener,
|
||||||
|
self.update_keystone_password,
|
||||||
|
admin_context)
|
||||||
|
|
||||||
# Monitor ceph to become responsive
|
# Monitor ceph to become responsive
|
||||||
if StorageBackendConfig.has_backend_configured(
|
if StorageBackendConfig.has_backend_configured(
|
||||||
|
@ -1641,6 +1653,19 @@ class ConductorManager(service.PeriodicService):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def update_keystone_password(self, context):
|
||||||
|
"""This method calls a puppet class
|
||||||
|
'openstack::keystone::password::runtime'
|
||||||
|
on keystone password change"""
|
||||||
|
|
||||||
|
personalities = [constants.CONTROLLER]
|
||||||
|
config_uuid = self._config_update_hosts(context, personalities)
|
||||||
|
config_dict = {
|
||||||
|
"personalities": personalities,
|
||||||
|
"classes": ["openstack::keystone::password::runtime"]
|
||||||
|
}
|
||||||
|
self._config_apply_runtime_manifest(context, config_uuid, config_dict)
|
||||||
|
|
||||||
def update_remotelogging_config(self, context):
|
def update_remotelogging_config(self, context):
|
||||||
"""Update the remotelogging configuration"""
|
"""Update the remotelogging configuration"""
|
||||||
|
|
||||||
|
@ -5823,7 +5848,7 @@ class ConductorManager(service.PeriodicService):
|
||||||
# Audit kubernetes local registry secrets info
|
# Audit kubernetes local registry secrets info
|
||||||
LOG.debug("Sysinv Conductor running periodic audit task for k8s local registry secrets.")
|
LOG.debug("Sysinv Conductor running periodic audit task for k8s local registry secrets.")
|
||||||
if self._app:
|
if self._app:
|
||||||
self._app.audit_local_registry_secrets()
|
self._app.audit_local_registry_secrets(context)
|
||||||
|
|
||||||
@periodic_task.periodic_task(spacing=CONF.conductor.audit_interval)
|
@periodic_task.periodic_task(spacing=CONF.conductor.audit_interval)
|
||||||
def _conductor_audit(self, context):
|
def _conductor_audit(self, context):
|
||||||
|
|
|
@ -347,6 +347,31 @@ class OpenStackOperator(object):
|
||||||
"snapshots before restoring volumes."))
|
"snapshots before restoring volumes."))
|
||||||
LOG.debug("Cinder DB ready for volume Restore")
|
LOG.debug("Cinder DB ready for volume Restore")
|
||||||
|
|
||||||
|
########################
|
||||||
|
# keystone user methods
|
||||||
|
########################
|
||||||
|
def _get_keystone_users(self):
|
||||||
|
"""Get a list of all users in keystone otherwise an empty list."""
|
||||||
|
user_list = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
user_list = self._get_keystone_client(OPENSTACK_CONFIG).users.list()
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Failed to get keystone user list:\n%s" % str(e))
|
||||||
|
|
||||||
|
return user_list
|
||||||
|
|
||||||
|
def get_keystone_admin_user(self):
|
||||||
|
"""Return keystone admin otherwise None."""
|
||||||
|
users = self._get_keystone_users()
|
||||||
|
|
||||||
|
try:
|
||||||
|
return [user for user in users if user.name == 'admin'][0]
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Failed to get keystone admin user:\n%s" % str(e))
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
# Primary Region Sysinv
|
# Primary Region Sysinv
|
||||||
# Region specific methods
|
# Region specific methods
|
||||||
|
|
Loading…
Reference in New Issue