Browse Source

Switch to oslo privsep

Please reference here:
https://docs.openstack.org/oslo.privsep/latest/user/index.html#converting-from-rootwrap-to-privsep

Change-Id: I5db0e64ec38d912f907b4ad483562120d030d726
tags/13.0.0.0rc1
zhurong 1 year ago
parent
commit
bd0d5a8a27
11 changed files with 87 additions and 20 deletions
  1. +5
    -0
      ceilometer/cmd/polling.py
  2. +3
    -2
      ceilometer/ipmi/platform/ipmitool.py
  3. +29
    -0
      ceilometer/privsep/__init__.py
  4. +25
    -0
      ceilometer/privsep/ipmitool.py
  5. +4
    -4
      ceilometer/tests/unit/ipmi/platform/test_intel_node_manager.py
  6. +3
    -3
      ceilometer/tests/unit/ipmi/platform/test_ipmi_sensor.py
  7. +0
    -8
      ceilometer/utils.py
  8. +1
    -3
      etc/ceilometer/rootwrap.d/ipmi.filters
  9. +1
    -0
      lower-constraints.txt
  10. +15
    -0
      releasenotes/notes/switch-to-oslo-privsep-b58f20a279f31bc0.yaml
  11. +1
    -0
      requirements.txt

+ 5
- 0
ceilometer/cmd/polling.py View File

@@ -14,13 +14,17 @@
# License for the specific language governing permissions and limitations
# under the License.

import shlex

import cotyledon
from cotyledon import oslo_config_glue
from oslo_config import cfg
from oslo_log import log
from oslo_privsep import priv_context

from ceilometer.polling import manager
from ceilometer import service
from ceilometer import utils

LOG = log.getLogger(__name__)

@@ -78,6 +82,7 @@ def main():
conf = cfg.ConfigOpts()
conf.register_cli_opts(CLI_OPTS)
service.prepare_service(conf=conf)
priv_context.init(root_helper=shlex.split(utils._get_root_helper()))
sm = cotyledon.ServiceManager()
sm.add(create_polling_service, args=(conf,))
oslo_config_glue.setup(sm, conf)


+ 3
- 2
ceilometer/ipmi/platform/ipmitool.py View File

@@ -17,7 +17,8 @@ from oslo_concurrency import processutils

from ceilometer.i18n import _
from ceilometer.ipmi.platform import exception as ipmiexcept
from ceilometer import utils

import ceilometer.privsep.ipmitool


# Following 2 functions are copied from ironic project to handle ipmitool's
@@ -123,7 +124,7 @@ def execute_ipmi_cmd(template=None):
command = f(self, **kwargs)
args.extend(command.split(" "))
try:
(out, __) = utils.execute(*args, run_as_root=True)
(out, __) = ceilometer.privsep.ipmitool.ipmi(*args)
except processutils.ProcessExecutionError:
raise ipmiexcept.IPMIException(_("running ipmitool failure"))
return _parse_output(out, template)


+ 29
- 0
ceilometer/privsep/__init__.py View File

@@ -0,0 +1,29 @@
#
# 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.

"""Setup privsep decorator."""

from oslo_privsep import capabilities
from oslo_privsep import priv_context

sys_admin_pctxt = priv_context.PrivContext(
'ceilometer',
cfg_section='ceilometer_sys_admin',
pypath=__name__ + '.sys_admin_pctxt',
capabilities=[capabilities.CAP_CHOWN,
capabilities.CAP_DAC_OVERRIDE,
capabilities.CAP_DAC_READ_SEARCH,
capabilities.CAP_FOWNER,
capabilities.CAP_NET_ADMIN,
capabilities.CAP_SYS_ADMIN],
)

+ 25
- 0
ceilometer/privsep/ipmitool.py View File

@@ -0,0 +1,25 @@
#
# 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.

"""
Helpers for impi related routines.
"""

from oslo_concurrency import processutils

import ceilometer.privsep


@ceilometer.privsep.sys_admin_pctxt.entrypoint
def ipmi(*cmd):
processutils.execute(*cmd)

+ 4
- 4
ceilometer/tests/unit/ipmi/platform/test_intel_node_manager.py View File

@@ -20,9 +20,9 @@ from oslotest import base
import six

from ceilometer.ipmi.platform import intel_node_manager as node_manager
from ceilometer.privsep import ipmitool
from ceilometer import service
from ceilometer.tests.unit.ipmi.platform import fake_utils
from ceilometer import utils


@six.add_metaclass(abc.ABCMeta)
@@ -56,7 +56,7 @@ class _Base(base.BaseTestCase):
class TestNodeManagerV3(_Base):

def init_test_engine(self):
utils.execute = mock.Mock(side_effect=fake_utils.execute_with_nm_v3)
ipmitool.ipmi = mock.Mock(side_effect=fake_utils.execute_with_nm_v3)

def test_read_airflow(self):
airflow = self.nm.read_airflow()
@@ -110,7 +110,7 @@ class TestNodeManagerV3(_Base):
class TestNodeManager(_Base):

