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
This commit is contained in:
parent
5f1abadf76
commit
bd0d5a8a27
@ -14,13 +14,17 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import shlex
|
||||||
|
|
||||||
import cotyledon
|
import cotyledon
|
||||||
from cotyledon import oslo_config_glue
|
from cotyledon import oslo_config_glue
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
from oslo_privsep import priv_context
|
||||||
|
|
||||||
from ceilometer.polling import manager
|
from ceilometer.polling import manager
|
||||||
from ceilometer import service
|
from ceilometer import service
|
||||||
|
from ceilometer import utils
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
@ -78,6 +82,7 @@ def main():
|
|||||||
conf = cfg.ConfigOpts()
|
conf = cfg.ConfigOpts()
|
||||||
conf.register_cli_opts(CLI_OPTS)
|
conf.register_cli_opts(CLI_OPTS)
|
||||||
service.prepare_service(conf=conf)
|
service.prepare_service(conf=conf)
|
||||||
|
priv_context.init(root_helper=shlex.split(utils._get_root_helper()))
|
||||||
sm = cotyledon.ServiceManager()
|
sm = cotyledon.ServiceManager()
|
||||||
sm.add(create_polling_service, args=(conf,))
|
sm.add(create_polling_service, args=(conf,))
|
||||||
oslo_config_glue.setup(sm, conf)
|
oslo_config_glue.setup(sm, conf)
|
||||||
|
@ -17,7 +17,8 @@ from oslo_concurrency import processutils
|
|||||||
|
|
||||||
from ceilometer.i18n import _
|
from ceilometer.i18n import _
|
||||||
from ceilometer.ipmi.platform import exception as ipmiexcept
|
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
|
# 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)
|
command = f(self, **kwargs)
|
||||||
args.extend(command.split(" "))
|
args.extend(command.split(" "))
|
||||||
try:
|
try:
|
||||||
(out, __) = utils.execute(*args, run_as_root=True)
|
(out, __) = ceilometer.privsep.ipmitool.ipmi(*args)
|
||||||
except processutils.ProcessExecutionError:
|
except processutils.ProcessExecutionError:
|
||||||
raise ipmiexcept.IPMIException(_("running ipmitool failure"))
|
raise ipmiexcept.IPMIException(_("running ipmitool failure"))
|
||||||
return _parse_output(out, template)
|
return _parse_output(out, template)
|
||||||
|
29
ceilometer/privsep/__init__.py
Normal file
29
ceilometer/privsep/__init__.py
Normal 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
ceilometer/privsep/ipmitool.py
Normal file
25
ceilometer/privsep/ipmitool.py
Normal 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)
|
@ -20,9 +20,9 @@ from oslotest import base
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from ceilometer.ipmi.platform import intel_node_manager as node_manager
|
from ceilometer.ipmi.platform import intel_node_manager as node_manager
|
||||||
|
from ceilometer.privsep import ipmitool
|
||||||
from ceilometer import service
|
from ceilometer import service
|
||||||
from ceilometer.tests.unit.ipmi.platform import fake_utils
|
from ceilometer.tests.unit.ipmi.platform import fake_utils
|
||||||
from ceilometer import utils
|
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
@ -56,7 +56,7 @@ class _Base(base.BaseTestCase):
|
|||||||
class TestNodeManagerV3(_Base):
|
class TestNodeManagerV3(_Base):
|
||||||
|
|
||||||
def init_test_engine(self):
|
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):
|
def test_read_airflow(self):
|
||||||
airflow = self.nm.read_airflow()
|
airflow = self.nm.read_airflow()
|
||||||
@ -110,7 +110,7 @@ class TestNodeManagerV3(_Base):
|
|||||||
class TestNodeManager(_Base):
|
class TestNodeManager(_Base):
|
||||||
|
|
||||||
def init_test_engine(self):
|
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):
|
def test_read_power_all(self):
|
||||||
power = self.nm.read_power_all()
|
power = self.nm.read_power_all()
|
||||||
@ -162,7 +162,7 @@ class TestNodeManager(_Base):
|
|||||||
class TestNonNodeManager(_Base):
|
class TestNonNodeManager(_Base):
|
||||||
|
|
||||||
def init_test_engine(self):
|
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):
|
def test_read_power_all(self):
|
||||||
# no NM support
|
# no NM support
|
||||||
|
@ -16,8 +16,8 @@ import mock
|
|||||||
from oslotest import base
|
from oslotest import base
|
||||||
|
|
||||||
from ceilometer.ipmi.platform import ipmi_sensor
|
from ceilometer.ipmi.platform import ipmi_sensor
|
||||||
|
from ceilometer.privsep import ipmitool
|
||||||
from ceilometer.tests.unit.ipmi.platform import fake_utils
|
from ceilometer.tests.unit.ipmi.platform import fake_utils
|
||||||
from ceilometer import utils
|
|
||||||
|
|
||||||
|
|
||||||
class TestIPMISensor(base.BaseTestCase):
|
class TestIPMISensor(base.BaseTestCase):
|
||||||
@ -25,7 +25,7 @@ class TestIPMISensor(base.BaseTestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestIPMISensor, self).setUp()
|
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()
|
self.ipmi = ipmi_sensor.IPMISensor()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -93,7 +93,7 @@ class TestNonIPMISensor(base.BaseTestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestNonIPMISensor, self).setUp()
|
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()
|
self.ipmi = ipmi_sensor.IPMISensor()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from oslo_concurrency import processutils
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
ROOTWRAP_CONF = "/etc/ceilometer/rootwrap.conf"
|
ROOTWRAP_CONF = "/etc/ceilometer/rootwrap.conf"
|
||||||
@ -43,13 +42,6 @@ def setup_root_helper(conf):
|
|||||||
ROOTWRAP_CONF = conf.rootwrap_config
|
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):
|
def spawn_thread(target, *args, **kwargs):
|
||||||
t = threading.Thread(target=target, args=args, kwargs=kwargs)
|
t = threading.Thread(target=target, args=args, kwargs=kwargs)
|
||||||
t.daemon = True
|
t.daemon = True
|
||||||
|
@ -2,6 +2,4 @@
|
|||||||
# This file should be owned by (and only-writeable by) the root user
|
# This file should be owned by (and only-writeable by) the root user
|
||||||
|
|
||||||
[Filters]
|
[Filters]
|
||||||
# ceilometer/ipmi/platform/ipmitool.py: 'ipmitool'
|
privsep-rootwrap-sys_admin: RegExpFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, ceilometer.privsep.sys_admin_pctxt, --privsep_sock_path, /tmp/.*
|
||||||
ipmitool: CommandFilter, ipmitool, root
|
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ oslo.i18n==3.15.3
|
|||||||
oslo.log==3.36.0
|
oslo.log==3.36.0
|
||||||
oslo.messaging==6.2.0
|
oslo.messaging==6.2.0
|
||||||
oslo.messaging[kafka]==6.2.0
|
oslo.messaging[kafka]==6.2.0
|
||||||
|
oslo.privsep==1.32.0
|
||||||
oslo.reports==1.18.0
|
oslo.reports==1.18.0
|
||||||
oslo.rootwrap==2.0.0
|
oslo.rootwrap==2.0.0
|
||||||
oslo.utils==3.37.0
|
oslo.utils==3.37.0
|
||||||
|
@ -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.
|
@ -19,6 +19,7 @@ oslo.rootwrap>=2.0.0 # Apache-2.0
|
|||||||
pbr>=2.0.0 # Apache-2.0
|
pbr>=2.0.0 # Apache-2.0
|
||||||
oslo.messaging>=6.2.0 # Apache-2.0
|
oslo.messaging>=6.2.0 # Apache-2.0
|
||||||
oslo.utils>=3.37.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
|
pysnmp<5.0.0,>=4.2.3 # BSD
|
||||||
python-glanceclient>=2.8.0 # Apache-2.0
|
python-glanceclient>=2.8.0 # Apache-2.0
|
||||||
python-keystoneclient>=3.15.0 # Apache-2.0
|
python-keystoneclient>=3.15.0 # Apache-2.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user