Adds PolicyActionHold so an admin can suspend specific actions on a computer without editing the policy itself, covering the break-glass case where a machine must be quiesced immediately. Holds cover multiple actions in one atomic submission rather than one row per action, so a partial failure cannot leave a half-applied hold. Duration is free-form with 0 meaning indefinite (migration 0006 makes expiresat nullable); the prior fixed ceiling was removed because an admin quiescing a misbehaving machine does not know in advance how long it needs, and a hold silently expiring is worse than one that must be cleared deliberately. The What This Does explainer reflects indefinite holds. collect_now exemption: refreshing status was denied on any endpoint with a non-empty effective policy even when the caller held the matching grant, because policy intersection silently removed the action. collect_now is a read-only status refresh with no side effects, so it now sits in POLICY_EXEMPT_ACTIONS alongside the other routine actions. Verified against a synthetic non-empty policy: operators can refresh status again while every write action stays gated.
40 lines
856 B
Python
40 lines
856 B
Python
"""Computers plugin models."""
|
|
|
|
from .computer import (
|
|
Computer,
|
|
ComputerType,
|
|
ComputerInstalledApp,
|
|
AccessProtocol,
|
|
ComputerAccess,
|
|
)
|
|
from .policy import (
|
|
ConfigurationPolicy,
|
|
ConfigurationPolicyAction,
|
|
BusinessPolicy,
|
|
BusinessPolicyItem,
|
|
POLICY_SOURCE_LOCAL,
|
|
POLICY_SOURCE_SHIPPED,
|
|
ACTION_MODE_DESIRED,
|
|
ACTION_MODE_GATE,
|
|
PolicyActionHold,
|
|
DEFAULT_HOLD_MINUTES,
|
|
)
|
|
|
|
__all__ = [
|
|
'Computer',
|
|
'ComputerType',
|
|
'ComputerInstalledApp',
|
|
'AccessProtocol',
|
|
'ComputerAccess',
|
|
'ConfigurationPolicy',
|
|
'ConfigurationPolicyAction',
|
|
'BusinessPolicy',
|
|
'BusinessPolicyItem',
|
|
'POLICY_SOURCE_LOCAL',
|
|
'POLICY_SOURCE_SHIPPED',
|
|
'ACTION_MODE_DESIRED',
|
|
'ACTION_MODE_GATE',
|
|
'PolicyActionHold',
|
|
'DEFAULT_HOLD_MINUTES',
|
|
]
|