[Bug]: deltaproxy ignores proxy_merge_pillar_in_opts, and drops a proxymodule module_executors declaration for sub-proxies
- Dominant language
- Python
- Stars
- 15.7k
- Forks
- 5.6k
- Avg merge
- 2d 44m
- Merged PRs (30d)
- 80
Description
Description
Two places where deltaproxy's proxy setup diverges from the single-proxy metaproxy.
1. The control proxy's pillar is merged into opts unconditionally, ignoring proxy_merge_pillar_in_opts.
salt/metaproxy/proxy.py guards the merge:
if self.opts.get("proxy_merge_pillar_in_opts"):
# Override proxy opts with pillar data when the user required. But do
# not override master in opts.
pillar = copy.deepcopy(self.opts["pillar"])
...
elif self.opts.get("proxy_mines_pillar"):
salt/metaproxy/deltaproxy.py has no guard -- it always merges, then evaluates proxy_mines_pillar as a separate if. So the documented option (default False) has no effect and the control proxy's pillar always overrides its opts.
This does not stop at the control proxy. Sub-proxy opts begin as a copy of the control proxy's opts (proxyopts = opts.copy() in subproxy_post_master_init), so anything the control proxy's pillar injected into opts is inherited by every sub-proxy.
2. A proxymodule's module_executors declaration is ignored for sub-proxies.
post_master_init reads it for the control proxy:
self.module_executors = self.proxy.get(
f"{fq_proxyname}.module_executors", lambda: []
)()
subproxy_post_master_init never sets it, so when thread_return does getattr(minion_instance, "module_executors", []) the attribute is missing and it falls through to the opts default. The single-proxy metaproxy honours the declaration.
Setup
salt 3008.2, one control proxy dpcontrol with three sub-proxies using the dummy proxytype.
Steps to reproduce -- 1
Put a plain key in the control proxy's pillar and leave proxy_merge_pillar_in_opts unset:
# control proxy pillar
proxy:
proxytype: deltaproxy
ids: [minion1, minion2, minion3]
n_marker: LEAKED_FROM_PILLAR
Then read it back from opts only:
salt dpcontrol config.get n_marker omit_pillar=True
salt minion1 config.get n_marker omit_pillar=True
salt minion2 config.get n_marker omit_pillar=True
Observed: all three return LEAKED_FROM_PILLAR, so the pillar key became an opts key on the control proxy and on every sub-proxy.
Expected: empty, since proxy_merge_pillar_in_opts is not set. With it set to True the merge should happen, as it does for a single proxy.
Steps to reproduce -- 2
Give the proxymodule a module_executors function:
def module_executors():
return ["direct_call"]
Instrumenting thread_return to report what it resolved shows the attribute is absent on every sub-proxy:
id=minion1 has_attr=False value='<MISSING>'
id=minion2 has_attr=False value='<MISSING>'
id=minion3 has_attr=False value='<MISSING>'
Expected: the sub-proxies pick up the proxymodule's declaration, as the control proxy and the single-proxy metaproxy do.
Versions Report
Salt Version:
Salt: 3008.2
Python Version:
Python: 3.10
Salt Package Information:
Package Type: onedir
Both reproduce against the current 3008.x branch head.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Compare salt/metaproxy/deltaproxy.py with salt/metaproxy/proxy.py, starting at subproxy_post_master_init, post_master_init, and thread_return. Verify the relevant deltaproxy tests or reproduction setup, then confirm that proxy_merge_pillar_in_opts controls the merge and that sub-proxies honor the proxymodule's module_executors declaration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devops, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100