Merge "Implementation of cli command and API to enable/disable apparmor module"

This commit is contained in:
Zuul 2022-11-07 22:28:03 +00:00 committed by Gerrit Code Review
commit bd8e60161d
9 changed files with 99 additions and 3 deletions

View File

@ -36,7 +36,7 @@ def _print_ihost_show(ihost, columns=None, output_format=None):
'tboot', 'vim_progress_status', 'software_load',
'install_state', 'install_state_info', 'inv_state',
'clock_synchronization', 'device_image_update',
'reboot_needed', 'max_cpu_mhz_configured', 'max_cpu_mhz_allowed']
'reboot_needed', 'max_cpu_mhz_configured', 'max_cpu_mhz_allowed', 'apparmor']
optional_fields = ['vsc_controllers', 'ttys_dcd']
if ihost.subfunctions != ihost.personality:
fields.append('subfunctions')

View File

@ -107,7 +107,7 @@ HOST_XML_ATTRIBUTES = ['hostname', 'personality', 'subfunctions',
'bm_ip', 'bm_type', 'bm_username',
'bm_password', 'boot_device', 'rootfs_device',
'install_output', 'console', 'vsc_controllers',
'power_on', 'location']
'power_on', 'location', 'apparmor']
def _get_controller_address(hostname):
@ -538,6 +538,9 @@ class Host(base.APIBase):
ttys_dcd = types.boolean
"Enable or disable serial console carrier detect"
apparmor = wtypes.text
"Enable/Disable apparmor state"
software_load = wtypes.text
"The current load software version"
@ -594,7 +597,8 @@ class Host(base.APIBase):
'iscsi_initiator_name',
'device_image_update', 'reboot_needed',
'inv_state', 'clock_synchronization',
'max_cpu_mhz_configured', 'max_cpu_mhz_allowed']
'max_cpu_mhz_configured', 'max_cpu_mhz_allowed',
'apparmor']
fields = minimum_fields if not expand else None
uhost = Host.from_rpc_object(rpc_ihost, fields)
@ -2062,6 +2066,15 @@ class HostController(rest.RestController):
if (hostupdate.ihost_orig['administrative'] ==
constants.ADMIN_UNLOCKED):
self.check_updates_while_unlocked(hostupdate, delta)
if 'apparmor' in delta:
raise wsme.exc.ClientSideError(
("This update is not allowed as host:%s is unlocked." %
(hostupdate.displayid)))
if 'apparmor' in delta and hostupdate.ihost_patch['apparmor'] \
not in [constants.APPARMOR_STATE_ENABLED, constants.APPARMOR_STATE_DISABLED]:
raise wsme.exc.ClientSideError(
("Invalid apparmor state. Allowed values:%s, %s." %
(constants.APPARMOR_STATE_ENABLED, constants.APPARMOR_STATE_DISABLED)))
current_ihosts = None
hostupdate.bm_type_changed_to_none = \
@ -2311,6 +2324,11 @@ class HostController(rest.RestController):
self._handle_ttys_dcd_change(hostupdate.ihost_orig,
hostupdate.ihost_patch['ttys_dcd'])
# check if apparmor is updated and notify the agent via conductor
if 'apparmor' in hostupdate.delta:
self._handle_apparmor_change(hostupdate.ihost_orig,
hostupdate.ihost_patch['apparmor'])
if 'clock_synchronization' in hostupdate.delta:
# perform rpc to conductor to perform config apply
pecan.request.rpcapi.update_clock_synchronization_config(
@ -4661,6 +4679,26 @@ class HostController(rest.RestController):
pecan.request.rpcapi.update_ttys_dcd(
pecan.request.context, ihost['uuid'])
@staticmethod
def _handle_apparmor_change(ihost, apparmor):
"""
Update GRUB CMDLINE to enable or disable apparmor.
:param ihost: unpatched ihost dictionary
:param apparmor: attribute supplied in patch
"""
LOG.info("%s _handle_apparmor_change from %s to %s" %
(ihost['hostname'], ihost['apparmor'], apparmor))
# check if the flag is changed
if apparmor is not None:
if ihost['apparmor'] is None or ihost['apparmor'] != apparmor:
if (ihost['administrative'] == constants.ADMIN_LOCKED and
ihost['availability'] == constants.AVAILABILITY_ONLINE):
LOG.info("Notify conductor apparmor change: (%s) (%s)" %
(ihost['uuid'], apparmor))
pecan.request.rpcapi.update_apparmor(
pecan.request.context, ihost['uuid'])
def mtc_action_apps_semantic_checks(self, action):
""" Enhance semantic checks from this class.
Let apps run semantic checks.

View File

@ -2186,3 +2186,7 @@ OS_UPGRADE_FEED_FOLDER = '/var/www/pages/feed/'
# Configuration support placeholders
CONFIGURABLE = 'configurable'
NOT_CONFIGURABLE = 'not-configurable'
# apparmor states
APPARMOR_STATE_ENABLED = 'enabled'
APPARMOR_STATE_DISABLED = 'disabled'

View File

@ -1135,6 +1135,22 @@ class ConductorManager(service.PeriodicService):
os.system("pkill -HUP dnsmasq")
def update_apparmor_config(self, context, ihost_uuid):
"""Update the GRUB CMDLINE to enable/disable apparmor"""
host = self.dbapi.ihost_get(ihost_uuid)
personalities = [constants.WORKER,
constants.CONTROLLER]
config_uuid = self._config_update_hosts(context,
personalities,
[host['uuid']])
config_dict = {
"personalities": personalities,
"host_uuids": [host['uuid']],
"classes": ['platform::config::apparmor::runtime'],
}
self._config_apply_runtime_manifest(context, config_uuid, config_dict)
def _update_pxe_config(self, host, load=None):
"""Set up the PXE config file for this host so it can run
the installer.

View File

@ -1182,6 +1182,18 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
self.make_msg('update_ttys_dcd',
ihost_uuid=ihost_uuid))
def update_apparmor(self, context, ihost_uuid):
"""Asynchronously, have a conductor update the apparmor GRUB CMDLINE.
Does the following tasks:
- Update puppet hiera configuration file and apply run time manifest
via an asynchronous rpc call to sysinv-agent
:param context: request context.
:ihost_uuid: the host uuid
"""
return self.call(context,
self.make_msg('update_apparmor_config',
ihost_uuid=ihost_uuid))
def start_import_load(self, context, path_to_iso, path_to_sig,
import_active=False, timeout=180):
"""Synchronously, mount the ISO and validate the load for import

View File

@ -0,0 +1,22 @@
#
# Copyright (c) 2022 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from sqlalchemy import Column, MetaData, Table
from sqlalchemy import String
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
migrate_engine.connect()
i_host = Table('i_host', meta, autoload=True)
i_host.create_column(Column('apparmor', String(64), default="disabled"))
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
raise NotImplementedError('SysInv databse downgrade is unsupported.')

View File

@ -225,6 +225,7 @@ class ihost(Base):
config_status = Column(String(255))
config_applied = Column(String(255))
config_target = Column(String(255))
apparmor = Column(String(64), default="disabled")
clock_synchronization = Column(String(32), default=constants.NTP)

View File

@ -50,6 +50,8 @@ class Host(base.SysinvObject):
'subfunctions': utils.str_or_none,
'subfunction_oper': utils.str_or_none,
'subfunction_avail': utils.str_or_none,
'apparmor': utils.str_or_none,
# Host is working on a blocking process
'reserved': utils.bool_or_none,
# NOTE: instance_uuid must be read-only when server is provisioned

View File

@ -277,6 +277,7 @@ class PlatformPuppet(base.BasePuppet):
config = {
'platform::params::hostname': host.hostname,
'platform::params::software_version': self.quoted_str(host.software_load),
'platform::params::apparmor': host.apparmor,
}
# optional parameters