179 lines
7.5 KiB
Diff
179 lines
7.5 KiB
Diff
From 483f79cb3b94c8c7d176e748892a040c71132cb3 Mon Sep 17 00:00:00 2001
|
|
From: Chad Smith <chad.smith@canonical.com>
|
|
Date: Sat, 4 Feb 2023 13:37:02 -0700
|
|
Subject: [PATCH] netplan: keep custom strict perms when 50-cloud-init.yaml
|
|
exists
|
|
|
|
Retain existing config file permissions when those permissions are
|
|
more strict than the default permissions set on
|
|
/etc/netplan/50-cloud-init.yaml.
|
|
---
|
|
cloudinit/net/netplan.py | 5 ++
|
|
.../unittests/test_distros/test_netconfig.py | 74 ++++++++++++-------
|
|
2 files changed, 53 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py
|
|
index 6bb2cb5..894b5db 100644
|
|
--- a/cloudinit/net/netplan.py
|
|
+++ b/cloudinit/net/netplan.py
|
|
@@ -237,6 +237,11 @@ class Renderer(renderer.Renderer):
|
|
header += "\n"
|
|
|
|
mode = 0o600 if features.NETPLAN_CONFIG_ROOT_READ_ONLY else 0o644
|
|
+ if os.path.exists(fpnplan):
|
|
+ current_mode = util.get_permissions(fpnplan)
|
|
+ if current_mode & mode == current_mode:
|
|
+ # preserve mode if existing perms are more strict than default
|
|
+ mode = current_mode
|
|
util.write_file(fpnplan, header + content, mode=mode)
|
|
|
|
if self.clean_default:
|
|
diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py
|
|
index bae2dc4..97659c4 100644
|
|
--- a/tests/unittests/test_distros/test_netconfig.py
|
|
+++ b/tests/unittests/test_distros/test_netconfig.py
|
|
@@ -391,7 +391,6 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
|
|
expected_cfgs = {
|
|
self.eni_path(): V1_NET_CFG_OUTPUT,
|
|
}
|
|
- # ub_distro.apply_network_config(V1_NET_CFG, False)
|
|
self._apply_and_verify_eni(self.distro.apply_network_config,
|
|
V1_NET_CFG,
|
|
expected_cfgs=expected_cfgs.copy())
|
|
@@ -411,8 +410,14 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase):
|
|
self.distro = self._get_distro('ubuntu', renderers=['netplan'])
|
|
self.devlist = ['eth0', 'lo']
|
|
|
|
- def _apply_and_verify_netplan(self, apply_fn, config, expected_cfgs=None,
|
|
- bringup=False):
|
|
+ def _apply_and_verify_netplan(
|
|
+ self,
|
|
+ apply_fn,
|
|
+ config,
|
|
+ expected_cfgs=None,
|
|
+ bringup=False,
|
|
+ previous_files=(),
|
|
+ ):
|
|
if not expected_cfgs:
|
|
raise ValueError('expected_cfg must not be None')
|
|
|
|
@@ -422,12 +427,12 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase):
|
|
with mock.patch("cloudinit.net.netplan.get_devicelist",
|
|
return_value=self.devlist):
|
|
with self.reRooted(tmpd) as tmpd:
|
|
+ for previous_path, content, mode in previous_files:
|
|
+ util.write_file(previous_path, content, mode=mode)
|
|
apply_fn(config, bringup)
|
|
|
|
results = dir2dict(tmpd)
|
|
-
|
|
- mode = 0o600 if features.NETPLAN_CONFIG_ROOT_READ_ONLY else 0o644
|
|
- for cfgpath, expected in expected_cfgs.items():
|
|
+ for cfgpath, expected, mode in expected_cfgs:
|
|
print("----------")
|
|
print(expected)
|
|
print("^^^^ expected | rendered VVVVVVV")
|
|
@@ -440,39 +445,56 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase):
|
|
return '/etc/netplan/50-cloud-init.yaml'
|
|
|
|
def test_apply_network_config_v1_to_netplan_ub(self):
|
|
- expected_cfgs = {
|
|
- self.netplan_path(): V1_TO_V2_NET_CFG_OUTPUT,
|
|
- }
|
|
+ expected_cfgs = (
|
|
+ (self.netplan_path(), V1_TO_V2_NET_CFG_OUTPUT, 0o600),
|
|
+ )
|
|
|
|
- # ub_distro.apply_network_config(V1_NET_CFG, False)
|
|
self._apply_and_verify_netplan(self.distro.apply_network_config,
|
|
V1_NET_CFG,
|
|
- expected_cfgs=expected_cfgs.copy())
|
|
+ expected_cfgs=expected_cfgs)
|
|
|
|
def test_apply_network_config_v1_ipv6_to_netplan_ub(self):
|
|
- expected_cfgs = {
|
|
- self.netplan_path(): V1_TO_V2_NET_CFG_IPV6_OUTPUT,
|
|
- }
|
|
+ expected_cfgs = (
|
|
+ (self.netplan_path(), V1_TO_V2_NET_CFG_IPV6_OUTPUT, 0o600),
|
|
+ )
|
|
|
|
- # ub_distro.apply_network_config(V1_NET_CFG_IPV6, False)
|
|
self._apply_and_verify_netplan(self.distro.apply_network_config,
|
|
V1_NET_CFG_IPV6,
|
|
- expected_cfgs=expected_cfgs.copy())
|
|
+ expected_cfgs=expected_cfgs)
|
|
|
|
def test_apply_network_config_v2_passthrough_ub(self):
|
|
- expected_cfgs = {
|
|
- self.netplan_path(): V2_TO_V2_NET_CFG_OUTPUT,
|
|
- }
|
|
- # ub_distro.apply_network_config(V2_NET_CFG, False)
|
|
+ expected_cfgs = (
|
|
+ (self.netplan_path(), V2_TO_V2_NET_CFG_OUTPUT, 0o600),
|
|
+ )
|
|
self._apply_and_verify_netplan(self.distro.apply_network_config,
|
|
V2_NET_CFG,
|
|
- expected_cfgs=expected_cfgs.copy())
|
|
+ expected_cfgs=expected_cfgs)
|
|
+
|
|
+ def test_apply_network_config_v2_passthrough_retain_orig_perms(self):
|
|
+ """Custom permissions on existing netplan is kept when more strict."""
|
|
+ expected_cfgs = (
|
|
+ (self.netplan_path(), V2_TO_V2_NET_CFG_OUTPUT, 0o640),
|
|
+ )
|
|
+ with mock.patch.object(
|
|
+ features, "NETPLAN_CONFIG_ROOT_READ_ONLY", False
|
|
+ ):
|
|
+ # When NETPLAN_CONFIG_ROOT_READ_ONLY is False default perms are 644
|
|
+ # we keep 640 because it's more strict.
|
|
+ # 1640 is used to assert sticky bit preserved across write
|
|
+ self._apply_and_verify_netplan(
|
|
+ self.distro.apply_network_config,
|
|
+ V2_NET_CFG,
|
|
+ expected_cfgs=expected_cfgs,
|
|
+ previous_files=(
|
|
+ ("/etc/netplan/50-cloud-init.yaml", "a", 0o640),
|
|
+ ),
|
|
+ )
|
|
|
|
def test_apply_network_config_v2_passthrough_ub_old_behavior(self):
|
|
"""Kinetic and earlier have 50-cloud-init.yaml world-readable"""
|
|
- expected_cfgs = {
|
|
- self.netplan_path(): V2_TO_V2_NET_CFG_OUTPUT,
|
|
- }
|
|
+ expected_cfgs = (
|
|
+ (self.netplan_path(), V2_TO_V2_NET_CFG_OUTPUT, 0o644),
|
|
+ )
|
|
# ub_distro.apply_network_config(V2_NET_CFG, False)
|
|
with mock.patch.object(
|
|
features, "NETPLAN_CONFIG_ROOT_READ_ONLY", False
|
|
@@ -480,7 +502,7 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase):
|
|
self._apply_and_verify_netplan(
|
|
self.distro.apply_network_config,
|
|
V2_NET_CFG,
|
|
- expected_cfgs=expected_cfgs.copy(),
|
|
+ expected_cfgs=expected_cfgs,
|
|
)
|
|
|
|
class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
@@ -771,7 +793,6 @@ class TestNetCfgDistroArch(TestNetCfgDistroBase):
|
|
"""),
|
|
}
|
|
|
|
- # ub_distro.apply_network_config(V1_NET_CFG, False)
|
|
self._apply_and_verify(self.distro.apply_network_config,
|
|
V1_NET_CFG,
|
|
expected_cfgs=expected_cfgs.copy(),
|
|
@@ -920,6 +941,7 @@ class TestNetCfgDistroPhoton(TestNetCfgDistroBase):
|
|
|
|
|
|
def get_mode(path, target=None):
|
|
+ # Mask upper st_mode bits like S_IFREG bit preserve sticky and isuid/osgid
|
|
return os.stat(subp.target_path(target, path)).st_mode & 0o777
|
|
|
|
# vi: ts=4 expandtab
|
|
--
|
|
2.33.0
|
|
|