138 lines
4.3 KiB
PHP
138 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Operations\Actionability;
|
|
|
|
use App\Support\OperationCatalog;
|
|
|
|
final class OperationRunActionabilityRegistry
|
|
{
|
|
/**
|
|
* @return array<string, OperationRunActionabilityPolicyDefinition>
|
|
*/
|
|
public function definitions(): array
|
|
{
|
|
$definitions = [];
|
|
|
|
$add = static function (OperationRunActionabilityPolicyDefinition $definition) use (&$definitions): void {
|
|
$definitions[$definition->canonicalType] = $definition;
|
|
};
|
|
|
|
$add(new OperationRunActionabilityPolicyDefinition(
|
|
canonicalType: 'provider.connection.check',
|
|
policyIdentifier: 'provider_connection_check_current_state_v1',
|
|
kind: 'provider_connection',
|
|
supersededByCanonicalTypes: ['provider.connection.check'],
|
|
matchContextKeys: ['provider_connection_id', 'provider'],
|
|
));
|
|
|
|
foreach ([
|
|
'inventory.sync',
|
|
'policy.sync',
|
|
'policy.snapshot',
|
|
'policy.export',
|
|
'directory.groups.sync',
|
|
'directory.role_definitions.sync',
|
|
'compliance.snapshot',
|
|
'permission.posture.check',
|
|
'entra.admin_roles.scan',
|
|
'rbac.health_check',
|
|
'tenant.sync',
|
|
'assignments.fetch',
|
|
'alerts.evaluate',
|
|
'alerts.deliver',
|
|
'ops.reconcile_adapter_runs',
|
|
] as $type) {
|
|
$add(new OperationRunActionabilityPolicyDefinition(
|
|
canonicalType: $type,
|
|
policyIdentifier: 'repeatable_later_success_v1',
|
|
kind: 'repeatable',
|
|
supersededByCanonicalTypes: [$type],
|
|
matchContextKeys: ['selection_hash', 'provider_connection_id', 'provider'],
|
|
));
|
|
}
|
|
|
|
foreach ([
|
|
'baseline.capture',
|
|
'baseline.compare',
|
|
'tenant.evidence.snapshot.generate',
|
|
'environment.review.compose',
|
|
'environment.review_pack.generate',
|
|
'backup_set.update',
|
|
'backup.schedule.execute',
|
|
'backup.schedule.retention',
|
|
] as $type) {
|
|
$add(new OperationRunActionabilityPolicyDefinition(
|
|
canonicalType: $type,
|
|
policyIdentifier: 'artifact_or_later_success_v1',
|
|
kind: 'artifact_or_later_success',
|
|
supersededByCanonicalTypes: [$type],
|
|
matchContextKeys: ['baseline_profile_id', 'backup_set_id', 'backup_schedule_id', 'selection_hash'],
|
|
));
|
|
}
|
|
|
|
foreach ([
|
|
'policy.delete',
|
|
'policy.restore',
|
|
'backup_set.archive',
|
|
'backup_set.restore',
|
|
'backup_set.delete',
|
|
'backup.schedule.purge',
|
|
'restore.execute',
|
|
'promotion.execute',
|
|
'assignments.restore',
|
|
'restore_run.delete',
|
|
'restore_run.restore',
|
|
'restore_run.force_delete',
|
|
'policy_version.prune',
|
|
'policy_version.restore',
|
|
'policy_version.force_delete',
|
|
] as $type) {
|
|
$add(new OperationRunActionabilityPolicyDefinition(
|
|
canonicalType: $type,
|
|
policyIdentifier: 'high_risk_manual_review_v1',
|
|
kind: 'manual_review',
|
|
));
|
|
}
|
|
|
|
return $definitions;
|
|
}
|
|
|
|
public function forCanonicalType(string $canonicalType): ?OperationRunActionabilityPolicyDefinition
|
|
{
|
|
return $this->definitions()[$canonicalType] ?? null;
|
|
}
|
|
|
|
/**
|
|
* @return list<string>
|
|
*/
|
|
public function coveredCanonicalTypes(): array
|
|
{
|
|
return array_values(array_unique(array_keys($this->definitions())));
|
|
}
|
|
|
|
/**
|
|
* @return list<string>
|
|
*/
|
|
public function uncoveredCanonicalTypes(): array
|
|
{
|
|
return array_values(array_diff(
|
|
array_keys(OperationCatalog::canonicalInventory()),
|
|
$this->coveredCanonicalTypes(),
|
|
));
|
|
}
|
|
|
|
/**
|
|
* @return list<string>
|
|
*/
|
|
public function canonicalTypesWithLaterSuccessPolicy(): array
|
|
{
|
|
return collect($this->definitions())
|
|
->flatMap(static fn (OperationRunActionabilityPolicyDefinition $definition): array => $definition->supersededByCanonicalTypes)
|
|
->unique()
|
|
->values()
|
|
->all();
|
|
}
|
|
}
|