Fleet console gap closures: critical tile, filters, policy card, action placement
This commit is contained in:
@@ -397,3 +397,51 @@ def get_effective_policy(asset_id: int):
|
||||
from ..services.policyresolver import effective_policy_for
|
||||
effective = effective_policy_for(asset_id)
|
||||
return success_response(effective.to_dict())
|
||||
|
||||
|
||||
@computers_bp.route('/asset/<int:asset_id>/policypanel', methods=['GET'])
|
||||
@require_permission('computers.view')
|
||||
def policy_panel(asset_id: int):
|
||||
"""Keyvalue panel: which policy governs this endpoint, and what it allows.
|
||||
|
||||
Provenance, not a control. It matters because the effective policy already
|
||||
narrows the command allowlist, so it is the answer to "why is Start greyed
|
||||
out on this PC" - which is otherwise invisible.
|
||||
|
||||
Returns an EMPTY field list rather than the feature-gate 404 when the
|
||||
feature is off. The panel contract hides a card with no fields; an error
|
||||
would render a broken card on every site that has not enabled policies,
|
||||
which is most of them.
|
||||
"""
|
||||
if not policy_flag_enabled():
|
||||
return success_response({'fields': []})
|
||||
|
||||
from ..services.policyresolver import effective_policy_for
|
||||
effective = effective_policy_for(asset_id)
|
||||
actions = effective.to_dict()
|
||||
if not actions:
|
||||
return success_response({'fields': []})
|
||||
|
||||
# One endpoint resolves through one winning business policy, but read the
|
||||
# ids off the actions rather than assuming: a fold can draw from more than
|
||||
# one configuration policy.
|
||||
businesspolicyids = {a['businesspolicyid'] for a in actions.values()
|
||||
if a.get('businesspolicyid')}
|
||||
configpolicyids = {a['configurationpolicyid'] for a in actions.values()
|
||||
if a.get('configurationpolicyid')}
|
||||
|
||||
names = []
|
||||
if businesspolicyids:
|
||||
names = [p.name for p in BusinessPolicy.query
|
||||
.filter(BusinessPolicy.businesspolicyid.in_(businesspolicyids)).all()]
|
||||
|
||||
gated = sum(1 for a in actions.values() if a.get('mode') == ACTION_MODE_GATE)
|
||||
desired = sum(1 for a in actions.values() if a.get('mode') == ACTION_MODE_DESIRED)
|
||||
|
||||
fields = []
|
||||
if names:
|
||||
fields.append({'label': 'Policy', 'value': ', '.join(sorted(names))})
|
||||
fields.append({'label': 'Configuration policies', 'value': str(len(configpolicyids))})
|
||||
fields.append({'label': 'Allowed actions', 'value': str(gated)})
|
||||
fields.append({'label': 'Desired state', 'value': str(desired)})
|
||||
return success_response({'fields': fields})
|
||||
|
||||
Reference in New Issue
Block a user