def init_test_engine(self):
utils.execute = mock.Mock(side_effect=fake_utils.execute_with_nm_v2)
ipmitool.ipmi = mock.Mock(side_effect=fake_utils.execute_with_nm_v2)

def test_read_power_all(self):
power = self.nm.read_power_all()
@@ -162,7 +162,7 @@ class TestNodeManager(_Base):
class TestNonNodeManager(_Base):

def init_test_engine(self):
utils.execute = mock.Mock(side_effect=fake_utils.execute_without_nm)
ipmitool.ipmi = mock.Mock(side_effect=fake_utils.execute_without_nm)

def test_read_power_all(self):
# no NM support


+ 3
- 3
ceilometer/tests/unit/ipmi/platform/test_ipmi_sensor.py View File

@@ -16,8 +16,8 @@ import mock
from oslotest import base

from ceilometer.ipmi.platform import ipmi_sensor
from ceilometer.privsep import ipmitool
from ceilometer.tests.unit.ipmi.platform import fake_utils
from ceilometer import utils


class TestIPMISensor(base.BaseTestCase):
@@ -25,7 +25,7 @@ class TestIPMISensor(base.BaseTestCase):
def setUp(self):
super(TestIPMISensor, self).setUp()

utils.execute = mock.Mock(side_effect=fake_utils.execute_with_nm_v2)
ipmitool.ipmi = mock.Mock(side_effect=fake_utils.execute_with_nm_v2)
self.ipmi = ipmi_sensor.IPMISensor()

@classmethod
@@ -93,7 +93,7 @@ class TestNonIPMISensor(base.BaseTestCase):
def setUp(self):
super(TestNonIPMISensor, self).setUp()

utils.execute = mock.Mock(side_effect=fake_utils.execute_without_ipmi)
ipmitool.ipmi = mock.Mock(side_effect=fake_utils.execute_without_ipmi)
self.ipmi = ipmi_sensor.IPMISensor()

@classmethod


+ 0
- 8
ceilometer/utils.py View File

@@ -20,7 +20,6 @@

import threading

from oslo_concurrency import processutils
from oslo_config import cfg

ROOTWRAP_CONF = "/etc/ceilometer/rootwrap.conf"
@@ -43,13 +42,6 @@ def setup_root_helper(conf):
ROOTWRAP_CONF = conf.rootwrap_config


def execute(*cmd, **kwargs):
"""Convenience wrapper around oslo's execute() method."""
if 'run_as_root' in kwargs and 'root_helper' not in kwargs:
kwargs['root_helper'] = _get_root_helper()
return processutils.execute(*cmd, **kwargs)


def spawn_thread(target, *args, **kwargs):
t = threading.Thread(target=target, args=args, kwargs=kwargs)
t.daemon = True


+ 1
- 3
etc/ceilometer/rootwrap.d/ipmi.filters View File

@@ -2,6 +2,4 @@
# This file should be owned by (and only-writeable by) the root user

[Filters]
# ceilometer/ipmi/platform/ipmitool.py: 'ipmitool'
ipmitool: CommandFilter, ipmitool, root

privsep-rootwrap-sys_admin: RegExpFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, ceilometer.privsep.sys_admin_pctxt, --privsep_sock_path, /tmp/.*

+ 1
- 0
lower-constraints.txt View File

@@ -21,6 +21,7 @@ oslo.i18n==3.15.3
oslo.log==3.36.0
oslo.messaging==6.2.0
oslo.messaging[kafka]==6.2.0
oslo.privsep==1.32.0
oslo.reports==1.18.0
oslo.rootwrap==2.0.0
oslo.utils==3.37.0


+ 15
- 0
releasenotes/notes/switch-to-oslo-privsep-b58f20a279f31bc0.yaml View File

@@ -0,0 +1,15 @@
---
security:
- |
Privsep transitions. Ceilometer is transitioning from using the older
style rootwrap privilege escalation path to the new style Oslo privsep
path. This should improve performance and security of Ceilometer
in the long term.
- |
Privsep daemons are now started by Ceilometer when required. These
daemons can be started via rootwrap if required. rootwrap configs
therefore need to be updated to include new privsep daemon invocations.
upgrade:
- |
The following commands are no longer required to be listed in your rootwrap
configuration: ipmitool.

+ 1
- 0
requirements.txt View File

@@ -19,6 +19,7 @@ oslo.rootwrap>=2.0.0 # Apache-2.0
pbr>=2.0.0 # Apache-2.0
oslo.messaging>=6.2.0 # Apache-2.0
oslo.utils>=3.37.0 # Apache-2.0
oslo.privsep>=1.32.0 # Apache-2.0
pysnmp<5.0.0,>=4.2.3 # BSD
python-glanceclient>=2.8.0 # Apache-2.0
python-keystoneclient>=3.15.0 # Apache-2.0


Loading…
Cancel
Save